Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / child / webcrypto / structured_clone.cc
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.
4
5 #include "content/child/webcrypto/structured_clone.h"
6
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"
13
14 namespace content {
15
16 namespace webcrypto {
17
18 namespace {
19
20 // Returns the key format to use for structured cloning.
21 blink::WebCryptoKeyFormat GetCloneFormatForKeyType(
22     blink::WebCryptoKeyType type) {
23   switch (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;
30   }
31
32   NOTREACHED();
33   return blink::WebCryptoKeyFormatRaw;
34 }
35
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:
48       break;
49     default:
50       break;
51   }
52   return blink::WebCryptoAlgorithm::createNull();
53 }
54
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.
59 //
60 // A failure here implies either a bug in the code, or that the serialized data
61 // was corrupted.
62 bool ValidateDeserializedKey(const blink::WebCryptoKey& key,
63                              const blink::WebCryptoKeyAlgorithm& algorithm,
64                              blink::WebCryptoKeyType type) {
65   if (algorithm.id() != key.algorithm().id())
66     return false;
67
68   if (key.type() != type)
69     return false;
70
71   switch (algorithm.paramsType()) {
72     case blink::WebCryptoKeyAlgorithmParamsTypeAes:
73       if (algorithm.aesParams()->lengthBits() !=
74           key.algorithm().aesParams()->lengthBits())
75         return false;
76       break;
77     case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
78       if (algorithm.rsaHashedParams()->modulusLengthBits() !=
79           key.algorithm().rsaHashedParams()->modulusLengthBits())
80         return false;
81       if (algorithm.rsaHashedParams()->publicExponent().size() !=
82           key.algorithm().rsaHashedParams()->publicExponent().size())
83         return false;
84       if (memcmp(algorithm.rsaHashedParams()->publicExponent().data(),
85                  key.algorithm().rsaHashedParams()->publicExponent().data(),
86                  key.algorithm().rsaHashedParams()->publicExponent().size()) !=
87           0)
88         return false;
89       break;
90     case blink::WebCryptoKeyAlgorithmParamsTypeNone:
91     case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
92       break;
93     default:
94       return false;
95   }
96
97   return true;
98 }
99
100 }  // namespace
101
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);
106 }
107
108 // Note that this function is called from the target Blink thread.
109 bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
110                             blink::WebCryptoKeyType type,
111                             bool extractable,
112                             blink::WebCryptoKeyUsageMask usages,
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
117   // are held.
118   //
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),
124                             key_data,
125                             KeyAlgorithmToImportAlgorithm(algorithm),
126                             extractable,
127                             usages,
128                             key);
129   if (status.IsError())
130     return false;
131   return ValidateDeserializedKey(*key, algorithm, type);
132 }
133
134 }  // namespace webcrypto
135
136 }  // namespace content