diff options
Diffstat (limited to 'net/base/asn1_util.cc')
-rw-r--r-- | net/base/asn1_util.cc | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/net/base/asn1_util.cc b/net/base/asn1_util.cc index ee25d41..a1e8637 100644 --- a/net/base/asn1_util.cc +++ b/net/base/asn1_util.cc @@ -14,11 +14,32 @@ bool ParseElement(base::StringPiece* in, unsigned *out_header_len) { const uint8* data = reinterpret_cast<const uint8*>(in->data()); + // We don't support kAny and kOptional at the same time. + if ((tag_value & kAny) && (tag_value & kOptional)) + return false; + + if (in->empty() && (tag_value & kOptional)) { + if (out_header_len) + *out_header_len = 0; + if (out) + *out = base::StringPiece(); + return true; + } + if (in->size() < 2) return false; - if (tag_value != kAny && static_cast<unsigned char>(data[0]) != tag_value) + if (tag_value != kAny && + static_cast<unsigned char>(data[0]) != (tag_value & 0xff)) { + if (tag_value & kOptional) { + if (out_header_len) + *out_header_len = 0; + if (out) + *out = base::StringPiece(); + return true; + } return false; + } size_t len = 0; if ((data[1] & 0x80) == 0) { @@ -71,9 +92,9 @@ bool GetElement(base::StringPiece* in, return true; } -// SeekToSPKI changes |cert| so that it points to a suffix of the original -// value where the suffix begins at the start of the ASN.1 SubjectPublicKeyInfo -// value. +// SeekToSPKI changes |cert| so that it points to a suffix of the +// TBSCertificate where the suffix begins at the start of the ASN.1 +// SubjectPublicKeyInfo value. static bool SeekToSPKI(base::StringPiece* cert) { // From RFC 5280, section 4.1 // Certificate ::= SEQUENCE { @@ -94,14 +115,19 @@ static bool SeekToSPKI(base::StringPiece* cert) { if (!GetElement(cert, kSEQUENCE, &certificate)) return false; + // We don't allow junk after the certificate. + if (!cert->empty()) + return false; + base::StringPiece tbs_certificate; if (!GetElement(&certificate, kSEQUENCE, &tbs_certificate)) return false; - // The version is optional, so a failure to parse it is fine. - GetElement(&tbs_certificate, - kCompound | kContextSpecific | 0, - NULL); + if (!GetElement(&tbs_certificate, + kOptional | kConstructed | kContextSpecific | 0, + NULL)) { + return false; + } // serialNumber if (!GetElement(&tbs_certificate, kINTEGER, NULL)) @@ -134,6 +160,7 @@ bool ExtractSPKIFromDERCert(base::StringPiece cert, bool ExtractCRLURLsFromDERCert(base::StringPiece cert, std::vector<base::StringPiece>* urls_out) { urls_out->clear(); + std::vector<base::StringPiece> tmp_urls_out; if (!SeekToSPKI(&cert)) return false; @@ -150,17 +177,21 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert, if (!GetElement(&cert, kSEQUENCE, NULL)) return false; // issuerUniqueID - GetElement(&cert, kCompound | kContextSpecific | 1, NULL); + if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL)) + return false; // subjectUniqueID - GetElement(&cert, kCompound | kContextSpecific | 2, NULL); + if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL)) + return false; base::StringPiece extensions_seq; - if (!GetElement(&cert, kCompound | kContextSpecific | 3, + if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 3, &extensions_seq)) { - // If there are no extensions, then there are no CRL URLs. - return true; + return false; } + if (extensions_seq.empty()) + return true; + // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension // Extension ::= SEQUENCE { // extnID OBJECT IDENTIFIER, @@ -218,7 +249,7 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert, return false; base::StringPiece name; - if (!GetElement(&distrib_point, kContextSpecific | kCompound | 0, + if (!GetElement(&distrib_point, kContextSpecific | kConstructed | 0, &name)) { // If it doesn't contain a name then we skip it. continue; @@ -231,7 +262,8 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert, continue; } - if (GetElement(&distrib_point, kContextSpecific | kCompound | 2, NULL)) { + if (GetElement(&distrib_point, + kContextSpecific | kConstructed | 2, NULL)) { // If it contains a alternative issuer, then we skip it. continue; } @@ -240,8 +272,10 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert, // fullName [0] GeneralNames, // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } base::StringPiece general_names; - if (!GetElement(&name, kContextSpecific | kCompound | 0, &general_names)) + if (!GetElement(&name, + kContextSpecific | kConstructed | 0, &general_names)) { continue; + } // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName // GeneralName ::= CHOICE { @@ -251,7 +285,7 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert, while (general_names.size() > 0) { base::StringPiece url; if (GetElement(&general_names, kContextSpecific | 6, &url)) { - urls_out->push_back(url); + tmp_urls_out.push_back(url); } else { if (!GetElement(&general_names, kAny, NULL)) return false; @@ -260,6 +294,7 @@ bool ExtractCRLURLsFromDERCert(base::StringPiece cert, } } + urls_out->swap(tmp_urls_out); return true; } |