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 #define LOG_TAG "IdentityCredentialSupport"
18 
19 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
20 
21 #define _POSIX_C_SOURCE 199309L
22 
23 #include <ctype.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <time.h>
27 #include <iomanip>
28 
29 #include <openssl/aes.h>
30 #include <openssl/bn.h>
31 #include <openssl/crypto.h>
32 #include <openssl/ec.h>
33 #include <openssl/err.h>
34 #include <openssl/evp.h>
35 #include <openssl/hkdf.h>
36 #include <openssl/hmac.h>
37 #include <openssl/objects.h>
38 #include <openssl/pem.h>
39 #include <openssl/pkcs12.h>
40 #include <openssl/rand.h>
41 #include <openssl/x509.h>
42 #include <openssl/x509_vfy.h>
43 
44 #include <android-base/logging.h>
45 #include <android-base/stringprintf.h>
46 
47 #include <cppbor.h>
48 #include <cppbor_parse.h>
49 
50 #include <android/hardware/keymaster/4.0/types.h>
51 #include <keymaster/authorization_set.h>
52 #include <keymaster/contexts/pure_soft_keymaster_context.h>
53 #include <keymaster/contexts/soft_attestation_cert.h>
54 #include <keymaster/keymaster_tags.h>
55 #include <keymaster/km_openssl/attestation_utils.h>
56 
57 namespace android {
58 namespace hardware {
59 namespace identity {
60 namespace support {
61 
62 using ::std::pair;
63 using ::std::unique_ptr;
64 
65 // ---------------------------------------------------------------------------
66 // Miscellaneous utilities.
67 // ---------------------------------------------------------------------------
68 
hexdump(const string & name,const vector<uint8_t> & data)69 void hexdump(const string& name, const vector<uint8_t>& data) {
70     fprintf(stderr, "%s: dumping %zd bytes\n", name.c_str(), data.size());
71     size_t n, m, o;
72     for (n = 0; n < data.size(); n += 16) {
73         fprintf(stderr, "%04zx  ", n);
74         for (m = 0; m < 16 && n + m < data.size(); m++) {
75             fprintf(stderr, "%02x ", data[n + m]);
76         }
77         for (o = m; o < 16; o++) {
78             fprintf(stderr, "   ");
79         }
80         fprintf(stderr, " ");
81         for (m = 0; m < 16 && n + m < data.size(); m++) {
82             int c = data[n + m];
83             fprintf(stderr, "%c", isprint(c) ? c : '.');
84         }
85         fprintf(stderr, "\n");
86     }
87     fprintf(stderr, "\n");
88 }
89 
encodeHex(const uint8_t * data,size_t dataLen)90 string encodeHex(const uint8_t* data, size_t dataLen) {
91     static const char hexDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
92                                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
93 
94     string ret;
95     ret.resize(dataLen * 2);
96     for (size_t n = 0; n < dataLen; n++) {
97         uint8_t byte = data[n];
98         ret[n * 2 + 0] = hexDigits[byte >> 4];
99         ret[n * 2 + 1] = hexDigits[byte & 0x0f];
100     }
101 
102     return ret;
103 }
104 
encodeHex(const string & str)105 string encodeHex(const string& str) {
106     return encodeHex(reinterpret_cast<const uint8_t*>(str.data()), str.size());
107 }
108 
encodeHex(const vector<uint8_t> & data)109 string encodeHex(const vector<uint8_t>& data) {
110     return encodeHex(data.data(), data.size());
111 }
112 
113 // Returns -1 on error, otherwise an integer in the range 0 through 15, both inclusive.
parseHexDigit(char hexDigit)114 int parseHexDigit(char hexDigit) {
115     if (hexDigit >= '0' && hexDigit <= '9') {
116         return int(hexDigit) - '0';
117     } else if (hexDigit >= 'a' && hexDigit <= 'f') {
118         return int(hexDigit) - 'a' + 10;
119     } else if (hexDigit >= 'A' && hexDigit <= 'F') {
120         return int(hexDigit) - 'A' + 10;
121     }
122     return -1;
123 }
124 
decodeHex(const string & hexEncoded)125 optional<vector<uint8_t>> decodeHex(const string& hexEncoded) {
126     vector<uint8_t> out;
127     size_t hexSize = hexEncoded.size();
128     if ((hexSize & 1) != 0) {
129         LOG(ERROR) << "Size of data cannot be odd";
130         return {};
131     }
132 
133     out.resize(hexSize / 2);
134     for (size_t n = 0; n < hexSize / 2; n++) {
135         int upperNibble = parseHexDigit(hexEncoded[n * 2]);
136         int lowerNibble = parseHexDigit(hexEncoded[n * 2 + 1]);
137         if (upperNibble == -1 || lowerNibble == -1) {
138             LOG(ERROR) << "Invalid hex digit at position " << n;
139             return {};
140         }
141         out[n] = (upperNibble << 4) + lowerNibble;
142     }
143 
144     return out;
145 }
146 
147 // ---------------------------------------------------------------------------
148 // CBOR utilities.
149 // ---------------------------------------------------------------------------
150 
cborAreAllElementsNonCompound(const cppbor::CompoundItem * compoundItem)151 static bool cborAreAllElementsNonCompound(const cppbor::CompoundItem* compoundItem) {
152     if (compoundItem->type() == cppbor::ARRAY) {
153         const cppbor::Array* array = compoundItem->asArray();
154         for (size_t n = 0; n < array->size(); n++) {
155             const cppbor::Item* entry = (*array)[n].get();
156             switch (entry->type()) {
157                 case cppbor::ARRAY:
158                 case cppbor::MAP:
159                     return false;
160                 default:
161                     break;
162             }
163         }
164     } else {
165         const cppbor::Map* map = compoundItem->asMap();
166         for (size_t n = 0; n < map->size(); n++) {
167             auto [keyEntry, valueEntry] = (*map)[n];
168             switch (keyEntry->type()) {
169                 case cppbor::ARRAY:
170                 case cppbor::MAP:
171                     return false;
172                 default:
173                     break;
174             }
175             switch (valueEntry->type()) {
176                 case cppbor::ARRAY:
177                 case cppbor::MAP:
178                     return false;
179                 default:
180                     break;
181             }
182         }
183     }
184     return true;
185 }
186 
cborPrettyPrintInternal(const cppbor::Item * item,string & out,size_t indent,size_t maxBStrSize,const vector<string> & mapKeysToNotPrint)187 static bool cborPrettyPrintInternal(const cppbor::Item* item, string& out, size_t indent,
188                                     size_t maxBStrSize, const vector<string>& mapKeysToNotPrint) {
189     char buf[80];
190 
191     string indentString(indent, ' ');
192 
193     switch (item->type()) {
194         case cppbor::UINT:
195             snprintf(buf, sizeof(buf), "%" PRIu64, item->asUint()->unsignedValue());
196             out.append(buf);
197             break;
198 
199         case cppbor::NINT:
200             snprintf(buf, sizeof(buf), "%" PRId64, item->asNint()->value());
201             out.append(buf);
202             break;
203 
204         case cppbor::BSTR: {
205             const cppbor::Bstr* bstr = item->asBstr();
206             const vector<uint8_t>& value = bstr->value();
207             if (value.size() > maxBStrSize) {
208                 unsigned char digest[SHA_DIGEST_LENGTH];
209                 SHA_CTX ctx;
210                 SHA1_Init(&ctx);
211                 SHA1_Update(&ctx, value.data(), value.size());
212                 SHA1_Final(digest, &ctx);
213                 char buf2[SHA_DIGEST_LENGTH * 2 + 1];
214                 for (size_t n = 0; n < SHA_DIGEST_LENGTH; n++) {
215                     snprintf(buf2 + n * 2, 3, "%02x", digest[n]);
216                 }
217                 snprintf(buf, sizeof(buf), "<bstr size=%zd sha1=%s>", value.size(), buf2);
218                 out.append(buf);
219             } else {
220                 out.append("{");
221                 for (size_t n = 0; n < value.size(); n++) {
222                     if (n > 0) {
223                         out.append(", ");
224                     }
225                     snprintf(buf, sizeof(buf), "0x%02x", value[n]);
226                     out.append(buf);
227                 }
228                 out.append("}");
229             }
230         } break;
231 
232         case cppbor::TSTR:
233             out.append("'");
234             {
235                 // TODO: escape "'" characters
236                 out.append(item->asTstr()->value().c_str());
237             }
238             out.append("'");
239             break;
240 
241         case cppbor::ARRAY: {
242             const cppbor::Array* array = item->asArray();
243             if (array->size() == 0) {
244                 out.append("[]");
245             } else if (cborAreAllElementsNonCompound(array)) {
246                 out.append("[");
247                 for (size_t n = 0; n < array->size(); n++) {
248                     if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
249                                                  mapKeysToNotPrint)) {
250                         return false;
251                     }
252                     out.append(", ");
253                 }
254                 out.append("]");
255             } else {
256                 out.append("[\n" + indentString);
257                 for (size_t n = 0; n < array->size(); n++) {
258                     out.append("  ");
259                     if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
260                                                  mapKeysToNotPrint)) {
261                         return false;
262                     }
263                     out.append(",\n" + indentString);
264                 }
265                 out.append("]");
266             }
267         } break;
268 
269         case cppbor::MAP: {
270             const cppbor::Map* map = item->asMap();
271 
272             if (map->size() == 0) {
273                 out.append("{}");
274             } else {
275                 out.append("{\n" + indentString);
276                 for (size_t n = 0; n < map->size(); n++) {
277                     out.append("  ");
278 
279                     auto [map_key, map_value] = (*map)[n];
280 
281                     if (!cborPrettyPrintInternal(map_key.get(), out, indent + 2, maxBStrSize,
282                                                  mapKeysToNotPrint)) {
283                         return false;
284                     }
285                     out.append(" : ");
286                     if (map_key->type() == cppbor::TSTR &&
287                         std::find(mapKeysToNotPrint.begin(), mapKeysToNotPrint.end(),
288                                   map_key->asTstr()->value()) != mapKeysToNotPrint.end()) {
289                         out.append("<not printed>");
290                     } else {
291                         if (!cborPrettyPrintInternal(map_value.get(), out, indent + 2, maxBStrSize,
292                                                      mapKeysToNotPrint)) {
293                             return false;
294                         }
295                     }
296                     out.append(",\n" + indentString);
297                 }
298                 out.append("}");
299             }
300         } break;
301 
302         case cppbor::SEMANTIC: {
303             const cppbor::Semantic* semantic = item->asSemantic();
304             snprintf(buf, sizeof(buf), "tag %" PRIu64 " ", semantic->value());
305             out.append(buf);
306             cborPrettyPrintInternal(semantic->child().get(), out, indent, maxBStrSize,
307                                     mapKeysToNotPrint);
308         } break;
309 
310         case cppbor::SIMPLE:
311             const cppbor::Bool* asBool = item->asSimple()->asBool();
312             const cppbor::Null* asNull = item->asSimple()->asNull();
313             if (asBool != nullptr) {
314                 out.append(asBool->value() ? "true" : "false");
315             } else if (asNull != nullptr) {
316                 out.append("null");
317             } else {
318                 LOG(ERROR) << "Only boolean/null is implemented for SIMPLE";
319                 return false;
320             }
321             break;
322     }
323 
324     return true;
325 }
326 
cborPrettyPrint(const vector<uint8_t> & encodedCbor,size_t maxBStrSize,const vector<string> & mapKeysToNotPrint)327 string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize,
328                        const vector<string>& mapKeysToNotPrint) {
329     auto [item, _, message] = cppbor::parse(encodedCbor);
330     if (item == nullptr) {
331         LOG(ERROR) << "Data to pretty print is not valid CBOR: " << message;
332         return "";
333     }
334 
335     string out;
336     cborPrettyPrintInternal(item.get(), out, 0, maxBStrSize, mapKeysToNotPrint);
337     return out;
338 }
339 
340 // ---------------------------------------------------------------------------
341 // Crypto functionality / abstraction.
342 // ---------------------------------------------------------------------------
343 
344 struct EVP_CIPHER_CTX_Deleter {
operator ()android::hardware::identity::support::EVP_CIPHER_CTX_Deleter345     void operator()(EVP_CIPHER_CTX* ctx) const {
346         if (ctx != nullptr) {
347             EVP_CIPHER_CTX_free(ctx);
348         }
349     }
350 };
351 
352 using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>;
353 
354 // bool getRandom(size_t numBytes, vector<uint8_t>& output) {
getRandom(size_t numBytes)355 optional<vector<uint8_t>> getRandom(size_t numBytes) {
356     vector<uint8_t> output;
357     output.resize(numBytes);
358     if (RAND_bytes(output.data(), numBytes) != 1) {
359         LOG(ERROR) << "RAND_bytes: failed getting " << numBytes << " random";
360         return {};
361     }
362     return output;
363 }
364 
decryptAes128Gcm(const vector<uint8_t> & key,const vector<uint8_t> & encryptedData,const vector<uint8_t> & additionalAuthenticatedData)365 optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
366                                            const vector<uint8_t>& encryptedData,
367                                            const vector<uint8_t>& additionalAuthenticatedData) {
368     int cipherTextSize = int(encryptedData.size()) - kAesGcmIvSize - kAesGcmTagSize;
369     if (cipherTextSize < 0) {
370         LOG(ERROR) << "encryptedData too small";
371         return {};
372     }
373     unsigned char* nonce = (unsigned char*)encryptedData.data();
374     unsigned char* cipherText = nonce + kAesGcmIvSize;
375     unsigned char* tag = cipherText + cipherTextSize;
376 
377     vector<uint8_t> plainText;
378     plainText.resize(cipherTextSize);
379 
380     auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
381     if (ctx.get() == nullptr) {
382         LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
383         return {};
384     }
385 
386     if (EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
387         LOG(ERROR) << "EVP_DecryptInit_ex: failed";
388         return {};
389     }
390 
391     if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
392         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
393         return {};
394     }
395 
396     if (EVP_DecryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(), nonce) != 1) {
397         LOG(ERROR) << "EVP_DecryptInit_ex: failed";
398         return {};
399     }
400 
401     int numWritten;
402     if (additionalAuthenticatedData.size() > 0) {
403         if (EVP_DecryptUpdate(ctx.get(), NULL, &numWritten,
404                               (unsigned char*)additionalAuthenticatedData.data(),
405                               additionalAuthenticatedData.size()) != 1) {
406             LOG(ERROR) << "EVP_DecryptUpdate: failed for additionalAuthenticatedData";
407             return {};
408         }
409         if ((size_t)numWritten != additionalAuthenticatedData.size()) {
410             LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
411                        << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
412             return {};
413         }
414     }
415 
416     if (EVP_DecryptUpdate(ctx.get(), (unsigned char*)plainText.data(), &numWritten, cipherText,
417                           cipherTextSize) != 1) {
418         LOG(ERROR) << "EVP_DecryptUpdate: failed";
419         return {};
420     }
421     if (numWritten != cipherTextSize) {
422         LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
423                    << cipherTextSize << ")";
424         return {};
425     }
426 
427     if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagSize, tag)) {
428         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting expected tag";
429         return {};
430     }
431 
432     int ret = EVP_DecryptFinal_ex(ctx.get(), (unsigned char*)plainText.data() + numWritten,
433                                   &numWritten);
434     if (ret != 1) {
435         LOG(ERROR) << "EVP_DecryptFinal_ex: failed";
436         return {};
437     }
438     if (numWritten != 0) {
439         LOG(ERROR) << "EVP_DecryptFinal_ex: Unexpected non-zero outl=" << numWritten;
440         return {};
441     }
442 
443     return plainText;
444 }
445 
encryptAes128Gcm(const vector<uint8_t> & key,const vector<uint8_t> & nonce,const vector<uint8_t> & data,const vector<uint8_t> & additionalAuthenticatedData)446 optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
447                                            const vector<uint8_t>& data,
448                                            const vector<uint8_t>& additionalAuthenticatedData) {
449     if (key.size() != kAes128GcmKeySize) {
450         LOG(ERROR) << "key is not kAes128GcmKeySize bytes";
451         return {};
452     }
453     if (nonce.size() != kAesGcmIvSize) {
454         LOG(ERROR) << "nonce is not kAesGcmIvSize bytes";
455         return {};
456     }
457 
458     // The result is the nonce (kAesGcmIvSize bytes), the ciphertext, and
459     // finally the tag (kAesGcmTagSize bytes).
460     vector<uint8_t> encryptedData;
461     encryptedData.resize(data.size() + kAesGcmIvSize + kAesGcmTagSize);
462     unsigned char* noncePtr = (unsigned char*)encryptedData.data();
463     unsigned char* cipherText = noncePtr + kAesGcmIvSize;
464     unsigned char* tag = cipherText + data.size();
465     memcpy(noncePtr, nonce.data(), kAesGcmIvSize);
466 
467     auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
468     if (ctx.get() == nullptr) {
469         LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
470         return {};
471     }
472 
473     if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
474         LOG(ERROR) << "EVP_EncryptInit_ex: failed";
475         return {};
476     }
477 
478     if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
479         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
480         return {};
481     }
482 
483     if (EVP_EncryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(),
484                            (unsigned char*)nonce.data()) != 1) {
485         LOG(ERROR) << "EVP_EncryptInit_ex: failed";
486         return {};
487     }
488 
489     int numWritten;
490     if (additionalAuthenticatedData.size() > 0) {
491         if (EVP_EncryptUpdate(ctx.get(), NULL, &numWritten,
492                               (unsigned char*)additionalAuthenticatedData.data(),
493                               additionalAuthenticatedData.size()) != 1) {
494             LOG(ERROR) << "EVP_EncryptUpdate: failed for additionalAuthenticatedData";
495             return {};
496         }
497         if ((size_t)numWritten != additionalAuthenticatedData.size()) {
498             LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
499                        << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
500             return {};
501         }
502     }
503 
504     if (data.size() > 0) {
505         if (EVP_EncryptUpdate(ctx.get(), cipherText, &numWritten, (unsigned char*)data.data(),
506                               data.size()) != 1) {
507             LOG(ERROR) << "EVP_EncryptUpdate: failed";
508             return {};
509         }
510         if ((size_t)numWritten != data.size()) {
511             LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
512                        << data.size() << ")";
513             return {};
514         }
515     }
516 
517     if (EVP_EncryptFinal_ex(ctx.get(), cipherText + numWritten, &numWritten) != 1) {
518         LOG(ERROR) << "EVP_EncryptFinal_ex: failed";
519         return {};
520     }
521     if (numWritten != 0) {
522         LOG(ERROR) << "EVP_EncryptFinal_ex: Unexpected non-zero outl=" << numWritten;
523         return {};
524     }
525 
526     if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagSize, tag) != 1) {
527         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed getting tag";
528         return {};
529     }
530 
531     return encryptedData;
532 }
533 
534 struct EC_KEY_Deleter {
operator ()android::hardware::identity::support::EC_KEY_Deleter535     void operator()(EC_KEY* key) const {
536         if (key != nullptr) {
537             EC_KEY_free(key);
538         }
539     }
540 };
541 using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>;
542 
543 struct EVP_PKEY_Deleter {
operator ()android::hardware::identity::support::EVP_PKEY_Deleter544     void operator()(EVP_PKEY* key) const {
545         if (key != nullptr) {
546             EVP_PKEY_free(key);
547         }
548     }
549 };
550 using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
551 
552 struct EVP_PKEY_CTX_Deleter {
operator ()android::hardware::identity::support::EVP_PKEY_CTX_Deleter553     void operator()(EVP_PKEY_CTX* ctx) const {
554         if (ctx != nullptr) {
555             EVP_PKEY_CTX_free(ctx);
556         }
557     }
558 };
559 using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>;
560 
561 struct EC_GROUP_Deleter {
operator ()android::hardware::identity::support::EC_GROUP_Deleter562     void operator()(EC_GROUP* group) const {
563         if (group != nullptr) {
564             EC_GROUP_free(group);
565         }
566     }
567 };
568 using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>;
569 
570 struct EC_POINT_Deleter {
operator ()android::hardware::identity::support::EC_POINT_Deleter571     void operator()(EC_POINT* point) const {
572         if (point != nullptr) {
573             EC_POINT_free(point);
574         }
575     }
576 };
577 
578 using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>;
579 
580 struct ECDSA_SIG_Deleter {
operator ()android::hardware::identity::support::ECDSA_SIG_Deleter581     void operator()(ECDSA_SIG* sig) const {
582         if (sig != nullptr) {
583             ECDSA_SIG_free(sig);
584         }
585     }
586 };
587 using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>;
588 
589 struct X509_Deleter {
operator ()android::hardware::identity::support::X509_Deleter590     void operator()(X509* x509) const {
591         if (x509 != nullptr) {
592             X509_free(x509);
593         }
594     }
595 };
596 using X509_Ptr = unique_ptr<X509, X509_Deleter>;
597 
598 struct PKCS12_Deleter {
operator ()android::hardware::identity::support::PKCS12_Deleter599     void operator()(PKCS12* pkcs12) const {
600         if (pkcs12 != nullptr) {
601             PKCS12_free(pkcs12);
602         }
603     }
604 };
605 using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>;
606 
607 struct BIGNUM_Deleter {
operator ()android::hardware::identity::support::BIGNUM_Deleter608     void operator()(BIGNUM* bignum) const {
609         if (bignum != nullptr) {
610             BN_free(bignum);
611         }
612     }
613 };
614 using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>;
615 
616 struct ASN1_INTEGER_Deleter {
operator ()android::hardware::identity::support::ASN1_INTEGER_Deleter617     void operator()(ASN1_INTEGER* value) const {
618         if (value != nullptr) {
619             ASN1_INTEGER_free(value);
620         }
621     }
622 };
623 using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>;
624 
625 struct ASN1_TIME_Deleter {
operator ()android::hardware::identity::support::ASN1_TIME_Deleter626     void operator()(ASN1_TIME* value) const {
627         if (value != nullptr) {
628             ASN1_TIME_free(value);
629         }
630     }
631 };
632 using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>;
633 
634 struct X509_NAME_Deleter {
operator ()android::hardware::identity::support::X509_NAME_Deleter635     void operator()(X509_NAME* value) const {
636         if (value != nullptr) {
637             X509_NAME_free(value);
638         }
639     }
640 };
641 using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>;
642 
certificateChainJoin(const vector<vector<uint8_t>> & certificateChain)643 vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain) {
644     vector<uint8_t> ret;
645     for (const vector<uint8_t>& certificate : certificateChain) {
646         ret.insert(ret.end(), certificate.begin(), certificate.end());
647     }
648     return ret;
649 }
650 
certificateChainSplit(const vector<uint8_t> & certificateChain)651 optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain) {
652     const unsigned char* pStart = (unsigned char*)certificateChain.data();
653     const unsigned char* p = pStart;
654     const unsigned char* pEnd = p + certificateChain.size();
655     vector<vector<uint8_t>> certificates;
656     while (p < pEnd) {
657         size_t begin = p - pStart;
658         auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
659         size_t next = p - pStart;
660         if (x509 == nullptr) {
661             LOG(ERROR) << "Error parsing X509 certificate";
662             return {};
663         }
664         vector<uint8_t> cert =
665                 vector<uint8_t>(certificateChain.begin() + begin, certificateChain.begin() + next);
666         certificates.push_back(std::move(cert));
667     }
668     return certificates;
669 }
670 
parseX509Certificates(const vector<uint8_t> & certificateChain,vector<X509_Ptr> & parsedCertificates)671 static bool parseX509Certificates(const vector<uint8_t>& certificateChain,
672                                   vector<X509_Ptr>& parsedCertificates) {
673     const unsigned char* p = (unsigned char*)certificateChain.data();
674     const unsigned char* pEnd = p + certificateChain.size();
675     parsedCertificates.resize(0);
676     while (p < pEnd) {
677         auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
678         if (x509 == nullptr) {
679             LOG(ERROR) << "Error parsing X509 certificate";
680             return false;
681         }
682         parsedCertificates.push_back(std::move(x509));
683     }
684     return true;
685 }
686 
687 // TODO: Right now the only check we perform is to check that each certificate
688 //       is signed by its successor. We should - but currently don't - also check
689 //       things like valid dates etc.
690 //
691 //       It would be nice to use X509_verify_cert() instead of doing our own thing.
692 //
certificateChainValidate(const vector<uint8_t> & certificateChain)693 bool certificateChainValidate(const vector<uint8_t>& certificateChain) {
694     vector<X509_Ptr> certs;
695 
696     if (!parseX509Certificates(certificateChain, certs)) {
697         LOG(ERROR) << "Error parsing X509 certificates";
698         return false;
699     }
700 
701     if (certs.size() == 1) {
702         return true;
703     }
704 
705     for (size_t n = 1; n < certs.size(); n++) {
706         const X509_Ptr& keyCert = certs[n - 1];
707         const X509_Ptr& signingCert = certs[n];
708         EVP_PKEY_Ptr signingPubkey(X509_get_pubkey(signingCert.get()));
709         if (X509_verify(keyCert.get(), signingPubkey.get()) != 1) {
710             LOG(ERROR) << "Error validating cert at index " << n - 1
711                        << " is signed by its successor";
712             return false;
713         }
714     }
715 
716     return true;
717 }
718 
checkEcDsaSignature(const vector<uint8_t> & digest,const vector<uint8_t> & signature,const vector<uint8_t> & publicKey)719 bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
720                          const vector<uint8_t>& publicKey) {
721     const unsigned char* p = (unsigned char*)signature.data();
722     auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, signature.size()));
723     if (sig.get() == nullptr) {
724         LOG(ERROR) << "Error decoding DER encoded signature";
725         return false;
726     }
727 
728     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
729     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
730     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
731         1) {
732         LOG(ERROR) << "Error decoding publicKey";
733         return false;
734     }
735     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
736     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
737     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
738         LOG(ERROR) << "Memory allocation failed";
739         return false;
740     }
741     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
742         LOG(ERROR) << "Error setting group";
743         return false;
744     }
745     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
746         LOG(ERROR) << "Error setting point";
747         return false;
748     }
749     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
750         LOG(ERROR) << "Error setting key";
751         return false;
752     }
753 
754     int rc = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), ecKey.get());
755     if (rc != 1) {
756         LOG(ERROR) << "Error verifying signature (rc=" << rc << ")";
757         return false;
758     }
759 
760     return true;
761 }
762 
sha256(const vector<uint8_t> & data)763 vector<uint8_t> sha256(const vector<uint8_t>& data) {
764     vector<uint8_t> ret;
765     ret.resize(SHA256_DIGEST_LENGTH);
766     SHA256_CTX ctx;
767     SHA256_Init(&ctx);
768     SHA256_Update(&ctx, data.data(), data.size());
769     SHA256_Final((unsigned char*)ret.data(), &ctx);
770     return ret;
771 }
772 
signEcDsa(const vector<uint8_t> & key,const vector<uint8_t> & data)773 optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
774     auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
775     if (bn.get() == nullptr) {
776         LOG(ERROR) << "Error creating BIGNUM";
777         return {};
778     }
779 
780     auto ec_key = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
781     if (EC_KEY_set_private_key(ec_key.get(), bn.get()) != 1) {
782         LOG(ERROR) << "Error setting private key from BIGNUM";
783         return {};
784     }
785 
786     auto digest = sha256(data);
787     ECDSA_SIG* sig = ECDSA_do_sign(digest.data(), digest.size(), ec_key.get());
788     if (sig == nullptr) {
789         LOG(ERROR) << "Error signing digest";
790         return {};
791     }
792     size_t len = i2d_ECDSA_SIG(sig, nullptr);
793     vector<uint8_t> signature;
794     signature.resize(len);
795     unsigned char* p = (unsigned char*)signature.data();
796     i2d_ECDSA_SIG(sig, &p);
797     ECDSA_SIG_free(sig);
798     return signature;
799 }
800 
hmacSha256(const vector<uint8_t> & key,const vector<uint8_t> & data)801 optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data) {
802     HMAC_CTX ctx;
803     HMAC_CTX_init(&ctx);
804     if (HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha256(), nullptr /* impl */) != 1) {
805         LOG(ERROR) << "Error initializing HMAC_CTX";
806         return {};
807     }
808     if (HMAC_Update(&ctx, data.data(), data.size()) != 1) {
809         LOG(ERROR) << "Error updating HMAC_CTX";
810         return {};
811     }
812     vector<uint8_t> hmac;
813     hmac.resize(32);
814     unsigned int size = 0;
815     if (HMAC_Final(&ctx, hmac.data(), &size) != 1) {
816         LOG(ERROR) << "Error finalizing HMAC_CTX";
817         return {};
818     }
819     if (size != 32) {
820         LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
821         return {};
822     }
823     return hmac;
824 }
825 
826 // Generates the attestation certificate with the parameters passed in.  Note
827 // that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
828 // milli seconds since epoch.  We are setting them to milliseconds due to
829 // requirement in AuthorizationSet KM_DATE fields.  The certificate created is
830 // actually in seconds.
createAttestation(const EVP_PKEY * key,const vector<uint8_t> & applicationId,const vector<uint8_t> & challenge,uint64_t activeTimeMilliSeconds,uint64_t expireTimeMilliSeconds)831 optional<vector<vector<uint8_t>>> createAttestation(const EVP_PKEY* key,
832                                                     const vector<uint8_t>& applicationId,
833                                                     const vector<uint8_t>& challenge,
834                                                     uint64_t activeTimeMilliSeconds,
835                                                     uint64_t expireTimeMilliSeconds) {
836     ::keymaster::AuthorizationSet auth_set(
837             ::keymaster::AuthorizationSetBuilder()
838                     .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
839                                    challenge.size())
840                     .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
841                     // Even though identity attestation hal said the application
842                     // id should be in software enforced authentication set,
843                     // keymaster portable lib expect the input in this
844                     // parameter because the software enforced in input to keymaster
845                     // refers to the key software enforced properties. And this
846                     // parameter refers to properties of the attestation which
847                     // includes app id.
848                     .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
849                                    applicationId.data(), applicationId.size())
850                     .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
851 
852     // Unique id and device id is not applicable for identity credential attestation,
853     // so we don't need to set those or application id.
854     ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
855             ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
856 
857     ::keymaster::AuthorizationSet hwEnforced(
858             ::keymaster::AuthorizationSetBuilder()
859                     .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
860                     .Authorization(::keymaster::TAG_KEY_SIZE, 256)
861                     .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
862                     .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
863                     .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
864                     .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
865                     .Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY));
866 
867     const keymaster_cert_chain_t* attestation_chain =
868             ::keymaster::getAttestationChain(KM_ALGORITHM_EC, nullptr);
869 
870     if (attestation_chain == nullptr) {
871         LOG(ERROR) << "Error getting attestation chain";
872         return {};
873     }
874 
875     const keymaster_key_blob_t* attestation_signing_key =
876             ::keymaster::getAttestationKey(KM_ALGORITHM_EC, nullptr);
877     if (attestation_signing_key == nullptr) {
878         LOG(ERROR) << "Error getting attestation key";
879         return {};
880     }
881 
882     keymaster_error_t error;
883     ::keymaster::CertChainPtr cert_chain_out;
884     ::keymaster::PureSoftKeymasterContext context;
885 
886     // set identity version to 10 per hal requirements specified in IWriteableCredential.hal
887     // For now, the identity version in the attestation is set in the keymaster
888     // version field in the portable keymaster lib, which is a bit misleading.
889     uint identity_version = 10;
890     error = generate_attestation_from_EVP(key, swEnforced, hwEnforced, auth_set, context,
891                                           identity_version, *attestation_chain,
892                                           *attestation_signing_key, &cert_chain_out);
893 
894     if (KM_ERROR_OK != error || !cert_chain_out) {
895         LOG(ERROR) << "Error generate attestation from EVP key" << error;
896         return {};
897     }
898 
899     // translate certificate format from keymaster_cert_chain_t to vector<uint8_t>.
900     vector<vector<uint8_t>> attestationCertificate;
901     for (int i = 0; i < cert_chain_out->entry_count; i++) {
902         attestationCertificate.insert(
903                 attestationCertificate.end(),
904                 vector<uint8_t>(
905                         cert_chain_out->entries[i].data,
906                         cert_chain_out->entries[i].data + cert_chain_out->entries[i].data_length));
907     }
908 
909     return attestationCertificate;
910 }
911 
createEcKeyPairAndAttestation(const vector<uint8_t> & challenge,const vector<uint8_t> & applicationId)912 optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
913         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
914     auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
915     auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
916     auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
917 
918     if (ec_key.get() == nullptr || pkey.get() == nullptr) {
919         LOG(ERROR) << "Memory allocation failed";
920         return {};
921     }
922 
923     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
924         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
925         LOG(ERROR) << "Error generating key";
926         return {};
927     }
928 
929     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
930         LOG(ERROR) << "Error getting private key";
931         return {};
932     }
933 
934     uint64_t now = time(nullptr);
935     uint64_t secondsInOneYear = 365 * 24 * 60 * 60;
936     uint64_t expireTimeMs = (now + secondsInOneYear) * 1000;
937 
938     optional<vector<vector<uint8_t>>> attestationCert =
939             createAttestation(pkey.get(), applicationId, challenge, now * 1000, expireTimeMs);
940     if (!attestationCert) {
941         LOG(ERROR) << "Error create attestation from key and challenge";
942         return {};
943     }
944 
945     int size = i2d_PrivateKey(pkey.get(), nullptr);
946     if (size == 0) {
947         LOG(ERROR) << "Error generating public key encoding";
948         return {};
949     }
950 
951     vector<uint8_t> keyPair(size);
952     unsigned char* p = keyPair.data();
953     i2d_PrivateKey(pkey.get(), &p);
954 
955     return make_pair(keyPair, attestationCert.value());
956 }
957 
createEcKeyPair()958 optional<vector<uint8_t>> createEcKeyPair() {
959     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
960     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
961     if (ec_key.get() == nullptr || pkey.get() == nullptr) {
962         LOG(ERROR) << "Memory allocation failed";
963         return {};
964     }
965 
966     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
967     if (group.get() == nullptr) {
968         LOG(ERROR) << "Error creating EC group by curve name";
969         return {};
970     }
971 
972     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
973         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
974         LOG(ERROR) << "Error generating key";
975         return {};
976     }
977 
978     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
979         LOG(ERROR) << "Error getting private key";
980         return {};
981     }
982 
983     int size = i2d_PrivateKey(pkey.get(), nullptr);
984     if (size == 0) {
985         LOG(ERROR) << "Error generating public key encoding";
986         return {};
987     }
988     vector<uint8_t> keyPair;
989     keyPair.resize(size);
990     unsigned char* p = keyPair.data();
991     i2d_PrivateKey(pkey.get(), &p);
992     return keyPair;
993 }
994 
ecKeyPairGetPublicKey(const vector<uint8_t> & keyPair)995 optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair) {
996     const unsigned char* p = (const unsigned char*)keyPair.data();
997     auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
998     if (pkey.get() == nullptr) {
999         LOG(ERROR) << "Error parsing keyPair";
1000         return {};
1001     }
1002 
1003     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1004     if (ecKey.get() == nullptr) {
1005         LOG(ERROR) << "Failed getting EC key";
1006         return {};
1007     }
1008 
1009     auto ecGroup = EC_KEY_get0_group(ecKey.get());
1010     auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1011     int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1012                                   nullptr);
1013     if (size == 0) {
1014         LOG(ERROR) << "Error generating public key encoding";
1015         return {};
1016     }
1017 
1018     vector<uint8_t> publicKey;
1019     publicKey.resize(size);
1020     EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1021                        publicKey.size(), nullptr);
1022     return publicKey;
1023 }
1024 
ecKeyPairGetPrivateKey(const vector<uint8_t> & keyPair)1025 optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair) {
1026     const unsigned char* p = (const unsigned char*)keyPair.data();
1027     auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1028     if (pkey.get() == nullptr) {
1029         LOG(ERROR) << "Error parsing keyPair";
1030         return {};
1031     }
1032 
1033     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1034     if (ecKey.get() == nullptr) {
1035         LOG(ERROR) << "Failed getting EC key";
1036         return {};
1037     }
1038 
1039     const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey.get());
1040     if (bignum == nullptr) {
1041         LOG(ERROR) << "Error getting bignum from private key";
1042         return {};
1043     }
1044     vector<uint8_t> privateKey;
1045     privateKey.resize(BN_num_bytes(bignum));
1046     BN_bn2bin(bignum, privateKey.data());
1047     return privateKey;
1048 }
1049 
ecPrivateKeyToKeyPair(const vector<uint8_t> & privateKey)1050 optional<vector<uint8_t>> ecPrivateKeyToKeyPair(const vector<uint8_t>& privateKey) {
1051     auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
1052     if (bn.get() == nullptr) {
1053         LOG(ERROR) << "Error creating BIGNUM";
1054         return {};
1055     }
1056 
1057     auto ecKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1058     if (EC_KEY_set_private_key(ecKey.get(), bn.get()) != 1) {
1059         LOG(ERROR) << "Error setting private key from BIGNUM";
1060         return {};
1061     }
1062 
1063     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1064     if (pkey.get() == nullptr) {
1065         LOG(ERROR) << "Memory allocation failed";
1066         return {};
1067     }
1068 
1069     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1070         LOG(ERROR) << "Error getting private key";
1071         return {};
1072     }
1073 
1074     int size = i2d_PrivateKey(pkey.get(), nullptr);
1075     if (size == 0) {
1076         LOG(ERROR) << "Error generating public key encoding";
1077         return {};
1078     }
1079     vector<uint8_t> keyPair;
1080     keyPair.resize(size);
1081     unsigned char* p = keyPair.data();
1082     i2d_PrivateKey(pkey.get(), &p);
1083     return keyPair;
1084 }
1085 
ecKeyPairGetPkcs12(const vector<uint8_t> & keyPair,const string & name,const string & serialDecimal,const string & issuer,const string & subject,time_t validityNotBefore,time_t validityNotAfter)1086 optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
1087                                              const string& serialDecimal, const string& issuer,
1088                                              const string& subject, time_t validityNotBefore,
1089                                              time_t validityNotAfter) {
1090     const unsigned char* p = (const unsigned char*)keyPair.data();
1091     auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1092     if (pkey.get() == nullptr) {
1093         LOG(ERROR) << "Error parsing keyPair";
1094         return {};
1095     }
1096 
1097     auto x509 = X509_Ptr(X509_new());
1098     if (!x509.get()) {
1099         LOG(ERROR) << "Error creating X509 certificate";
1100         return {};
1101     }
1102 
1103     if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1104         LOG(ERROR) << "Error setting version to 3";
1105         return {};
1106     }
1107 
1108     if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1109         LOG(ERROR) << "Error setting public key";
1110         return {};
1111     }
1112 
1113     BIGNUM* bignumSerial = nullptr;
1114     if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1115         LOG(ERROR) << "Error parsing serial";
1116         return {};
1117     }
1118     auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1119     auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1120     if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1121         LOG(ERROR) << "Error setting serial";
1122         return {};
1123     }
1124 
1125     auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1126     if (x509Issuer.get() == nullptr ||
1127         X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1128                                    (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1129                                    0 /* set */) != 1 ||
1130         X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1131         LOG(ERROR) << "Error setting issuer";
1132         return {};
1133     }
1134 
1135     auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1136     if (x509Subject.get() == nullptr ||
1137         X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1138                                    (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1139                                    0 /* set */) != 1 ||
1140         X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1141         LOG(ERROR) << "Error setting subject";
1142         return {};
1143     }
1144 
1145     auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1146     if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1147         LOG(ERROR) << "Error setting notBefore";
1148         return {};
1149     }
1150 
1151     auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1152     if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1153         LOG(ERROR) << "Error setting notAfter";
1154         return {};
1155     }
1156 
1157     if (X509_sign(x509.get(), pkey.get(), EVP_sha256()) == 0) {
1158         LOG(ERROR) << "Error signing X509 certificate";
1159         return {};
1160     }
1161 
1162     // Ideally we wouldn't encrypt it (we're only using this function for
1163     // sending a key-pair over binder to the Android app) but BoringSSL does not
1164     // support this: from pkcs8_x509.c in BoringSSL: "In OpenSSL, -1 here means
1165     // to use no encryption, which we do not currently support."
1166     //
1167     // Passing nullptr as |pass|, though, means "no password". So we'll do that.
1168     // Compare with the receiving side - CredstoreIdentityCredential.java - where
1169     // an empty char[] is passed as the password.
1170     //
1171     auto pkcs12 = PKCS12_Ptr(PKCS12_create(nullptr, name.c_str(), pkey.get(), x509.get(),
1172                                            nullptr,  // ca
1173                                            0,        // nid_key
1174                                            0,        // nid_cert
1175                                            0,        // iter,
1176                                            0,        // mac_iter,
1177                                            0));      // keytype
1178     if (pkcs12.get() == nullptr) {
1179         char buf[128];
1180         long errCode = ERR_get_error();
1181         ERR_error_string_n(errCode, buf, sizeof buf);
1182         LOG(ERROR) << "Error creating PKCS12, code " << errCode << ": " << buf;
1183         return {};
1184     }
1185 
1186     unsigned char* buffer = nullptr;
1187     int length = i2d_PKCS12(pkcs12.get(), &buffer);
1188     if (length < 0) {
1189         LOG(ERROR) << "Error encoding PKCS12";
1190         return {};
1191     }
1192     vector<uint8_t> pkcs12Bytes;
1193     pkcs12Bytes.resize(length);
1194     memcpy(pkcs12Bytes.data(), buffer, length);
1195     OPENSSL_free(buffer);
1196 
1197     return pkcs12Bytes;
1198 }
1199 
ecPublicKeyGenerateCertificate(const vector<uint8_t> & publicKey,const vector<uint8_t> & signingKey,const string & serialDecimal,const string & issuer,const string & subject,time_t validityNotBefore,time_t validityNotAfter)1200 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
1201         const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
1202         const string& serialDecimal, const string& issuer, const string& subject,
1203         time_t validityNotBefore, time_t validityNotAfter) {
1204     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1205     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1206     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1207         1) {
1208         LOG(ERROR) << "Error decoding publicKey";
1209         return {};
1210     }
1211     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1212     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1213     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1214         LOG(ERROR) << "Memory allocation failed";
1215         return {};
1216     }
1217     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1218         LOG(ERROR) << "Error setting group";
1219         return {};
1220     }
1221     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1222         LOG(ERROR) << "Error setting point";
1223         return {};
1224     }
1225     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1226         LOG(ERROR) << "Error setting key";
1227         return {};
1228     }
1229 
1230     auto bn = BIGNUM_Ptr(BN_bin2bn(signingKey.data(), signingKey.size(), nullptr));
1231     if (bn.get() == nullptr) {
1232         LOG(ERROR) << "Error creating BIGNUM for private key";
1233         return {};
1234     }
1235     auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1236     if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1237         LOG(ERROR) << "Error setting private key from BIGNUM";
1238         return {};
1239     }
1240     auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1241     if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1242         LOG(ERROR) << "Error setting private key";
1243         return {};
1244     }
1245 
1246     auto x509 = X509_Ptr(X509_new());
1247     if (!x509.get()) {
1248         LOG(ERROR) << "Error creating X509 certificate";
1249         return {};
1250     }
1251 
1252     if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1253         LOG(ERROR) << "Error setting version to 3";
1254         return {};
1255     }
1256 
1257     if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1258         LOG(ERROR) << "Error setting public key";
1259         return {};
1260     }
1261 
1262     BIGNUM* bignumSerial = nullptr;
1263     if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1264         LOG(ERROR) << "Error parsing serial";
1265         return {};
1266     }
1267     auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1268     auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1269     if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1270         LOG(ERROR) << "Error setting serial";
1271         return {};
1272     }
1273 
1274     auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1275     if (x509Issuer.get() == nullptr ||
1276         X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1277                                    (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1278                                    0 /* set */) != 1 ||
1279         X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1280         LOG(ERROR) << "Error setting issuer";
1281         return {};
1282     }
1283 
1284     auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1285     if (x509Subject.get() == nullptr ||
1286         X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1287                                    (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1288                                    0 /* set */) != 1 ||
1289         X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1290         LOG(ERROR) << "Error setting subject";
1291         return {};
1292     }
1293 
1294     auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1295     if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1296         LOG(ERROR) << "Error setting notBefore";
1297         return {};
1298     }
1299 
1300     auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1301     if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1302         LOG(ERROR) << "Error setting notAfter";
1303         return {};
1304     }
1305 
1306     if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
1307         LOG(ERROR) << "Error signing X509 certificate";
1308         return {};
1309     }
1310 
1311     unsigned char* buffer = nullptr;
1312     int length = i2d_X509(x509.get(), &buffer);
1313     if (length < 0) {
1314         LOG(ERROR) << "Error DER encoding X509 certificate";
1315         return {};
1316     }
1317 
1318     vector<uint8_t> certificate;
1319     certificate.resize(length);
1320     memcpy(certificate.data(), buffer, length);
1321     OPENSSL_free(buffer);
1322     return certificate;
1323 }
1324 
ecdh(const vector<uint8_t> & publicKey,const vector<uint8_t> & privateKey)1325 optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey,
1326                                const vector<uint8_t>& privateKey) {
1327     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1328     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1329     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1330         1) {
1331         LOG(ERROR) << "Error decoding publicKey";
1332         return {};
1333     }
1334     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1335     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1336     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1337         LOG(ERROR) << "Memory allocation failed";
1338         return {};
1339     }
1340     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1341         LOG(ERROR) << "Error setting group";
1342         return {};
1343     }
1344     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1345         LOG(ERROR) << "Error setting point";
1346         return {};
1347     }
1348     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1349         LOG(ERROR) << "Error setting key";
1350         return {};
1351     }
1352 
1353     auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
1354     if (bn.get() == nullptr) {
1355         LOG(ERROR) << "Error creating BIGNUM for private key";
1356         return {};
1357     }
1358     auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1359     if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1360         LOG(ERROR) << "Error setting private key from BIGNUM";
1361         return {};
1362     }
1363     auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1364     if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1365         LOG(ERROR) << "Error setting private key";
1366         return {};
1367     }
1368 
1369     auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(privPkey.get(), NULL));
1370     if (ctx.get() == nullptr) {
1371         LOG(ERROR) << "Error creating context";
1372         return {};
1373     }
1374 
1375     if (EVP_PKEY_derive_init(ctx.get()) != 1) {
1376         LOG(ERROR) << "Error initializing context";
1377         return {};
1378     }
1379 
1380     if (EVP_PKEY_derive_set_peer(ctx.get(), pkey.get()) != 1) {
1381         LOG(ERROR) << "Error setting peer";
1382         return {};
1383     }
1384 
1385     /* Determine buffer length for shared secret */
1386     size_t secretLen = 0;
1387     if (EVP_PKEY_derive(ctx.get(), NULL, &secretLen) != 1) {
1388         LOG(ERROR) << "Error determing length of shared secret";
1389         return {};
1390     }
1391     vector<uint8_t> sharedSecret;
1392     sharedSecret.resize(secretLen);
1393 
1394     if (EVP_PKEY_derive(ctx.get(), sharedSecret.data(), &secretLen) != 1) {
1395         LOG(ERROR) << "Error deriving shared secret";
1396         return {};
1397     }
1398     return sharedSecret;
1399 }
1400 
hkdf(const vector<uint8_t> & sharedSecret,const vector<uint8_t> & salt,const vector<uint8_t> & info,size_t size)1401 optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
1402                                const vector<uint8_t>& info, size_t size) {
1403     vector<uint8_t> derivedKey;
1404     derivedKey.resize(size);
1405     if (HKDF(derivedKey.data(), derivedKey.size(), EVP_sha256(), sharedSecret.data(),
1406              sharedSecret.size(), salt.data(), salt.size(), info.data(), info.size()) != 1) {
1407         LOG(ERROR) << "Error deriving key";
1408         return {};
1409     }
1410     return derivedKey;
1411 }
1412 
removeLeadingZeroes(vector<uint8_t> & vec)1413 void removeLeadingZeroes(vector<uint8_t>& vec) {
1414     while (vec.size() >= 1 && vec[0] == 0x00) {
1415         vec.erase(vec.begin());
1416     }
1417 }
1418 
ecPublicKeyGetXandY(const vector<uint8_t> & publicKey)1419 tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(
1420         const vector<uint8_t>& publicKey) {
1421     if (publicKey.size() != 65 || publicKey[0] != 0x04) {
1422         LOG(ERROR) << "publicKey is not in the expected format";
1423         return std::make_tuple(false, vector<uint8_t>(), vector<uint8_t>());
1424     }
1425     vector<uint8_t> x, y;
1426     x.resize(32);
1427     y.resize(32);
1428     memcpy(x.data(), publicKey.data() + 1, 32);
1429     memcpy(y.data(), publicKey.data() + 33, 32);
1430 
1431     removeLeadingZeroes(x);
1432     removeLeadingZeroes(y);
1433 
1434     return std::make_tuple(true, x, y);
1435 }
1436 
certificateChainGetTopMostKey(const vector<uint8_t> & certificateChain)1437 optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain) {
1438     vector<X509_Ptr> certs;
1439     if (!parseX509Certificates(certificateChain, certs)) {
1440         return {};
1441     }
1442     if (certs.size() < 1) {
1443         LOG(ERROR) << "No certificates in chain";
1444         return {};
1445     }
1446 
1447     int algoId = OBJ_obj2nid(certs[0]->cert_info->key->algor->algorithm);
1448     if (algoId != NID_X9_62_id_ecPublicKey) {
1449         LOG(ERROR) << "Expected NID_X9_62_id_ecPublicKey, got " << OBJ_nid2ln(algoId);
1450         return {};
1451     }
1452 
1453     auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
1454     if (pkey.get() == nullptr) {
1455         LOG(ERROR) << "No public key";
1456         return {};
1457     }
1458 
1459     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1460     if (ecKey.get() == nullptr) {
1461         LOG(ERROR) << "Failed getting EC key";
1462         return {};
1463     }
1464 
1465     auto ecGroup = EC_KEY_get0_group(ecKey.get());
1466     auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1467     int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1468                                   nullptr);
1469     if (size == 0) {
1470         LOG(ERROR) << "Error generating public key encoding";
1471         return {};
1472     }
1473     vector<uint8_t> publicKey;
1474     publicKey.resize(size);
1475     EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1476                        publicKey.size(), nullptr);
1477     return publicKey;
1478 }
1479 
1480 // ---------------------------------------------------------------------------
1481 // COSE Utility Functions
1482 // ---------------------------------------------------------------------------
1483 
coseBuildToBeSigned(const vector<uint8_t> & encodedProtectedHeaders,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent)1484 vector<uint8_t> coseBuildToBeSigned(const vector<uint8_t>& encodedProtectedHeaders,
1485                                     const vector<uint8_t>& data,
1486                                     const vector<uint8_t>& detachedContent) {
1487     cppbor::Array sigStructure;
1488     sigStructure.add("Signature1");
1489     sigStructure.add(encodedProtectedHeaders);
1490 
1491     // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1492     // so external_aad is the empty bstr
1493     vector<uint8_t> emptyExternalAad;
1494     sigStructure.add(emptyExternalAad);
1495 
1496     // Next field is the payload, independently of how it's transported (RFC
1497     // 8152 section 4.4). Since our API specifies only one of |data| and
1498     // |detachedContent| can be non-empty, it's simply just the non-empty one.
1499     if (data.size() > 0) {
1500         sigStructure.add(data);
1501     } else {
1502         sigStructure.add(detachedContent);
1503     }
1504     return sigStructure.encode();
1505 }
1506 
coseEncodeHeaders(const cppbor::Map & protectedHeaders)1507 vector<uint8_t> coseEncodeHeaders(const cppbor::Map& protectedHeaders) {
1508     if (protectedHeaders.size() == 0) {
1509         cppbor::Bstr emptyBstr(vector<uint8_t>({}));
1510         return emptyBstr.encode();
1511     }
1512     return protectedHeaders.encode();
1513 }
1514 
1515 // From https://tools.ietf.org/html/rfc8152
1516 const int COSE_LABEL_ALG = 1;
1517 const int COSE_LABEL_X5CHAIN = 33;  // temporary identifier
1518 
1519 // From "COSE Algorithms" registry
1520 const int COSE_ALG_ECDSA_256 = -7;
1521 const int COSE_ALG_HMAC_256_256 = 5;
1522 
ecdsaSignatureCoseToDer(const vector<uint8_t> & ecdsaCoseSignature,vector<uint8_t> & ecdsaDerSignature)1523 bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
1524                              vector<uint8_t>& ecdsaDerSignature) {
1525     if (ecdsaCoseSignature.size() != 64) {
1526         LOG(ERROR) << "COSE signature length is " << ecdsaCoseSignature.size() << ", expected 64";
1527         return false;
1528     }
1529 
1530     auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
1531     if (rBn.get() == nullptr) {
1532         LOG(ERROR) << "Error creating BIGNUM for r";
1533         return false;
1534     }
1535 
1536     auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
1537     if (sBn.get() == nullptr) {
1538         LOG(ERROR) << "Error creating BIGNUM for s";
1539         return false;
1540     }
1541 
1542     ECDSA_SIG sig;
1543     sig.r = rBn.get();
1544     sig.s = sBn.get();
1545 
1546     size_t len = i2d_ECDSA_SIG(&sig, nullptr);
1547     ecdsaDerSignature.resize(len);
1548     unsigned char* p = (unsigned char*)ecdsaDerSignature.data();
1549     i2d_ECDSA_SIG(&sig, &p);
1550 
1551     return true;
1552 }
1553 
ecdsaSignatureDerToCose(const vector<uint8_t> & ecdsaDerSignature,vector<uint8_t> & ecdsaCoseSignature)1554 bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
1555                              vector<uint8_t>& ecdsaCoseSignature) {
1556     ECDSA_SIG* sig;
1557     const unsigned char* p = ecdsaDerSignature.data();
1558     sig = d2i_ECDSA_SIG(nullptr, &p, ecdsaDerSignature.size());
1559     if (sig == nullptr) {
1560         LOG(ERROR) << "Error decoding DER signature";
1561         return false;
1562     }
1563 
1564     ecdsaCoseSignature.clear();
1565     ecdsaCoseSignature.resize(64);
1566     if (BN_bn2binpad(sig->r, ecdsaCoseSignature.data(), 32) != 32) {
1567         LOG(ERROR) << "Error encoding r";
1568         return false;
1569     }
1570     if (BN_bn2binpad(sig->s, ecdsaCoseSignature.data() + 32, 32) != 32) {
1571         LOG(ERROR) << "Error encoding s";
1572         return false;
1573     }
1574     return true;
1575 }
1576 
coseSignEcDsa(const vector<uint8_t> & key,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent,const vector<uint8_t> & certificateChain)1577 optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
1578                                         const vector<uint8_t>& detachedContent,
1579                                         const vector<uint8_t>& certificateChain) {
1580     cppbor::Map unprotectedHeaders;
1581     cppbor::Map protectedHeaders;
1582 
1583     if (data.size() > 0 && detachedContent.size() > 0) {
1584         LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1585         return {};
1586     }
1587 
1588     protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
1589 
1590     if (certificateChain.size() != 0) {
1591         optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
1592         if (!certs) {
1593             LOG(ERROR) << "Error splitting certificate chain";
1594             return {};
1595         }
1596         if (certs.value().size() == 1) {
1597             unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
1598         } else {
1599             cppbor::Array certArray;
1600             for (const vector<uint8_t>& cert : certs.value()) {
1601                 certArray.add(cert);
1602             }
1603             unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
1604         }
1605     }
1606 
1607     vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1608     vector<uint8_t> toBeSigned =
1609             coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1610 
1611     optional<vector<uint8_t>> derSignature = signEcDsa(key, toBeSigned);
1612     if (!derSignature) {
1613         LOG(ERROR) << "Error signing toBeSigned data";
1614         return {};
1615     }
1616     vector<uint8_t> coseSignature;
1617     if (!ecdsaSignatureDerToCose(derSignature.value(), coseSignature)) {
1618         LOG(ERROR) << "Error converting ECDSA signature from DER to COSE format";
1619         return {};
1620     }
1621 
1622     cppbor::Array coseSign1;
1623     coseSign1.add(encodedProtectedHeaders);
1624     coseSign1.add(std::move(unprotectedHeaders));
1625     if (data.size() == 0) {
1626         cppbor::Null nullValue;
1627         coseSign1.add(std::move(nullValue));
1628     } else {
1629         coseSign1.add(data);
1630     }
1631     coseSign1.add(coseSignature);
1632     vector<uint8_t> signatureCoseSign1;
1633     signatureCoseSign1 = coseSign1.encode();
1634     return signatureCoseSign1;
1635 }
1636 
coseCheckEcDsaSignature(const vector<uint8_t> & signatureCoseSign1,const vector<uint8_t> & detachedContent,const vector<uint8_t> & publicKey)1637 bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
1638                              const vector<uint8_t>& detachedContent,
1639                              const vector<uint8_t>& publicKey) {
1640     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1641     if (item == nullptr) {
1642         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1643         return false;
1644     }
1645     const cppbor::Array* array = item->asArray();
1646     if (array == nullptr) {
1647         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1648         return false;
1649     }
1650     if (array->size() != 4) {
1651         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1652         return false;
1653     }
1654 
1655     const cppbor::Bstr* encodedProtectedHeadersBstr = (*array)[0]->asBstr();
1656     ;
1657     if (encodedProtectedHeadersBstr == nullptr) {
1658         LOG(ERROR) << "Value for encodedProtectedHeaders is not a bstr";
1659         return false;
1660     }
1661     const vector<uint8_t> encodedProtectedHeaders = encodedProtectedHeadersBstr->value();
1662 
1663     const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1664     if (unprotectedHeaders == nullptr) {
1665         LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1666         return false;
1667     }
1668 
1669     vector<uint8_t> data;
1670     const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1671     if (payloadAsSimple != nullptr) {
1672         if (payloadAsSimple->asNull() == nullptr) {
1673             LOG(ERROR) << "Value for payload is not null or a bstr";
1674             return false;
1675         }
1676     } else {
1677         const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1678         if (payloadAsBstr == nullptr) {
1679             LOG(ERROR) << "Value for payload is not null or a bstr";
1680             return false;
1681         }
1682         data = payloadAsBstr->value();  // TODO: avoid copy
1683     }
1684 
1685     if (data.size() > 0 && detachedContent.size() > 0) {
1686         LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1687         return false;
1688     }
1689 
1690     const cppbor::Bstr* signatureBstr = (*array)[3]->asBstr();
1691     if (signatureBstr == nullptr) {
1692         LOG(ERROR) << "Value for signature is a bstr";
1693         return false;
1694     }
1695     const vector<uint8_t>& coseSignature = signatureBstr->value();
1696 
1697     vector<uint8_t> derSignature;
1698     if (!ecdsaSignatureCoseToDer(coseSignature, derSignature)) {
1699         LOG(ERROR) << "Error converting ECDSA signature from COSE to DER format";
1700         return false;
1701     }
1702 
1703     vector<uint8_t> toBeSigned =
1704             coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1705     if (!checkEcDsaSignature(support::sha256(toBeSigned), derSignature, publicKey)) {
1706         LOG(ERROR) << "Signature check failed";
1707         return false;
1708     }
1709     return true;
1710 }
1711 
coseSignGetPayload(const vector<uint8_t> & signatureCoseSign1)1712 optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
1713     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1714     if (item == nullptr) {
1715         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1716         return {};
1717     }
1718     const cppbor::Array* array = item->asArray();
1719     if (array == nullptr) {
1720         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1721         return {};
1722     }
1723     if (array->size() != 4) {
1724         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1725         return {};
1726     }
1727 
1728     vector<uint8_t> data;
1729     const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1730     if (payloadAsSimple != nullptr) {
1731         if (payloadAsSimple->asNull() == nullptr) {
1732             LOG(ERROR) << "Value for payload is not null or a bstr";
1733             return {};
1734         }
1735         // payload is null, so |data| should be empty (as it is)
1736     } else {
1737         const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1738         if (payloadAsBstr == nullptr) {
1739             LOG(ERROR) << "Value for payload is not null or a bstr";
1740             return {};
1741         }
1742         // Copy payload into |data|
1743         data = payloadAsBstr->value();
1744     }
1745 
1746     return data;
1747 }
1748 
coseSignGetX5Chain(const vector<uint8_t> & signatureCoseSign1)1749 optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
1750     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1751     if (item == nullptr) {
1752         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1753         return {};
1754     }
1755     const cppbor::Array* array = item->asArray();
1756     if (array == nullptr) {
1757         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1758         return {};
1759     }
1760     if (array->size() != 4) {
1761         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1762         return {};
1763     }
1764 
1765     const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1766     if (unprotectedHeaders == nullptr) {
1767         LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1768         return {};
1769     }
1770 
1771     for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
1772         auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
1773         const cppbor::Int* number = keyItem->asInt();
1774         if (number == nullptr) {
1775             LOG(ERROR) << "Key item in top-level map is not a number";
1776             return {};
1777         }
1778         int label = number->value();
1779         if (label == COSE_LABEL_X5CHAIN) {
1780             const cppbor::Bstr* bstr = valueItem->asBstr();
1781             if (bstr != nullptr) {
1782                 return bstr->value();
1783             }
1784             const cppbor::Array* array = valueItem->asArray();
1785             if (array != nullptr) {
1786                 vector<uint8_t> certs;
1787                 for (size_t m = 0; m < array->size(); m++) {
1788                     const cppbor::Bstr* bstr = ((*array)[m])->asBstr();
1789                     if (bstr == nullptr) {
1790                         LOG(ERROR) << "Item in x5chain array is not a bstr";
1791                         return {};
1792                     }
1793                     const vector<uint8_t>& certValue = bstr->value();
1794                     certs.insert(certs.end(), certValue.begin(), certValue.end());
1795                 }
1796                 return certs;
1797             }
1798             LOG(ERROR) << "Value for x5chain label is not a bstr or array";
1799             return {};
1800         }
1801     }
1802     LOG(ERROR) << "Did not find x5chain label in unprotected headers";
1803     return {};
1804 }
1805 
coseBuildToBeMACed(const vector<uint8_t> & encodedProtectedHeaders,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent)1806 vector<uint8_t> coseBuildToBeMACed(const vector<uint8_t>& encodedProtectedHeaders,
1807                                    const vector<uint8_t>& data,
1808                                    const vector<uint8_t>& detachedContent) {
1809     cppbor::Array macStructure;
1810     macStructure.add("MAC0");
1811     macStructure.add(encodedProtectedHeaders);
1812 
1813     // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1814     // so external_aad is the empty bstr
1815     vector<uint8_t> emptyExternalAad;
1816     macStructure.add(emptyExternalAad);
1817 
1818     // Next field is the payload, independently of how it's transported (RFC
1819     // 8152 section 4.4). Since our API specifies only one of |data| and
1820     // |detachedContent| can be non-empty, it's simply just the non-empty one.
1821     if (data.size() > 0) {
1822         macStructure.add(data);
1823     } else {
1824         macStructure.add(detachedContent);
1825     }
1826 
1827     return macStructure.encode();
1828 }
1829 
coseMac0(const vector<uint8_t> & key,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent)1830 optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
1831                                    const vector<uint8_t>& detachedContent) {
1832     cppbor::Map unprotectedHeaders;
1833     cppbor::Map protectedHeaders;
1834 
1835     if (data.size() > 0 && detachedContent.size() > 0) {
1836         LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1837         return {};
1838     }
1839 
1840     protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
1841 
1842     vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1843     vector<uint8_t> toBeMACed = coseBuildToBeMACed(encodedProtectedHeaders, data, detachedContent);
1844 
1845     optional<vector<uint8_t>> mac = hmacSha256(key, toBeMACed);
1846     if (!mac) {
1847         LOG(ERROR) << "Error MACing toBeMACed data";
1848         return {};
1849     }
1850 
1851     cppbor::Array array;
1852     array.add(encodedProtectedHeaders);
1853     array.add(std::move(unprotectedHeaders));
1854     if (data.size() == 0) {
1855         cppbor::Null nullValue;
1856         array.add(std::move(nullValue));
1857     } else {
1858         array.add(data);
1859     }
1860     array.add(mac.value());
1861     return array.encode();
1862 }
1863 
1864 // ---------------------------------------------------------------------------
1865 // Utility functions specific to IdentityCredential.
1866 // ---------------------------------------------------------------------------
1867 
chunkVector(const vector<uint8_t> & content,size_t maxChunkSize)1868 vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize) {
1869     vector<vector<uint8_t>> ret;
1870 
1871     size_t contentSize = content.size();
1872     if (contentSize <= maxChunkSize) {
1873         ret.push_back(content);
1874         return ret;
1875     }
1876 
1877     size_t numChunks = (contentSize + maxChunkSize - 1) / maxChunkSize;
1878 
1879     size_t pos = 0;
1880     for (size_t n = 0; n < numChunks; n++) {
1881         size_t size = contentSize - pos;
1882         if (size > maxChunkSize) {
1883             size = maxChunkSize;
1884         }
1885         auto begin = content.begin() + pos;
1886         auto end = content.begin() + pos + size;
1887         ret.emplace_back(vector<uint8_t>(begin, end));
1888         pos += maxChunkSize;
1889     }
1890 
1891     return ret;
1892 }
1893 
1894 
1895 vector<uint8_t> testHardwareBoundKey = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1896 
getTestHardwareBoundKey()1897 const vector<uint8_t>& getTestHardwareBoundKey() {
1898     return testHardwareBoundKey;
1899 }
1900 
1901 }  // namespace support
1902 }  // namespace identity
1903 }  // namespace hardware
1904 }  // namespace android
1905