summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-05-06 20:21:51 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2013-05-06 20:21:51 +0000
commit3e7a5a2188accd38f4bee36449ced7d36b717aa9 (patch)
treef5e345f3191db3f23b1d98a7c0feb599f527d47d /crypto
parentf7e1ba4804f7365e6ab47a34e019532b428b1546 (diff)
parent6a71da569514b7b3dc8041ea06daf21313826b80 (diff)
downloadlibcore-3e7a5a2188accd38f4bee36449ced7d36b717aa9.zip
libcore-3e7a5a2188accd38f4bee36449ced7d36b717aa9.tar.gz
libcore-3e7a5a2188accd38f4bee36449ced7d36b717aa9.tar.bz2
Merge "NativeCrypto: replace Harmony routines with OpenSSL"
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/main/java/org/conscrypt/NativeCrypto.java2
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java109
-rw-r--r--crypto/src/main/native/org_conscrypt_NativeCrypto.cpp11
3 files changed, 40 insertions, 82 deletions
diff --git a/crypto/src/main/java/org/conscrypt/NativeCrypto.java b/crypto/src/main/java/org/conscrypt/NativeCrypto.java
index 208f89e..c6d1b2d 100644
--- a/crypto/src/main/java/org/conscrypt/NativeCrypto.java
+++ b/crypto/src/main/java/org/conscrypt/NativeCrypto.java
@@ -445,6 +445,8 @@ public final class NativeCrypto {
public static native int get_X509_ex_flags(long x509ctx);
+ public static native int X509_check_issued(long ctx, long ctx2);
+
// --- X509 EXFLAG ---------------------------------------------------------
public static final int EXFLAG_CA = 0x10;
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
index 4c4f6ce..1356776 100644
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
+++ b/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
@@ -23,25 +23,17 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.math.BigInteger;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
import libcore.io.IoUtils;
-import libcore.util.Objects;
-import org.apache.harmony.security.x501.Name;
-import org.apache.harmony.security.x509.AuthorityKeyIdentifier;
-import org.apache.harmony.security.x509.GeneralName;
-import org.apache.harmony.security.x509.GeneralNames;
-import org.apache.harmony.security.x509.SubjectKeyIdentifier;
/**
* A source for trusted root certificate authority (CA) certificates
@@ -380,81 +372,30 @@ public final class TrustedCertificateStore {
return null;
}
- private static AuthorityKeyIdentifier getAuthorityKeyIdentifier(X509Certificate cert) {
- final byte[] akidBytes = cert.getExtensionValue("2.5.29.35");
- if (akidBytes == null) {
- return null;
- }
-
- try {
- return AuthorityKeyIdentifier.decode(akidBytes);
- } catch (IOException e) {
- return null;
- }
+ private static boolean isSelfIssuedCertificate(OpenSSLX509Certificate cert) {
+ final long ctx = cert.getContext();
+ return NativeCrypto.X509_check_issued(ctx, ctx) == 0;
}
- private static SubjectKeyIdentifier getSubjectKeyIdentifier(X509Certificate cert) {
- final byte[] skidBytes = cert.getExtensionValue("2.5.29.14");
- if (skidBytes == null) {
+ /**
+ * Converts the {@code cert} to the internal OpenSSL X.509 format so we can
+ * run {@link NativeCrypto} methods on it.
+ */
+ private static OpenSSLX509Certificate convertToOpenSSLIfNeeded(X509Certificate cert)
+ throws CertificateException {
+ if (cert == null) {
return null;
}
- try {
- return SubjectKeyIdentifier.decode(skidBytes);
- } catch (IOException e) {
- return null;
+ if (cert instanceof OpenSSLX509Certificate) {
+ return (OpenSSLX509Certificate) cert;
}
- }
- private static boolean isSelfSignedCertificate(X509Certificate cert) {
- if (!Objects.equal(cert.getSubjectX500Principal(), cert.getIssuerX500Principal())) {
- return false;
- }
-
- final AuthorityKeyIdentifier akid = getAuthorityKeyIdentifier(cert);
- if (akid != null) {
- final byte[] akidKeyId = akid.getKeyIdentifier();
- if (akidKeyId != null) {
- final SubjectKeyIdentifier skid = getSubjectKeyIdentifier(cert);
- if (!Arrays.equals(akidKeyId, skid.getKeyIdentifier())) {
- return false;
- }
- }
-
- final BigInteger akidSerial = akid.getAuthorityCertSerialNumber();
- if (akidSerial != null && !akidSerial.equals(cert.getSerialNumber())) {
- return false;
- }
-
- final GeneralNames possibleIssuerNames = akid.getAuthorityCertIssuer();
- if (possibleIssuerNames != null) {
- GeneralName issuerName = null;
-
- /* Get the first Directory Name (DN) to match how OpenSSL works. */
- for (GeneralName possibleName : possibleIssuerNames.getNames()) {
- if (possibleName.getTag() == GeneralName.DIR_NAME) {
- issuerName = possibleName;
- break;
- }
- }
-
- if (issuerName != null) {
- final String issuerCanonical = ((Name) issuerName.getName())
- .getName(X500Principal.CANONICAL);
-
- try {
- final String subjectCanonical = new Name(cert.getSubjectX500Principal()
- .getEncoded()).getName(X500Principal.CANONICAL);
- if (!issuerCanonical.equals(subjectCanonical)) {
- return false;
- }
- } catch (IOException ignored) {
- }
- }
- }
+ try {
+ return OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
+ } catch (Exception e) {
+ throw new CertificateException(e);
}
-
- return true;
}
/**
@@ -463,24 +404,28 @@ public final class TrustedCertificateStore {
* can't be completed, the most complete chain available will be returned.
* This means that a list with only the {@code leaf} certificate is returned
* if no issuer certificates could be found.
+ *
+ * @throws CertificateException if there was a problem parsing the
+ * certificates
*/
- public List<X509Certificate> getCertificateChain(X509Certificate leaf) {
- final List<X509Certificate> chain = new ArrayList<X509Certificate>();
- chain.add(leaf);
+ public List<X509Certificate> getCertificateChain(X509Certificate leaf)
+ throws CertificateException {
+ final List<OpenSSLX509Certificate> chain = new ArrayList<OpenSSLX509Certificate>();
+ chain.add(convertToOpenSSLIfNeeded(leaf));
for (int i = 0; true; i++) {
- X509Certificate cert = chain.get(i);
- if (isSelfSignedCertificate(cert)) {
+ OpenSSLX509Certificate cert = chain.get(i);
+ if (isSelfIssuedCertificate(cert)) {
break;
}
- X509Certificate issuer = findIssuer(cert);
+ OpenSSLX509Certificate issuer = convertToOpenSSLIfNeeded(findIssuer(cert));
if (issuer == null) {
break;
}
chain.add(issuer);
}
- return chain;
+ return new ArrayList<X509Certificate>(chain);
}
// like java.security.cert.CertSelector but with X509Certificate and without cloning
diff --git a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp b/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
index 562a614..9ee9c8e 100644
--- a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
+++ b/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
@@ -4165,6 +4165,16 @@ static jint NativeCrypto_get_X509_ex_flags(JNIEnv* env, jclass, jlong x509Ref) {
return x509->ex_flags;
}
+static jboolean NativeCrypto_X509_check_issued(JNIEnv* env, jclass, jlong x509Ref1, jlong x509Ref2) {
+ X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
+ X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
+ JNI_TRACE("X509_check_issued(%p, %p)", x509_1, x509_2);
+
+ int ret = X509_check_issued(x509_1, x509_2);
+ JNI_TRACE("X509_check_issued(%p, %p) => %d", x509_1, x509_2, ret);
+ return ret;
+}
+
static void get_X509_signature(X509 *x509, ASN1_BIT_STRING** signature) {
*signature = x509->signature;
}
@@ -7876,6 +7886,7 @@ static JNINativeMethod sNativeCryptoMethods[] = {
NATIVE_METHOD(NativeCrypto, get_X509_signature, "(J)[B"),
NATIVE_METHOD(NativeCrypto, get_X509_CRL_signature, "(J)[B"),
NATIVE_METHOD(NativeCrypto, get_X509_ex_flags, "(J)I"),
+ NATIVE_METHOD(NativeCrypto, X509_check_issued, "(JJ)I"),
NATIVE_METHOD(NativeCrypto, d2i_X509_CRL_bio, "(J)J"),
NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509_CRL, "(J)J"),
NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_cert, "(JJ)J"),