mitm.common.security.smime.SMIMEAttributeUtils.java Source code

Java tutorial

Introduction

Here is the source code for mitm.common.security.smime.SMIMEAttributeUtils.java

Source

/*
 * 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);
    }
}