Java tutorial
/* ======================================================================== * Copyright (c) 2011 The University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ======================================================================== */ package edu.washington.iam.tools; import java.lang.Exception; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.Date; import java.util.Enumeration; import java.util.Collection; import java.io.StringReader; import java.io.IOException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; import java.security.cert.X509Certificate; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import javax.security.auth.x500.X500Principal; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; public final class IamCertificateHelper { private static final Logger log = LoggerFactory.getLogger(IamCertificateHelper.class); /* extract some info from the submitted CSR */ public static int parseCsr(IamCertificate cert) throws IamCertificateException { try { PEMReader pRd = new PEMReader(new StringReader(cert.pemRequest)); PKCS10CertificationRequest request = (PKCS10CertificationRequest) pRd.readObject(); if (request == null) throw new IamCertificateException("invalid CSR (request)"); CertificationRequestInfo info = request.getCertificationRequestInfo(); if (info == null) throw new IamCertificateException("invalid CSR (info)"); X509Name dn = info.getSubject(); if (dn == null) throw new IamCertificateException("invalid CSR (dn)"); log.debug("dn=" + dn.toString()); cert.dn = dn.toString(); try { List cns = dn.getValues(X509Name.CN); cert.cn = (String) (cns.get(0)); log.debug("cn=" + cert.cn); cert.names.add(cert.cn); // first entry for names is always cn cns = dn.getValues(X509Name.C); cert.dnC = (String) (cns.get(0)); cns = dn.getValues(X509Name.ST); cert.dnST = (String) (cns.get(0)); } catch (Exception e) { log.debug("get cn error: " + e); throw new IamCertificateException("invalid CSR"); } // see if we've got alt names (in extensions) ASN1Set attrs = info.getAttributes(); if (attrs != null) { for (int a = 0; a < attrs.size(); a++) { Attribute attr = Attribute.getInstance(attrs.getObjectAt(a)); if (attr.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) { // is the extension X509Extensions extensions = X509Extensions.getInstance(attr.getAttrValues().getObjectAt(0)); // get the subAltName extension DERObjectIdentifier sanoid = new DERObjectIdentifier( X509Extensions.SubjectAlternativeName.getId()); X509Extension xext = extensions.getExtension(sanoid); if (xext != null) { log.debug("processing altname extensions"); ASN1Object asn1 = X509Extension.convertValueToObject(xext); Enumeration dit = DERSequence.getInstance(asn1).getObjects(); while (dit.hasMoreElements()) { GeneralName gn = GeneralName.getInstance(dit.nextElement()); log.debug("altname tag=" + gn.getTagNo()); log.debug("altname name=" + gn.getName().toString()); if (gn.getTagNo() == GeneralName.dNSName) cert.names.add(gn.getName().toString()); } } } } } // check key size PublicKey pk = request.getPublicKey(); log.debug("key alg = " + pk.getAlgorithm()); log.debug("key fmt = " + pk.getFormat()); if (pk.getAlgorithm().equals("RSA")) { RSAPublicKey rpk = (RSAPublicKey) pk; cert.keySize = rpk.getModulus().bitLength(); log.debug("key size = " + cert.keySize); } } catch (IOException e) { log.debug("ioerror: " + e); throw new IamCertificateException("invalid CSR " + e.getMessage()); } catch (Exception e) { log.debug("excp: " + e); throw new IamCertificateException("invalid CSR"); } return 1; } /* extract some info from the Cert */ public static int parseCert(IamCertificate cert) throws IamCertificateException { try { // log.debug("parse certt: " + cert.pemCert); PEMReader pRd = new PEMReader(new StringReader(cert.pemCert)); X509Certificate x509 = (X509Certificate) pRd.readObject(); if (x509 == null) { log.info("bad cert"); throw new IamCertificateException("invalid cert PEM"); } cert.snStr = x509.getSerialNumber().toString(); cert.issued = x509.getNotBefore(); cert.expires = x509.getNotAfter(); // log.debug("pem expires = " + cert.expires); X500Principal prin = x509.getIssuerX500Principal(); cert.issuerDn = prin.toString(); // log.debug("issuer = " + cert.issuerDn); prin = x509.getSubjectX500Principal(); cert.dn = prin.toString(); // log.debug("principal = " + cert.dn); // see if we've got alt names (in extensions) try { Collection<List<?>> ans = x509.getSubjectAlternativeNames(); if (ans != null) { // log.debug("ans size = " + ans.size()); Iterator it = ans.iterator(); while (it.hasNext()) { List an = (List) it.next(); if (an.size() == 2) { // log.debug("an0="+an.get(0).toString() + " an1=" + an.get(1).toString()); if (an.get(0) instanceof Integer && an.get(1) instanceof String) { if ((Integer) an.get(0) == 2) cert.names.add((String) an.get(1)); } } } } if (cert.cn.equals("") && cert.names.size() > 0) cert.cn = cert.names.get(0); } catch (CertificateParsingException e) { log.info("parse error on alt names: " + e); } // check for expired /*** try { x509.checkValidity(); } catch (CertificateExpiredException e) { cert.status = IamCertificate.CERT_STATUS_EXPIRED; } catch (CertificateNotYetValidException e) { log.debug("not yet valid?"); } ***/ // get the key size PublicKey pk = x509.getPublicKey(); if (pk.getAlgorithm().equals("RSA")) { RSAPublicKey rpk = (RSAPublicKey) pk; cert.keySize = rpk.getModulus().bitLength(); // log.debug("pub key size = " + cert.keySize); } return 1; } catch (IOException e) { log.info("ioerror: " + e); throw new IamCertificateException("invalid cert: ioerror"); } catch (Exception ex) { log.info("excp: " + ex); throw new IamCertificateException("invalid cert: excep"); } } }