blob: cdb601fd6a1eee342dbab87a038fce13d0645aff [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.kerby.kerberos.kerb.client.preauth.pkinit.certs;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
/**
* Generates an X.509 "trust anchor" certificate programmatically.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class TrustAnchorGenerator {
/**
* Create CA certificate.
*
* @param publicKey
* @param privateKey
* @param dn
* @param validityDays
* @param friendlyName
* @return The certificate.
* @throws InvalidKeyException
* @throws SecurityException
* @throws SignatureException
* @throws NoSuchAlgorithmException
* @throws DataLengthException
* @throws CertificateException
*/
public static X509Certificate generate(PublicKey publicKey, PrivateKey privateKey,
String dn, int validityDays, String friendlyName)
throws InvalidKeyException, SecurityException, SignatureException,
NoSuchAlgorithmException, DataLengthException, CertificateException {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
// Set certificate attributes.
certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
X509Principal x509Principal = new X509Principal(dn);
certGen.setIssuerDN(x509Principal);
certGen.setSubjectDN(x509Principal);
certGen.setNotBefore(new Date());
Calendar expiry = Calendar.getInstance();
expiry.add(Calendar.DAY_OF_YEAR, validityDays);
certGen.setNotAfter(expiry.getTime());
certGen.setPublicKey(publicKey);
certGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
certGen
.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()))));
certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(1));
certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature
| KeyUsage.keyCertSign | KeyUsage.cRLSign));
X509Certificate cert = certGen.generate(privateKey);
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;
bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(friendlyName));
bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
new SubjectKeyIdentifier(getDigest(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()))));
return cert;
}
private static byte[] getDigest(SubjectPublicKeyInfo spki) {
Digest digest = new SHA1Digest();
byte[] resBuf = new byte[digest.getDigestSize()];
byte[] bytes = spki.getPublicKeyData().getBytes();
digest.update(bytes, 0, bytes.length);
digest.doFinal(resBuf, 0);
return resBuf;
}
}