OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "jwk.h" | 5 #include "jwk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <map> | 9 #include <map> |
10 | 10 |
11 #include "base/json/json_reader.h" | 11 #include "base/json/json_reader.h" |
12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/strings/string_piece.h" | 14 #include "base/strings/string_piece.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "content/child/webcrypto/crypto_data.h" | 16 #include "content/child/webcrypto/crypto_data.h" |
17 #include "content/child/webcrypto/platform_crypto.h" | 17 #include "content/child/webcrypto/platform_crypto.h" |
18 #include "content/child/webcrypto/shared_crypto.h" | 18 #include "content/child/webcrypto/shared_crypto.h" |
19 #include "content/child/webcrypto/status.h" | 19 #include "content/child/webcrypto/status.h" |
20 #include "content/child/webcrypto/webcrypto_util.h" | 20 #include "content/child/webcrypto/webcrypto_util.h" |
21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
22 | 22 |
23 // JSON Web Key Format (JWK) | |
24 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-21 | |
25 // | |
26 // A JWK is a simple JSON dictionary with the following entries | |
27 // - "kty" (Key Type) Parameter, REQUIRED | |
28 // - <kty-specific parameters, see below>, REQUIRED | |
29 // - "use" (Key Use) Parameter, OPTIONAL | |
30 // - "key_ops" (Key Operations) Parameter, OPTIONAL | |
31 // - "alg" (Algorithm) Parameter, OPTIONAL | |
32 // - "ext" (Key Exportability), OPTIONAL | |
33 // (all other entries are ignored) | |
34 // | |
35 // OPTIONAL here means that this code does not require the entry to be present | |
36 // in the incoming JWK, because the method input parameters contain similar | |
37 // information. If the optional JWK entry is present, it will be validated | |
38 // against the corresponding input parameter for consistency and combined with | |
39 // it according to rules defined below. A special case is that the method | |
40 // input parameter 'algorithm' is also optional. If it is null, the JWK 'alg' | |
41 // value (if present) is used as a fallback. | |
Ryan Sleevi
2014/05/08 23:41:25
This is no longer true.
eroman
2014/05/08 23:43:27
Indeed. Do you want me to fix it as part of this r
| |
42 // | |
43 // Input 'key_data' contains the JWK. To build a Web Crypto Key, the JWK | |
44 // values are parsed out and combined with the method input parameters to | |
45 // build a Web Crypto Key: | |
46 // Web Crypto Key type <-- (deduced) | |
47 // Web Crypto Key extractable <-- JWK ext + input extractable | |
48 // Web Crypto Key algorithm <-- JWK alg + input algorithm | |
49 // Web Crypto Key keyUsage <-- JWK use, key_ops + input usage_mask | |
50 // Web Crypto Key keying material <-- kty-specific parameters | |
51 // | |
52 // Values for each JWK entry are case-sensitive and defined in | |
53 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18. | |
54 // Note that not all values specified by JOSE are handled by this code. Only | |
55 // handled values are listed. | |
56 // - kty (Key Type) | |
57 // +-------+--------------------------------------------------------------+ | |
58 // | "RSA" | RSA [RFC3447] | | |
59 // | "oct" | Octet sequence (used to represent symmetric keys) | | |
60 // +-------+--------------------------------------------------------------+ | |
61 // | |
62 // - key_ops (Key Use Details) | |
63 // The key_ops field is an array that contains one or more strings from | |
64 // the table below, and describes the operations for which this key may be | |
65 // used. | |
66 // +-------+--------------------------------------------------------------+ | |
67 // | "encrypt" | encrypt operations | | |
68 // | "decrypt" | decrypt operations | | |
69 // | "sign" | sign (MAC) operations | | |
70 // | "verify" | verify (MAC) operations | | |
71 // | "wrapKey" | key wrap | | |
72 // | "unwrapKey" | key unwrap | | |
73 // | "deriveKey" | key derivation | | |
74 // | "deriveBits" | key derivation TODO(padolph): not currently supported | | |
75 // +-------+--------------------------------------------------------------+ | |
76 // | |
77 // - use (Key Use) | |
78 // The use field contains a single entry from the table below. | |
79 // +-------+--------------------------------------------------------------+ | |
80 // | "sig" | equivalent to key_ops of [sign, verify] | | |
81 // | "enc" | equivalent to key_ops of [encrypt, decrypt, wrapKey, | | |
82 // | | unwrapKey, deriveKey, deriveBits] | | |
83 // +-------+--------------------------------------------------------------+ | |
84 // | |
85 // NOTE: If both "use" and "key_ops" JWK members are present, the usages | |
86 // specified by them MUST be consistent. In particular, the "use" value | |
87 // "sig" corresponds to "sign" and/or "verify". The "use" value "enc" | |
88 // corresponds to all other values defined above. If "key_ops" values | |
89 // corresponding to both "sig" and "enc" "use" values are present, the "use" | |
90 // member SHOULD NOT be present, and if present, its value MUST NOT be | |
91 // either "sig" or "enc". | |
92 // | |
93 // - ext (Key Exportability) | |
94 // +-------+--------------------------------------------------------------+ | |
95 // | true | Key may be exported from the trusted environment | | |
96 // | false | Key cannot exit the trusted environment | | |
97 // +-------+--------------------------------------------------------------+ | |
98 // | |
99 // - alg (Algorithm) | |
100 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18 | |
101 // +--------------+-------------------------------------------------------+ | |
102 // | Digital Signature or MAC Algorithm | | |
103 // +--------------+-------------------------------------------------------+ | |
104 // | "HS1" | HMAC using SHA-1 hash algorithm | | |
105 // | "HS256" | HMAC using SHA-256 hash algorithm | | |
106 // | "HS384" | HMAC using SHA-384 hash algorithm | | |
107 // | "HS512" | HMAC using SHA-512 hash algorithm | | |
108 // | "RS1" | RSASSA using SHA-1 hash algorithm | |
109 // | "RS256" | RSASSA using SHA-256 hash algorithm | | |
110 // | "RS384" | RSASSA using SHA-384 hash algorithm | | |
111 // | "RS512" | RSASSA using SHA-512 hash algorithm | | |
112 // +--------------+-------------------------------------------------------| | |
113 // | Key Management Algorithm | | |
114 // +--------------+-------------------------------------------------------+ | |
115 // | "RSA1_5" | RSAES-PKCS1-V1_5 [RFC3447] | | |
116 // | "RSA-OAEP" | RSAES using Optimal Asymmetric Encryption Padding | | |
117 // | | (OAEP) [RFC3447], with the default parameters | | |
118 // | | specified by RFC3447 in Section A.2.1 | | |
119 // | "A128KW" | Advanced Encryption Standard (AES) Key Wrap Algorithm | | |
120 // | | [RFC3394] using 128 bit keys | | |
121 // | "A192KW" | AES Key Wrap Algorithm using 192 bit keys | | |
122 // | "A256KW" | AES Key Wrap Algorithm using 256 bit keys | | |
123 // | "A128GCM" | AES in Galois/Counter Mode (GCM) [NIST.800-38D] using | | |
124 // | | 128 bit keys | | |
125 // | "A192GCM" | AES GCM using 192 bit keys | | |
126 // | "A256GCM" | AES GCM using 256 bit keys | | |
127 // | "A128CBC" | AES in Cipher Block Chaining Mode (CBC) with PKCS #5 | | |
128 // | | padding [NIST.800-38A] | | |
129 // | "A192CBC" | AES CBC using 192 bit keys | | |
130 // | "A256CBC" | AES CBC using 256 bit keys | | |
131 // +--------------+-------------------------------------------------------+ | |
132 // | |
133 // kty-specific parameters | |
134 // The value of kty determines the type and content of the keying material | |
135 // carried in the JWK to be imported. Currently only two possibilities are | |
136 // supported: a raw key or an RSA public key. RSA private keys are not | |
137 // supported because typical applications seldom need to import a private key, | |
138 // and the large number of JWK parameters required to describe one. | |
139 // - kty == "oct" (symmetric or other raw key) | |
140 // +-------+--------------------------------------------------------------+ | |
141 // | "k" | Contains the value of the symmetric (or other single-valued) | | |
142 // | | key. It is represented as the base64url encoding of the | | |
143 // | | octet sequence containing the key value. | | |
144 // +-------+--------------------------------------------------------------+ | |
145 // - kty == "RSA" (RSA public key) | |
146 // +-------+--------------------------------------------------------------+ | |
147 // | "n" | Contains the modulus value for the RSA public key. It is | | |
148 // | | represented as the base64url encoding of the value's | | |
149 // | | unsigned big endian representation as an octet sequence. | | |
150 // +-------+--------------------------------------------------------------+ | |
151 // | "e" | Contains the exponent value for the RSA public key. It is | | |
152 // | | represented as the base64url encoding of the value's | | |
153 // | | unsigned big endian representation as an octet sequence. | | |
154 // +-------+--------------------------------------------------------------+ | |
155 // | |
156 // Consistency and conflict resolution | |
157 // The 'algorithm', 'extractable', and 'usage_mask' input parameters | |
158 // may be different than the corresponding values inside the JWK. The Web | |
159 // Crypto spec says that if a JWK value is present but is inconsistent with | |
160 // the input value, it is an error and the operation must fail. If no | |
161 // inconsistency is found then the input parameters are used. | |
162 // | |
163 // algorithm | |
164 // If the JWK algorithm is provided, it must match the web crypto input | |
165 // algorithm (both the algorithm ID and inner hash if applicable). | |
166 // | |
167 // extractable | |
168 // If the JWK ext field is true but the input parameter is false, make the | |
169 // Web Crypto Key non-extractable. Conversely, if the JWK ext field is | |
170 // false but the input parameter is true, it is an inconsistency. If both | |
171 // are true or both are false, use that value. | |
172 // | |
173 // usage_mask | |
174 // The input usage_mask must be a strict subset of the interpreted JWK use | |
175 // value, else it is judged inconsistent. In all cases the input usage_mask | |
176 // is used as the final usage_mask. | |
177 // | |
178 | |
23 namespace content { | 179 namespace content { |
24 | 180 |
25 namespace webcrypto { | 181 namespace webcrypto { |
26 | 182 |
27 namespace { | 183 namespace { |
28 | 184 |
29 // Creates an RSASSA-PKCS1-v1_5 algorithm. It is an error to call this with a | 185 // Creates an RSASSA-PKCS1-v1_5 algorithm. It is an error to call this with a |
30 // hash_id that is not a SHA*. | 186 // hash_id that is not a SHA*. |
31 blink::WebCryptoAlgorithm CreateRsaSsaImportAlgorithm( | 187 blink::WebCryptoAlgorithm CreateRsaSsaImportAlgorithm( |
32 blink::WebCryptoAlgorithmId hash_id) { | 188 blink::WebCryptoAlgorithmId hash_id) { |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
456 return Status::Success(); | 612 return Status::Success(); |
457 } | 613 } |
458 | 614 |
459 } // namespace | 615 } // namespace |
460 | 616 |
461 Status ImportKeyJwk(const CryptoData& key_data, | 617 Status ImportKeyJwk(const CryptoData& key_data, |
462 const blink::WebCryptoAlgorithm& algorithm, | 618 const blink::WebCryptoAlgorithm& algorithm, |
463 bool extractable, | 619 bool extractable, |
464 blink::WebCryptoKeyUsageMask usage_mask, | 620 blink::WebCryptoKeyUsageMask usage_mask, |
465 blink::WebCryptoKey* key) { | 621 blink::WebCryptoKey* key) { |
466 // TODO(padolph): Generalize this comment to include export, and move to top | |
467 // of file. | |
468 | |
469 // The goal of this method is to extract key material and meta data from the | |
470 // incoming JWK, combine them with the input parameters, and ultimately import | |
471 // a Web Crypto Key. | |
472 // | |
473 // JSON Web Key Format (JWK) | |
474 // http://tools.ietf.org/html/draft-ietf-jose-json-web-key-21 | |
475 // | |
476 // A JWK is a simple JSON dictionary with the following entries | |
477 // - "kty" (Key Type) Parameter, REQUIRED | |
478 // - <kty-specific parameters, see below>, REQUIRED | |
479 // - "use" (Key Use) Parameter, OPTIONAL | |
480 // - "key_ops" (Key Operations) Parameter, OPTIONAL | |
481 // - "alg" (Algorithm) Parameter, OPTIONAL | |
482 // - "ext" (Key Exportability), OPTIONAL | |
483 // (all other entries are ignored) | |
484 // | |
485 // OPTIONAL here means that this code does not require the entry to be present | |
486 // in the incoming JWK, because the method input parameters contain similar | |
487 // information. If the optional JWK entry is present, it will be validated | |
488 // against the corresponding input parameter for consistency and combined with | |
489 // it according to rules defined below. A special case is that the method | |
490 // input parameter 'algorithm' is also optional. If it is null, the JWK 'alg' | |
491 // value (if present) is used as a fallback. | |
492 // | |
493 // Input 'key_data' contains the JWK. To build a Web Crypto Key, the JWK | |
494 // values are parsed out and combined with the method input parameters to | |
495 // build a Web Crypto Key: | |
496 // Web Crypto Key type <-- (deduced) | |
497 // Web Crypto Key extractable <-- JWK ext + input extractable | |
498 // Web Crypto Key algorithm <-- JWK alg + input algorithm | |
499 // Web Crypto Key keyUsage <-- JWK use, key_ops + input usage_mask | |
500 // Web Crypto Key keying material <-- kty-specific parameters | |
501 // | |
502 // Values for each JWK entry are case-sensitive and defined in | |
503 // http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18. | |
504 // Note that not all values specified by JOSE are handled by this code. Only | |
505 // handled values are listed. | |
506 // - kty (Key Type) | |
507 // +-------+--------------------------------------------------------------+ | |
508 // | "RSA" | RSA [RFC3447] | | |
509 // | "oct" | Octet sequence (used to represent symmetric keys) | | |
510 // +-------+--------------------------------------------------------------+ | |
511 // | |
512 // - key_ops (Key Use Details) | |
513 // The key_ops field is an array that contains one or more strings from | |
514 // the table below, and describes the operations for which this key may be | |
515 // used. | |
516 // +-------+--------------------------------------------------------------+ | |
517 // | "encrypt" | encrypt operations | | |
518 // | "decrypt" | decrypt operations | | |
519 // | "sign" | sign (MAC) operations | | |
520 // | "verify" | verify (MAC) operations | | |
521 // | "wrapKey" | key wrap | | |
522 // | "unwrapKey" | key unwrap | | |
523 // | "deriveKey" | key derivation | | |
524 // | "deriveBits" | key derivation TODO(padolph): not currently supported | | |
525 // +-------+--------------------------------------------------------------+ | |
526 // | |
527 // - use (Key Use) | |
528 // The use field contains a single entry from the table below. | |
529 // +-------+--------------------------------------------------------------+ | |
530 // | "sig" | equivalent to key_ops of [sign, verify] | | |
531 // | "enc" | equivalent to key_ops of [encrypt, decrypt, wrapKey, | | |
532 // | | unwrapKey, deriveKey, deriveBits] | | |
533 // +-------+--------------------------------------------------------------+ | |
534 // | |
535 // NOTE: If both "use" and "key_ops" JWK members are present, the usages | |
536 // specified by them MUST be consistent. In particular, the "use" value | |
537 // "sig" corresponds to "sign" and/or "verify". The "use" value "enc" | |
538 // corresponds to all other values defined above. If "key_ops" values | |
539 // corresponding to both "sig" and "enc" "use" values are present, the "use" | |
540 // member SHOULD NOT be present, and if present, its value MUST NOT be | |
541 // either "sig" or "enc". | |
542 // | |
543 // - ext (Key Exportability) | |
544 // +-------+--------------------------------------------------------------+ | |
545 // | true | Key may be exported from the trusted environment | | |
546 // | false | Key cannot exit the trusted environment | | |
547 // +-------+--------------------------------------------------------------+ | |
548 // | |
549 // - alg (Algorithm) | |
550 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18 | |
551 // +--------------+-------------------------------------------------------+ | |
552 // | Digital Signature or MAC Algorithm | | |
553 // +--------------+-------------------------------------------------------+ | |
554 // | "HS1" | HMAC using SHA-1 hash algorithm | | |
555 // | "HS256" | HMAC using SHA-256 hash algorithm | | |
556 // | "HS384" | HMAC using SHA-384 hash algorithm | | |
557 // | "HS512" | HMAC using SHA-512 hash algorithm | | |
558 // | "RS1" | RSASSA using SHA-1 hash algorithm | |
559 // | "RS256" | RSASSA using SHA-256 hash algorithm | | |
560 // | "RS384" | RSASSA using SHA-384 hash algorithm | | |
561 // | "RS512" | RSASSA using SHA-512 hash algorithm | | |
562 // +--------------+-------------------------------------------------------| | |
563 // | Key Management Algorithm | | |
564 // +--------------+-------------------------------------------------------+ | |
565 // | "RSA1_5" | RSAES-PKCS1-V1_5 [RFC3447] | | |
566 // | "RSA-OAEP" | RSAES using Optimal Asymmetric Encryption Padding | | |
567 // | | (OAEP) [RFC3447], with the default parameters | | |
568 // | | specified by RFC3447 in Section A.2.1 | | |
569 // | "A128KW" | Advanced Encryption Standard (AES) Key Wrap Algorithm | | |
570 // | | [RFC3394] using 128 bit keys | | |
571 // | "A192KW" | AES Key Wrap Algorithm using 192 bit keys | | |
572 // | "A256KW" | AES Key Wrap Algorithm using 256 bit keys | | |
573 // | "A128GCM" | AES in Galois/Counter Mode (GCM) [NIST.800-38D] using | | |
574 // | | 128 bit keys | | |
575 // | "A192GCM" | AES GCM using 192 bit keys | | |
576 // | "A256GCM" | AES GCM using 256 bit keys | | |
577 // | "A128CBC" | AES in Cipher Block Chaining Mode (CBC) with PKCS #5 | | |
578 // | | padding [NIST.800-38A] | | |
579 // | "A192CBC" | AES CBC using 192 bit keys | | |
580 // | "A256CBC" | AES CBC using 256 bit keys | | |
581 // +--------------+-------------------------------------------------------+ | |
582 // | |
583 // kty-specific parameters | |
584 // The value of kty determines the type and content of the keying material | |
585 // carried in the JWK to be imported. Currently only two possibilities are | |
586 // supported: a raw key or an RSA public key. RSA private keys are not | |
587 // supported because typical applications seldom need to import a private key, | |
588 // and the large number of JWK parameters required to describe one. | |
589 // - kty == "oct" (symmetric or other raw key) | |
590 // +-------+--------------------------------------------------------------+ | |
591 // | "k" | Contains the value of the symmetric (or other single-valued) | | |
592 // | | key. It is represented as the base64url encoding of the | | |
593 // | | octet sequence containing the key value. | | |
594 // +-------+--------------------------------------------------------------+ | |
595 // - kty == "RSA" (RSA public key) | |
596 // +-------+--------------------------------------------------------------+ | |
597 // | "n" | Contains the modulus value for the RSA public key. It is | | |
598 // | | represented as the base64url encoding of the value's | | |
599 // | | unsigned big endian representation as an octet sequence. | | |
600 // +-------+--------------------------------------------------------------+ | |
601 // | "e" | Contains the exponent value for the RSA public key. It is | | |
602 // | | represented as the base64url encoding of the value's | | |
603 // | | unsigned big endian representation as an octet sequence. | | |
604 // +-------+--------------------------------------------------------------+ | |
605 // | |
606 // Consistency and conflict resolution | |
607 // The 'algorithm', 'extractable', and 'usage_mask' input parameters | |
608 // may be different than the corresponding values inside the JWK. The Web | |
609 // Crypto spec says that if a JWK value is present but is inconsistent with | |
610 // the input value, it is an error and the operation must fail. If no | |
611 // inconsistency is found then the input parameters are used. | |
612 // | |
613 // algorithm | |
614 // If the JWK algorithm is provided, it must match the web crypto input | |
615 // algorithm (both the algorithm ID and inner hash if applicable). | |
616 // | |
617 // extractable | |
618 // If the JWK ext field is true but the input parameter is false, make the | |
619 // Web Crypto Key non-extractable. Conversely, if the JWK ext field is | |
620 // false but the input parameter is true, it is an inconsistency. If both | |
621 // are true or both are false, use that value. | |
622 // | |
623 // usage_mask | |
624 // The input usage_mask must be a strict subset of the interpreted JWK use | |
625 // value, else it is judged inconsistent. In all cases the input usage_mask | |
626 // is used as the final usage_mask. | |
627 // | |
628 | |
629 if (!key_data.byte_length()) | 622 if (!key_data.byte_length()) |
630 return Status::ErrorImportEmptyKeyData(); | 623 return Status::ErrorImportEmptyKeyData(); |
631 DCHECK(key); | 624 DCHECK(key); |
632 | 625 |
633 // Parse the incoming JWK JSON. | 626 // Parse the incoming JWK JSON. |
634 base::StringPiece json_string(reinterpret_cast<const char*>(key_data.bytes()), | 627 base::StringPiece json_string(reinterpret_cast<const char*>(key_data.bytes()), |
635 key_data.byte_length()); | 628 key_data.byte_length()); |
636 scoped_ptr<base::Value> value(base::JSONReader::Read(json_string)); | 629 scoped_ptr<base::Value> value(base::JSONReader::Read(json_string)); |
637 // Note, bare pointer dict_value is ok since it points into scoped value. | 630 // Note, bare pointer dict_value is ok since it points into scoped value. |
638 base::DictionaryValue* dict_value = NULL; | 631 base::DictionaryValue* dict_value = NULL; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
835 | 828 |
836 std::string json; | 829 std::string json; |
837 base::JSONWriter::Write(&jwk_dict, &json); | 830 base::JSONWriter::Write(&jwk_dict, &json); |
838 buffer->assign(json.data(), json.data() + json.size()); | 831 buffer->assign(json.data(), json.data() + json.size()); |
839 return Status::Success(); | 832 return Status::Success(); |
840 } | 833 } |
841 | 834 |
842 } // namespace webcrypto | 835 } // namespace webcrypto |
843 | 836 |
844 } // namespace content | 837 } // namespace content |
OLD | NEW |