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.certificate; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; import mitm.common.security.asn1.ASN1Utils; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.X509Extension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Helper for getting all the AltNames from a altName collection. * * TODO: Add support for other AltNames */ public class AltNamesInspector { private final static Logger logger = LoggerFactory.getLogger(AltNamesInspector.class); /* * GeneralNames :: = SEQUENCE SIZE (1..MAX) OF GeneralName * * GeneralName ::= CHOICE { * otherName [0] OtherName, * rfc822Name [1] IA5String, * dNSName [2] IA5String, * x400Address [3] ORAddress, * directoryName [4] Name, * ediPartyName [5] EDIPartyName, * uniformResourceIdentifier [6] IA5String, * iPAddress [7] OCTET STRING, * registeredID [8] OBJECT IDENTIFIER} */ private static final int otherNameTag = 0; private static final int rfc822NameTag = 1; private static final int dnsNameTag = 2; private static final int x400AddressTag = 3; private static final int directoryNameTag = 4; private static final int ediPartyNameTag = 5; private static final int uniformResourceIdentifierTag = 6; private static final int iPAddressTag = 7; private static final int registeredIDTag = 8; private final List<String> rfc822Names = new LinkedList<String>(); private final List<String> dnsNames = new LinkedList<String>(); /** * Use this constructor for X509certificate.getSubjectAlternativeNames() * @param altNames */ public AltNamesInspector(Collection<List<?>> altNames) { parseAltNames(altNames); } /** * Use this constructor for ASN1Utils.getExtensionValue(X509Extension, String) * @param altName */ public AltNamesInspector(ASN1Sequence altName) { if (altName != null) { Collection<List<?>> altNames = new LinkedList<List<?>>(); for (int i = 0; i < altName.size(); i++) { GeneralName generalName = GeneralName.getInstance(altName.getObjectAt(i)); ASN1Encodable obj = generalName.getName(); String value; switch (generalName.getTagNo()) { case rfc822NameTag: case dnsNameTag: case uniformResourceIdentifierTag: value = DERIA5String.getInstance(obj).getString(); break; default: value = obj.toString(); } List<Object> list = new LinkedList<Object>(); list.add(generalName.getTagNo()); list.add(value); altNames.add(list); } parseAltNames(altNames); } } public AltNamesInspector(X509Certificate certificate) throws IOException { this((ASN1Sequence) ASN1Utils.getExtensionValue(certificate, X509Extension.subjectAlternativeName.getId())); } private List<String> toStringList(List<?> items, List<String> list) { /* skip the first element because it contains the tag */ for (int i = 1; i < items.size(); i++) { Object item = items.get(i); if (!(item instanceof String)) { logger.warn("String expected."); continue; } list.add((String) item); } return list; } private void parseOtherName(List<?> items) { /* not-yet implemented */ } private void parseRFC822Name(List<?> items) { if ((Integer) items.get(0) != rfc822NameTag) { throw new IllegalStateException("rfc822NameTag expected."); } toStringList(items, rfc822Names); } private void parseDNSName(List<?> items) { if ((Integer) items.get(0) != dnsNameTag) { throw new IllegalStateException("dnsNameTag expected."); } toStringList(items, dnsNames); } private void parseX400Address(List<?> items) { /* not-yet implemented */ } private void parseDirectoryName(List<?> items) { /* not-yet implemented */ } private void parseEDIPatyName(List<?> items) { /* not-yet implemented */ } private void parseUniformResourceIdentifier(List<?> items) { /* not-yet implemented */ } private void parseIPAddress(List<?> items) { /* not-yet implemented */ } private void parseRegisteredID(List<?> items) { /* not-yet implemented */ } private void parseAltNames(Collection<List<?>> altNames) { if (altNames != null) { for (List<?> choice : altNames) { Object tagObject = choice.get(0); /* the tag object should be an integer */ if (!(tagObject instanceof Integer)) { logger.warn("The tag should be an integer"); continue; } int tag = (Integer) tagObject; switch (tag) { case otherNameTag: parseOtherName(choice); break; case rfc822NameTag: parseRFC822Name(choice); break; case dnsNameTag: parseDNSName(choice); break; case x400AddressTag: parseX400Address(choice); break; case directoryNameTag: parseDirectoryName(choice); break; case ediPartyNameTag: parseEDIPatyName(choice); break; case uniformResourceIdentifierTag: parseUniformResourceIdentifier(choice); break; case iPAddressTag: parseIPAddress(choice); break; case registeredIDTag: parseRegisteredID(choice); break; default: logger.warn("Unknown tag: " + tag); } } } } public List<String> getRFC822Names() { return Collections.unmodifiableList(rfc822Names); } public List<String> getDNSNames() { return Collections.unmodifiableList(dnsNames); } }