Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/cert/internal/signature_algorithm.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include "net/der/input.h" | |
| 10 #include "net/der/parser.h" | |
| 11 | |
| 12 namespace net { | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 // From RFC 3279 section 2.2.1: | |
| 17 // sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { | |
| 18 // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) | |
| 19 // pkcs-1(1) 5 } | |
| 20 // In dotted notation: 1.2.840.113549.1.1.5 | |
| 21 const uint8_t kOidSha1WithRsaEncryption[] = | |
| 22 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05}; | |
| 23 | |
| 24 // From RFC 4055 section 6: | |
| 25 // pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) | |
| 26 // us(840) rsadsi(113549) pkcs(1) 1 } | |
| 27 | |
| 28 // From RFC 4055 section 5: | |
| 29 // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } | |
| 30 // In dotted notation: 1.2.840.113549.1.1.11 | |
| 31 const uint8_t kOidSha256WithRsaEncryption[] = | |
| 32 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b}; | |
| 33 | |
| 34 // From RFC 4055 section 5: | |
| 35 // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } | |
| 36 // In dotted notation: 1.2.840.113549.1.1.12 | |
| 37 const uint8_t kOidSha384WithRsaEncryption[] = | |
| 38 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c}; | |
| 39 | |
| 40 // From RFC 4055 section 5: | |
| 41 // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } | |
| 42 // In dotted notation: 1.2.840.113549.1.1.13 | |
| 43 const uint8_t kOidSha512WithRsaEncryption[] = | |
| 44 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d}; | |
| 45 | |
| 46 // From RFC 3279 section 2.2.3: | |
| 47 // ansi-X9-62 OBJECT IDENTIFIER ::= { | |
| 48 // iso(1) member-body(2) us(840) 10045 } | |
| 49 // | |
| 50 // id-ecSigType OBJECT IDENTIFIER ::= { | |
| 51 // ansi-X9-62 signatures(4) } | |
| 52 // | |
| 53 // ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { | |
| 54 // id-ecSigType 1 } | |
| 55 // In dotted notation: 1.2.840.10045.4.1 | |
| 56 const uint8_t kOidEcdsaWithSha1[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01}; | |
| 57 | |
| 58 // From RFC 5758 section 3.2: | |
| 59 // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) | |
| 60 // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 } | |
| 61 // In dotted notation: 1.2.840.10045.4.3.2 | |
| 62 const uint8_t kOidEcdsaWithSha256[] = | |
| 63 {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02}; | |
| 64 | |
| 65 // From RFC 5758 section 3.2: | |
| 66 // ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) | |
| 67 // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 } | |
| 68 // In dotted notation: 1.2.840.10045.4.3.3 | |
| 69 const uint8_t kOidEcdsaWithSha384[] = | |
| 70 {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03}; | |
| 71 | |
| 72 // From RFC 5758 section 3.2: | |
| 73 // ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) | |
| 74 // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 } | |
| 75 // In dotted notation: 1.2.840.10045.4.3.4 | |
| 76 const uint8_t kOidEcdsaWithSha512[] = | |
| 77 {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04}; | |
| 78 | |
| 79 // Assigns |out| with the values |algorithm| and |digest|. The passed in | |
| 80 // |algorithm_identifier_parser| is expected to be positioned after the | |
| 81 // algorithm OID. The parameters field will be consumed, and it must be either | |
| 82 // NULL or missing. | |
| 83 // | |
| 84 // Returns true on success. | |
| 85 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
| |
| 86 SignatureAlgorithmId algorithm, | |
| 87 DigestAlgorithmId digest, | |
| 88 der::Parser* algorithm_identifier_parser, | |
| 89 SignatureAlgorithm* out) { | |
| 90 // The specifications for RSA PKCS #1 v1.5 and ECDSA signature algorithm are | |
| 91 // inconsistent on whether the parameters field must be NULL, omitted, or can | |
| 92 // be either. | |
| 93 // | |
| 94 // This implementation is more permissive, and will accept both NULL and | |
| 95 // omitted parameters. | |
| 96 // | |
| 97 // For reference... | |
| 98 // | |
| 99 // RFC 5758 section-3.2: | |
| 100 // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or | |
| 101 // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field | |
| 102 // as an AlgorithmIdentifier, the encoding MUST omit the parameters | |
| 103 // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one | |
| 104 // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with- | |
| 105 // SHA384, or ecdsa-with-SHA512. | |
| 106 // | |
| 107 // RFC 3279 section 2.2.1 (in reference to sha-1WithRSAEncryption): | |
| 108 // When any of these three OIDs appears within the ASN.1 type | |
| 109 // AlgorithmIdentifier, the parameters component of that type SHALL be | |
| 110 // the ASN.1 type NULL. | |
| 111 // | |
| 112 // RFC 3279 section 2.2.3: | |
| 113 // When the ecdsa-with-SHA1 algorithm identifier appears as the | |
| 114 // algorithm field in an AlgorithmIdentifier, the encoding MUST omit the | |
| 115 // parameters field. That is, the AlgorithmIdentifier SHALL be a | |
| 116 // SEQUENCE of one component: the OBJECT IDENTIFIER ecdsa-with-SHA1. | |
| 117 // | |
| 118 // RFC 4055 section 5 (in reference to sha256WithRSAEncryption et al): | |
| 119 // When any of these four object identifiers appears within an | |
| 120 // AlgorithmIdentifier, the parameters MUST be NULL. Implementations | |
| 121 // MUST accept the parameters being absent as well as present. | |
| 122 | |
| 123 if (algorithm_identifier_parser->HasMore()) { | |
| 124 der::Input null_value; | |
| 125 if (!algorithm_identifier_parser->ReadTag(der::kNull, &null_value)) | |
| 126 return false; | |
| 127 | |
| 128 if (null_value.Length() != 0) | |
| 129 return false; // Not a NULL value | |
| 130 | |
| 131 // After consuming the NULL params there shouldn't be anything left. | |
| 132 if (algorithm_identifier_parser->HasMore()) | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 136 out->algorithm = algorithm; | |
| 137 out->digest = digest; | |
| 138 | |
| 139 return true; | |
| 140 } | |
| 141 | |
| 142 } // namespace | |
| 143 | |
| 144 bool SignatureAlgorithm::AssignFromDer(const der::Input& in) { | |
| 145 // RFC 5280 section 4.1.1.2 defines signatureAlgorithm as: | |
| 146 // | |
| 147 // AlgorithmIdentifier ::= SEQUENCE { | |
| 148 // algorithm OBJECT IDENTIFIER, | |
| 149 // parameters ANY DEFINED BY algorithm OPTIONAL } | |
| 150 | |
| 151 der::Parser parser(in); | |
| 152 | |
| 153 der::Parser algorithm_identifier_parser; | |
| 154 if (!parser.ReadSequence(&algorithm_identifier_parser)) | |
| 155 return false; | |
| 156 | |
| 157 der::Input oid; | |
| 158 if (!algorithm_identifier_parser.ReadTag(der::kOid, &oid)) | |
| 159 return false; | |
| 160 | |
| 161 // TODO(eroman): Each OID is tested for equality in order, which is not | |
| 162 // particularly efficient. | |
| 163 | |
| 164 if (oid.Equals(kOidSha1WithRsaEncryption)) { | |
| 165 return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5, | |
| 166 DigestAlgorithmId::Sha1, | |
| 167 &algorithm_identifier_parser, this); | |
| 168 } | |
| 169 | |
| 170 if (oid.Equals(kOidSha256WithRsaEncryption)) { | |
| 171 return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5, | |
| 172 DigestAlgorithmId::Sha256, | |
| 173 &algorithm_identifier_parser, this); | |
| 174 } | |
| 175 | |
| 176 if (oid.Equals(kOidSha384WithRsaEncryption)) { | |
| 177 return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5, | |
| 178 DigestAlgorithmId::Sha384, | |
| 179 &algorithm_identifier_parser, this); | |
| 180 } | |
| 181 | |
| 182 if (oid.Equals(kOidSha512WithRsaEncryption)) { | |
| 183 return AssignFromDerEmptyParams(SignatureAlgorithmId::RsaPkcs1_5, | |
| 184 DigestAlgorithmId::Sha512, | |
| 185 &algorithm_identifier_parser, this); | |
| 186 } | |
| 187 | |
| 188 if (oid.Equals(kOidEcdsaWithSha1)) { | |
| 189 return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa, | |
| 190 DigestAlgorithmId::Sha1, | |
| 191 &algorithm_identifier_parser, this); | |
| 192 } | |
| 193 | |
| 194 if (oid.Equals(kOidEcdsaWithSha256)) { | |
| 195 return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa, | |
| 196 DigestAlgorithmId::Sha256, | |
| 197 &algorithm_identifier_parser, this); | |
| 198 } | |
| 199 | |
| 200 if (oid.Equals(kOidEcdsaWithSha384)) { | |
| 201 return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa, | |
| 202 DigestAlgorithmId::Sha384, | |
| 203 &algorithm_identifier_parser, this); | |
| 204 } | |
| 205 | |
| 206 if (oid.Equals(kOidEcdsaWithSha512)) { | |
| 207 return AssignFromDerEmptyParams(SignatureAlgorithmId::Ecdsa, | |
| 208 DigestAlgorithmId::Sha512, | |
| 209 &algorithm_identifier_parser, this); | |
| 210 } | |
| 211 | |
| 212 return false; // Unsupported OID. | |
| 213 } | |
| 214 | |
| 215 bool SignatureAlgorithm::Equals(const SignatureAlgorithm& other) const { | |
| 216 return algorithm == other.algorithm && digest == other.digest; | |
| 217 } | |
| 218 | |
| 219 } // namespace net | |
| OLD | NEW |