All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cesecore.certificates.util.cert.SubjectDirAttrExtension Maven / Gradle / Ivy

/*************************************************************************
 *                                                                       *
 *  CESeCore: CE Security Core                                           *
 *                                                                       *
 *  This software is free software; you can redistribute it and/or       *
 *  modify it under the terms of the GNU Lesser General Public           *
 *  License as published by the Free Software Foundation; either         *
 *  version 2.1 of the License, or any later version.                    *
 *                                                                       *
 *  See terms of license at gnu.org.                                     *
 *                                                                       *
 *************************************************************************/
package org.cesecore.certificates.util.cert;

import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.DERGeneralizedTime;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.x509.Attribute;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.X509DefaultEntryConverter;
import org.cesecore.util.CertTools;

/**
 * A class for reading values from SubjectDirectoryAttributes extension.
 *
 * @version $Id: SubjectDirAttrExtension.java 25905 2017-05-27 00:53:42Z jeklund $
 */
public class SubjectDirAttrExtension extends CertTools {

    private static final Logger log = Logger.getLogger(SubjectDirAttrExtension.class);
    
    /**
     * inhibits creation of new SubjectDirAttrExtension
     */
    private SubjectDirAttrExtension() {
    }

    /**
	 * SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
	 *
	 * Attribute ::= SEQUENCE {
     *  type AttributeType,
     *  values SET OF AttributeValue }
     *  -- at least one value is required
     * 
     * AttributeType ::= OBJECT IDENTIFIER
     * AttributeValue ::= ANY
     * 
	 * SubjectDirectoryAttributes is of form 
	 * dateOfBirth=<19590927>, placeOfBirth=, gender=, countryOfCitizenship=, countryOfResidence=
     * 
     * Supported subjectDirectoryAttributes are the ones above 
	 *
	 * @param certificate containing subject directory attributes
	 * @return String containing directoryAttributes of form the form specified above or null if no directoryAttributes exist. 
	 *   Values in returned String is from CertTools constants. 
	 *   DirectoryAttributes not supported are simply not shown in the resulting string.  
     *  
	 * @throws java.text.ParseException when id_pda_dateOfBirth is malformed
	 */
	public static String getSubjectDirectoryAttributes(Certificate certificate) throws ParseException {
		log.debug("Search for SubjectDirectoryAttributes");
        String result = "";
        if (certificate instanceof X509Certificate) {
			X509Certificate x509cert = (X509Certificate) certificate;
	        ASN1Primitive obj = CertTools.getExtensionValue(x509cert, Extension.subjectDirectoryAttributes.getId());
	        if (obj == null) {
	            return null;
	        }
	        ASN1Sequence seq = (ASN1Sequence)obj;
	        
	        String prefix = "";
			SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMdd");
	        for (int i = 0; i < seq.size(); i++) {
	        	Attribute attr = Attribute.getInstance(seq.getObjectAt(i));
	        	if (!StringUtils.isEmpty(result)) {
	        		prefix = ", ";
	        	}
	        	if (attr.getAttrType().getId().equals(id_pda_dateOfBirth)) {
	        		ASN1Set set = attr.getAttrValues();
	        		// Come on, we'll only allow one dateOfBirth, we're not allowing such frauds with multiple birth dates
	        		ASN1GeneralizedTime time = ASN1GeneralizedTime.getInstance(set.getObjectAt(0));
	        		Date date = time.getDate();
	        		String dateStr = dateF.format(date);
	        		result += prefix + "dateOfBirth="+dateStr; 
	        	}
	        	if (attr.getAttrType().getId().equals(id_pda_placeOfBirth)) {
	        		ASN1Set set = attr.getAttrValues();
	        		// same here only one placeOfBirth
	        		String pb = ((ASN1String)set.getObjectAt(0)).getString();
	        		result += prefix + "placeOfBirth="+pb;        			
	        	}
	        	if (attr.getAttrType().getId().equals(id_pda_gender)) {
	        		ASN1Set set = attr.getAttrValues();
	        		// same here only one gender
	        		String g = ((ASN1String)set.getObjectAt(0)).getString();
	        		result += prefix + "gender="+g;        			
	        	}
	        	if (attr.getAttrType().getId().equals(id_pda_countryOfCitizenship)) {
	        		ASN1Set set = attr.getAttrValues();
	        		// same here only one citizenship
	        		String g = ((ASN1String)set.getObjectAt(0)).getString();
	        		result += prefix + "countryOfCitizenship="+g;        			
	        	}
	        	if (attr.getAttrType().getId().equals(id_pda_countryOfResidence)) {
	        		ASN1Set set = attr.getAttrValues();
	        		// same here only one residence
	        		String g = ((ASN1String)set.getObjectAt(0)).getString();
	        		result += prefix + "countryOfResidence="+g;        			
	        	}
	        }
        }
        if (StringUtils.isEmpty(result)) {
            return null;
        }
        return result;            
	}

