|
19 | 19 | import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
|
20 | 20 | import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
|
21 | 21 | import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
|
| 22 | +import org.bouncycastle.cms.jcajce.JceKeyAgreeEnvelopedRecipient; |
22 | 23 | import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
|
| 24 | + |
23 | 25 | import org.bouncycastle.cms.jcajce.ZlibCompressor;
|
24 | 26 | import org.bouncycastle.cms.jcajce.ZlibExpanderProvider;
|
25 | 27 | import org.bouncycastle.crypto.util.PrivateKeyFactory;
|
@@ -198,62 +200,67 @@ public String calculateMIC(MimeBodyPart part, String digest, boolean includeHead
|
198 | 200 | return micResult.toString();
|
199 | 201 | }
|
200 | 202 |
|
201 |
| - public MimeBodyPart decrypt(MimeBodyPart part, Certificate cert, Key key) throws GeneralSecurityException, MessagingException, CMSException, IOException, SMIMEException { |
202 |
| - // Make sure the data is encrypted |
| 203 | + public MimeBodyPart decrypt(MimeBodyPart part, Certificate cert, Key key) |
| 204 | + throws GeneralSecurityException, MessagingException, CMSException, IOException, SMIMEException { |
| 205 | + |
203 | 206 | if (!isEncrypted(part)) {
|
204 | 207 | throw new GeneralSecurityException("Content-Type indicates data isn't encrypted");
|
205 | 208 | }
|
206 | 209 |
|
207 |
| - // Cast parameters to what BC needs |
208 | 210 | X509Certificate x509Cert = castCertificate(cert);
|
209 |
| - |
210 |
| - // Parse the MIME body into an SMIME envelope object |
211 | 211 | SMIMEEnveloped envelope = new SMIMEEnveloped(part);
|
212 |
| - |
213 |
| - // Get the recipient object for decryption |
214 |
| - if (logger.isDebugEnabled()) { |
215 |
| - logger.debug("Extracted X500 info:: PRINCIPAL : " + x509Cert.getIssuerX500Principal() + " :: NAME : " + x509Cert.getIssuerX500Principal().getName()); |
216 |
| - } |
217 |
| - |
218 | 212 | X500Name x500Name = new X500Name(x509Cert.getIssuerX500Principal().getName());
|
219 |
| - KeyTransRecipientId certRecId = new KeyTransRecipientId(x500Name, x509Cert.getSerialNumber()); |
220 | 213 | RecipientInformationStore recipientInfoStore = envelope.getRecipientInfos();
|
221 |
| - |
222 | 214 | Collection<RecipientInformation> recipients = recipientInfoStore.getRecipients();
|
223 | 215 |
|
224 | 216 | if (recipients == null) {
|
225 | 217 | throw new GeneralSecurityException("Certificate recipients could not be extracted from the inbound message envelope.");
|
226 | 218 | }
|
227 |
| - //RecipientInformation recipientInfo = recipientInfoStore.get(recId); |
228 |
| - //Object recipient = null; |
229 | 219 |
|
230 | 220 | boolean foundRecipient = false;
|
231 |
| - for (Iterator<RecipientInformation> iterator = recipients.iterator(); iterator.hasNext(); ) { |
232 |
| - RecipientInformation recipientInfo = iterator.next(); |
233 |
| - //recipient = iterator.next(); |
234 |
| - if (recipientInfo instanceof KeyTransRecipientInformation) { |
235 |
| - // X509CertificateHolder x509CertHolder = new X509CertificateHolder(x509Cert.getEncoded()); |
| 221 | + for (RecipientInformation recipientInfo : recipients) { |
236 | 222 |
|
237 |
| - //RecipientId rid = recipientInfo.getRID(); |
| 223 | + if (recipientInfo instanceof KeyTransRecipientInformation && key.getAlgorithm().equalsIgnoreCase("RSA")) { |
| 224 | + KeyTransRecipientId certRecId = new KeyTransRecipientId(x500Name, x509Cert.getSerialNumber()); |
238 | 225 | if (certRecId.match(recipientInfo) && !foundRecipient) {
|
239 | 226 | foundRecipient = true;
|
240 |
| - // byte[] decryptedData = recipientInfo.getContent(new JceKeyTransEnvelopedRecipient((PrivateKey)key).setProvider("BC")); |
241 |
| - byte[] decryptedData = recipientInfo.getContent(new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey(PrivateKeyInfo.getInstance(key.getEncoded())))); |
| 227 | + byte[] decryptedData = recipientInfo.getContent( |
| 228 | + new BcRSAKeyTransEnvelopedRecipient(PrivateKeyFactory.createKey( |
| 229 | + PrivateKeyInfo.getInstance(key.getEncoded()))) |
| 230 | + ); |
| 231 | + return SMIMEUtil.toMimeBodyPart(decryptedData); |
| 232 | + } |
242 | 233 |
|
| 234 | + } else if (recipientInfo instanceof KeyAgreeRecipientInformation && key.getAlgorithm().equalsIgnoreCase("EC")) { |
| 235 | + KeyAgreeRecipientId certRecId = new KeyAgreeRecipientId(x500Name, x509Cert.getSerialNumber()); |
| 236 | + if (certRecId.match(recipientInfo) && !foundRecipient) { |
| 237 | + foundRecipient = true; |
| 238 | + byte[] decryptedData = recipientInfo.getContent( |
| 239 | + new JceKeyAgreeEnvelopedRecipient((PrivateKey) key).setProvider("BC") |
| 240 | + ); |
243 | 241 | return SMIMEUtil.toMimeBodyPart(decryptedData);
|
244 |
| - } else { |
245 |
| - if (logger.isDebugEnabled()) { |
246 |
| - logger.debug("Failed match on recipient ID's:: RID type from msg:" + recipientInfo.getRID().getType() + " RID type from priv cert: " + certRecId.getType()); |
247 |
| - } |
| 242 | + } |
| 243 | + } else { |
| 244 | + if (logger.isDebugEnabled()) { |
| 245 | + logger.debug("Failed match on recipient ID's:: RID type from msg: " |
| 246 | + + recipientInfo.getRID().getType() |
| 247 | + + " RID type from priv cert: " |
| 248 | + + (recipientInfo instanceof KeyTransRecipientInformation ? "0" : "2")); |
248 | 249 | }
|
249 | 250 | }
|
250 | 251 | }
|
251 |
| - throw new GeneralSecurityException( |
252 |
| - "Matching certificate recipient could not be found trying to decrypt the message." |
253 |
| - + " Either the sender has encrypted the message with a public key that does not match" |
254 |
| - + " a private key in your keystore or the there is a problem in your keystore where the private key has not been imported or is corrupt."); |
| 252 | + |
| 253 | + if (!foundRecipient) { |
| 254 | + throw new GeneralSecurityException( |
| 255 | + "Matching certificate recipient could not be found trying to decrypt the message." |
| 256 | + + " Either the sender has encrypted the message with a public key that does not match" |
| 257 | + + " a private key in your keystore or there is a problem in your keystore where the private key has not been imported or is corrupt."); |
| 258 | + } |
| 259 | + |
| 260 | + return null; |
255 | 261 | }
|
256 | 262 |
|
| 263 | + |
257 | 264 | public void deinitialize() {
|
258 | 265 | }
|
259 | 266 |
|
|
0 commit comments