diff options
author | Jerome Poichet <jpoichet@google.com> | 2014-09-12 08:26:08 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-09-12 08:26:08 +0000 |
commit | 1b6f39a9b15773c496fd0fdc281db6e8ce3a4161 (patch) | |
tree | 43530ffb6d12253c1153ff6d343eba92549b4d94 | |
parent | 5304090b17fb5c07091e8573047fb7e8bf2699a7 (diff) | |
parent | 8e47158fabd5bad4282644c6e9ed9ac99c603e33 (diff) | |
download | google-tv-pairing-protocol-1b6f39a9b15773c496fd0fdc281db6e8ce3a4161.tar.gz |
am 8e47158f: Root certificate and signing certificates
* commit '8e47158fabd5bad4282644c6e9ed9ac99c603e33':
Root certificate and signing certificates
-rw-r--r-- | java/src/com/google/polo/ssl/CsrUtil.java | 156 | ||||
-rw-r--r-- | java/src/com/google/polo/ssl/SslUtil.java | 17 |
2 files changed, 161 insertions, 12 deletions
diff --git a/java/src/com/google/polo/ssl/CsrUtil.java b/java/src/com/google/polo/ssl/CsrUtil.java new file mode 100644 index 0000000..d5ff7bc --- /dev/null +++ b/java/src/com/google/polo/ssl/CsrUtil.java @@ -0,0 +1,156 @@ +package com.google.polo.ssl; + +import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.ExtendedKeyUsage; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.asn1.x509.KeyPurposeId; +import org.bouncycastle.asn1.x509.KeyUsage; +import org.bouncycastle.asn1.x509.X509Extensions; +import org.bouncycastle.asn1.x509.X509Name; +import org.bouncycastle.x509.X509V3CertificateGenerator; +import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; +import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; + +import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.util.Calendar; +import java.util.Date; + +/** + * Utility class to generate X509 Root Certificates and Issue X509 Certificates signed by a root + * Certificate. + */ +public class CsrUtil { + private static final String SIGNATURE_ALGORITHM = "SHA256WithRSAEncryption"; + private static final String EMAIL = "android-tv-remote-support@google.com"; + private static final int NOT_BEFORE_NUMBER_OF_DAYS = -30; + private static final int NOT_AFTER_NUMBER_OF_DAYS = 10 * 365; + + /** + * Generate a X509 Certificate that should be used as an authority/root certificate only. + * + * This certificate shouldn't be used for communications, only as an authority as it won't have + * the correct flags. + * + * @param rootName Common Name used in certificate. + * @param rootPair Key Pair used to signed the certificate + * @return + * @throws GeneralSecurityException + */ + public static X509Certificate generateX509V3AuthorityCertificate(String rootName, + KeyPair rootPair) + throws GeneralSecurityException { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_YEAR, NOT_BEFORE_NUMBER_OF_DAYS); + Date notBefore = new Date(calendar.getTimeInMillis()); + calendar.add(Calendar.DAY_OF_YEAR, NOT_AFTER_NUMBER_OF_DAYS); + Date notAfter = new Date(calendar.getTimeInMillis()); + + BigInteger serialNumber = BigInteger.valueOf(Math.abs(System.currentTimeMillis())); + + return generateX509V3AuthorityCertificate(rootName, rootPair, notBefore, notAfter, serialNumber); + } + + + @SuppressWarnings("deprecation") + static X509Certificate generateX509V3AuthorityCertificate(String rootName, + KeyPair rootPair, Date notBefore, Date notAfter, BigInteger serialNumber) + throws GeneralSecurityException { + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + X509Name dnName = new X509Name(rootName); + + certGen.setSerialNumber(serialNumber); + certGen.setIssuerDN(dnName); + certGen.setSubjectDN(dnName); + certGen.setNotBefore(notBefore); + certGen.setNotAfter(notAfter); + certGen.setPublicKey(rootPair.getPublic()); + certGen.setSignatureAlgorithm(SIGNATURE_ALGORITHM); + + certGen.addExtension(X509Extensions.BasicConstraints, true, + new BasicConstraints(0)); + + certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature + | KeyUsage.keyEncipherment | KeyUsage.keyCertSign)); + + AuthorityKeyIdentifier authIdentifier = SslUtil.createAuthorityKeyIdentifier( + rootPair.getPublic(), dnName, serialNumber); + + certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, true, authIdentifier); + certGen.addExtension(X509Extensions.SubjectKeyIdentifier, true, + new SubjectKeyIdentifierStructure(rootPair.getPublic())); + + certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames( + new GeneralName(GeneralName.rfc822Name, EMAIL))); + + X509Certificate cert = certGen.generate(rootPair.getPrivate()); + return cert; + } + + + /** + * Given a public key and an authority certificate and key pair, issue an X509 Certificate + * chain signed by the provided authority certificate. + * + * @param name Common name used in the issued certificate. + * @param publicKey Public key to use in issued certificate. + * @param rootCert Root certificate used to issue the new certificate. + * @param rootPair Root key pair used to issue the new certificate. + * @return Array containing the issued certificate and the provided root certificate. + * @throws GeneralSecurityException + */ + public static X509Certificate[] issueX509V3Certificate(String name, PublicKey publicKey, + X509Certificate rootCert, KeyPair rootPair) throws GeneralSecurityException { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_YEAR, NOT_BEFORE_NUMBER_OF_DAYS); + Date notBefore = new Date(calendar.getTimeInMillis()); + calendar.add(Calendar.DAY_OF_YEAR, NOT_AFTER_NUMBER_OF_DAYS); + Date notAfter = new Date(calendar.getTimeInMillis()); + + BigInteger serialNumber = BigInteger.valueOf(Math.abs(System.currentTimeMillis())); + + return issueX509V3Certificate(name, publicKey, rootCert, rootPair, notBefore, notAfter, serialNumber); + } + + @SuppressWarnings("deprecation") + static X509Certificate[] issueX509V3Certificate(String name, PublicKey publicKey, + X509Certificate rootCert, KeyPair rootPair, Date notBefore, Date notAfter, + BigInteger serialNumber) throws GeneralSecurityException { + + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + X509Name dnName = new X509Name(name); + + certGen.setSerialNumber(serialNumber); + certGen.setIssuerDN(rootCert.getSubjectX500Principal()); + certGen.setNotBefore(notBefore); + certGen.setNotAfter(notAfter); + certGen.setSubjectDN(dnName); + certGen.setPublicKey(publicKey); + certGen.setSignatureAlgorithm(SIGNATURE_ALGORITHM); + + // Use Root Certificate as the authority + certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, + new AuthorityKeyIdentifierStructure(rootCert)); + // Use provided public key for the subject + certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, + new SubjectKeyIdentifierStructure(publicKey)); + // This is not a CA certificate, do not allow + certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); + // This can be used for signature and encryption + certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature + | KeyUsage.keyEncipherment)); + // This is used for server authentication + certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage( + KeyPurposeId.id_kp_serverAuth)); + + X509Certificate issuedCert = certGen.generate(rootPair.getPrivate()); + + return new X509Certificate[] { issuedCert, rootCert }; + } +} diff --git a/java/src/com/google/polo/ssl/SslUtil.java b/java/src/com/google/polo/ssl/SslUtil.java index e27d4f7..e575770 100644 --- a/java/src/com/google/polo/ssl/SslUtil.java +++ b/java/src/com/google/polo/ssl/SslUtil.java @@ -93,11 +93,10 @@ public class SslUtil { * @throws GeneralSecurityException on error generating the certificate */ @SuppressWarnings("deprecation") + @Deprecated public static X509Certificate generateX509V1Certificate(KeyPair pair, String name) throws GeneralSecurityException { - java.security.Security.addProvider( - new org.bouncycastle.jce.provider.BouncyCastleProvider()); Calendar calendar = Calendar.getInstance(); calendar.set(2009, 0, 1); @@ -118,9 +117,7 @@ public class SslUtil { certGen.setPublicKey(pair.getPublic()); certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); - // This method is deprecated, but Android Eclair does not provide the - // generate() methods. - X509Certificate cert = certGen.generateX509Certificate(pair.getPrivate(), "BC"); + X509Certificate cert = certGen.generate(pair.getPrivate()); return cert; } @@ -139,8 +136,6 @@ public class SslUtil { public static X509Certificate generateX509V3Certificate(KeyPair pair, String name, Date notBefore, Date notAfter, BigInteger serialNumber) throws GeneralSecurityException { - java.security.Security.addProvider( - new org.bouncycastle.jce.provider.BouncyCastleProvider()); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); X509Name dnName = new X509Name(name); @@ -186,11 +181,9 @@ public class SslUtil { SubjectKeyIdentifier.getInstance(pair.getPublic().getEncoded())); certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames( - new GeneralName(GeneralName.rfc822Name, "googletv@test.test"))); + new GeneralName(GeneralName.rfc822Name, "android-tv-remote-support@google.com"))); - // This method is deprecated, but Android Eclair does not provide the - // generate() methods. - X509Certificate cert = certGen.generateX509Certificate(pair.getPrivate(), "BC"); + X509Certificate cert = certGen.generate(pair.getPrivate()); return cert; } @@ -214,7 +207,7 @@ public class SslUtil { * @param serialNumber the serial number * @return a new {@link AuthorityKeyIdentifier} */ - private static AuthorityKeyIdentifier createAuthorityKeyIdentifier( + static AuthorityKeyIdentifier createAuthorityKeyIdentifier( PublicKey publicKey, X509Name name, BigInteger serialNumber) { GeneralName genName = new GeneralName(name); SubjectPublicKeyInfo info; |