use of org.bouncycastle.cms.RecipientId in project nhin-d by DirectProject.
the class SMIMECryptographerImpl method decrypt.
/**
* Decrypts an entity with the provided certificates' private key.
* @param encryptedEntity The entity that will be decrypted.
* @param decryptingCertificate The certificates whose private keys will be used to decrypt the message.
* @return A MimeEntity containing the decrypted part.
*/
public MimeEntity decrypt(MimeEntity encryptedEntity, Collection<X509CertificateEx> decryptingCertificates) {
if (decryptingCertificates == null || decryptingCertificates.size() == 0) {
throw new IllegalArgumentException();
}
MimeEntity retEntity = null;
try {
if (LOGGER.isDebugEnabled()) {
final byte[] encryptedContent = encryptedEntity.getContentAsBytes();
writePreDecrypt(encryptedContent);
}
final SMIMEEnveloped m = new SMIMEEnveloped(encryptedEntity);
if (!this.isAllowedEncryptionAlgorithm(m.getEncryptionAlgOID()))
throw new NHINDException(MimeError.DisallowedEncryptionAlgorithm, "The encryption algorithm " + m.getEncryptionAlgOID() + " is not allowed");
for (X509CertificateEx decryptCert : decryptingCertificates) {
final RecipientId recId = generateRecipientSelector(decryptCert);
final RecipientInformationStore recipients = m.getRecipientInfos();
final DirectRecipientInformation recipient = decFactory.createInstance(recipients.get(recId), m);
if (recipient == null)
continue;
final byte[] decryptedPayload = recipient.getDecryptedContent(decryptCert.getPrivateKey());
if (LOGGER.isDebugEnabled()) {
writePostDecrypt(decryptedPayload);
}
final ByteArrayInputStream inStream = new ByteArrayInputStream(decryptedPayload);
retEntity = new MimeEntity(inStream);
break;
}
} catch (MessagingException e) {
throw new MimeException(MimeError.InvalidMimeEntity, e);
} catch (Exception e) {
throw new MimeException(MimeError.Unexpected, e);
}
if (retEntity == null) {
throw new NHINDException(MimeError.Unexpected, "None of the the provided decryption certs were found in message's RecipientsInfo set.");
}
return retEntity;
}
use of org.bouncycastle.cms.RecipientId in project ats-framework by Axway.
the class SMimePackageEncryptor method decrypt.
@PublicAtsApi
public Package decrypt(Package sourcePackage) throws ActionException {
// for connection management to IMAP store
boolean storeReconnected = false;
if (sourcePackage instanceof MimePackage) {
try {
storeReconnected = ((MimePackage) sourcePackage).reconnectStoreIfClosed();
} catch (MessagingException ex) {
throw new ActionException("Could not reopen IMAP connection", ex);
}
}
try {
KeyStore ks = getKeystore();
RecipientId recId = new JceKeyTransRecipientId((X509Certificate) ks.getCertificate(aliasOrCN));
MimeMessage msg = getMimeMessage(sourcePackage);
SMIMEEnveloped m = new SMIMEEnveloped(msg);
RecipientInformationStore recipients = m.getRecipientInfos();
RecipientInformation recipient = recipients.get(recId);
PrivateKey privateKey = (PrivateKey) ks.getKey(aliasOrCN, certPassword.toCharArray());
JceKeyTransRecipient jceKey = new JceKeyTransEnvelopedRecipient(privateKey).setProvider(BouncyCastleProvider.PROVIDER_NAME);
MimeBodyPart result = null;
try {
result = SMIMEUtil.toMimeBodyPart(recipient.getContent(jceKey));
if (LOG.isDebugEnabled()) {
LOG.debug("Successfully decrypted message with subject '" + msg.getSubject() + "' with private key alias: " + aliasOrCN);
}
} catch (SMIMEException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Could not decrypt message with subject '" + sourcePackage.getSubject() + "' with private key alias '" + aliasOrCN + "'", e);
}
}
SMIMESigned signedMessage = null;
MimeMessage decryptedMsg = new MimeMessage(Session.getInstance(new Properties()));
if (result != null) {
Object content = result.getContent();
Enumeration<?> hLineEnum = msg.getAllHeaderLines();
while (hLineEnum.hasMoreElements()) {
decryptedMsg.addHeaderLine((String) hLineEnum.nextElement());
}
decryptedMsg.setContent(content, result.getContentType());
// in order getPlainTextBody getHtmlTextBody to work as they do not work with attachments
decryptedMsg.removeHeader("Content-Disposition");
// check if the message is signed
try {
if (content instanceof MimeMultipart) {
MimeMultipart multipartContent = (MimeMultipart) content;
if (multipartContent.getContentType() != null && multipartContent.getContentType().toLowerCase().contains(CONTENT_TYPE_MULTIPART_SIGNED)) {
signedMessage = new SMIMESigned(multipartContent);
}
} else if (content instanceof SMIMESigned) {
signedMessage = (SMIMESigned) content;
} else if (content instanceof BASE64DecoderStream) {
// com.sun.mail.util.BASE64DecoderStream - JavaMail API dependency. Seems still available
// in JavaMail 2.0 so not an issue if using other non-Oracle/OpenJDK JVMs
// will throw exception if not signed
signedMessage = new SMIMESigned(decryptedMsg);
}
} catch (Exception e) {
// the message is not signed
// log.debug( "Could not construct signed message instance", e );
}
}
if (signedMessage != null) {
// remove signature from the message
decryptedMsg.setContent(signedMessage.getContent().getContent(), signedMessage.getContent().getContentType());
MimePackage mimePackage = new MimePackage(decryptedMsg);
// keep the SMIMESigned message for further signature verification
mimePackage.setSMIMESignedMessage(signedMessage);
return mimePackage;
}
return new MimePackage(decryptedMsg);
} catch (Exception e) {
throw new ActionException(DECRYPTION_EXCEPTION, e);
} finally {
if (storeReconnected) {
// and sourcePackage should be instanceof MimePackage
try {
((MimePackage) sourcePackage).closeStoreConnection(true);
} catch (MessagingException ex) {
// do not hide possible exception thrown in catch block
LOG.debug(ex);
}
}
}
}
use of org.bouncycastle.cms.RecipientId in project nhin-d by DirectProject.
the class MessagaeDecryptor method main.
public static void main(String[] args) {
try {
final KeyStore store = KeyStore.getInstance("pkcs12");
store.load(FileUtils.openInputStream(new File("/users/gm2552/Desktop/ops.p12")), "".toCharArray());
final String alias = store.aliases().nextElement();
final PrivateKey entry = (PrivateKey) store.getKey(alias, "".toCharArray());
final X509Certificate cert = (X509Certificate) store.getCertificate(alias);
/*
for (String arg :args)
{
if (arg )
}
*/
//String encryptedStuff = FileUtils.readFileToString(new File("users/gm2552/Desktop/cry.eml"));
InputStream inStream = FileUtils.openInputStream(new File("/users/gm2552/Desktop/cry2.eml"));
MimeBodyPart part = new MimeBodyPart(inStream);
final SMIMEEnveloped m = new SMIMEEnveloped(part);
RecipientId recId = new RecipientId();
recId.setIssuer(cert.getIssuerX500Principal().getEncoded());
recId.setSerialNumber(cert.getSerialNumber());
final RecipientInformationStore recipients = m.getRecipientInfos();
final DirectRecipientInformation recipient = new SplitDirectRecipientInformationFactory().createInstance(recipients.get(recId), m);
final byte[] decryptedPayload = recipient.getDecryptedContent(entry);
System.out.println("Alg OID: " + m.getEncryptionAlgOID());
} catch (Exception e) {
e.printStackTrace();
}
}
use of org.bouncycastle.cms.RecipientId in project nhin-d by DirectProject.
the class SMIMECryptographerImpl method generateRecipientSelector.
/*
* Construct an RecipientId. Added private function to support multiple versions of BC libraries.
*/
private RecipientId generateRecipientSelector(X509Certificate decryptCert) {
RecipientId retVal = null;
Class<RecipientId> loadClass = null;
try {
// support for bcmail-jdk15-146
loadClass = (Class<RecipientId>) getClass().getClassLoader().loadClass("org.bouncycastle.cms.jcajce.JceKeyTransRecipientId");
Constructor<RecipientId> constructor = loadClass.getConstructor(X509Certificate.class);
retVal = constructor.newInstance(decryptCert);
} catch (Throwable e) {
if (LOGGER.isDebugEnabled()) {
StringBuilder builder = new StringBuilder("bcmail-jdk15-146 org.bouncycastle.cms.jcajce.JceKeyTransRecipientId class not found.");
builder.append("\r\n\tAttempt to fall back to bcmail-jdk15-140 org.bouncycastle.cms.RecipientId");
LOGGER.debug(builder.toString());
}
}
if (retVal == null) {
try {
// fall back to bcmail-jdk15-140 interfaces
loadClass = (Class<RecipientId>) getClass().getClassLoader().loadClass("org.bouncycastle.cms.RecipientId");
retVal = loadClass.newInstance();
retVal.setSerialNumber(decryptCert.getSerialNumber());
retVal.setIssuer(decryptCert.getIssuerX500Principal().getEncoded());
} catch (Throwable e) {
LOGGER.error("Attempt to fall back to bcmail-jdk15-140 org.bouncycastle.cms.RecipientId failed.", e);
}
}
return retVal;
}
use of org.bouncycastle.cms.RecipientId in project pdfbox by apache.
the class PublicKeySecurityHandler method prepareForDecryption.
/**
* Prepares everything to decrypt the document.
*
* @param encryption encryption dictionary, can be retrieved via
* {@link PDDocument#getEncryption()}
* @param documentIDArray document id which is returned via
* {@link org.apache.pdfbox.cos.COSDocument#getDocumentID()} (not used by
* this handler)
* @param decryptionMaterial Information used to decrypt the document.
*
* @throws IOException If there is an error accessing data. If verbose mode
* is enabled, the exception message will provide more details why the
* match wasn't successful.
*/
@Override
public void prepareForDecryption(PDEncryption encryption, COSArray documentIDArray, DecryptionMaterial decryptionMaterial) throws IOException {
if (!(decryptionMaterial instanceof PublicKeyDecryptionMaterial)) {
throw new IOException("Provided decryption material is not compatible with the document");
}
setDecryptMetadata(encryption.isEncryptMetaData());
if (encryption.getLength() != 0) {
this.keyLength = encryption.getLength();
}
PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial) decryptionMaterial;
try {
boolean foundRecipient = false;
X509Certificate certificate = material.getCertificate();
X509CertificateHolder materialCert = null;
if (certificate != null) {
materialCert = new X509CertificateHolder(certificate.getEncoded());
}
// the decrypted content of the enveloped data that match
// the certificate in the decryption material provided
byte[] envelopedData = null;
// the bytes of each recipient in the recipients array
byte[][] recipientFieldsBytes = new byte[encryption.getRecipientsLength()][];
int recipientFieldsLength = 0;
int i = 0;
StringBuilder extraInfo = new StringBuilder();
for (; i < encryption.getRecipientsLength(); i++) {
COSString recipientFieldString = encryption.getRecipientStringAt(i);
byte[] recipientBytes = recipientFieldString.getBytes();
CMSEnvelopedData data = new CMSEnvelopedData(recipientBytes);
Collection<RecipientInformation> recipCertificatesIt = data.getRecipientInfos().getRecipients();
int j = 0;
for (RecipientInformation ri : recipCertificatesIt) {
// Impl: if a matching certificate was previously found it is an error,
// here we just don't care about it
RecipientId rid = ri.getRID();
if (!foundRecipient && rid.match(materialCert)) {
foundRecipient = true;
PrivateKey privateKey = (PrivateKey) material.getPrivateKey();
envelopedData = ri.getContent(new JceKeyTransEnvelopedRecipient(privateKey));
break;
}
j++;
if (certificate != null) {
extraInfo.append('\n');
extraInfo.append(j);
extraInfo.append(": ");
if (rid instanceof KeyTransRecipientId) {
appendCertInfo(extraInfo, (KeyTransRecipientId) rid, certificate, materialCert);
}
}
}
recipientFieldsBytes[i] = recipientBytes;
recipientFieldsLength += recipientBytes.length;
}
if (!foundRecipient || envelopedData == null) {
throw new IOException("The certificate matches none of " + i + " recipient entries" + extraInfo.toString());
}
if (envelopedData.length != 24) {
throw new IOException("The enveloped data does not contain 24 bytes");
}
// now envelopedData contains:
// - the 20 bytes seed
// - the 4 bytes of permission for the current user
byte[] accessBytes = new byte[4];
System.arraycopy(envelopedData, 20, accessBytes, 0, 4);
AccessPermission currentAccessPermission = new AccessPermission(accessBytes);
currentAccessPermission.setReadOnly();
setCurrentAccessPermission(currentAccessPermission);
// what we will put in the SHA1 = the seed + each byte contained in the recipients array
byte[] sha1Input = new byte[recipientFieldsLength + 20];
// put the seed in the sha1 input
System.arraycopy(envelopedData, 0, sha1Input, 0, 20);
// put each bytes of the recipients array in the sha1 input
int sha1InputOffset = 20;
for (byte[] recipientFieldsByte : recipientFieldsBytes) {
System.arraycopy(recipientFieldsByte, 0, sha1Input, sha1InputOffset, recipientFieldsByte.length);
sha1InputOffset += recipientFieldsByte.length;
}
MessageDigest md = MessageDigests.getSHA1();
byte[] mdResult = md.digest(sha1Input);
// we have the encryption key ...
encryptionKey = new byte[this.keyLength / 8];
System.arraycopy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
} catch (CMSException | KeyStoreException | CertificateEncodingException e) {
throw new IOException(e);
}
}
Aggregations