Index: net/base/x509_certificate.cc |
diff --git a/net/base/x509_certificate.cc b/net/base/x509_certificate.cc |
index 9c69b4a4b4cd369b56da1abf01fd83620cf8be97..df62ec8281a23ae373ae3de57c75dcad1f334006 100644 |
--- a/net/base/x509_certificate.cc |
+++ b/net/base/x509_certificate.cc |
@@ -204,8 +204,56 @@ CertificateList X509Certificate::CreateCertificateListFromBytes( |
const char* data, int length, int format) { |
OSCertHandles certificates; |
+ // Check to see if it is in a PEM-encoded form. This check is performed |
+ // first, as both OS X and NSS will both try to convert if they detect |
+ // PEM encoding, except they don't do it consistently between the two. |
+ base::StringPiece data_string(data, length); |
+ std::vector<std::string> pem_headers; |
+ |
+ // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally |
+ // valid PEM block header for any format. |
+ pem_headers.push_back(kCertificateHeader); |
+ if (format & FORMAT_PKCS7) |
+ pem_headers.push_back(kPKCS7Header); |
+ |
+ PEMTokenizer pem_tok(data_string, pem_headers); |
+ while (pem_tok.GetNext()) { |
+ std::string decoded(pem_tok.data()); |
+ |
+ OSCertHandle handle = NULL; |
+ if (format & FORMAT_PEM_CERT_SEQUENCE) |
+ handle = CreateOSCertHandleFromBytes(decoded.c_str(), decoded.size()); |
+ if (handle != NULL) { |
+ // Parsed a DER encoded certificate. All PEM blocks that follow must |
+ // also be DER encoded certificates wrapped inside of PEM blocks. |
+ format = FORMAT_PEM_CERT_SEQUENCE; |
+ certificates.push_back(handle); |
+ continue; |
+ } |
+ |
+ // If the first block failed to parse as a DER certificate, and |
+ // formats other than PEM are acceptable, check to see if the decoded |
+ // data is one of the accepted formats. |
+ if (format & ~FORMAT_PEM_CERT_SEQUENCE) { |
+ for (size_t i = 0; certificates.empty() && |
+ i < arraysize(kFormatDecodePriority); ++i) { |
+ if (format & kFormatDecodePriority[i]) { |
+ certificates = CreateOSCertHandlesFromBytes(decoded.c_str(), |
+ decoded.size(), kFormatDecodePriority[i]); |
+ } |
+ } |
+ } |
+ |
+ // Stop parsing after the first block for any format but a sequence of |
+ // PEM-encoded DER certificates. The case of FORMAT_PEM_CERT_SEQUENCE |
+ // is handled above, and continues processing until a certificate fails |
+ // to parse. |
+ break; |
+ } |
+ |
// Try each of the formats, in order of parse preference, to see if |data| |
- // contains the binary representation of a Format. |
+ // contains the binary representation of a Format, if it failed to parse |
+ // as a PEM certificate/chain. |
for (size_t i = 0; certificates.empty() && |
i < arraysize(kFormatDecodePriority); ++i) { |
if (format & kFormatDecodePriority[i]) |
@@ -213,53 +261,6 @@ CertificateList X509Certificate::CreateCertificateListFromBytes( |
kFormatDecodePriority[i]); |
} |
- // No certs were read. Check to see if it is in a PEM-encoded form. |
- if (certificates.empty()) { |
- base::StringPiece data_string(data, length); |
- std::vector<std::string> pem_headers; |
- |
- // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally |
- // valid PEM block header for any format. |
- pem_headers.push_back(kCertificateHeader); |
- if (format & FORMAT_PKCS7) |
- pem_headers.push_back(kPKCS7Header); |
- |
- PEMTokenizer pem_tok(data_string, pem_headers); |
- while (pem_tok.GetNext()) { |
- std::string decoded(pem_tok.data()); |
- |
- OSCertHandle handle = NULL; |
- if (format & FORMAT_PEM_CERT_SEQUENCE) |
- handle = CreateOSCertHandleFromBytes(decoded.c_str(), decoded.size()); |
- if (handle != NULL) { |
- // Parsed a DER encoded certificate. All PEM blocks that follow must |
- // also be DER encoded certificates wrapped inside of PEM blocks. |
- format = FORMAT_PEM_CERT_SEQUENCE; |
- certificates.push_back(handle); |
- continue; |
- } |
- |
- // If the first block failed to parse as a DER certificate, and |
- // formats other than PEM are acceptable, check to see if the decoded |
- // data is one of the accepted formats. |
- if (format & ~FORMAT_PEM_CERT_SEQUENCE) { |
- for (size_t i = 0; certificates.empty() && |
- i < arraysize(kFormatDecodePriority); ++i) { |
- if (format & kFormatDecodePriority[i]) { |
- certificates = CreateOSCertHandlesFromBytes(decoded.c_str(), |
- decoded.size(), kFormatDecodePriority[i]); |
- } |
- } |
- } |
- |
- // Stop parsing after the first block for any format but a sequence of |
- // PEM-encoded DER certificates. The case of FORMAT_PEM_CERT_SEQUENCE |
- // is handled above, and continues processing until a certificate fails |
- // to parse. |
- break; |
- } |
- } |
- |
CertificateList results; |
// No certificates parsed. |
if (certificates.empty()) |