1 /*
2  * Copyright 2019, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
18 #define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
19 
20 #include <openssl/evp.h>
21 
22 #include <cstdint>
23 #include <map>
24 #include <optional>
25 #include <string>
26 #include <tuple>
27 #include <utility>
28 #include <vector>
29 
30 namespace android {
31 namespace hardware {
32 namespace identity {
33 namespace support {
34 
35 using ::std::map;
36 using ::std::optional;
37 using ::std::pair;
38 using ::std::string;
39 using ::std::tuple;
40 using ::std::vector;
41 
42 // The semantic tag for a bstr which includes Encoded CBOR (RFC 7049, section 2.4)
43 const int kSemanticTagEncodedCbor = 24;
44 
45 // ---------------------------------------------------------------------------
46 // Miscellaneous utilities.
47 // ---------------------------------------------------------------------------
48 
49 // Dumps the data in |data| to stderr. The written data will be of the following
50 // form for the call hexdump("signature", data) where |data| is of size 71:
51 //
52 //   signature: dumping 71 bytes
53 //   0000  30 45 02 21 00 ac c6 12 60 56 a2 e9 ee 16 be 14  0E.!....`V......
54 //   0010  69 7f c4 00 95 8c e8 55 1f 22 de 34 0b 08 8a 3b  i......U.".4...;
55 //   0020  a0 56 54 05 07 02 20 58 77 d9 8c f9 eb 41 df fd  .VT... Xw....A..
56 //   0030  c1 a3 14 e0 bf b0 a2 c5 0c b6 85 8c 4a 0d f9 2b  ............J..+
57 //   0040  b7 8f d2 1d 9b 11 ac                             .......
58 //
59 // This should only be used for debugging.
60 void hexdump(const string& name, const vector<uint8_t>& data);
61 
62 string encodeHex(const string& str);
63 
64 string encodeHex(const vector<uint8_t>& data);
65 
66 string encodeHex(const uint8_t* data, size_t dataLen);
67 
68 optional<vector<uint8_t>> decodeHex(const string& hexEncoded);
69 
70 // ---------------------------------------------------------------------------
71 // CBOR utilities.
72 // ---------------------------------------------------------------------------
73 
74 // Returns pretty-printed CBOR for |value|.
75 //
76 // Only valid CBOR should be passed to this function.
77 //
78 // If a byte-string is larger than |maxBStrSize| its contents will not be
79 // printed, instead the value of the form "<bstr size=1099016
80 // sha1=ef549cca331f73dfae2090e6a37c04c23f84b07b>" will be printed. Pass zero
81 // for |maxBStrSize| to disable this.
82 //
83 // The |mapKeysToNotPrint| parameter specifies the name of map values
84 // to not print. This is useful for unit tests.
85 string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize = 32,
86                        const vector<string>& mapKeysToNotPrint = {});
87 
88 // ---------------------------------------------------------------------------
89 // Crypto functionality / abstraction.
90 // ---------------------------------------------------------------------------
91 
92 constexpr size_t kAesGcmIvSize = 12;
93 constexpr size_t kAesGcmTagSize = 16;
94 constexpr size_t kAes128GcmKeySize = 16;
95 
96 // Returns |numBytes| bytes of random data.
97 optional<vector<uint8_t>> getRandom(size_t numBytes);
98 
99 // Calculates the SHA-256 of |data|.
100 vector<uint8_t> sha256(const vector<uint8_t>& data);
101 
102 // Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
103 // returns resulting plaintext. The format of |encryptedData| must
104 // be as specified in the encryptAes128Gcm() function.
105 optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
106                                            const vector<uint8_t>& encryptedData,
107                                            const vector<uint8_t>& additionalAuthenticatedData);
108 
109 // Encrypts |data| with |key| and |additionalAuthenticatedData| using |nonce|,
110 // returns the resulting (nonce || ciphertext || tag).
111 optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
112                                            const vector<uint8_t>& data,
113                                            const vector<uint8_t>& additionalAuthenticatedData);
114 
115 // ---------------------------------------------------------------------------
116 // EC crypto functionality / abstraction (only supports P-256).
117 // ---------------------------------------------------------------------------
118 
119 // Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
120 // DER encoded private key.  Also generates an attestation using the |challenge|
121 // and |applicationId|, and returns the generated certificate chain.
122 //
123 // The notBeffore field will be the current time and the notAfter will be the same
124 // same time as the batch certificate.
125 //
126 // The first parameter of the return value is the keyPair generated, second return in
127 // the pair is the attestation certificate generated.
128 //
129 optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
130         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
131         bool isTestCredential);
132 
133 // Alternate version of createEcKeyPairAndAttestation that accepts an attestation key
134 // blob to sign the generated key. Only a single certificate is returned, rather than
135 // a full chain.
136 //
137 optional<std::pair<vector<uint8_t>, vector<uint8_t>>> createEcKeyPairWithAttestationKey(
138         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
139         const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attestationKeyCert,
140         bool isTestCredential);
141 
142 // (TODO: remove when no longer used by 3rd party.)
143 optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
144         const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
145         const vector<uint8_t>& applicationId);
146 
147 // Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
148 // private key in DER format (as specified in RFC 5915).
149 //
150 optional<vector<uint8_t>> createEcKeyPair();
151 
152 // For an EC key |keyPair| encoded in DER format, extracts the public key in
153 // uncompressed point form.
154 //
155 optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair);
156 
157 // For an EC key |keyPair| encoded in DER format, extracts the private key as
158 // an EC uncompressed key.
159 //
160 optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair);
161 
162 // Creates a DER encoded representation from a private key (which must be uncompressed,
163 // e.g. 32 bytes).
164 //
165 optional<vector<uint8_t>> ecPrivateKeyToKeyPair(const vector<uint8_t>& privateKey);
166 
167 // For an EC key |keyPair| encoded in DER format, creates a PKCS#12 structure
168 // with the key-pair (not using a password to encrypt the data). The public key
169 // in the created structure is included as a certificate, using the given fields
170 // |serialDecimal|, |issuer|, |subject|, |validityNotBefore|, and
171 // |validityNotAfter|.
172 //
173 optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
174                                              const string& serialDecimal, const string& issuer,
175                                              const string& subject, time_t validityNotBefore,
176                                              time_t validityNotAfter);
177 
178 // Signs |data| with |key| (which must be in the format returned by
179 // ecKeyPairGetPrivateKey()). Signature is returned and will be in DER format.
180 //
181 optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data);
182 
183 // Like signEcDsa() but instead of taking the data to be signed, takes a digest
184 // of it instead.
185 //
186 optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key,
187                                           const vector<uint8_t>& dataDigest);
188 
189 // Calculates the HMAC with SHA-256 for |data| using |key|. The calculated HMAC
190 // is returned and will be 32 bytes.
191 //
192 optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data);
193 
194 // Checks that |signature| (in DER format) is a valid signature of |digest|,
195 // made with |publicKey| (which must be in the format returned by
196 // ecKeyPairGetPublicKey()).
197 //
198 bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
199                          const vector<uint8_t>& publicKey);
200 
201 // Extracts the public-key from the top-most certificate in |certificateChain|
202 // (which should be a concatenated chain of DER-encoded X.509 certificates).
203 //
204 // The returned public key will be in the same format as returned by
205 // ecKeyPairGetPublicKey().
206 //
207 optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain);
208 
209 // Extracts the public-key from the top-most certificate in |certificateChain|
210 // (which should be a concatenated chain of DER-encoded X.509 certificates).
211 //
212 // Return offset and size of the public-key
213 //
214 optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate);
215 
216 // Extracts the TbsCertificate from the top-most certificate in |certificateChain|
217 // (which should be a concatenated chain of DER-encoded X.509 certificates).
218 //
219 // Return offset and size of the TbsCertificate
220 //
221 optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate);
222 
223 // Extracts the Signature from the top-most certificate in |certificateChain|
224 // (which should be a concatenated chain of DER-encoded X.509 certificates).
225 //
226 // Return offset and size of the Signature
227 //
228 optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate);
229 
230 // Extracts notBefore and notAfter from the top-most certificate in |certificateChain
231 // (which should be a concatenated chain of DER-encoded X.509 certificates).
232 //
233 // Returns notBefore and notAfter in that order.
234 //
235 optional<pair<time_t, time_t>> certificateGetValidity(const vector<uint8_t>& x509Certificate);
236 
237 // Looks for an extension with OID in |oidStr| which must be an stored as an OCTET STRING.
238 //
239 optional<vector<uint8_t>> certificateGetExtension(const vector<uint8_t>& x509Certificate,
240                                                   const string& oidStr);
241 
242 // Generates a X.509 certificate for |publicKey| (which must be in the format
243 // returned by ecKeyPairGetPublicKey()).
244 //
245 // The certificate is signed by |signingKey| (which must be in the format
246 // returned by ecKeyPairGetPrivateKey())
247 //
248 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
249         const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
250         const string& serialDecimal, const string& issuer, const string& subject,
251         time_t validityNotBefore, time_t validityNotAfter,
252         const map<string, vector<uint8_t>>& extensions);
253 
254 // Identical behavior to the above version of ecPublicKeyGenerateCertificate, except this
255 // overload takes OpenSSL key parameters instead of key bitstrings as inputs.
256 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
257         EVP_PKEY* publicKey, EVP_PKEY* signingKey, const string& serialDecimal,
258         const string& issuer, const string& subject, time_t validityNotBefore,
259         time_t validityNotAfter, const map<string, vector<uint8_t>>& extensions);
260 
261 // Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
262 // format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
263 // in the format returned by ecKeyPairGetPrivateKey()).
264 //
265 // On success, the computed shared secret is returned.
266 //
267 optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey, const vector<uint8_t>& privateKey);
268 
269 // Key derivation function using SHA-256, conforming to RFC 5869.
270 //
271 // On success, the derived key is returned.
272 //
273 optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
274                                const vector<uint8_t>& info, size_t size);
275 
276 // Returns the X and Y coordinates from |publicKey| (which must be in the format
277 // returned by ecKeyPairGetPublicKey()).
278 //
279 // Success is indicated by the first value in the returned tuple. If successful,
280 // the returned coordinates will be in uncompressed form.
281 //
282 tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(const vector<uint8_t>& publicKey);
283 
284 // Concatenates all certificates into |certificateChain| together into a
285 // single bytestring.
286 //
287 // This is the reverse operation of certificateChainSplit().
288 vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain);
289 
290 // Splits all the certificates in a single bytestring into individual
291 // certificates.
292 //
293 // Returns nothing if |certificateChain| contains invalid data.
294 //
295 // This is the reverse operation of certificateChainJoin().
296 optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain);
297 
298 // Validates that the certificate chain is valid. In particular, checks that each
299 // certificate in the chain is signed by the public key in the following certificate.
300 //
301 // Returns false if |certificateChain| failed validation or if each certificate
302 // is not signed by its successor.
303 //
304 bool certificateChainValidate(const vector<uint8_t>& certificateChain);
305 
306 // Returns true if |certificate| is signed by |publicKey|.
307 //
308 bool certificateSignedByPublicKey(const vector<uint8_t>& certificate,
309                                   const vector<uint8_t>& publicKey);
310 
311 // Signs |data| and |detachedContent| with |key| (which must be in the format
312 // returned by ecKeyPairGetPrivateKey()).
313 //
314 // On success, the Signature is returned and will be in COSE_Sign1 format.
315 //
316 // If |certificateChain| is non-empty it's included in the 'x5chain'
317 // protected header element (as as described in'draft-ietf-cose-x509-04').
318 //
319 optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
320                                         const vector<uint8_t>& detachedContent,
321                                         const vector<uint8_t>& certificateChain);
322 
323 // Creates a COSE_Signature1 where |signatureToBeSigned| is the ECDSA signature
324 // of the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process".
325 //
326 // The |signatureToBeSigned| is expected to be 64 bytes and contain the R value,
327 // then the S value.
328 //
329 // The |data| parameter will be included in the COSE_Sign1 CBOR.
330 //
331 // If |certificateChain| is non-empty it's included in the 'x5chain'
332 // protected header element (as as described in'draft-ietf-cose-x509-04').
333 //
334 optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned,
335                                                      const vector<uint8_t>& data,
336                                                      const vector<uint8_t>& certificateChain);
337 
338 // Checks that |signatureCoseSign1| (in COSE_Sign1 format) is a valid signature
339 // made with |public_key| (which must be in the format returned by
340 // ecKeyPairGetPublicKey()) where |detachedContent| is the detached content.
341 //
342 bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
343                              const vector<uint8_t>& detachedContent,
344                              const vector<uint8_t>& publicKey);
345 
346 // Converts a DER-encoded signature to the format used in 'signature' bstr in COSE_Sign1.
347 bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
348                              vector<uint8_t>& ecdsaCoseSignature);
349 
350 // Converts from the format in in 'signature' bstr in COSE_Sign1 to DER encoding.
351 bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
352                              vector<uint8_t>& ecdsaDerSignature);
353 
354 // Extracts the payload from a COSE_Sign1.
355 optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1);
356 
357 // Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1.
358 optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1);
359 
360 // Extracts the signature algorithm from a COSE_Sign1.
361 optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1);
362 
363 // Extracts the X.509 certificate chain, if present. Returns the data as a
364 // concatenated chain of DER-encoded X.509 certificates
365 //
366 // Returns nothing if there is no 'x5chain' element or an error occurs.
367 //
368 optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1);
369 
370 // MACs |data| and |detachedContent| with |key| (which can be any sequence of
371 // bytes).
372 //
373 // If successful, the MAC is returned and will be in COSE_Mac0 format.
374 //
375 optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
376                                    const vector<uint8_t>& detachedContent);
377 
378 // Creates a COSE_Mac0 where |digestToBeMaced| is the HMAC-SHA256
379 // of the ToBeMaced CBOR from RFC 8051 "6.3. How to Compute and Verify a MAC".
380 //
381 // The |digestToBeMaced| is expected to be 32 bytes.
382 //
383 // The |data| parameter will be included in the COSE_Mac0 CBOR.
384 //
385 optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced,
386                                             const vector<uint8_t>& data);
387 
388 // ---------------------------------------------------------------------------
389 // Utility functions specific to IdentityCredential.
390 // ---------------------------------------------------------------------------
391 
392 optional<vector<uint8_t>> calcMac(const vector<uint8_t>& sessionTranscriptEncoded,
393                                   const string& docType,
394                                   const vector<uint8_t>& deviceNameSpacesEncoded,
395                                   const vector<uint8_t>& eMacKey);
396 
397 optional<vector<uint8_t>> calcEMacKey(const vector<uint8_t>& privateKey,
398                                       const vector<uint8_t>& publicKey,
399                                       const vector<uint8_t>& sessionTranscriptBytes);
400 
401 // Returns the testing AES-128 key where all bits are set to 0.
402 const vector<uint8_t>& getTestHardwareBoundKey();
403 
404 // Splits the given bytestring into chunks. If the given vector is smaller or equal to
405 // |maxChunkSize| a vector with |content| as the only element is returned. Otherwise
406 // |content| is split into N vectors each of size |maxChunkSize| except the final element
407 // may be smaller than |maxChunkSize|.
408 vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize);
409 
410 // Extract the issuer subject name from the leaf cert in the given chain,
411 // returning it as DER-encoded bytes.
412 optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate);
413 
414 }  // namespace support
415 }  // namespace identity
416 }  // namespace hardware
417 }  // namespace android
418 
419 #endif  // IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
420