S/MIME: fixed class cast exceptions

master
M66B 2 weeks ago
parent 0f56862661
commit 00da519046

@ -173,7 +173,10 @@ import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSProcessableFile; import org.bouncycastle.cms.CMSProcessableFile;
import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSTypedData; import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.KeyAgreeRecipientInformation;
import org.bouncycastle.cms.KeyTransRecipientInformation;
import org.bouncycastle.cms.PKIXRecipientId; import org.bouncycastle.cms.PKIXRecipientId;
import org.bouncycastle.cms.Recipient;
import org.bouncycastle.cms.RecipientInformation; import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore; import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.SignerId; import org.bouncycastle.cms.SignerId;
@ -181,6 +184,8 @@ import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.SignerInformationVerifier; import org.bouncycastle.cms.SignerInformationVerifier;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.cms.jcajce.JceKeyAgreeAuthEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransAuthEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransAuthEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; import org.bouncycastle.cms.jcajce.JceKeyTransRecipient;
@ -10645,21 +10650,18 @@ public class FragmentMessages extends FragmentBase
String contentAlgorithmOid; String contentAlgorithmOid;
String parserClass; String parserClass;
JceKeyTransRecipient recipient;
if (authEnveloped) { if (authEnveloped) {
CMSAuthEnvelopedDataParser parser = new CMSAuthEnvelopedDataParser(fis); CMSAuthEnvelopedDataParser parser = new CMSAuthEnvelopedDataParser(fis);
recipientStore = parser.getRecipientInfos(); recipientStore = parser.getRecipientInfos();
contentAlgorithm = parser.getEncryptionAlgOID(); contentAlgorithm = parser.getEncryptionAlgOID();
contentAlgorithmOid = parser.getEncAlgOID(); contentAlgorithmOid = parser.getEncAlgOID();
parserClass = parser.getClass().getName(); parserClass = parser.getClass().getName();
recipient = new JceKeyTransAuthEnvelopedRecipient(privkey);
} else { } else {
CMSEnvelopedDataParser parser = new CMSEnvelopedDataParser(fis); CMSEnvelopedDataParser parser = new CMSEnvelopedDataParser(fis);
recipientStore = parser.getRecipientInfos(); recipientStore = parser.getRecipientInfos();
contentAlgorithm = parser.getContentEncryptionAlgorithm(); contentAlgorithm = parser.getContentEncryptionAlgorithm();
contentAlgorithmOid = parser.getEncryptionAlgOID(); contentAlgorithmOid = parser.getEncryptionAlgOID();
parserClass = parser.getClass().getName(); parserClass = parser.getClass().getName();
recipient = new JceKeyTransEnvelopedRecipient(privkey);
} }
// Get recipient info // Get recipient info
@ -10668,8 +10670,7 @@ public class FragmentMessages extends FragmentBase
EntityLog.log(context, "s/mime private key" + EntityLog.log(context, "s/mime private key" +
" algo=" + privkey.getAlgorithm() + " algo=" + privkey.getAlgorithm() +
" serial=" + chain[0].getSerialNumber() + " serial=" + chain[0].getSerialNumber());
" class=" + recipient.getClass());
for (RecipientInformation recipientInfo : recipients) { for (RecipientInformation recipientInfo : recipients) {
String algo; String algo;
try { try {
@ -10713,6 +10714,7 @@ public class FragmentMessages extends FragmentBase
PKIXRecipientId recipientId = (PKIXRecipientId) recipientInfo.getRID(); PKIXRecipientId recipientId = (PKIXRecipientId) recipientInfo.getRID();
if (serialno != null && serialno.equals(recipientId.getSerialNumber())) { if (serialno != null && serialno.equals(recipientId.getSerialNumber())) {
try { try {
Recipient recipient = createRecipient(recipientInfo, authEnveloped, privkey);
InputStream is = recipientInfo.getContentStream(recipient).getContentStream(); InputStream is = recipientInfo.getContentStream(recipient).getContentStream();
decodeMessage(context, is, message, args); decodeMessage(context, is, message, args);
decoded = true; decoded = true;
@ -10722,9 +10724,6 @@ public class FragmentMessages extends FragmentBase
Log.w(ex); Log.w(ex);
last = ex; last = ex;
} catch (Throwable ex) { } catch (Throwable ex) {
// java.lang.ClassCastException: org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient cannot be cast to org.bouncycastle.cms.KeyAgreeRecipient
// at org.bouncycastle.cms.KeyAgreeRecipientInformation.getRecipientOperator(Unknown Source:1)
// at org.bouncycastle.cms.RecipientInformation.getContentStream(Unknown Source:0)
Log.e(ex); Log.e(ex);
last = ex; last = ex;
} }
@ -10736,6 +10735,7 @@ public class FragmentMessages extends FragmentBase
if (count < list.size()) { if (count < list.size()) {
RecipientInformation recipientInfo = list.get(count); RecipientInformation recipientInfo = list.get(count);
try { try {
Recipient recipient = createRecipient(recipientInfo, authEnveloped, privkey);
InputStream is = recipientInfo.getContentStream(recipient).getContentStream(); InputStream is = recipientInfo.getContentStream(recipient).getContentStream();
decodeMessage(context, is, message, args); decodeMessage(context, is, message, args);
decoded = true; decoded = true;
@ -10744,9 +10744,6 @@ public class FragmentMessages extends FragmentBase
Log.w(ex); Log.w(ex);
last = ex; last = ex;
} catch (Throwable ex) { } catch (Throwable ex) {
// java.lang.ClassCastException: org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient cannot be cast to org.bouncycastle.cms.KeyAgreeRecipient
// at org.bouncycastle.cms.KeyAgreeRecipientInformation.getRecipientOperator(Unknown Source:1)
// at org.bouncycastle.cms.RecipientInformation.getContentStream(Unknown Source:0)
Log.e(ex); Log.e(ex);
last = ex; last = ex;
} }
@ -11000,6 +10997,20 @@ public class FragmentMessages extends FragmentBase
} }
} }
private static Recipient createRecipient(RecipientInformation info, boolean authEnveloped, PrivateKey privateKey) throws CMSException {
if (info instanceof KeyTransRecipientInformation)
return (authEnveloped
? new JceKeyTransAuthEnvelopedRecipient(privateKey)
: new JceKeyTransEnvelopedRecipient(privateKey));
if (info instanceof KeyAgreeRecipientInformation)
return (authEnveloped
? new JceKeyAgreeAuthEnvelopedRecipient(privateKey)
: new JceKeyAgreeEnvelopedRecipient(privateKey));
throw new CMSException("Unsupported recipient type: " + info.getClass().getName());
}
private void decodeMessage(Context context, InputStream is, EntityMessage message, Bundle args) throws MessagingException, IOException { private void decodeMessage(Context context, InputStream is, EntityMessage message, Bundle args) throws MessagingException, IOException {
int type = args.getInt("type"); int type = args.getInt("type");
String alias = args.getString("alias"); String alias = args.getString("alias");
@ -11013,6 +11024,11 @@ public class FragmentMessages extends FragmentBase
MessageHelper.MessageParts parts = helper.getMessageParts(); MessageHelper.MessageParts parts = helper.getMessageParts();
String protect_subject = parts.getProtectedSubject(); String protect_subject = parts.getProtectedSubject();
// Ensure stream is read to the end to check AEAD tag
byte[] buffer = new byte[Helper.BUFFER_SIZE];
while (is.read(buffer) != -1)
;
// Write decrypted body // Write decrypted body
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean debug = prefs.getBoolean("debug", false); boolean debug = prefs.getBoolean("debug", false);

Loading…
Cancel
Save