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