blob: bf6a5c3c4520dc5f416db7c0d498fdb99aeb1a4c [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());
961 auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
962 if (ec_key.get() == nullptr || pkey.get() == nullptr) {
963 LOG(ERROR) << "Memory allocation failed";
964 return {};
965 }
966
967 if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
968 EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
969 LOG(ERROR) << "Error generating key";
970 return {};
971 }
972
973 if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
974 LOG(ERROR) << "Error getting private key";
975 return {};
976 }
977
978 int size = i2d_PrivateKey(pkey.get(), nullptr);
979 if (size == 0) {
980 LOG(ERROR) << "Error generating public key encoding";
981 return {};
982 }
983 vector<uint8_t> keyPair;
984 keyPair.resize(size);
985 unsigned char* p = keyPair.data();
986 i2d_PrivateKey(pkey.get(), &p);
987 return keyPair;
988}
989
990optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair) {
991 const unsigned char* p = (const unsigned char*)keyPair.data();
992 auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
993 if (pkey.get() == nullptr) {
994 LOG(ERROR) << "Error parsing keyPair";
995 return {};
996 }
997
998 auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
999 if (ecKey.get() == nullptr) {
1000 LOG(ERROR) << "Failed getting EC key";
1001 return {};
1002 }
1003
1004 auto ecGroup = EC_KEY_get0_group(ecKey.get());
1005 auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1006 int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1007 nullptr);
1008 if (size == 0) {
1009 LOG(ERROR) << "Error generating public key encoding";
1010 return {};
1011 }
1012
1013 vector<uint8_t> publicKey;
1014 publicKey.resize(size);
1015 EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1016 publicKey.size(), nullptr);
1017 return publicKey;
1018}
1019
1020optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair) {
1021 const unsigned char* p = (const unsigned char*)keyPair.data();
1022 auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1023 if (pkey.get() == nullptr) {
1024 LOG(ERROR) << "Error parsing keyPair";
1025 return {};
1026 }
1027
1028 auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1029 if (ecKey.get() == nullptr) {
1030 LOG(ERROR) << "Failed getting EC key";
1031 return {};
1032 }
1033
1034 const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey.get());
1035 if (bignum == nullptr) {
1036 LOG(ERROR) << "Error getting bignum from private key";
1037 return {};
1038 }
1039 vector<uint8_t> privateKey;
1040 privateKey.resize(BN_num_bytes(bignum));
1041 BN_bn2bin(bignum, privateKey.data());
1042 return privateKey;
1043}
1044
1045optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
1046 const string& serialDecimal, const string& issuer,
1047 const string& subject, time_t validityNotBefore,
1048 time_t validityNotAfter) {
1049 const unsigned char* p = (const unsigned char*)keyPair.data();
1050 auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1051 if (pkey.get() == nullptr) {
1052 LOG(ERROR) << "Error parsing keyPair";
1053 return {};
1054 }
1055
1056 auto x509 = X509_Ptr(X509_new());
1057 if (!x509.get()) {
1058 LOG(ERROR) << "Error creating X509 certificate";
1059 return {};
1060 }
1061
1062 if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1063 LOG(ERROR) << "Error setting version to 3";
1064 return {};
1065 }
1066
1067 if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1068 LOG(ERROR) << "Error setting public key";
1069 return {};
1070 }
1071
1072 BIGNUM* bignumSerial = nullptr;
1073 if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1074 LOG(ERROR) << "Error parsing serial";
1075 return {};
1076 }
1077 auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1078 auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1079 if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1080 LOG(ERROR) << "Error setting serial";
1081 return {};
1082 }
1083
1084 auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1085 if (x509Issuer.get() == nullptr ||
1086 X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1087 (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1088 0 /* set */) != 1 ||
1089 X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1090 LOG(ERROR) << "Error setting issuer";
1091 return {};
1092 }
1093
1094 auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1095 if (x509Subject.get() == nullptr ||
1096 X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1097 (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1098 0 /* set */) != 1 ||
1099 X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1100 LOG(ERROR) << "Error setting subject";
1101 return {};
1102 }
1103
1104 auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1105 if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1106 LOG(ERROR) << "Error setting notBefore";
1107 return {};
1108 }
1109
1110 auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1111 if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1112 LOG(ERROR) << "Error setting notAfter";
1113 return {};
1114 }
1115
1116 if (X509_sign(x509.get(), pkey.get(), EVP_sha256()) == 0) {
1117 LOG(ERROR) << "Error signing X509 certificate";
1118 return {};
1119 }
1120
1121 // Ideally we wouldn't encrypt it (we're only using this function for
1122 // sending a key-pair over binder to the Android app) but BoringSSL does not
1123 // support this: from pkcs8_x509.c in BoringSSL: "In OpenSSL, -1 here means
1124 // to use no encryption, which we do not currently support."
1125 //
1126 // Passing nullptr as |pass|, though, means "no password". So we'll do that.
1127 // Compare with the receiving side - CredstoreIdentityCredential.java - where
1128 // an empty char[] is passed as the password.
1129 //
1130 auto pkcs12 = PKCS12_Ptr(PKCS12_create(nullptr, name.c_str(), pkey.get(), x509.get(),
1131 nullptr, // ca
1132 0, // nid_key
1133 0, // nid_cert
1134 0, // iter,
1135 0, // mac_iter,
1136 0)); // keytype
1137 if (pkcs12.get() == nullptr) {
1138 char buf[128];
1139 long errCode = ERR_get_error();
1140 ERR_error_string_n(errCode, buf, sizeof buf);
1141 LOG(ERROR) << "Error creating PKCS12, code " << errCode << ": " << buf;
1142 return {};
1143 }
1144
1145 unsigned char* buffer = nullptr;
1146 int length = i2d_PKCS12(pkcs12.get(), &buffer);
1147 if (length < 0) {
1148 LOG(ERROR) << "Error encoding PKCS12";
1149 return {};
1150 }
1151 vector<uint8_t> pkcs12Bytes;
1152 pkcs12Bytes.resize(length);
1153 memcpy(pkcs12Bytes.data(), buffer, length);
1154 OPENSSL_free(buffer);
1155
1156 return pkcs12Bytes;
1157}
1158
1159optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
1160 const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
1161 const string& serialDecimal, const string& issuer, const string& subject,
1162 time_t validityNotBefore, time_t validityNotAfter) {
1163 auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1164 auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1165 if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1166 1) {
1167 LOG(ERROR) << "Error decoding publicKey";
1168 return {};
1169 }
1170 auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1171 auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1172 if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1173 LOG(ERROR) << "Memory allocation failed";
1174 return {};
1175 }
1176 if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1177 LOG(ERROR) << "Error setting group";
1178 return {};
1179 }
1180 if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1181 LOG(ERROR) << "Error setting point";
1182 return {};
1183 }
1184 if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1185 LOG(ERROR) << "Error setting key";
1186 return {};
1187 }
1188
1189 auto bn = BIGNUM_Ptr(BN_bin2bn(signingKey.data(), signingKey.size(), nullptr));
1190 if (bn.get() == nullptr) {
1191 LOG(ERROR) << "Error creating BIGNUM for private key";
1192 return {};
1193 }
1194 auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1195 if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1196 LOG(ERROR) << "Error setting private key from BIGNUM";
1197 return {};
1198 }
1199 auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1200 if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1201 LOG(ERROR) << "Error setting private key";
1202 return {};
1203 }
1204
1205 auto x509 = X509_Ptr(X509_new());
1206 if (!x509.get()) {
1207 LOG(ERROR) << "Error creating X509 certificate";
1208 return {};
1209 }
1210
1211 if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1212 LOG(ERROR) << "Error setting version to 3";
1213 return {};
1214 }
1215
1216 if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1217 LOG(ERROR) << "Error setting public key";
1218 return {};
1219 }
1220
1221 BIGNUM* bignumSerial = nullptr;
1222 if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1223 LOG(ERROR) << "Error parsing serial";
1224 return {};
1225 }
1226 auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1227 auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1228 if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1229 LOG(ERROR) << "Error setting serial";
1230 return {};
1231 }
1232
1233 auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1234 if (x509Issuer.get() == nullptr ||
1235 X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1236 (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1237 0 /* set */) != 1 ||
1238 X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1239 LOG(ERROR) << "Error setting issuer";
1240 return {};
1241 }
1242
1243 auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1244 if (x509Subject.get() == nullptr ||
1245 X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1246 (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1247 0 /* set */) != 1 ||
1248 X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1249 LOG(ERROR) << "Error setting subject";
1250 return {};
1251 }
1252
1253 auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1254 if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1255 LOG(ERROR) << "Error setting notBefore";
1256 return {};
1257 }
1258
1259 auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1260 if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1261 LOG(ERROR) << "Error setting notAfter";
1262 return {};
1263 }
1264
1265 if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
1266 LOG(ERROR) << "Error signing X509 certificate";
1267 return {};
1268 }
1269
1270 unsigned char* buffer = nullptr;
1271 int length = i2d_X509(x509.get(), &buffer);
1272 if (length < 0) {
1273 LOG(ERROR) << "Error DER encoding X509 certificate";
1274 return {};
1275 }
1276
1277 vector<uint8_t> certificate;
1278 certificate.resize(length);
1279 memcpy(certificate.data(), buffer, length);
1280 OPENSSL_free(buffer);
1281 return certificate;
1282}
1283
1284optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey,
1285 const vector<uint8_t>& privateKey) {
1286 auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1287 auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1288 if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1289 1) {
1290 LOG(ERROR) << "Error decoding publicKey";
1291 return {};
1292 }
1293 auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1294 auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1295 if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1296 LOG(ERROR) << "Memory allocation failed";
1297 return {};
1298 }
1299 if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1300 LOG(ERROR) << "Error setting group";
1301 return {};
1302 }
1303 if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1304 LOG(ERROR) << "Error setting point";
1305 return {};
1306 }
1307 if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1308 LOG(ERROR) << "Error setting key";
1309 return {};
1310 }
1311
1312 auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
1313 if (bn.get() == nullptr) {
1314 LOG(ERROR) << "Error creating BIGNUM for private key";
1315 return {};
1316 }
1317 auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1318 if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1319 LOG(ERROR) << "Error setting private key from BIGNUM";
1320 return {};
1321 }
1322 auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1323 if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1324 LOG(ERROR) << "Error setting private key";
1325 return {};
1326 }
1327
1328 auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(privPkey.get(), NULL));
1329 if (ctx.get() == nullptr) {
1330 LOG(ERROR) << "Error creating context";
1331 return {};
1332 }
1333
1334 if (EVP_PKEY_derive_init(ctx.get()) != 1) {
1335 LOG(ERROR) << "Error initializing context";
1336 return {};
1337 }
1338
1339 if (EVP_PKEY_derive_set_peer(ctx.get(), pkey.get()) != 1) {
1340 LOG(ERROR) << "Error setting peer";
1341 return {};
1342 }
1343
1344 /* Determine buffer length for shared secret */
1345 size_t secretLen = 0;
1346 if (EVP_PKEY_derive(ctx.get(), NULL, &secretLen) != 1) {
1347 LOG(ERROR) << "Error determing length of shared secret";
1348 return {};
1349 }
1350 vector<uint8_t> sharedSecret;
1351 sharedSecret.resize(secretLen);
1352
1353 if (EVP_PKEY_derive(ctx.get(), sharedSecret.data(), &secretLen) != 1) {
1354 LOG(ERROR) << "Error deriving shared secret";
1355 return {};
1356 }
1357 return sharedSecret;
1358}
1359
1360optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
1361 const vector<uint8_t>& info, size_t size) {
1362 vector<uint8_t> derivedKey;
1363 derivedKey.resize(size);
1364 if (HKDF(derivedKey.data(), derivedKey.size(), EVP_sha256(), sharedSecret.data(),
1365 sharedSecret.size(), salt.data(), salt.size(), info.data(), info.size()) != 1) {
1366 LOG(ERROR) << "Error deriving key";
1367 return {};
1368 }
1369 return derivedKey;
1370}
1371
1372void removeLeadingZeroes(vector<uint8_t>& vec) {
1373 while (vec.size() >= 1 && vec[0] == 0x00) {
1374 vec.erase(vec.begin());
1375 }
1376}
1377
1378tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(
1379 const vector<uint8_t>& publicKey) {
1380 if (publicKey.size() != 65 || publicKey[0] != 0x04) {
1381 LOG(ERROR) << "publicKey is not in the expected format";
1382 return std::make_tuple(false, vector<uint8_t>(), vector<uint8_t>());
1383 }
1384 vector<uint8_t> x, y;
1385 x.resize(32);
1386 y.resize(32);
1387 memcpy(x.data(), publicKey.data() + 1, 32);
1388 memcpy(y.data(), publicKey.data() + 33, 32);
1389
1390 removeLeadingZeroes(x);
1391 removeLeadingZeroes(y);
1392
1393 return std::make_tuple(true, x, y);
1394}
1395
1396optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain) {
1397 vector<X509_Ptr> certs;
1398 if (!parseX509Certificates(certificateChain, certs)) {
1399 return {};
1400 }
1401 if (certs.size() < 1) {
1402 LOG(ERROR) << "No certificates in chain";
1403 return {};
1404 }
1405
1406 int algoId = OBJ_obj2nid(certs[0]->cert_info->key->algor->algorithm);
1407 if (algoId != NID_X9_62_id_ecPublicKey) {
1408 LOG(ERROR) << "Expected NID_X9_62_id_ecPublicKey, got " << OBJ_nid2ln(algoId);
1409 return {};
1410 }
1411
1412 auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
1413 if (pkey.get() == nullptr) {
1414 LOG(ERROR) << "No public key";
1415 return {};
1416 }
1417
1418 auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1419 if (ecKey.get() == nullptr) {
1420 LOG(ERROR) << "Failed getting EC key";
1421 return {};
1422 }
1423
1424 auto ecGroup = EC_KEY_get0_group(ecKey.get());
1425 auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1426 int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1427 nullptr);
1428 if (size == 0) {
1429 LOG(ERROR) << "Error generating public key encoding";
1430 return {};
1431 }
1432 vector<uint8_t> publicKey;
1433 publicKey.resize(size);
1434 EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1435 publicKey.size(), nullptr);
1436 return publicKey;
1437}
1438
1439// ---------------------------------------------------------------------------
1440// COSE Utility Functions
1441// ---------------------------------------------------------------------------
1442
1443vector<uint8_t> coseBuildToBeSigned(const vector<uint8_t>& encodedProtectedHeaders,
1444 const vector<uint8_t>& data,
1445 const vector<uint8_t>& detachedContent) {
1446 cppbor::Array sigStructure;
1447 sigStructure.add("Signature1");
1448 sigStructure.add(encodedProtectedHeaders);
1449
1450 // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1451 // so external_aad is the empty bstr
1452 vector<uint8_t> emptyExternalAad;
1453 sigStructure.add(emptyExternalAad);
1454
1455 // Next field is the payload, independently of how it's transported (RFC
1456 // 8152 section 4.4). Since our API specifies only one of |data| and
1457 // |detachedContent| can be non-empty, it's simply just the non-empty one.
1458 if (data.size() > 0) {
1459 sigStructure.add(data);
1460 } else {
1461 sigStructure.add(detachedContent);
1462 }
1463 return sigStructure.encode();
1464}
1465
1466vector<uint8_t> coseEncodeHeaders(const cppbor::Map& protectedHeaders) {
1467 if (protectedHeaders.size() == 0) {
1468 cppbor::Bstr emptyBstr(vector<uint8_t>({}));
1469 return emptyBstr.encode();
1470 }
1471 return protectedHeaders.encode();
1472}
1473
1474// From https://tools.ietf.org/html/rfc8152
1475const int COSE_LABEL_ALG = 1;
1476const int COSE_LABEL_X5CHAIN = 33; // temporary identifier
1477
1478// From "COSE Algorithms" registry
1479const int COSE_ALG_ECDSA_256 = -7;
1480const int COSE_ALG_HMAC_256_256 = 5;
1481
1482bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
1483 vector<uint8_t>& ecdsaDerSignature) {
1484 if (ecdsaCoseSignature.size() != 64) {
1485 LOG(ERROR) << "COSE signature length is " << ecdsaCoseSignature.size() << ", expected 64";
1486 return false;
1487 }
1488
1489 auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
1490 if (rBn.get() == nullptr) {
1491 LOG(ERROR) << "Error creating BIGNUM for r";
1492 return false;
1493 }
1494
1495 auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
1496 if (sBn.get() == nullptr) {
1497 LOG(ERROR) << "Error creating BIGNUM for s";
1498 return false;
1499 }
1500
1501 ECDSA_SIG sig;
1502 sig.r = rBn.get();
1503 sig.s = sBn.get();
1504
1505 size_t len = i2d_ECDSA_SIG(&sig, nullptr);
1506 ecdsaDerSignature.resize(len);
1507 unsigned char* p = (unsigned char*)ecdsaDerSignature.data();
1508 i2d_ECDSA_SIG(&sig, &p);
1509
1510 return true;
1511}
1512
1513bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
1514 vector<uint8_t>& ecdsaCoseSignature) {
1515 ECDSA_SIG* sig;
1516 const unsigned char* p = ecdsaDerSignature.data();
1517 sig = d2i_ECDSA_SIG(nullptr, &p, ecdsaDerSignature.size());
1518 if (sig == nullptr) {
1519 LOG(ERROR) << "Error decoding DER signature";
1520 return false;
1521 }
1522
1523 ecdsaCoseSignature.clear();
1524 ecdsaCoseSignature.resize(64);
1525 if (BN_bn2binpad(sig->r, ecdsaCoseSignature.data(), 32) != 32) {
1526 LOG(ERROR) << "Error encoding r";
1527 return false;
1528 }
1529 if (BN_bn2binpad(sig->s, ecdsaCoseSignature.data() + 32, 32) != 32) {
1530 LOG(ERROR) << "Error encoding s";
1531 return false;
1532 }
1533 return true;
1534}
1535
1536optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
1537 const vector<uint8_t>& detachedContent,
1538 const vector<uint8_t>& certificateChain) {
1539 cppbor::Map unprotectedHeaders;
1540 cppbor::Map protectedHeaders;
1541
1542 if (data.size() > 0 && detachedContent.size() > 0) {
1543 LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1544 return {};
1545 }
1546
1547 protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
1548
1549 if (certificateChain.size() != 0) {
1550 optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
1551 if (!certs) {
1552 LOG(ERROR) << "Error splitting certificate chain";
1553 return {};
1554 }
1555 if (certs.value().size() == 1) {
1556 unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
1557 } else {
1558 cppbor::Array certArray;
1559 for (const vector<uint8_t>& cert : certs.value()) {
1560 certArray.add(cert);
1561 }
1562 unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
1563 }
1564 }
1565
1566 vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1567 vector<uint8_t> toBeSigned =
1568 coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1569
1570 optional<vector<uint8_t>> derSignature = signEcDsa(key, toBeSigned);
1571 if (!derSignature) {
1572 LOG(ERROR) << "Error signing toBeSigned data";
1573 return {};
1574 }
1575 vector<uint8_t> coseSignature;
1576 if (!ecdsaSignatureDerToCose(derSignature.value(), coseSignature)) {
1577 LOG(ERROR) << "Error converting ECDSA signature from DER to COSE format";
1578 return {};
1579 }
1580
1581 cppbor::Array coseSign1;
1582 coseSign1.add(encodedProtectedHeaders);
1583 coseSign1.add(std::move(unprotectedHeaders));
1584 if (data.size() == 0) {
1585 cppbor::Null nullValue;
1586 coseSign1.add(std::move(nullValue));
1587 } else {
1588 coseSign1.add(data);
1589 }
1590 coseSign1.add(coseSignature);
1591 vector<uint8_t> signatureCoseSign1;
1592 signatureCoseSign1 = coseSign1.encode();
1593 return signatureCoseSign1;
1594}
1595
1596bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
1597 const vector<uint8_t>& detachedContent,
1598 const vector<uint8_t>& publicKey) {
1599 auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1600 if (item == nullptr) {
1601 LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1602 return false;
1603 }
1604 const cppbor::Array* array = item->asArray();
1605 if (array == nullptr) {
1606 LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1607 return false;
1608 }
1609 if (array->size() != 4) {
1610 LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1611 return false;
1612 }
1613
1614 const cppbor::Bstr* encodedProtectedHeadersBstr = (*array)[0]->asBstr();
1615 ;
1616 if (encodedProtectedHeadersBstr == nullptr) {
1617 LOG(ERROR) << "Value for encodedProtectedHeaders is not a bstr";
1618 return false;
1619 }
1620 const vector<uint8_t> encodedProtectedHeaders = encodedProtectedHeadersBstr->value();
1621
1622 const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1623 if (unprotectedHeaders == nullptr) {
1624 LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1625 return false;
1626 }
1627
1628 vector<uint8_t> data;
1629 const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1630 if (payloadAsSimple != nullptr) {
1631 if (payloadAsSimple->asNull() == nullptr) {
1632 LOG(ERROR) << "Value for payload is not null or a bstr";
1633 return false;
1634 }
1635 } else {
1636 const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1637 if (payloadAsBstr == nullptr) {
1638 LOG(ERROR) << "Value for payload is not null or a bstr";
1639 return false;
1640 }
1641 data = payloadAsBstr->value(); // TODO: avoid copy
1642 }
1643
1644 if (data.size() > 0 && detachedContent.size() > 0) {
1645 LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1646 return false;
1647 }
1648
1649 const cppbor::Bstr* signatureBstr = (*array)[3]->asBstr();
1650 if (signatureBstr == nullptr) {
1651 LOG(ERROR) << "Value for signature is a bstr";
1652 return false;
1653 }
1654 const vector<uint8_t>& coseSignature = signatureBstr->value();
1655
1656 vector<uint8_t> derSignature;
1657 if (!ecdsaSignatureCoseToDer(coseSignature, derSignature)) {
1658 LOG(ERROR) << "Error converting ECDSA signature from COSE to DER format";
1659 return false;
1660 }
1661
1662 vector<uint8_t> toBeSigned =
1663 coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1664 if (!checkEcDsaSignature(support::sha256(toBeSigned), derSignature, publicKey)) {
1665 LOG(ERROR) << "Signature check failed";
1666 return false;
1667 }
1668 return true;
1669}
1670
1671optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
1672 auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1673 if (item == nullptr) {
1674 LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1675 return {};
1676 }
1677 const cppbor::Array* array = item->asArray();
1678 if (array == nullptr) {
1679 LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1680 return {};
1681 }
1682 if (array->size() != 4) {
1683 LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1684 return {};
1685 }
1686
1687 vector<uint8_t> data;
1688 const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1689 if (payloadAsSimple != nullptr) {
1690 if (payloadAsSimple->asNull() == nullptr) {
1691 LOG(ERROR) << "Value for payload is not null or a bstr";
1692 return {};
1693 }
1694 // payload is null, so |data| should be empty (as it is)
1695 } else {
1696 const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1697 if (payloadAsBstr == nullptr) {
1698 LOG(ERROR) << "Value for payload is not null or a bstr";
1699 return {};
1700 }
1701 // Copy payload into |data|
1702 data = payloadAsBstr->value();
1703 }
1704
1705 return data;
1706}
1707
1708optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
1709 auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1710 if (item == nullptr) {
1711 LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1712 return {};
1713 }
1714 const cppbor::Array* array = item->asArray();
1715 if (array == nullptr) {
1716 LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1717 return {};
1718 }
1719 if (array->size() != 4) {
1720 LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1721 return {};
1722 }
1723
1724 const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1725 if (unprotectedHeaders == nullptr) {
1726 LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1727 return {};
1728 }
1729
1730 for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
1731 auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
1732 const cppbor::Int* number = keyItem->asInt();
1733 if (number == nullptr) {
1734 LOG(ERROR) << "Key item in top-level map is not a number";
1735 return {};
1736 }
1737 int label = number->value();
1738 if (label == COSE_LABEL_X5CHAIN) {
1739 const cppbor::Bstr* bstr = valueItem->asBstr();
1740 if (bstr != nullptr) {
1741 return bstr->value();
1742 }
1743 const cppbor::Array* array = valueItem->asArray();
1744 if (array != nullptr) {
1745 vector<uint8_t> certs;
1746 for (size_t m = 0; m < array->size(); m++) {
1747 const cppbor::Bstr* bstr = ((*array)[m])->asBstr();
1748 if (bstr == nullptr) {
1749 LOG(ERROR) << "Item in x5chain array is not a bstr";
1750 return {};
1751 }
1752 const vector<uint8_t>& certValue = bstr->value();
1753 certs.insert(certs.end(), certValue.begin(), certValue.end());
1754 }
1755 return certs;
1756 }
1757 LOG(ERROR) << "Value for x5chain label is not a bstr or array";
1758 return {};
1759 }
1760 }
1761 LOG(ERROR) << "Did not find x5chain label in unprotected headers";
1762 return {};
1763}
1764
1765vector<uint8_t> coseBuildToBeMACed(const vector<uint8_t>& encodedProtectedHeaders,
1766 const vector<uint8_t>& data,
1767 const vector<uint8_t>& detachedContent) {
1768 cppbor::Array macStructure;
1769 macStructure.add("MAC0");
1770 macStructure.add(encodedProtectedHeaders);
1771
1772 // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1773 // so external_aad is the empty bstr
1774 vector<uint8_t> emptyExternalAad;
1775 macStructure.add(emptyExternalAad);
1776
1777 // Next field is the payload, independently of how it's transported (RFC
1778 // 8152 section 4.4). Since our API specifies only one of |data| and
1779 // |detachedContent| can be non-empty, it's simply just the non-empty one.
1780 if (data.size() > 0) {
1781 macStructure.add(data);
1782 } else {
1783 macStructure.add(detachedContent);
1784 }
1785
1786 return macStructure.encode();
1787}
1788
1789optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
1790 const vector<uint8_t>& detachedContent) {
1791 cppbor::Map unprotectedHeaders;
1792 cppbor::Map protectedHeaders;
1793
1794 if (data.size() > 0 && detachedContent.size() > 0) {
1795 LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1796 return {};
1797 }
1798
1799 protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
1800
1801 vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1802 vector<uint8_t> toBeMACed = coseBuildToBeMACed(encodedProtectedHeaders, data, detachedContent);
1803
1804 optional<vector<uint8_t>> mac = hmacSha256(key, toBeMACed);
1805 if (!mac) {
1806 LOG(ERROR) << "Error MACing toBeMACed data";
1807 return {};
1808 }
1809
1810 cppbor::Array array;
1811 array.add(encodedProtectedHeaders);
1812 array.add(std::move(unprotectedHeaders));
1813 if (data.size() == 0) {
1814 cppbor::Null nullValue;
1815 array.add(std::move(nullValue));
1816 } else {
1817 array.add(data);
1818 }
1819 array.add(mac.value());
1820 return array.encode();
1821}
1822
1823// ---------------------------------------------------------------------------
David Zeuthenc75ac312019-10-28 13:16:45 -04001824// Utility functions specific to IdentityCredential.
1825// ---------------------------------------------------------------------------
1826
David Zeuthenc75ac312019-10-28 13:16:45 -04001827vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize) {
1828 vector<vector<uint8_t>> ret;
1829
1830 size_t contentSize = content.size();
1831 if (contentSize <= maxChunkSize) {
1832 ret.push_back(content);
1833 return ret;
1834 }
1835
1836 size_t numChunks = (contentSize + maxChunkSize - 1) / maxChunkSize;
1837
1838 size_t pos = 0;
1839 for (size_t n = 0; n < numChunks; n++) {
1840 size_t size = contentSize - pos;
1841 if (size > maxChunkSize) {
1842 size = maxChunkSize;
1843 }
1844 auto begin = content.begin() + pos;
1845 auto end = content.begin() + pos + size;
1846 ret.emplace_back(vector<uint8_t>(begin, end));
1847 pos += maxChunkSize;
1848 }
1849
1850 return ret;
1851}
1852
David Zeuthenc75ac312019-10-28 13:16:45 -04001853
1854vector<uint8_t> testHardwareBoundKey = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1855
1856const vector<uint8_t>& getTestHardwareBoundKey() {
1857 return testHardwareBoundKey;
1858}
1859
David Zeuthenc75ac312019-10-28 13:16:45 -04001860} // namespace support
1861} // namespace identity
1862} // namespace hardware
1863} // namespace android