Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Unified Diff: net/cert/internal/signature_algorithm.cc

Issue 1218753002: Add DER parsing of AlgorithmId for signatures. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove clang-format off and just accept its formatting Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/cert/internal/signature_algorithm.cc
diff --git a/net/cert/internal/signature_algorithm.cc b/net/cert/internal/signature_algorithm.cc
new file mode 100644
index 0000000000000000000000000000000000000000..99c5f3f98b681e6e5c9642e217814074ab7701e4
--- /dev/null
+++ b/net/cert/internal/signature_algorithm.cc
@@ -0,0 +1,219 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/internal/signature_algorithm.h"
+
+#include <stdint.h>
+
+#include "net/der/input.h"
+#include "net/der/parser.h"
+
+namespace net {
+
+namespace {
+
+// From RFC 3279 section 2.2.1:
+// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= {
+// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+// pkcs-1(1) 5 }
+// In dotted notation: 1.2.840.113549.1.1.5
+const uint8_t kOidSha1WithRsaEncryption[] =
+ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05};
+
+// From RFC 4055 section 6:
+// pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) rsadsi(113549) pkcs(1) 1 }
+
+// From RFC 4055 section 5:
+// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+// In dotted notation: 1.2.840.113549.1.1.11
+const uint8_t kOidSha256WithRsaEncryption[] =
+ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b};
+
+// From RFC 4055 section 5:
+// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+// In dotted notation: 1.2.840.113549.1.1.12
+const uint8_t kOidSha384WithRsaEncryption[] =
+ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c};
+
+// From RFC 4055 section 5:
+// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+// In dotted notation: 1.2.840.113549.1.1.13
+const uint8_t kOidSha512WithRsaEncryption[] =
+ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d};
+
+// From RFC 3279 section 2.2.3:
+// ansi-X9-62 OBJECT IDENTIFIER ::= {
+// iso(1) member-body(2) us(840) 10045 }
+//
+// id-ecSigType OBJECT IDENTIFIER ::= {
+// ansi-X9-62 signatures(4) }
+//
+// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+// id-ecSigType 1 }
+// In dotted notation: 1.2.840.10045.4.1
+const uint8_t kOidEcdsaWithSha1[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01};
+
+// From RFC 5758 section 3.2:
+// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
+// In dotted notation: 1.2.840.10045.4.3.2
+const uint8_t kOidEcdsaWithSha256[] =
+ {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02};
+
+// From RFC 5758 section 3.2:
+// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
+// In dotted notation: 1.2.840.10045.4.3.3
+const uint8_t kOidEcdsaWithSha384[] =
+ {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03};
+
+// From RFC 5758 section 3.2:
+// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
+// In dotted notation: 1.2.840.10045.4.3.4
+const uint8_t kOidEcdsaWithSha512[] =
+ {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04};
+
+// Assigns |out| with the values |algorithm| and |digest|. The passed in
+// |algorithm_identifier_parser| is expected to be positioned after the
+// algorithm OID. The parameters field will be consumed, and it must be either
+// NULL or missing.
+//
+// Returns true on success.
+WARN_UNUSED_RESULT bool AssignFromDerEmptyParams(
Ryan Sleevi 2015/06/29 14:45:24 end of line, not beginning.
eroman 2015/06/29 15:19:00 OK, I changed the other instance, but had to leave
Ryan Sleevi 2015/06/29 16:06:57 Yeah, this is part of why Peter and several others
+ SignatureAlgorithmId algorithm,
+ DigestAlgorithmId digest,
+ der::Parser* algorithm_identifier_parser,
+ SignatureAlgorithm* out) {
+ // The specifications for RSA PKCS #1 v1.5 and ECDSA signature algorithm are
+ // inconsistent on whether the parameters field must be NULL, omitted, or can
+ // be either.
+ //
+ // This implementation is more permissive, and will accept both NULL and
+ // omitted parameters.
+ //
+ // For reference...
+ //
+ // RFC 5758 section-3.2:
+ // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
+ // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
+ // as an AlgorithmIdentifier, the encoding MUST omit the parameters
+ // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
+ // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
+ // SHA384, or ecdsa-with-SHA512.
+ //
+ // RFC 3279 section 2.2.1 (in reference to sha-1WithRSAEncryption):
+ // When any of these three OIDs appears within the ASN.1 type
+ // AlgorithmIdentifier, the parameters component of that type SHALL be
+ // the ASN.1 type NULL.
+ //
+ // RFC 3279 section 2.2.3:
+ // When the ecdsa-with-SHA1 algorithm identifier appears as the
+ // algorithm field in an AlgorithmIdentifier, the encoding MUST omit the
+ // parameters field. That is, the AlgorithmIdentifier SHALL be a
+ // SEQUENCE of one component: the OBJECT IDENTIFIER ecdsa-with-SHA1.
+ //
+ // RFC 4055 section 5 (in reference to sha256WithRSAEncryption et al):
+ // When any of these four object identifiers appears within an
+ // AlgorithmIdentifier, the parameters MUST be NULL. Implementations
+ // MUST accept the parameters being absent as well as present.
+
+ if (algorithm_identifier_parser->HasMore()) {
+ der::Input null_value;
+ if (!algorithm_identifier_parser->ReadTag(der::kNull, &null_value))
+ return false;
+
+ if (null_value.Length() != 0)
+ return false; // Not a NULL value
+
+ // After consuming the NULL params there shouldn't be anything left.
+ if (algorithm_identifier_parser->HasMore())
+ return false;
+ }
+
+ out->algorithm = algorithm;
+ out->digest = digest;
+
+ return true;
+}
+
+} // namespace
+
+bool SignatureAlgorithm::AssignFromDer(const der::Input& in) {
+ // RFC 5280 section 4.1.1.2 defines signatureAlgorithm as:
+ //
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER,
+ // parameters ANY DEFINED BY algorithm OPTIONAL }
+
+ der::Parser parser(in);
+
+ der::Parser algorithm_identifier_parser;
+ if (!parser.ReadSequence(&algorithm_identifier_parser))
+ return false;
+
+ der::Input oid;
+ if (!algorithm_identifier_parser.ReadTag(der::kOid, &oid))
+ return false;
+
+ // TODO(eroman): Each OID is tested for equality in order, which is not
+ // particularly efficient.
+
+ if (oid.Equals(kOidSha1WithRsaEncryption)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5,
+ DigestAlgorithmId::Sha1,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidSha256WithRsaEncryption)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5,
+ DigestAlgorithmId::Sha256,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidSha384WithRsaEncryption)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5,
+ DigestAlgorithmId::Sha384,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidSha512WithRsaEncryption)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5,
+ DigestAlgorithmId::Sha512,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidEcdsaWithSha1)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa,
+ DigestAlgorithmId::Sha1,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidEcdsaWithSha256)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa,
+ DigestAlgorithmId::Sha256,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidEcdsaWithSha384)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa,
+ DigestAlgorithmId::Sha384,
+ &algorithm_identifier_parser, this);
+ }
+
+ if (oid.Equals(kOidEcdsaWithSha512)) {
+ return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa,
+ DigestAlgorithmId::Sha512,
+ &algorithm_identifier_parser, this);
+ }
+
+ return false; // Unsupported OID.
+}
+
+bool SignatureAlgorithm::Equals(const SignatureAlgorithm& other) const {
+ return algorithm == other.algorithm && digest == other.digest;
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698