summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Poichet <jpoichet@google.com>2014-07-31 21:19:03 -0700
committerJerome Poichet <jpoichet@google.com>2014-08-06 14:12:27 -0700
commit8e47158fabd5bad4282644c6e9ed9ac99c603e33 (patch)
tree53b1bc4cfe79bb8e28482f29a9b854dde3770997
parent7a318a6755e0065553919fd2185eaef6df960a5c (diff)
downloadgoogle-tv-pairing-protocol-8e47158fabd5bad4282644c6e9ed9ac99c603e33.tar.gz
Root certificate and signing certificatesandroid-cts-5.1_r9android-cts-5.1_r8android-cts-5.1_r7android-cts-5.1_r6android-cts-5.1_r5android-cts-5.1_r4android-cts-5.1_r3android-cts-5.1_r28android-cts-5.1_r27android-cts-5.1_r26android-cts-5.1_r25android-cts-5.1_r24android-cts-5.1_r23android-cts-5.1_r22android-cts-5.1_r21android-cts-5.1_r20android-cts-5.1_r2android-cts-5.1_r19android-cts-5.1_r18android-cts-5.1_r17android-cts-5.1_r16android-cts-5.1_r15android-cts-5.1_r14android-cts-5.1_r13android-cts-5.1_r10android-cts-5.1_r1android-cts-5.0_r9android-cts-5.0_r8android-cts-5.0_r7android-cts-5.0_r6android-cts-5.0_r5android-cts-5.0_r4android-cts-5.0_r3android-5.1.1_r9android-5.1.1_r8android-5.1.1_r7android-5.1.1_r6android-5.1.1_r5android-5.1.1_r4android-5.1.1_r38android-5.1.1_r37android-5.1.1_r36android-5.1.1_r35android-5.1.1_r34android-5.1.1_r33android-5.1.1_r30android-5.1.1_r3android-5.1.1_r29android-5.1.1_r28android-5.1.1_r26android-5.1.1_r25android-5.1.1_r24android-5.1.1_r23android-5.1.1_r22android-5.1.1_r20android-5.1.1_r2android-5.1.1_r19android-5.1.1_r18android-5.1.1_r17android-5.1.1_r16android-5.1.1_r15android-5.1.1_r14android-5.1.1_r13android-5.1.1_r12android-5.1.1_r10android-5.1.1_r1android-5.1.0_r5android-5.1.0_r4android-5.1.0_r3android-5.1.0_r1android-5.0.2_r3android-5.0.2_r1android-5.0.1_r1android-5.0.0_r7android-5.0.0_r6android-5.0.0_r5.1android-5.0.0_r5android-5.0.0_r4android-5.0.0_r3android-5.0.0_r2android-5.0.0_r1lollipop-releaselollipop-mr1-wfc-releaselollipop-mr1-releaselollipop-mr1-fi-releaselollipop-mr1-devlollipop-mr1-cts-releaselollipop-devlollipop-cts-release
- Add method to generate a Root Certificate (allowing a chain of 1) - Add method to sign a provided "certificate" - Really if provided with a public key, generate a chain of a new certificate signed with the Root certificate - Changed certificate dates from -30 days and +10 years from day it was generated - Changed email in certificate Change-Id: I405417d0b3c495d8bda83d4ca21a803c4667bbb6
-rw-r--r--java/src/com/google/polo/ssl/CsrUtil.java156
-rw-r--r--java/src/com/google/polo/ssl/SslUtil.java17
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 cf0b3da..3d092b3 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 {
new SubjectKeyIdentifierStructure(pair.getPublic()));
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;