blob: dc49ddc992204f4b1b3d5b35806ea8eb36a5cbe5 [file] [log] [blame]
David Zeuthenc75ac312019-10-28 13:16:45 -04001/*
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
Selene Huang459cb802020-01-08 22:59:02 -080050#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
David Zeuthenc75ac312019-10-28 13:16:45 -040057namespace android {
58namespace hardware {
59namespace identity {
60namespace support {
61
62using ::std::pair;
63using ::std::unique_ptr;
64
65// ---------------------------------------------------------------------------
66// Miscellaneous utilities.
67// ---------------------------------------------------------------------------
68
69void 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
90string 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
105string encodeHex(const string& str) {
106 return encodeHex(reinterpret_cast<const uint8_t*>(str.data()), str.size());
107}
108
109string 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.
114int 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
125optional<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
151static 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
187static 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
327string 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
344struct EVP_CIPHER_CTX_Deleter {
345 void operator()(EVP_CIPHER_CTX* ctx) const {
346 if (ctx != nullptr) {
347 EVP_CIPHER_CTX_free(ctx);
348 }
349 }
350};
351
352using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>;
353
354// bool getRandom(size_t numBytes, vector<uint8_t>& output) {
355optional<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
365optional<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
446optional<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
534struct EC_KEY_Deleter {
535 void operator()(EC_KEY* key) const {
536 if (key != nullptr) {
537 EC_KEY_free(key);
538 }
539 }
540};
541using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>;
542
543struct EVP_PKEY_Deleter {
544 void operator()(EVP_PKEY* key) const {
545 if (key != nullptr) {
546 EVP_PKEY_free(key);
547 }
548 }
549};
550using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
551
552struct EVP_PKEY_CTX_Deleter {
553 void operator()(EVP_PKEY_CTX* ctx) const {
554 if (ctx != nullptr) {
555 EVP_PKEY_CTX_free(ctx);
556 }
557 }
558};
559using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>;
560
561struct EC_GROUP_Deleter {
562 void operator()(EC_GROUP* group) const {
563 if (group != nullptr) {
564 EC_GROUP_free(group);
565 }
566 }
567};
568using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>;
569
570struct EC_POINT_Deleter {
571 void operator()(EC_POINT* point) const {
572 if (point != nullptr) {
573 EC_POINT_free(point);
574 }
575 }
576};
577
578using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>;
579
580struct ECDSA_SIG_Deleter {
581 void operator()(ECDSA_SIG* sig) const {
582 if (sig != nullptr) {
583 ECDSA_SIG_free(sig);
584 }
585 }
586};
587using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>;
588
589struct X509_Deleter {
590 void operator()(X509* x509) const {
591 if (x509 != nullptr) {
592 X509_free(x509);
593 }
594 }
595};
596using X509_Ptr = unique_ptr<X509, X509_Deleter>;
597
598struct PKCS12_Deleter {
599 void operator()(PKCS12* pkcs12) const {
600 if (pkcs12 != nullptr) {
601 PKCS12_free(pkcs12);
602 }
603 }
604};
605using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>;
606
607struct BIGNUM_Deleter {
608 void operator()(BIGNUM* bignum) const {
609 if (bignum != nullptr) {
610 BN_free(bignum);
611 }
612 }
613};
614using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>;
615
616struct ASN1_INTEGER_Deleter {
617 void operator()(ASN1_INTEGER* value) const {
618 if (value != nullptr) {
619 ASN1_INTEGER_free(value);
620 }
621 }
622};
623using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>;
624
625struct ASN1_TIME_Deleter {
626 void operator()(ASN1_TIME* value) const {
627 if (value != nullptr) {
628 ASN1_TIME_free(value);
629 }
630 }
631};
632using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>;
633
634struct X509_NAME_Deleter {
635 void operator()(X509_NAME* value) const {
636 if (value != nullptr) {
637 X509_NAME_free(value);
638 }
639 }
640};
641using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>;
642
643vector<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
651optional<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
671static 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//
693bool 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
719bool 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
763vector<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
773optional<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
801optional<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
Selene Huang459cb802020-01-08 22:59:02 -0800826// 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.
831optional<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
912optional<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
David Zeuthenc75ac312019-10-28 13:16:45 -0400958optional<vector<uint8_t>> createEcKeyPair() {
959 auto ec_key = EC_KEY_Ptr(EC_KEY_new());
960 auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
David Zeuthenc75ac312019-10-28 13:16:45 -0400961 if (ec_key.get() == nullptr || pkey.get() == nullptr) {
962 LOG(ERROR) << "Memory allocation failed";
963 return {};
964 }
965
Selene Huang92b61d62020-03-04 02:24:16 -0800966 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
David Zeuthenc75ac312019-10-28 13:16:45 -0400972 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
995optional<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
1025optional<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
1050optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
1051 const string& serialDecimal, const string& issuer,
1052 const string& subject, time_t validityNotBefore,
1053 time_t validityNotAfter) {
1054 const unsigned char* p = (const unsigned char*)keyPair.data();
1055 auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1056 if (pkey.get() == nullptr) {
1057 LOG(ERROR) << "Error parsing keyPair";
1058 return {};
1059 }
1060
1061 auto x509 = X509_Ptr(X509_new());
1062 if (!x509.get()) {
1063 LOG(ERROR) << "Error creating X509 certificate";
1064 return {};
1065 }
1066
1067 if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1068 LOG(ERROR) << "Error setting version to 3";
1069 return {};
1070 }
1071
1072 if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1073 LOG(ERROR) << "Error setting public key";
1074 return {};
1075 }
1076
1077 BIGNUM* bignumSerial = nullptr;
1078 if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1079 LOG(ERROR) << "Error parsing serial";
1080 return {};
1081 }
1082 auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1083 auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1084 if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1085 LOG(ERROR) << "Error setting serial";
1086 return {};
1087 }
1088
1089 auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1090 if (x509Issuer.get() == nullptr ||
1091 X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1092 (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1093 0 /* set */) != 1 ||
1094 X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1095 LOG(ERROR) << "Error setting issuer";
1096 return {};
1097 }
1098
1099 auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1100 if (x509Subject.get() == nullptr ||
1101 X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1102 (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1103 0 /* set */) != 1 ||
1104 X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1105 LOG(ERROR) << "Error setting subject";
1106 return {};
1107 }
1108
1109 auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1110 if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1111 LOG(ERROR) << "Error setting notBefore";
1112 return {};
1113 }
1114
1115 auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1116 if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1117 LOG(ERROR) << "Error setting notAfter";
1118 return {};
1119 }
1120
1121 if (X509_sign(x509.get(), pkey.get(), EVP_sha256()) == 0) {
1122 LOG(ERROR) << "Error signing X509 certificate";
1123 return {};
1124 }
1125
1126 // Ideally we wouldn't encrypt it (we're only using this function for
1127 // sending a key-pair over binder to the Android app) but BoringSSL does not
1128 // support this: from pkcs8_x509.c in BoringSSL: "In OpenSSL, -1 here means
1129 // to use no encryption, which we do not currently support."
1130 //
1131 // Passing nullptr as |pass|, though, means "no password". So we'll do that.
1132 // Compare with the receiving side - CredstoreIdentityCredential.java - where
1133 // an empty char[] is passed as the password.
1134 //
1135 auto pkcs12 = PKCS12_Ptr(PKCS12_create(nullptr, name.c_str(), pkey.get(), x509.get(),
1136 nullptr, // ca
1137 0, // nid_key
1138 0, // nid_cert
1139 0, // iter,
1140 0, // mac_iter,
1141 0)); // keytype
1142 if (pkcs12.get() == nullptr) {
1143 char buf[128];
1144 long errCode = ERR_get_error();
1145 ERR_error_string_n(errCode, buf, sizeof buf);
1146 LOG(ERROR) << "Error creating PKCS12, code " << errCode << ": " << buf;
1147 return {};
1148 }
1149
1150 unsigned char* buffer = nullptr;
1151 int length = i2d_PKCS12(pkcs12.get(), &buffer);
1152 if (length < 0) {
1153 LOG(ERROR) << "Error encoding PKCS12";
1154 return {};
1155 }
1156 vector<uint8_t> pkcs12Bytes;
1157 pkcs12Bytes.resize(length);
1158 memcpy(pkcs12Bytes.data(), buffer, length);
1159 OPENSSL_free(buffer);
1160
1161 return pkcs12Bytes;
1162}
1163
1164optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
1165 const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
1166 const string& serialDecimal, const string& issuer, const string& subject,
1167 time_t validityNotBefore, time_t validityNotAfter) {
1168 auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1169 auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1170 if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1171 1) {
1172 LOG(ERROR) << "Error decoding publicKey";
1173 return {};
1174 }
1175 auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1176 auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1177 if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1178 LOG(ERROR) << "Memory allocation failed";
1179 return {};
1180 }
1181 if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1182 LOG(ERROR) << "Error setting group";
1183 return {};
1184 }
1185 if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1186 LOG(ERROR) << "Error setting point";
1187 return {};
1188 }
1189 if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1190 LOG(ERROR) << "Error setting key";
1191 return {};
1192 }
1193
1194 auto bn = BIGNUM_Ptr(BN_bin2bn(signingKey.data(), signingKey.size(), nullptr));
1195 if (bn.get() == nullptr) {
1196 LOG(ERROR) << "Error creating BIGNUM for private key";
1197 return {};
1198 }
1199 auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1200 if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1201 LOG(ERROR) << "Error setting private key from BIGNUM";
1202 return {};
1203 }
1204 auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1205 if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1206 LOG(ERROR) << "Error setting private key";
1207 return {};
1208 }
1209
1210 auto x509 = X509_Ptr(X509_new());
1211 if (!x509.get()) {
1212 LOG(ERROR) << "Error creating X509 certificate";
1213 return {};
1214 }
1215
1216 if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1217 LOG(ERROR) << "Error setting version to 3";
1218 return {};
1219 }
1220
1221 if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1222 LOG(ERROR) << "Error setting public key";
1223 return {};
1224 }
1225
1226 BIGNUM* bignumSerial = nullptr;
1227 if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1228 LOG(ERROR) << "Error parsing serial";
1229 return {};
1230 }
1231 auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1232 auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1233 if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1234 LOG(ERROR) << "Error setting serial";
1235 return {};
1236 }
1237
1238 auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1239 if (x509Issuer.get() == nullptr ||
1240 X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1241 (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1242 0 /* set */) != 1 ||
1243 X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1244 LOG(ERROR) << "Error setting issuer";
1245 return {};
1246 }
1247
1248 auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1249 if (x509Subject.get() == nullptr ||
1250 X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1251 (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1252 0 /* set */) != 1 ||
1253 X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1254 LOG(ERROR) << "Error setting subject";
1255 return {};
1256 }
1257
1258 auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1259 if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1260 LOG(ERROR) << "Error setting notBefore";
1261 return {};
1262 }
1263
1264 auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1265 if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1266 LOG(ERROR) << "Error setting notAfter";
1267 return {};
1268 }
1269
1270 if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
1271 LOG(ERROR) << "Error signing X509 certificate";
1272 return {};
1273 }
1274
1275 unsigned char* buffer = nullptr;
1276 int length = i2d_X509(x509.get(), &buffer);
1277 if (length < 0) {
1278 LOG(ERROR) << "Error DER encoding X509 certificate";
1279 return {};
1280 }
1281
1282 vector<uint8_t> certificate;
1283 certificate.resize(length);
1284 memcpy(certificate.data(), buffer, length);
1285 OPENSSL_free(buffer);
1286 return certificate;
1287}
1288
1289optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey,
1290 const vector<uint8_t>& privateKey) {
1291 auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1292 auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1293 if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1294 1) {
1295 LOG(ERROR) << "Error decoding publicKey";
1296 return {};
1297 }
1298 auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1299 auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1300 if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1301 LOG(ERROR) << "Memory allocation failed";
1302 return {};
1303 }
1304 if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1305 LOG(ERROR) << "Error setting group";
1306 return {};
1307 }
1308 if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1309 LOG(ERROR) << "Error setting point";
1310 return {};
1311 }
1312 if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1313 LOG(ERROR) << "Error setting key";
1314 return {};
1315 }
1316
1317 auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
1318 if (bn.get() == nullptr) {
1319 LOG(ERROR) << "Error creating BIGNUM for private key";
1320 return {};
1321 }
1322 auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1323 if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1324 LOG(ERROR) << "Error setting private key from BIGNUM";
1325 return {};
1326 }
1327 auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1328 if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1329 LOG(ERROR) << "Error setting private key";
1330 return {};
1331 }
1332
1333 auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(privPkey.get(), NULL));
1334 if (ctx.get() == nullptr) {
1335 LOG(ERROR) << "Error creating context";
1336 return {};
1337 }
1338
1339 if (EVP_PKEY_derive_init(ctx.get()) != 1) {
1340 LOG(ERROR) << "Error initializing context";
1341 return {};
1342 }
1343
1344 if (EVP_PKEY_derive_set_peer(ctx.get(), pkey.get()) != 1) {
1345 LOG(ERROR) << "Error setting peer";
1346 return {};
1347 }
1348
1349 /* Determine buffer length for shared secret */
1350 size_t secretLen = 0;
1351 if (EVP_PKEY_derive(ctx.get(), NULL, &secretLen) != 1) {
1352 LOG(ERROR) << "Error determing length of shared secret";
1353 return {};
1354 }
1355 vector<uint8_t> sharedSecret;
1356 sharedSecret.resize(secretLen);
1357
1358 if (EVP_PKEY_derive(ctx.get(), sharedSecret.data(), &secretLen) != 1) {
1359 LOG(ERROR) << "Error deriving shared secret";
1360 return {};
1361 }
1362 return sharedSecret;
1363}
1364
1365optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
1366 const vector<uint8_t>& info, size_t size) {
1367 vector<uint8_t> derivedKey;
1368 derivedKey.resize(size);
1369 if (HKDF(derivedKey.data(), derivedKey.size(), EVP_sha256(), sharedSecret.data(),
1370 sharedSecret.size(), salt.data(), salt.size(), info.data(), info.size()) != 1) {
1371 LOG(ERROR) << "Error deriving key";
1372 return {};
1373 }
1374 return derivedKey;
1375}
1376
1377void removeLeadingZeroes(vector<uint8_t>& vec) {
1378 while (vec.size() >= 1 && vec[0] == 0x00) {
1379 vec.erase(vec.begin());
1380 }
1381}
1382
1383tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(
1384 const vector<uint8_t>& publicKey) {
1385 if (publicKey.size() != 65 || publicKey[0] != 0x04) {
1386 LOG(ERROR) << "publicKey is not in the expected format";
1387 return std::make_tuple(false, vector<uint8_t>(), vector<uint8_t>());
1388 }
1389 vector<uint8_t> x, y;
1390 x.resize(32);
1391 y.resize(32);
1392 memcpy(x.data(), publicKey.data() + 1, 32);
1393 memcpy(y.data(), publicKey.data() + 33, 32);
1394
1395 removeLeadingZeroes(x);
1396 removeLeadingZeroes(y);
1397
1398 return std::make_tuple(true, x, y);
1399}
1400
1401optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain) {
1402 vector<X509_Ptr> certs;
1403 if (!parseX509Certificates(certificateChain, certs)) {
1404 return {};
1405 }
1406 if (certs.size() < 1) {
1407 LOG(ERROR) << "No certificates in chain";
1408 return {};
1409 }
1410
1411 int algoId = OBJ_obj2nid(certs[0]->cert_info->key->algor->algorithm);
1412 if (algoId != NID_X9_62_id_ecPublicKey) {
1413 LOG(ERROR) << "Expected NID_X9_62_id_ecPublicKey, got " << OBJ_nid2ln(algoId);
1414 return {};
1415 }
1416
1417 auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
1418 if (pkey.get() == nullptr) {
1419 LOG(ERROR) << "No public key";
1420 return {};
1421 }
1422
1423 auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1424 if (ecKey.get() == nullptr) {
1425 LOG(ERROR) << "Failed getting EC key";
1426 return {};
1427 }
1428
1429 auto ecGroup = EC_KEY_get0_group(ecKey.get());
1430 auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1431 int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1432 nullptr);
1433 if (size == 0) {
1434 LOG(ERROR) << "Error generating public key encoding";
1435 return {};
1436 }
1437 vector<uint8_t> publicKey;
1438 publicKey.resize(size);
1439 EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1440 publicKey.size(), nullptr);
1441 return publicKey;
1442}
1443
1444// ---------------------------------------------------------------------------
1445// COSE Utility Functions
1446// ---------------------------------------------------------------------------
1447
1448vector<uint8_t> coseBuildToBeSigned(const vector<uint8_t>& encodedProtectedHeaders,
1449 const vector<uint8_t>& data,
1450 const vector<uint8_t>& detachedContent) {
1451 cppbor::Array sigStructure;
1452 sigStructure.add("Signature1");
1453 sigStructure.add(encodedProtectedHeaders);
1454
1455 // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1456 // so external_aad is the empty bstr
1457 vector<uint8_t> emptyExternalAad;
1458 sigStructure.add(emptyExternalAad);
1459
1460 // Next field is the payload, independently of how it's transported (RFC
1461 // 8152 section 4.4). Since our API specifies only one of |data| and
1462 // |detachedContent| can be non-empty, it's simply just the non-empty one.
1463 if (data.size() > 0) {
1464 sigStructure.add(data);
1465 } else {
1466 sigStructure.add(detachedContent);
1467 }
1468 return sigStructure.encode();
1469}
1470
1471vector<uint8_t> coseEncodeHeaders(const cppbor::Map& protectedHeaders) {
1472 if (protectedHeaders.size() == 0) {
1473 cppbor::Bstr emptyBstr(vector<uint8_t>({}));
1474 return emptyBstr.encode();
1475 }
1476 return protectedHeaders.encode();
1477}
1478
1479// From https://tools.ietf.org/html/rfc8152
1480const int COSE_LABEL_ALG = 1;
1481const int COSE_LABEL_X5CHAIN = 33; // temporary identifier
1482
1483// From "COSE Algorithms" registry
1484const int COSE_ALG_ECDSA_256 = -7;
1485const int COSE_ALG_HMAC_256_256 = 5;
1486
1487bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
1488 vector<uint8_t>& ecdsaDerSignature) {
1489 if (ecdsaCoseSignature.size() != 64) {
1490 LOG(ERROR) << "COSE signature length is " << ecdsaCoseSignature.size() << ", expected 64";
1491 return false;
1492 }
1493
1494 auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
1495 if (rBn.get() == nullptr) {
1496 LOG(ERROR) << "Error creating BIGNUM for r";
1497 return false;
1498 }
1499
1500 auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
1501 if (sBn.get() == nullptr) {
1502 LOG(ERROR) << "Error creating BIGNUM for s";
1503 return false;
1504 }
1505
1506 ECDSA_SIG sig;
1507 sig.r = rBn.get();
1508 sig.s = sBn.get();
1509
1510 size_t len = i2d_ECDSA_SIG(&sig, nullptr);
1511 ecdsaDerSignature.resize(len);
1512 unsigned char* p = (unsigned char*)ecdsaDerSignature.data();
1513 i2d_ECDSA_SIG(&sig, &p);
1514
1515 return true;
1516}
1517
1518bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
1519 vector<uint8_t>& ecdsaCoseSignature) {
1520 ECDSA_SIG* sig;
1521 const unsigned char* p = ecdsaDerSignature.data();
1522 sig = d2i_ECDSA_SIG(nullptr, &p, ecdsaDerSignature.size());
1523 if (sig == nullptr) {
1524 LOG(ERROR) << "Error decoding DER signature";
1525 return false;
1526 }
1527
1528 ecdsaCoseSignature.clear();
1529 ecdsaCoseSignature.resize(64);
1530 if (BN_bn2binpad(sig->r, ecdsaCoseSignature.data(), 32) != 32) {
1531 LOG(ERROR) << "Error encoding r";
1532 return false;
1533 }
1534 if (BN_bn2binpad(sig->s, ecdsaCoseSignature.data() + 32, 32) != 32) {
1535 LOG(ERROR) << "Error encoding s";
1536 return false;
1537 }
1538 return true;
1539}
1540
1541optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
1542 const vector<uint8_t>& detachedContent,
1543 const vector<uint8_t>& certificateChain) {
1544 cppbor::Map unprotectedHeaders;
1545 cppbor::Map protectedHeaders;
1546
1547 if (data.size() > 0 && detachedContent.size() > 0) {
1548 LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1549 return {};
1550 }
1551
1552 protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
1553
1554 if (certificateChain.size() != 0) {
1555 optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
1556 if (!certs) {
1557 LOG(ERROR) << "Error splitting certificate chain";
1558 return {};
1559 }
1560 if (certs.value().size() == 1) {
1561 unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
1562 } else {
1563 cppbor::Array certArray;
1564 for (const vector<uint8_t>& cert : certs.value()) {
1565 certArray.add(cert);
1566 }
1567 unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
1568 }
1569 }
1570
1571 vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1572 vector<uint8_t> toBeSigned =
1573 coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1574
1575 optional<vector<uint8_t>> derSignature = signEcDsa(key, toBeSigned);
1576 if (!derSignature) {
1577 LOG(ERROR) << "Error signing toBeSigned data";
1578 return {};
1579 }
1580 vector<uint8_t> coseSignature;
1581 if (!ecdsaSignatureDerToCose(derSignature.value(), coseSignature)) {
1582 LOG(ERROR) << "Error converting ECDSA signature from DER to COSE format";
1583 return {};
1584 }
1585
1586 cppbor::Array coseSign1;
1587 coseSign1.add(encodedProtectedHeaders);
1588 coseSign1.add(std::move(unprotectedHeaders));
1589 if (data.size() == 0) {
1590 cppbor::Null nullValue;
1591 coseSign1.add(std::move(nullValue));
1592 } else {
1593 coseSign1.add(data);
1594 }
1595 coseSign1.add(coseSignature);
1596 vector<uint8_t> signatureCoseSign1;
1597 signatureCoseSign1 = coseSign1.encode();
1598 return signatureCoseSign1;
1599}
1600
1601bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
1602 const vector<uint8_t>& detachedContent,
1603 const vector<uint8_t>& publicKey) {
1604 auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1605 if (item == nullptr) {
1606 LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1607 return false;
1608 }
1609 const cppbor::Array* array = item->asArray();
1610 if (array == nullptr) {
1611 LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1612 return false;
1613 }
1614 if (array->size() != 4) {
1615 LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1616 return false;
1617 }
1618
1619 const cppbor::Bstr* encodedProtectedHeadersBstr = (*array)[0]->asBstr();
1620 ;
1621 if (encodedProtectedHeadersBstr == nullptr) {
1622 LOG(ERROR) << "Value for encodedProtectedHeaders is not a bstr";
1623 return false;
1624 }
1625 const vector<uint8_t> encodedProtectedHeaders = encodedProtectedHeadersBstr->value();
1626
1627 const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1628 if (unprotectedHeaders == nullptr) {
1629 LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1630 return false;
1631 }
1632
1633 vector<uint8_t> data;
1634 const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1635 if (payloadAsSimple != nullptr) {
1636 if (payloadAsSimple->asNull() == nullptr) {
1637 LOG(ERROR) << "Value for payload is not null or a bstr";
1638 return false;
1639 }
1640 } else {
1641 const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1642 if (payloadAsBstr == nullptr) {
1643 LOG(ERROR) << "Value for payload is not null or a bstr";
1644 return false;
1645 }
1646 data = payloadAsBstr->value(); // TODO: avoid copy
1647 }
1648
1649 if (data.size() > 0 && detachedContent.size() > 0) {
1650 LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1651 return false;
1652 }
1653
1654 const cppbor::Bstr* signatureBstr = (*array)[3]->asBstr();
1655 if (signatureBstr == nullptr) {
1656 LOG(ERROR) << "Value for signature is a bstr";
1657 return false;
1658 }
1659 const vector<uint8_t>& coseSignature = signatureBstr->value();
1660
1661 vector<uint8_t> derSignature;
1662 if (!ecdsaSignatureCoseToDer(coseSignature, derSignature)) {
1663 LOG(ERROR) << "Error converting ECDSA signature from COSE to DER format";
1664 return false;
1665 }
1666
1667 vector<uint8_t> toBeSigned =
1668 coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1669 if (!checkEcDsaSignature(support::sha256(toBeSigned), derSignature, publicKey)) {
1670 LOG(ERROR) << "Signature check failed";
1671 return false;
1672 }
1673 return true;
1674}
1675
1676optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
1677 auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1678 if (item == nullptr) {
1679 LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1680 return {};
1681 }
1682 const cppbor::Array* array = item->asArray();
1683 if (array == nullptr) {
1684 LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1685 return {};
1686 }
1687 if (array->size() != 4) {
1688 LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1689 return {};
1690 }
1691
1692 vector<uint8_t> data;
1693 const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1694 if (payloadAsSimple != nullptr) {
1695 if (payloadAsSimple->asNull() == nullptr) {
1696 LOG(ERROR) << "Value for payload is not null or a bstr";
1697 return {};
1698 }
1699 // payload is null, so |data| should be empty (as it is)
1700 } else {
1701 const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1702 if (payloadAsBstr == nullptr) {
1703 LOG(ERROR) << "Value for payload is not null or a bstr";
1704 return {};
1705 }
1706 // Copy payload into |data|
1707 data = payloadAsBstr->value();
1708 }
1709
1710 return data;
1711}
1712
1713optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
1714 auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1715 if (item == nullptr) {
1716 LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1717 return {};
1718 }
1719 const cppbor::Array* array = item->asArray();
1720 if (array == nullptr) {
1721 LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1722 return {};
1723 }
1724 if (array->size() != 4) {
1725 LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1726 return {};
1727 }
1728
1729 const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1730 if (unprotectedHeaders == nullptr) {
1731 LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1732 return {};
1733 }
1734
1735 for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
1736 auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
1737 const cppbor::Int* number = keyItem->asInt();
1738 if (number == nullptr) {
1739 LOG(ERROR) << "Key item in top-level map is not a number";
1740 return {};
1741 }
1742 int label = number->value();
1743 if (label == COSE_LABEL_X5CHAIN) {
1744 const cppbor::Bstr* bstr = valueItem->asBstr();
1745 if (bstr != nullptr) {
1746 return bstr->value();
1747 }
1748 const cppbor::Array* array = valueItem->asArray();
1749 if (array != nullptr) {
1750 vector<uint8_t> certs;
1751 for (size_t m = 0; m < array->size(); m++) {
1752 const cppbor::Bstr* bstr = ((*array)[m])->asBstr();
1753 if (bstr == nullptr) {
1754 LOG(ERROR) << "Item in x5chain array is not a bstr";
1755 return {};
1756 }
1757 const vector<uint8_t>& certValue = bstr->value();
1758 certs.insert(certs.end(), certValue.begin(), certValue.end());
1759 }
1760 return certs;
1761 }
1762 LOG(ERROR) << "Value for x5chain label is not a bstr or array";
1763 return {};
1764 }
1765 }
1766 LOG(ERROR) << "Did not find x5chain label in unprotected headers";
1767 return {};
1768}
1769
1770vector<uint8_t> coseBuildToBeMACed(const vector<uint8_t>& encodedProtectedHeaders,
1771 const vector<uint8_t>& data,
1772 const vector<uint8_t>& detachedContent) {
1773 cppbor::Array macStructure;
1774 macStructure.add("MAC0");
1775 macStructure.add(encodedProtectedHeaders);
1776
1777 // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1778 // so external_aad is the empty bstr
1779 vector<uint8_t> emptyExternalAad;
1780 macStructure.add(emptyExternalAad);
1781
1782 // Next field is the payload, independently of how it's transported (RFC
1783 // 8152 section 4.4). Since our API specifies only one of |data| and
1784 // |detachedContent| can be non-empty, it's simply just the non-empty one.
1785 if (data.size() > 0) {
1786 macStructure.add(data);
1787 } else {
1788 macStructure.add(detachedContent);
1789 }
1790
1791 return macStructure.encode();
1792}
1793
1794optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
1795 const vector<uint8_t>& detachedContent) {
1796 cppbor::Map unprotectedHeaders;
1797 cppbor::Map protectedHeaders;
1798
1799 if (data.size() > 0 && detachedContent.size() > 0) {
1800 LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1801 return {};
1802 }
1803
1804 protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
1805
1806 vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1807 vector<uint8_t> toBeMACed = coseBuildToBeMACed(encodedProtectedHeaders, data, detachedContent);
1808
1809 optional<vector<uint8_t>> mac = hmacSha256(key, toBeMACed);
1810 if (!mac) {
1811 LOG(ERROR) << "Error MACing toBeMACed data";
1812 return {};
1813 }
1814
1815 cppbor::Array array;
1816 array.add(encodedProtectedHeaders);
1817 array.add(std::move(unprotectedHeaders));
1818 if (data.size() == 0) {
1819 cppbor::Null nullValue;
1820 array.add(std::move(nullValue));
1821 } else {
1822 array.add(data);
1823 }
1824 array.add(mac.value());
1825 return array.encode();
1826}
1827
1828// ---------------------------------------------------------------------------
David Zeuthenc75ac312019-10-28 13:16:45 -04001829// Utility functions specific to IdentityCredential.
1830// ---------------------------------------------------------------------------
1831
David Zeuthenc75ac312019-10-28 13:16:45 -04001832vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize) {
1833 vector<vector<uint8_t>> ret;
1834
1835 size_t contentSize = content.size();
1836 if (contentSize <= maxChunkSize) {
1837 ret.push_back(content);
1838 return ret;
1839 }
1840
1841 size_t numChunks = (contentSize + maxChunkSize - 1) / maxChunkSize;
1842
1843 size_t pos = 0;
1844 for (size_t n = 0; n < numChunks; n++) {
1845 size_t size = contentSize - pos;
1846 if (size > maxChunkSize) {
1847 size = maxChunkSize;
1848 }
1849 auto begin = content.begin() + pos;
1850 auto end = content.begin() + pos + size;
1851 ret.emplace_back(vector<uint8_t>(begin, end));
1852 pos += maxChunkSize;
1853 }
1854
1855 return ret;
1856}
1857
David Zeuthenc75ac312019-10-28 13:16:45 -04001858
1859vector<uint8_t> testHardwareBoundKey = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1860
1861const vector<uint8_t>& getTestHardwareBoundKey() {
1862 return testHardwareBoundKey;
1863}
1864
David Zeuthenc75ac312019-10-28 13:16:45 -04001865} // namespace support
1866} // namespace identity
1867} // namespace hardware
1868} // namespace android