[WPE] Build more files under WebCore as unified sources and get rid of WebCorePlatfor...
[WebKit-https.git] / Source / WebCore / crypto / gcrypt / GCryptUtilities.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2017 Metrological Group B.V.
4  * Copyright (C) 2017 Igalia S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #pragma once
29
30 #include "CryptoAlgorithmIdentifier.h"
31 #include <array>
32 #include <cstring>
33 #include <gcrypt.h>
34 #include <pal/crypto/CryptoDigest.h>
35 #include <pal/crypto/gcrypt/Handle.h>
36 #include <pal/crypto/gcrypt/Utilities.h>
37
38 namespace WebCore {
39
40 namespace CryptoConstants {
41
42 static const std::array<uint8_t, 18> s_ecPublicKeyIdentifier { { "1.2.840.10045.2.1" } };
43 static const std::array<uint8_t, 13> s_ecDHIdentifier { { "1.3.132.1.12" } };
44
45 static const std::array<uint8_t, 20> s_secp256r1Identifier { { "1.2.840.10045.3.1.7" } };
46 static const std::array<uint8_t, 13> s_secp384r1Identifier { { "1.3.132.0.34" } };
47 static const std::array<uint8_t, 13> s_secp521r1Identifier { { "1.3.132.0.35" } };
48
49 static const std::array<uint8_t, 21> s_rsaEncryptionIdentifier { { "1.2.840.113549.1.1.1" } };
50 static const std::array<uint8_t, 21> s_RSAES_OAEPIdentifier { { "1.2.840.113549.1.1.7" } };
51 static const std::array<uint8_t, 22> s_RSASSA_PSSIdentifier { { "1.2.840.113549.1.1.10" } };
52
53 static const std::array<uint8_t, 2> s_asn1NullValue { { 0x05, 0x00 } };
54 static const std::array<uint8_t, 1> s_asn1Version0 { { 0x00 } };
55 static const std::array<uint8_t, 1> s_asn1Version1 { { 0x01 } };
56
57 static const std::array<uint8_t, 1> s_ecUncompressedFormatLeadingByte { { 0x04 } };
58
59 template<size_t N>
60 static inline bool matches(const void* lhs, size_t size, const std::array<uint8_t, N>& rhs)
61 {
62     if (size != rhs.size())
63         return false;
64
65     return !std::memcmp(lhs, rhs.data(), rhs.size());
66 }
67
68 } // namespace CryptoConstants
69
70 static inline std::optional<const char*> hashAlgorithmName(CryptoAlgorithmIdentifier identifier)
71 {
72     switch (identifier) {
73     case CryptoAlgorithmIdentifier::SHA_1:
74         return "sha1";
75     case CryptoAlgorithmIdentifier::SHA_224:
76         return "sha224";
77     case CryptoAlgorithmIdentifier::SHA_256:
78         return "sha256";
79     case CryptoAlgorithmIdentifier::SHA_384:
80         return "sha384";
81     case CryptoAlgorithmIdentifier::SHA_512:
82         return "sha512";
83     default:
84         return std::nullopt;
85     }
86 }
87
88 static inline std::optional<int> hmacAlgorithm(CryptoAlgorithmIdentifier identifier)
89 {
90     switch (identifier) {
91     case CryptoAlgorithmIdentifier::SHA_1:
92         return GCRY_MAC_HMAC_SHA1;
93     case CryptoAlgorithmIdentifier::SHA_224:
94         return GCRY_MAC_HMAC_SHA224;
95     case CryptoAlgorithmIdentifier::SHA_256:
96         return GCRY_MAC_HMAC_SHA256;
97     case CryptoAlgorithmIdentifier::SHA_384:
98         return GCRY_MAC_HMAC_SHA384;
99     case CryptoAlgorithmIdentifier::SHA_512:
100         return GCRY_MAC_HMAC_SHA512;
101     default:
102         return std::nullopt;
103     }
104 }
105
106 static inline std::optional<int> digestAlgorithm(CryptoAlgorithmIdentifier identifier)
107 {
108     switch (identifier) {
109     case CryptoAlgorithmIdentifier::SHA_1:
110         return GCRY_MD_SHA1;
111     case CryptoAlgorithmIdentifier::SHA_224:
112         return GCRY_MD_SHA224;
113     case CryptoAlgorithmIdentifier::SHA_256:
114         return GCRY_MD_SHA256;
115     case CryptoAlgorithmIdentifier::SHA_384:
116         return GCRY_MD_SHA384;
117     case CryptoAlgorithmIdentifier::SHA_512:
118         return GCRY_MD_SHA512;
119     default:
120         return std::nullopt;
121     }
122 }
123
124 static inline std::optional<PAL::CryptoDigest::Algorithm> hashCryptoDigestAlgorithm(CryptoAlgorithmIdentifier identifier)
125 {
126     switch (identifier) {
127     case CryptoAlgorithmIdentifier::SHA_1:
128         return PAL::CryptoDigest::Algorithm::SHA_1;
129     case CryptoAlgorithmIdentifier::SHA_224:
130         return PAL::CryptoDigest::Algorithm::SHA_224;
131     case CryptoAlgorithmIdentifier::SHA_256:
132         return PAL::CryptoDigest::Algorithm::SHA_256;
133     case CryptoAlgorithmIdentifier::SHA_384:
134         return PAL::CryptoDigest::Algorithm::SHA_384;
135     case CryptoAlgorithmIdentifier::SHA_512:
136         return PAL::CryptoDigest::Algorithm::SHA_512;
137     default:
138         return std::nullopt;
139     }
140 }
141
142 static inline std::optional<size_t> mpiLength(gcry_mpi_t paramMPI)
143 {
144     // Retrieve the MPI length for the unsigned format.
145     size_t dataLength = 0;
146     gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI);
147     if (error != GPG_ERR_NO_ERROR) {
148         PAL::GCrypt::logError(error);
149         return std::nullopt;
150     }
151
152     return dataLength;
153 }
154
155 static inline std::optional<size_t> mpiLength(gcry_sexp_t paramSexp)
156 {
157     // Retrieve the MPI value stored in the s-expression: (name mpi-data)
158     PAL::GCrypt::Handle<gcry_mpi_t> paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG));
159     if (!paramMPI)
160         return std::nullopt;
161
162     return mpiLength(paramMPI);
163 }
164
165 static inline std::optional<Vector<uint8_t>> mpiData(gcry_mpi_t paramMPI)
166 {
167     // Retrieve the MPI length.
168     auto length = mpiLength(paramMPI);
169     if (!length)
170         return std::nullopt;
171
172     // Copy the MPI data into a properly-sized buffer.
173     Vector<uint8_t> output(*length);
174     gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI);
175     if (error != GPG_ERR_NO_ERROR) {
176         PAL::GCrypt::logError(error);
177         return std::nullopt;
178     }
179
180     return output;
181 }
182
183 static inline std::optional<Vector<uint8_t>> mpiData(gcry_sexp_t paramSexp)
184 {
185     // Retrieve the MPI value stored in the s-expression: (name mpi-data)
186     PAL::GCrypt::Handle<gcry_mpi_t> paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG));
187     if (!paramMPI)
188         return std::nullopt;
189
190     return mpiData(paramMPI);
191 }
192
193 static inline std::optional<Vector<uint8_t>> mpiSignedData(gcry_mpi_t mpi)
194 {
195     auto data = mpiData(mpi);
196     if (!data)
197         return std::nullopt;
198
199     if (data->at(0) & 0x80)
200         data->insert(0, 0x00);
201
202     return data;
203 }
204
205 static inline std::optional<Vector<uint8_t>> mpiSignedData(gcry_sexp_t paramSexp)
206 {
207     auto data = mpiData(paramSexp);
208     if (!data)
209         return std::nullopt;
210
211     if (data->at(0) & 0x80)
212         data->insert(0, 0x00);
213
214     return data;
215 }
216
217 } // namespace WebCore