blob: 3fe3fe85547c4c572ddd26da76862b18bc79af6a [file] [log] [blame]
eromand62cb472015-09-18 18:24:231// 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 "components/webcrypto/key.h"
6
7#include "base/logging.h"
8#include "base/macros.h"
9#include "components/webcrypto/crypto_data.h"
10#include "components/webcrypto/status.h"
11#include "components/webcrypto/webcrypto_util.h"
12
13namespace webcrypto {
14
15namespace {
16
17class SymKey;
18class AsymKey;
19
20// Base class for wrapping OpenSSL keys in a type that can be passed to
21// Blink (blink::WebCryptoKeyHandle).
22//
23// In addition to the key's internal OpenSSL representation (EVP_PKEY or just
24// raw bytes), each key maintains a copy of its serialized form in either
25// 'raw', 'pkcs8', or 'spki' format. This is to allow structured cloning of
26// keys to be done synchronously from the target Blink thread, without having to
27// lock access to the key throughout the code.
28class Key : public blink::WebCryptoKeyHandle {
29 public:
30 explicit Key(const CryptoData& serialized_key_data)
31 : serialized_key_data_(
32 serialized_key_data.bytes(),
33 serialized_key_data.bytes() + serialized_key_data.byte_length()) {}
34
35 ~Key() override {}
36
37 // Helpers to add some safety to casting.
38 virtual SymKey* AsSymKey() { return nullptr; }
39 virtual AsymKey* AsAsymKey() { return nullptr; }
40
41 const std::vector<uint8_t>& serialized_key_data() const {
42 return serialized_key_data_;
43 }
44
45 private:
46 const std::vector<uint8_t> serialized_key_data_;
47};
48
49class SymKey : public Key {
50 public:
51 explicit SymKey(const CryptoData& raw_key_data) : Key(raw_key_data) {}
52
53 SymKey* AsSymKey() override { return this; }
54
55 const std::vector<uint8_t>& raw_key_data() const {
56 return serialized_key_data();
57 }
58
59 private:
60 DISALLOW_COPY_AND_ASSIGN(SymKey);
61};
62
63class AsymKey : public Key {
64 public:
65 AsymKey(crypto::ScopedEVP_PKEY pkey,
66 const std::vector<uint8_t>& serialized_key_data)
67 : Key(CryptoData(serialized_key_data)), pkey_(pkey.Pass()) {}
68
69 AsymKey* AsAsymKey() override { return this; }
70
71 EVP_PKEY* pkey() { return pkey_.get(); }
72
73 private:
74 crypto::ScopedEVP_PKEY pkey_;
75
76 DISALLOW_COPY_AND_ASSIGN(AsymKey);
77};
78
79Key* GetKey(const blink::WebCryptoKey& key) {
80 return reinterpret_cast<Key*>(key.handle());
81}
82
83} // namespace
84
85const std::vector<uint8_t>& GetSymmetricKeyData(
86 const blink::WebCryptoKey& key) {
87 DCHECK_EQ(blink::WebCryptoKeyTypeSecret, key.type());
88 return GetKey(key)->AsSymKey()->raw_key_data();
89}
90
91EVP_PKEY* GetEVP_PKEY(const blink::WebCryptoKey& key) {
92 DCHECK_NE(blink::WebCryptoKeyTypeSecret, key.type());
93 return GetKey(key)->AsAsymKey()->pkey();
94}
95
96const std::vector<uint8_t>& GetSerializedKeyData(
97 const blink::WebCryptoKey& key) {
98 return GetKey(key)->serialized_key_data();
99}
100
101blink::WebCryptoKeyHandle* CreateSymmetricKeyHandle(
102 const CryptoData& key_bytes) {
103 return new SymKey(key_bytes);
104}
105
106blink::WebCryptoKeyHandle* CreateAsymmetricKeyHandle(
107 crypto::ScopedEVP_PKEY pkey,
108 const std::vector<uint8_t>& serialized_key_data) {
109 return new AsymKey(pkey.Pass(), serialized_key_data);
110}
111
112} // namespace webcrypto