Java tutorial
/* * Copyright (c) 2008-2012, Martijn Brinkers, Djigzo. * * This file is part of Djigzo email encryption. * * Djigzo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License * version 3, 19 November 2007 as published by the Free Software * Foundation. * * Djigzo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with Djigzo. If not, see <http://www.gnu.org/licenses/> * * Additional permission under GNU AGPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, * wsdl4j-1.6.1.jar (or modified versions of these libraries), * containing parts covered by the terms of Eclipse Public License, * tyrex license, freemarker license, dom4j license, mx4j license, * Spice Software License, Common Development and Distribution License * (CDDL), Common Public License (CPL) the licensors of this Program grant * you additional permission to convey the resulting work. */ package mitm.common.security.smime; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.LinkedList; import java.util.List; import mitm.common.security.certificate.X500PrincipalInspector; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.CMSAttributes; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.Time; import org.bouncycastle.asn1.smime.SMIMEAttributes; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; public class SMIMEAttributeUtils { /** * Returns a SMIMECapabilityVector filled with all the encryption ciphers from SMIMEEncryptionAlgorithm. * * @return the SMIMECapabilityVector */ public static SMIMECapabilityVector getDefaultSMIMECapabilityVector() { SMIMECapabilityVector capabilities = new SMIMECapabilityVector(); /* add all SMIME encryption algorithms that are supported */ for (SMIMEEncryptionAlgorithm algorithm : SMIMEEncryptionAlgorithm.values()) { if (algorithm.isFixedSize()) { capabilities.addCapability(algorithm.getOID()); } else { /* some ciphers require an additional key size parameter */ capabilities.addCapability(algorithm.getOID(), algorithm.defaultKeySize()); } } return capabilities; } /** * Returns a SMIMECapability Attribute filled with all the encryption ciphers from SMIMEEncryptionAlgorithm. * * @return the SMIMECapabilityVector */ public static Attribute getDefaultSMIMECapabilityAttribute() { return new SMIMECapabilitiesAttribute(getDefaultSMIMECapabilityVector()); } /** * Returns a list of SMIMECapability objects if the AttributeTable contains the * smimeCapabilities attribute. If no attributes are found an empty list is returned. * * @param attributes */ public static List<SMIMECapability> getSMIMECapabilities(AttributeTable attributes) { List<SMIMECapability> capabilities = new LinkedList<SMIMECapability>(); if (attributes != null) { Attribute attr = attributes.get(SMIMEAttributes.smimeCapabilities); if (attr != null) { ASN1Set set = attr.getAttrValues(); if (set != null && set.size() > 0) { ASN1Encodable obj = set.getObjectAt(0); if (obj instanceof ASN1Sequence) { ASN1Sequence sequence = (ASN1Sequence) obj; for (int i = 0; i < sequence.size(); i++) { ASN1Encodable der = sequence.getObjectAt(i); if (der instanceof ASN1Sequence) { SMIMECapability capability = new SMIMECapability((ASN1Sequence) der); capabilities.add(capability); } } } } } } return capabilities; } /** * Returns a signingTime attribute with the specified time * * @param signingTime * @return */ public static Attribute getSigningTimeAttribute(Date signingTime) { return new Attribute(CMSAttributes.signingTime, new DERSet(new Time(signingTime))); } /** * Returns a signingTime attribute with the current time * * @param signingTime * @return */ public static Attribute getSigningTimeAttribute() { return new Attribute(CMSAttributes.signingTime, new DERSet(new Time(new Date()))); } /** * Returns the Date from the given signing time attribute * @param signingTimeAttribute * @return */ public static Date getSigningTime(Attribute signingTimeAttribute) { Date date = null; if (signingTimeAttribute != null) { Time time = Time.getInstance(signingTimeAttribute.getAttrValues().getObjectAt(0).toASN1Primitive()); if (time != null) { date = time.getDate(); } } return date; } /** * Returns the signing time attribute. Null if signing time attribute is not available. * @param attributes * @return */ public static Date getSigningTime(AttributeTable attributes) { if (attributes == null) { return null; } Attribute signingTimeAttribute = attributes.get(CMSAttributes.signingTime); return getSigningTime(signingTimeAttribute); } /** * Returns a S/MIME encryption key preference attribute for the given certificate. * * Note: an S/MIME message should only contain one S/MIME encryption key preference * * @param certificate * @return * @throws IOException */ public static SMIMEEncryptionKeyPreferenceAttribute getSMIMEEncryptionKeyPreferenceAttribute( X509Certificate certificate) throws IOException { X500PrincipalInspector principalInspector = new X500PrincipalInspector( certificate.getIssuerX500Principal()); IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(principalInspector.getX500Name(), certificate.getSerialNumber()); return new SMIMEEncryptionKeyPreferenceAttribute(issuerSerial); } /** * Returns a Outlook specific S/MIME encryption key preference attribute for the given certificate * * Note: an S/MIME message should only contain one S/MIME encryption key preference * * @param certificate * @return * @throws IOException */ public static OLSMIMEEncryptionKeyPreferenceAttribute getOLSMIMEEncryptionKeyPreferenceAttribute( X509Certificate certificate) throws IOException { X500PrincipalInspector principalInspector = new X500PrincipalInspector( certificate.getIssuerX500Principal()); IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(principalInspector.getX500Name(), certificate.getSerialNumber()); return new OLSMIMEEncryptionKeyPreferenceAttribute(issuerSerial); } /** * Returns a AttributeTable with default SMIMECapabilityAttribute and current singing time and * if encryptionCertificate is specified SMIMEEncryptionKeyPreference and OLSMIMEEncryptionKeyPreference * are added as well. * * @throws IOException */ public static AttributeTable getDefaultSignedAttributes(X509Certificate encryptionCertificate) throws IOException { ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); signedAttrs.add(getDefaultSMIMECapabilityAttribute()); signedAttrs.add(getSigningTimeAttribute()); if (encryptionCertificate != null) { signedAttrs.add(getSMIMEEncryptionKeyPreferenceAttribute(encryptionCertificate)); signedAttrs.add(getOLSMIMEEncryptionKeyPreferenceAttribute(encryptionCertificate)); } return new AttributeTable(signedAttrs); } /** * Returns a AttributeTable with default SMIMECapabilityAttribute and current singing time. * * @throws IOException */ public static AttributeTable getDefaultSignedAttributes() throws IOException { return getDefaultSignedAttributes(null); } }