Skip to content

Commit

Permalink
markenwerk#5: Implement API to return the (CN) subject of the first c…
Browse files Browse the repository at this point in the history
…ertificate on a MimePart. This subject is actually the email address of the person to which the certificate was issued to, a value often used by email clients to display "Signed by: <from-address>".
  • Loading branch information
bbottema committed Apr 13, 2019
1 parent dde9d81 commit 97a76ab
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/main/java/net/markenwerk/utils/mail/smime/SmimeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@
import org.bouncycastle.asn1.smime.SMIMECapability;
import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
Expand Down Expand Up @@ -491,6 +494,61 @@ private static boolean checkSignature(SMIMESigned smimeSigned) throws MessagingE
throw handledException(e);
}
}

/**
* @param mimeMultipart
* The {@link MimeMultipart} to be checked.
* @return The subject / address to which the certificate was issued to. Email clients may use this to show
* {@code "Signed by: <subject / address>"}
*/
public static String getSignedByAddress(MimeMultipart mimeMultipart) {
try {
return getSignedByAddress(new SMIMESigned(mimeMultipart));
} catch (Exception e) {
throw handledException(e);
}
}

/**
* @param mimePart
* The {@link MimePart} to be checked.
* @return The subject / address to which the certificate was issued to. Email clients may use this to show
* {@code "Signed by: <subject / address>"}
*/
public static String getSignedByAddress(MimePart mimePart) {
try {
if (mimePart.isMimeType("multipart/signed")) {
return getSignedByAddress(new SMIMESigned((MimeMultipart) mimePart.getContent()));
} else if (mimePart.isMimeType("application/pkcs7-mime") || mimePart.isMimeType("application/x-pkcs7-mime")) {
return getSignedByAddress(new SMIMESigned(mimePart));
} else {
throw new SmimeException("Message not signed");
}
} catch (Exception e) {
throw handledException(e);
}
}

/**
* Returns the subject / address to which the certificate was issued to. Email clients may use this to show
* {@code "Signed by: <subject / address>"}
*/
private static String getSignedByAddress(SMIMESigned smimeSigned) {
try {
@SuppressWarnings("rawtypes")
Store certificates = smimeSigned.getCertificates();

SignerInformation signerInformation = smimeSigned.getSignerInfos().getSigners().iterator().next();
X509Certificate certificate = getCertificate(certificates, signerInformation.getSID());
SignerInformationVerifier verifier = getVerifier(certificate);
X500Name x500name = verifier.getAssociatedCertificate().getSubject();
RDN cn = x500name.getRDNs(BCStyle.CN)[0];
return IETFUtils.valueToString(cn.getFirst().getValue());

} catch (Exception e) {
throw handledException(e);
}
}

private static X509Certificate getCertificate(@SuppressWarnings("rawtypes") Store certificates, SignerId signerId)
throws CertificateException {
Expand Down

0 comments on commit 97a76ab

Please sign in to comment.