1/*
2 * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "CryptoKey.h"
29#include "CryptoKeyPair.h"
30#include "ExceptionOr.h"
31
32#if ENABLE(WEB_CRYPTO)
33
34#if OS(DARWIN) && !PLATFORM(GTK)
35#include "CommonCryptoUtilities.h"
36
37typedef CCECCryptorRef PlatformECKey;
38namespace WebCore {
39struct CCECCryptorRefDeleter {
40 void operator()(CCECCryptorRef key) const { CCECCryptorRelease(key); }
41};
42}
43typedef std::unique_ptr<typename std::remove_pointer<CCECCryptorRef>::type, WebCore::CCECCryptorRefDeleter> PlatformECKeyContainer;
44#endif
45
46#if PLATFORM(GTK) || PLATFORM(WPE)
47#include <pal/crypto/gcrypt/Handle.h>
48
49typedef gcry_sexp_t PlatformECKey;
50typedef std::unique_ptr<typename std::remove_pointer<gcry_sexp_t>::type, PAL::GCrypt::HandleDeleter<gcry_sexp_t>> PlatformECKeyContainer;
51#endif
52
53
54namespace WebCore {
55
56struct JsonWebKey;
57
58class CryptoKeyEC final : public CryptoKey {
59public:
60 enum class NamedCurve {
61 P256,
62 P384,
63 P521,
64 };
65
66 static Ref<CryptoKeyEC> create(CryptoAlgorithmIdentifier identifier, NamedCurve curve, CryptoKeyType type, PlatformECKeyContainer&& platformKey, bool extractable, CryptoKeyUsageBitmap usages)
67 {
68 return adoptRef(*new CryptoKeyEC(identifier, curve, type, WTFMove(platformKey), extractable, usages));
69 }
70 virtual ~CryptoKeyEC() = default;
71
72 static ExceptionOr<CryptoKeyPair> generatePair(CryptoAlgorithmIdentifier, const String& curve, bool extractable, CryptoKeyUsageBitmap);
73 static RefPtr<CryptoKeyEC> importRaw(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
74 static RefPtr<CryptoKeyEC> importJwk(CryptoAlgorithmIdentifier, const String& curve, JsonWebKey&&, bool extractable, CryptoKeyUsageBitmap);
75 static RefPtr<CryptoKeyEC> importSpki(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
76 static RefPtr<CryptoKeyEC> importPkcs8(CryptoAlgorithmIdentifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
77
78 ExceptionOr<Vector<uint8_t>> exportRaw() const;
79 ExceptionOr<JsonWebKey> exportJwk() const;
80 ExceptionOr<Vector<uint8_t>> exportSpki() const;
81 ExceptionOr<Vector<uint8_t>> exportPkcs8() const;
82
83 size_t keySizeInBits() const;
84 NamedCurve namedCurve() const { return m_curve; }
85 String namedCurveString() const;
86 PlatformECKey platformKey() const { return m_platformKey.get(); }
87 static bool isValidECAlgorithm(CryptoAlgorithmIdentifier);
88
89private:
90 CryptoKeyEC(CryptoAlgorithmIdentifier, NamedCurve, CryptoKeyType, PlatformECKeyContainer&&, bool extractable, CryptoKeyUsageBitmap);
91
92 CryptoKeyClass keyClass() const final { return CryptoKeyClass::EC; }
93
94 KeyAlgorithm algorithm() const final;
95
96 static bool platformSupportedCurve(NamedCurve);
97 static Optional<CryptoKeyPair> platformGeneratePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap);
98 static RefPtr<CryptoKeyEC> platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
99 static RefPtr<CryptoKeyEC> platformImportJWKPublic(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap);
100 static RefPtr<CryptoKeyEC> platformImportJWKPrivate(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, Vector<uint8_t>&& d, bool extractable, CryptoKeyUsageBitmap);
101 static RefPtr<CryptoKeyEC> platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
102 static RefPtr<CryptoKeyEC> platformImportPkcs8(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
103 Vector<uint8_t> platformExportRaw() const;
104 bool platformAddFieldElements(JsonWebKey&) const;
105 Vector<uint8_t> platformExportSpki() const;
106 Vector<uint8_t> platformExportPkcs8() const;
107
108 PlatformECKeyContainer m_platformKey;
109 NamedCurve m_curve;
110};
111
112} // namespace WebCore
113
114SPECIALIZE_TYPE_TRAITS_CRYPTO_KEY(CryptoKeyEC, CryptoKeyClass::EC)
115
116#endif // ENABLE(WEB_CRYPTO)
117