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
3 // found in the LICENSE file.
5 #include "content/child/webcrypto/structured_clone.h"
7 #include "base/logging.h"
8 #include "content/child/webcrypto/algorithm_dispatch.h"
9 #include "content/child/webcrypto/platform_crypto.h"
10 #include "content/child/webcrypto/status.h"
11 #include "content/child/webcrypto/webcrypto_util.h"
12 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
20 // Returns the key format to use for structured cloning.
21 blink::WebCryptoKeyFormat
GetCloneFormatForKeyType(
22 blink::WebCryptoKeyType type
) {
24 case blink::WebCryptoKeyTypeSecret
:
25 return blink::WebCryptoKeyFormatRaw
;
26 case blink::WebCryptoKeyTypePublic
:
27 return blink::WebCryptoKeyFormatSpki
;
28 case blink::WebCryptoKeyTypePrivate
:
29 return blink::WebCryptoKeyFormatPkcs8
;
33 return blink::WebCryptoKeyFormatRaw
;
36 // Converts a KeyAlgorithm into an equivalent Algorithm for import.
37 blink::WebCryptoAlgorithm
KeyAlgorithmToImportAlgorithm(
38 const blink::WebCryptoKeyAlgorithm
& algorithm
) {
39 switch (algorithm
.paramsType()) {
40 case blink::WebCryptoKeyAlgorithmParamsTypeAes
:
41 return CreateAlgorithm(algorithm
.id());
42 case blink::WebCryptoKeyAlgorithmParamsTypeHmac
:
43 return CreateHmacImportAlgorithm(algorithm
.hmacParams()->hash().id());
44 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed
:
45 return CreateRsaHashedImportAlgorithm(
46 algorithm
.id(), algorithm
.rsaHashedParams()->hash().id());
47 case blink::WebCryptoKeyAlgorithmParamsTypeNone
:
52 return blink::WebCryptoAlgorithm::createNull();
55 // There is some duplicated information in the serialized format used by
56 // structured clone (since the KeyAlgorithm is serialized separately from the
57 // key data). Use this extra information to further validate what was
58 // deserialized from the key data.
60 // A failure here implies either a bug in the code, or that the serialized data
62 bool ValidateDeserializedKey(const blink::WebCryptoKey
& key
,
63 const blink::WebCryptoKeyAlgorithm
& algorithm
,
64 blink::WebCryptoKeyType type
) {
65 if (algorithm
.id() != key
.algorithm().id())
68 if (key
.type() != type
)
71 switch (algorithm
.paramsType()) {
72 case blink::WebCryptoKeyAlgorithmParamsTypeAes
:
73 if (algorithm
.aesParams()->lengthBits() !=
74 key
.algorithm().aesParams()->lengthBits())
77 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed
:
78 if (algorithm
.rsaHashedParams()->modulusLengthBits() !=
79 key
.algorithm().rsaHashedParams()->modulusLengthBits())
81 if (algorithm
.rsaHashedParams()->publicExponent().size() !=
82 key
.algorithm().rsaHashedParams()->publicExponent().size())
84 if (memcmp(algorithm
.rsaHashedParams()->publicExponent().data(),
85 key
.algorithm().rsaHashedParams()->publicExponent().data(),
86 key
.algorithm().rsaHashedParams()->publicExponent().size()) !=
90 case blink::WebCryptoKeyAlgorithmParamsTypeNone
:
91 case blink::WebCryptoKeyAlgorithmParamsTypeHmac
:
102 // Note that this function is called from the target Blink thread.
103 bool SerializeKeyForClone(const blink::WebCryptoKey
& key
,
104 blink::WebVector
<uint8_t>* key_data
) {
105 return PlatformSerializeKeyForClone(key
, key_data
);
108 // Note that this function is called from the target Blink thread.
109 bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm
& algorithm
,
110 blink::WebCryptoKeyType type
,
112 blink::WebCryptoKeyUsageMask usage_mask
,
113 const CryptoData
& key_data
,
114 blink::WebCryptoKey
* key
) {
115 // TODO(eroman): This should not call into the platform crypto layer.
116 // Otherwise it runs the risk of stalling while the NSS/OpenSSL global locks
119 // An alternate approach is to defer the key import until the key is used.
120 // However this means that any deserialization errors would have to be
121 // surfaced as WebCrypto errors, leading to slightly different behaviors. For
122 // instance you could clone a key which fails to be deserialized.
123 Status status
= ImportKey(GetCloneFormatForKeyType(type
),
125 KeyAlgorithmToImportAlgorithm(algorithm
),
129 if (status
.IsError())
131 return ValidateDeserializedKey(*key
, algorithm
, type
);
134 } // namespace webcrypto
136 } // namespace content