- add sources.
[platform/framework/web/crosswalk.git] / src / net / cert / jwk_serializer_nss.cc
1 // Copyright 2013 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/jwk_serializer.h"
6
7 #include <cert.h>
8 #include <keyhi.h>
9 #include <nss.h>
10
11 #include "base/base64.h"
12 #include "base/values.h"
13 #include "crypto/nss_util.h"
14 #include "crypto/scoped_nss_types.h"
15
16 namespace net {
17
18 namespace JwkSerializer {
19
20 namespace {
21
22 bool ConvertEcPrime256v1PublicKeyInfoToJwk(
23     CERTSubjectPublicKeyInfo* spki,
24     base::DictionaryValue* public_key_jwk) {
25   static const int kUncompressedEncodingType = 4;
26   static const int kPrime256v1PublicKeyLength = 64;
27   // The public key value is encoded as 0x04 + 64 bytes of public key.
28   // NSS gives the length as the bit length.
29   if (spki->subjectPublicKey.len != (kPrime256v1PublicKeyLength + 1) * 8 ||
30       spki->subjectPublicKey.data[0] != kUncompressedEncodingType)
31     return false;
32
33   public_key_jwk->SetString("alg", "EC");
34   public_key_jwk->SetString("crv", "P-256");
35
36   base::StringPiece x(
37       reinterpret_cast<char*>(spki->subjectPublicKey.data + 1),
38       kPrime256v1PublicKeyLength / 2);
39   std::string x_b64;
40   base::Base64Encode(x, &x_b64);
41   public_key_jwk->SetString("x", x_b64);
42
43   base::StringPiece y(
44       reinterpret_cast<char*>(spki->subjectPublicKey.data + 1 +
45                               kPrime256v1PublicKeyLength / 2),
46       kPrime256v1PublicKeyLength / 2);
47   std::string y_b64;
48   base::Base64Encode(y, &y_b64);
49   public_key_jwk->SetString("y", y_b64);
50   return true;
51 }
52
53 bool ConvertEcPublicKeyInfoToJwk(
54     CERTSubjectPublicKeyInfo* spki,
55     base::DictionaryValue* public_key_jwk) {
56   // 1.2.840.10045.3.1.7
57   // (iso.member-body.us.ansi-x9-62.ellipticCurve.primeCurve.prime256v1)
58   // (This includes the DER-encoded type (OID) and length: parameters can be
59   // anything, so the DER type isn't implied, and NSS includes it.)
60   static const unsigned char kPrime256v1[] = {
61     0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
62   };
63   if (spki->algorithm.parameters.len == sizeof(kPrime256v1) &&
64       !memcmp(spki->algorithm.parameters.data, kPrime256v1,
65               sizeof(kPrime256v1))) {
66     return ConvertEcPrime256v1PublicKeyInfoToJwk(spki, public_key_jwk);
67   }
68   // TODO(juanlang): other curves
69   return false;
70 }
71
72 typedef scoped_ptr_malloc<
73     CERTSubjectPublicKeyInfo,
74     crypto::NSSDestroyer<CERTSubjectPublicKeyInfo,
75                          SECKEY_DestroySubjectPublicKeyInfo> >
76     ScopedCERTSubjectPublicKeyInfo;
77
78 }  // namespace
79
80 bool ConvertSpkiFromDerToJwk(
81     const base::StringPiece& spki_der,
82     base::DictionaryValue* public_key_jwk) {
83   public_key_jwk->Clear();
84
85   crypto::EnsureNSSInit();
86
87   if (!NSS_IsInitialized())
88     return false;
89
90   SECItem sec_item;
91   sec_item.data = const_cast<unsigned char*>(
92       reinterpret_cast<const unsigned char*>(spki_der.data()));
93   sec_item.len = spki_der.size();
94   ScopedCERTSubjectPublicKeyInfo spki(
95       SECKEY_DecodeDERSubjectPublicKeyInfo(&sec_item));
96   if (!spki)
97     return false;
98
99   // 1.2.840.10045.2
100   // (iso.member-body.us.ansi-x9-62.id-ecPublicKey)
101   // (This omits the ASN.1 encoding of the type (OID) and length: the fact that
102   // this is an OID is already clear, and NSS omits it here.)
103   static const unsigned char kIdEcPublicKey[] = {
104     0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01
105   };
106   bool rv = false;
107   if (spki->algorithm.algorithm.len == sizeof(kIdEcPublicKey) &&
108       !memcmp(spki->algorithm.algorithm.data, kIdEcPublicKey,
109               sizeof(kIdEcPublicKey))) {
110     rv = ConvertEcPublicKeyInfoToJwk(spki.get(), public_key_jwk);
111   }
112   // TODO(juanlang): other algorithms
113   return rv;
114 }
115
116 }  // namespace JwkSerializer
117
118 }  // namespace net