    /**
     * From subjectDirAttributes string as defined in getSubjectDirAttribute 
     * @param dirAttr string of SubjectDirectoryAttributes
     * @return A Collection of ASN.1 Attribute (org.bouncycastle.asn1.x509), or an empty Collection, never null
     * @see #getSubjectDirectoryAttributes(Certificate)
     */
    public static Collection getSubjectDirectoryAttributes(String dirAttr) {
    	ArrayList ret = new ArrayList();
    	Attribute attr = null;
        String value = CertTools.getPartFromDN(dirAttr, "countryOfResidence");
        if (!StringUtils.isEmpty(value)) {
        	ASN1EncodableVector vec = new ASN1EncodableVector();
        	vec.add(new DERPrintableString(value));
        	attr = new Attribute(new ASN1ObjectIdentifier(id_pda_countryOfResidence),new DERSet(vec));
        	ret.add(attr);
        }
        value = CertTools.getPartFromDN(dirAttr, "countryOfCitizenship");
        if (!StringUtils.isEmpty(value)) {
        	ASN1EncodableVector vec = new ASN1EncodableVector();
        	vec.add(new DERPrintableString(value));
        	attr = new Attribute(new ASN1ObjectIdentifier(id_pda_countryOfCitizenship),new DERSet(vec));
        	ret.add(attr);
        }
        value = CertTools.getPartFromDN(dirAttr, "gender");
        if (!StringUtils.isEmpty(value)) {
        	ASN1EncodableVector vec = new ASN1EncodableVector();
        	vec.add(new DERPrintableString(value));
        	attr = new Attribute(new ASN1ObjectIdentifier(id_pda_gender),new DERSet(vec));
        	ret.add(attr);
        }
        value = CertTools.getPartFromDN(dirAttr, "placeOfBirth");
        if (!StringUtils.isEmpty(value)) {
        	ASN1EncodableVector vec = new ASN1EncodableVector();
        	X509DefaultEntryConverter conv = new X509DefaultEntryConverter();
        	ASN1Primitive obj = conv.getConvertedValue(new ASN1ObjectIdentifier(id_pda_placeOfBirth), value);
        	vec.add(obj);
        	attr = new Attribute(new ASN1ObjectIdentifier(id_pda_placeOfBirth),new DERSet(vec));
        	ret.add(attr);
        }        
        // dateOfBirth that is a GeneralizedTime
        // The correct format for this is YYYYMMDD, it will be padded to YYYYMMDD120000Z
        value = CertTools.getPartFromDN(dirAttr, "dateOfBirth");
        if (!StringUtils.isEmpty(value)) {
            if (value.length() == 8) {
                value += "120000Z"; // standard format according to rfc3739
            	ASN1EncodableVector vec = new ASN1EncodableVector();
                vec.add(new DERGeneralizedTime(value));
                attr = new Attribute(new ASN1ObjectIdentifier(id_pda_dateOfBirth),new DERSet(vec));
                ret.add(attr);                
            } else {
                log.error("Wrong length of data for 'dateOfBirth', should be of format YYYYMMDD, skipping...");
            }
        }
        return ret;
    }
    

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy