Merge "Transitioning identity to external_libcppbor"
This commit is contained in:
commit
303991b322
17 changed files with 69 additions and 354 deletions
|
@ -31,7 +31,7 @@ cc_library_static {
|
|||
],
|
||||
static_libs: [
|
||||
"libbase",
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
"libutils",
|
||||
"libsoft_attestation_cert",
|
||||
"libkeymaster_portable",
|
||||
|
@ -91,7 +91,7 @@ cc_binary {
|
|||
],
|
||||
static_libs: [
|
||||
"libbase",
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
"libutils",
|
||||
"libsoft_attestation_cert",
|
||||
"libkeymaster_portable",
|
||||
|
|
|
@ -488,7 +488,7 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval(
|
|||
}
|
||||
|
||||
for (size_t n = 0; n < nsMap->size(); n++) {
|
||||
auto [nsKeyItem, nsValueItem] = (*nsMap)[n];
|
||||
auto& [nsKeyItem, nsValueItem] = (*nsMap)[n];
|
||||
const cppbor::Tstr* nsKey = nsKeyItem->asTstr();
|
||||
const cppbor::Map* nsInnerMap = nsValueItem->asMap();
|
||||
if (nsKey == nullptr || nsInnerMap == nullptr) {
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cppbor/cppbor.h>
|
||||
#include <cppbor.h>
|
||||
|
||||
#include "IdentityCredentialStore.h"
|
||||
#include "SecureHardwareProxy.h"
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#include <android-base/logging.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
#include <cppbor/cppbor.h>
|
||||
#include <cppbor/cppbor_parse.h>
|
||||
#include <cppbor.h>
|
||||
#include <cppbor_parse.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ cc_test {
|
|||
"libcrypto",
|
||||
],
|
||||
static_libs: [
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
"libkeymaster_portable",
|
||||
"libpuresoftkeymasterdevice",
|
||||
"android.hardware.keymaster@4.0",
|
||||
|
|
|
@ -118,7 +118,7 @@ TEST_P(AuthenticationKeyTests, proofOfProvisionInAuthKeyCert) {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
|
|
@ -126,7 +126,7 @@ TEST_P(DeleteCredentialTests, Delete) {
|
|||
optional<vector<uint8_t>> proofOfDeletion =
|
||||
support::coseSignGetPayload(proofOfDeletionSignature);
|
||||
ASSERT_TRUE(proofOfDeletion);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfDeletion.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfDeletion.value(), 32, {});
|
||||
EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', true, ]", cborPretty);
|
||||
EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {}, // Additional data
|
||||
credentialPubKey_));
|
||||
|
@ -153,7 +153,7 @@ TEST_P(DeleteCredentialTests, DeleteWithChallenge) {
|
|||
optional<vector<uint8_t>> proofOfDeletion =
|
||||
support::coseSignGetPayload(proofOfDeletionSignature);
|
||||
ASSERT_TRUE(proofOfDeletion);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfDeletion.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfDeletion.value(), 32, {});
|
||||
EXPECT_EQ("['ProofOfDeletion', 'org.iso.18013-5.2019.mdl', {0x41, 0x42, 0x43}, true, ]",
|
||||
cborPretty);
|
||||
EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfDeletionSignature, {}, // Additional data
|
||||
|
|
|
@ -231,7 +231,7 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
|
||||
cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
@ -339,8 +339,8 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
|
||||
vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
|
||||
cppbor::Array sessionTranscript = cppbor::Array()
|
||||
.add(cppbor::Semantic(24, deviceEngagementBytes))
|
||||
.add(cppbor::Semantic(24, eReaderPubBytes));
|
||||
.add(cppbor::SemanticTag(24, deviceEngagementBytes))
|
||||
.add(cppbor::SemanticTag(24, eReaderPubBytes));
|
||||
vector<uint8_t> sessionTranscriptEncoded = sessionTranscript.encode();
|
||||
|
||||
vector<uint8_t> itemsRequestBytes =
|
||||
|
@ -353,7 +353,7 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
.add("Home address", true))
|
||||
.add("Image", cppbor::Map().add("Portrait image", false)))
|
||||
.encode();
|
||||
cborPretty = support::cborPrettyPrint(itemsRequestBytes, 32, {"EphemeralPublicKey"});
|
||||
cborPretty = cppbor::prettyPrint(itemsRequestBytes, 32, {"EphemeralPublicKey"});
|
||||
EXPECT_EQ(
|
||||
"{\n"
|
||||
" 'nameSpaces' : {\n"
|
||||
|
@ -373,10 +373,10 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.add(cppbor::SemanticTag(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
cppbor::SemanticTag(24, encodedReaderAuthentication).encode();
|
||||
optional<vector<uint8_t>> readerSignature =
|
||||
support::coseSignEcDsa(readerKey, {}, // content
|
||||
encodedReaderAuthenticationBytes, // detached content
|
||||
|
@ -443,7 +443,7 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
vector<uint8_t> mac;
|
||||
vector<uint8_t> deviceNameSpacesEncoded;
|
||||
ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
|
||||
cborPretty = support::cborPrettyPrint(deviceNameSpacesEncoded, 32, {});
|
||||
cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
|
||||
ASSERT_EQ(
|
||||
"{\n"
|
||||
" 'PersonalData' : {\n"
|
||||
|
@ -462,10 +462,11 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
string docType = "org.iso.18013-5.2019.mdl";
|
||||
optional<vector<uint8_t>> readerEphemeralPrivateKey =
|
||||
support::ecKeyPairGetPrivateKey(readerEphemeralKeyPair.value());
|
||||
optional<vector<uint8_t>> eMacKey = support::calcEMacKey(
|
||||
readerEphemeralPrivateKey.value(), // Private Key
|
||||
signingPubKey.value(), // Public Key
|
||||
cppbor::Semantic(24, sessionTranscript.encode()).encode()); // SessionTranscriptBytes
|
||||
optional<vector<uint8_t>> eMacKey =
|
||||
support::calcEMacKey(readerEphemeralPrivateKey.value(), // Private Key
|
||||
signingPubKey.value(), // Public Key
|
||||
cppbor::SemanticTag(24, sessionTranscript.encode())
|
||||
.encode()); // SessionTranscriptBytes
|
||||
optional<vector<uint8_t>> calculatedMac =
|
||||
support::calcMac(sessionTranscript.encode(), // SessionTranscript
|
||||
docType, // DocType
|
||||
|
@ -486,7 +487,7 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
testEntriesEntryCounts)
|
||||
.isOk());
|
||||
ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
|
||||
cborPretty = support::cborPrettyPrint(deviceNameSpacesEncoded, 32, {});
|
||||
cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
|
||||
ASSERT_EQ("{}", cborPretty);
|
||||
// Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
|
||||
calculatedMac = support::calcMac(sessionTranscript.encode(), // SessionTranscript
|
||||
|
@ -508,7 +509,7 @@ TEST_P(EndToEndTests, createAndRetrieveCredential) {
|
|||
testEntriesEntryCounts)
|
||||
.isOk());
|
||||
ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
|
||||
cborPretty = support::cborPrettyPrint(deviceNameSpacesEncoded, 32, {});
|
||||
cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
|
||||
ASSERT_EQ("{}", cborPretty);
|
||||
// Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
|
||||
calculatedMac = support::calcMac(sessionTranscript.encode(), // SessionTranscript
|
||||
|
|
|
@ -131,7 +131,7 @@ TEST_P(ProveOwnershipTests, proveOwnership) {
|
|||
optional<vector<uint8_t>> proofOfOwnership =
|
||||
support::coseSignGetPayload(proofOfOwnershipSignature);
|
||||
ASSERT_TRUE(proofOfOwnership);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfOwnership.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfOwnership.value(), 32, {});
|
||||
EXPECT_EQ("['ProofOfOwnership', 'org.iso.18013-5.2019.mdl', {0x11, 0x12}, true, ]", cborPretty);
|
||||
EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfOwnershipSignature, {}, // Additional data
|
||||
credentialPubKey_));
|
||||
|
|
|
@ -262,8 +262,8 @@ void ReaderAuthTests::retrieveData(const vector<uint8_t>& readerPrivateKey,
|
|||
vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
|
||||
vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
|
||||
cppbor::Array sessionTranscript = cppbor::Array()
|
||||
.add(cppbor::Semantic(24, deviceEngagementBytes))
|
||||
.add(cppbor::Semantic(24, eReaderPubBytes));
|
||||
.add(cppbor::SemanticTag(24, deviceEngagementBytes))
|
||||
.add(cppbor::SemanticTag(24, eReaderPubBytes));
|
||||
vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
|
||||
|
||||
vector<uint8_t> itemsRequestBytes;
|
||||
|
@ -293,10 +293,10 @@ void ReaderAuthTests::retrieveData(const vector<uint8_t>& readerPrivateKey,
|
|||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.add(cppbor::SemanticTag(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
cppbor::SemanticTag(24, encodedReaderAuthentication).encode();
|
||||
|
||||
optional<vector<uint8_t>> readerSignature =
|
||||
support::coseSignEcDsa(readerPrivateKey, // private key for reader
|
||||
|
@ -517,8 +517,8 @@ TEST_P(ReaderAuthTests, ephemeralKeyNotInSessionTranscript) {
|
|||
vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
|
||||
vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
|
||||
cppbor::Array sessionTranscript = cppbor::Array()
|
||||
.add(cppbor::Semantic(24, deviceEngagementBytes))
|
||||
.add(cppbor::Semantic(24, eReaderPubBytes));
|
||||
.add(cppbor::SemanticTag(24, deviceEngagementBytes))
|
||||
.add(cppbor::SemanticTag(24, eReaderPubBytes));
|
||||
vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
|
||||
|
||||
vector<uint8_t> itemsRequestBytes;
|
||||
|
@ -535,10 +535,10 @@ TEST_P(ReaderAuthTests, ephemeralKeyNotInSessionTranscript) {
|
|||
cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.add(cppbor::SemanticTag(24, itemsRequestBytes))
|
||||
.encode();
|
||||
vector<uint8_t> encodedReaderAuthenticationBytes =
|
||||
cppbor::Semantic(24, encodedReaderAuthentication).encode();
|
||||
cppbor::SemanticTag(24, encodedReaderAuthentication).encode();
|
||||
|
||||
vector<vector<uint8_t>> readerCertChain = {cert_reader_SelfSigned_};
|
||||
optional<vector<uint8_t>> readerSignature =
|
||||
|
|
|
@ -114,7 +114,7 @@ TEST_P(TestCredentialTests, testCredential) {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
|
|
@ -114,7 +114,7 @@ void UpdateCredentialTests::provisionData() {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
@ -195,7 +195,7 @@ TEST_P(UpdateCredentialTests, updateCredential) {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
|
|
@ -160,8 +160,8 @@ cppbor::Map calcSessionTranscript(const vector<uint8_t>& ePublicKey) {
|
|||
// Let SessionTranscript be a map here (it's an array in EndToEndTest) just
|
||||
// to check that the implementation can deal with either.
|
||||
cppbor::Map sessionTranscript;
|
||||
sessionTranscript.add(42, cppbor::Semantic(24, deviceEngagementBytes));
|
||||
sessionTranscript.add(43, cppbor::Semantic(24, eReaderPubBytes));
|
||||
sessionTranscript.add(42, cppbor::SemanticTag(24, deviceEngagementBytes));
|
||||
sessionTranscript.add(43, cppbor::SemanticTag(24, eReaderPubBytes));
|
||||
return sessionTranscript;
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ void UserAuthTests::retrieveData(HardwareAuthToken authToken, VerificationToken
|
|||
vector<uint8_t> dataToSign = cppbor::Array()
|
||||
.add("ReaderAuthentication")
|
||||
.add(sessionTranscript_.clone())
|
||||
.add(cppbor::Semantic(24, itemsRequestBytes))
|
||||
.add(cppbor::SemanticTag(24, itemsRequestBytes))
|
||||
.encode();
|
||||
}
|
||||
|
||||
|
|
|
@ -338,8 +338,7 @@ TEST_P(IdentityCredentialTests, verifyOneProfileAndEntryPass) {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
string cborPretty =
|
||||
support::cborPrettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
@ -449,9 +448,9 @@ TEST_P(IdentityCredentialTests, verifyManyProfilesAndEntriesPass) {
|
|||
optional<vector<uint8_t>> proofOfProvisioning =
|
||||
support::coseSignGetPayload(proofOfProvisioningSignature);
|
||||
ASSERT_TRUE(proofOfProvisioning);
|
||||
string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(),
|
||||
32, //
|
||||
{"readerCertificate"});
|
||||
string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(),
|
||||
32, //
|
||||
{"readerCertificate"});
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" 'ProofOfProvisioning',\n"
|
||||
|
|
|
@ -42,7 +42,7 @@ cc_library {
|
|||
"libpuresoftkeymasterdevice",
|
||||
],
|
||||
static_libs: [
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ cc_test {
|
|||
"libhardware",
|
||||
],
|
||||
static_libs: [
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
"libgmock",
|
||||
],
|
||||
test_suites: ["general-tests"],
|
||||
|
@ -89,7 +89,7 @@ cc_test {
|
|||
"tests/cppbor_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
"libbase",
|
||||
],
|
||||
static_libs: [
|
||||
|
@ -104,7 +104,7 @@ cc_test_host {
|
|||
"tests/cppbor_test.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libcppbor",
|
||||
"libcppbor_external",
|
||||
"libbase",
|
||||
],
|
||||
static_libs: [
|
||||
|
|
|
@ -147,199 +147,6 @@ optional<vector<uint8_t>> decodeHex(const string& hexEncoded) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CBOR utilities.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static bool cborAreAllElementsNonCompound(const cppbor::CompoundItem* compoundItem) {
|
||||
if (compoundItem->type() == cppbor::ARRAY) {
|
||||
const cppbor::Array* array = compoundItem->asArray();
|
||||
for (size_t n = 0; n < array->size(); n++) {
|
||||
const cppbor::Item* entry = (*array)[n].get();
|
||||
switch (entry->type()) {
|
||||
case cppbor::ARRAY:
|
||||
case cppbor::MAP:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const cppbor::Map* map = compoundItem->asMap();
|
||||
for (size_t n = 0; n < map->size(); n++) {
|
||||
auto [keyEntry, valueEntry] = (*map)[n];
|
||||
switch (keyEntry->type()) {
|
||||
case cppbor::ARRAY:
|
||||
case cppbor::MAP:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (valueEntry->type()) {
|
||||
case cppbor::ARRAY:
|
||||
case cppbor::MAP:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cborPrettyPrintInternal(const cppbor::Item* item, string& out, size_t indent,
|
||||
size_t maxBStrSize, const vector<string>& mapKeysToNotPrint) {
|
||||
char buf[80];
|
||||
|
||||
string indentString(indent, ' ');
|
||||
|
||||
switch (item->type()) {
|
||||
case cppbor::UINT:
|
||||
snprintf(buf, sizeof(buf), "%" PRIu64, item->asUint()->unsignedValue());
|
||||
out.append(buf);
|
||||
break;
|
||||
|
||||
case cppbor::NINT:
|
||||
snprintf(buf, sizeof(buf), "%" PRId64, item->asNint()->value());
|
||||
out.append(buf);
|
||||
break;
|
||||
|
||||
case cppbor::BSTR: {
|
||||
const cppbor::Bstr* bstr = item->asBstr();
|
||||
const vector<uint8_t>& value = bstr->value();
|
||||
if (value.size() > maxBStrSize) {
|
||||
unsigned char digest[SHA_DIGEST_LENGTH];
|
||||
SHA_CTX ctx;
|
||||
SHA1_Init(&ctx);
|
||||
SHA1_Update(&ctx, value.data(), value.size());
|
||||
SHA1_Final(digest, &ctx);
|
||||
char buf2[SHA_DIGEST_LENGTH * 2 + 1];
|
||||
for (size_t n = 0; n < SHA_DIGEST_LENGTH; n++) {
|
||||
snprintf(buf2 + n * 2, 3, "%02x", digest[n]);
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "<bstr size=%zd sha1=%s>", value.size(), buf2);
|
||||
out.append(buf);
|
||||
} else {
|
||||
out.append("{");
|
||||
for (size_t n = 0; n < value.size(); n++) {
|
||||
if (n > 0) {
|
||||
out.append(", ");
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "0x%02x", value[n]);
|
||||
out.append(buf);
|
||||
}
|
||||
out.append("}");
|
||||
}
|
||||
} break;
|
||||
|
||||
case cppbor::TSTR:
|
||||
out.append("'");
|
||||
{
|
||||
// TODO: escape "'" characters
|
||||
out.append(item->asTstr()->value().c_str());
|
||||
}
|
||||
out.append("'");
|
||||
break;
|
||||
|
||||
case cppbor::ARRAY: {
|
||||
const cppbor::Array* array = item->asArray();
|
||||
if (array->size() == 0) {
|
||||
out.append("[]");
|
||||
} else if (cborAreAllElementsNonCompound(array)) {
|
||||
out.append("[");
|
||||
for (size_t n = 0; n < array->size(); n++) {
|
||||
if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
|
||||
mapKeysToNotPrint)) {
|
||||
return false;
|
||||
}
|
||||
out.append(", ");
|
||||
}
|
||||
out.append("]");
|
||||
} else {
|
||||
out.append("[\n" + indentString);
|
||||
for (size_t n = 0; n < array->size(); n++) {
|
||||
out.append(" ");
|
||||
if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
|
||||
mapKeysToNotPrint)) {
|
||||
return false;
|
||||
}
|
||||
out.append(",\n" + indentString);
|
||||
}
|
||||
out.append("]");
|
||||
}
|
||||
} break;
|
||||
|
||||
case cppbor::MAP: {
|
||||
const cppbor::Map* map = item->asMap();
|
||||
|
||||
if (map->size() == 0) {
|
||||
out.append("{}");
|
||||
} else {
|
||||
out.append("{\n" + indentString);
|
||||
for (size_t n = 0; n < map->size(); n++) {
|
||||
out.append(" ");
|
||||
|
||||
auto [map_key, map_value] = (*map)[n];
|
||||
|
||||
if (!cborPrettyPrintInternal(map_key.get(), out, indent + 2, maxBStrSize,
|
||||
mapKeysToNotPrint)) {
|
||||
return false;
|
||||
}
|
||||
out.append(" : ");
|
||||
if (map_key->type() == cppbor::TSTR &&
|
||||
std::find(mapKeysToNotPrint.begin(), mapKeysToNotPrint.end(),
|
||||
map_key->asTstr()->value()) != mapKeysToNotPrint.end()) {
|
||||
out.append("<not printed>");
|
||||
} else {
|
||||
if (!cborPrettyPrintInternal(map_value.get(), out, indent + 2, maxBStrSize,
|
||||
mapKeysToNotPrint)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
out.append(",\n" + indentString);
|
||||
}
|
||||
out.append("}");
|
||||
}
|
||||
} break;
|
||||
|
||||
case cppbor::SEMANTIC: {
|
||||
const cppbor::Semantic* semantic = item->asSemantic();
|
||||
snprintf(buf, sizeof(buf), "tag %" PRIu64 " ", semantic->value());
|
||||
out.append(buf);
|
||||
cborPrettyPrintInternal(semantic->child().get(), out, indent, maxBStrSize,
|
||||
mapKeysToNotPrint);
|
||||
} break;
|
||||
|
||||
case cppbor::SIMPLE:
|
||||
const cppbor::Bool* asBool = item->asSimple()->asBool();
|
||||
const cppbor::Null* asNull = item->asSimple()->asNull();
|
||||
if (asBool != nullptr) {
|
||||
out.append(asBool->value() ? "true" : "false");
|
||||
} else if (asNull != nullptr) {
|
||||
out.append("null");
|
||||
} else {
|
||||
LOG(ERROR) << "Only boolean/null is implemented for SIMPLE";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize,
|
||||
const vector<string>& mapKeysToNotPrint) {
|
||||
auto [item, _, message] = cppbor::parse(encodedCbor);
|
||||
if (item == nullptr) {
|
||||
LOG(ERROR) << "Data to pretty print is not valid CBOR: " << message;
|
||||
return "";
|
||||
}
|
||||
|
||||
string out;
|
||||
cborPrettyPrintInternal(item.get(), out, 0, maxBStrSize, mapKeysToNotPrint);
|
||||
return out;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Crypto functionality / abstraction.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -2140,7 +1947,7 @@ optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1) {
|
|||
}
|
||||
|
||||
for (size_t n = 0; n < protectedHeaders->size(); n++) {
|
||||
auto [keyItem, valueItem] = (*protectedHeaders)[n];
|
||||
auto& [keyItem, valueItem] = (*protectedHeaders)[n];
|
||||
const cppbor::Int* number = keyItem->asInt();
|
||||
if (number == nullptr) {
|
||||
LOG(ERROR) << "Key item in top-level map is not a number";
|
||||
|
@ -2183,7 +1990,7 @@ optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCos
|
|||
}
|
||||
|
||||
for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
|
||||
auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
|
||||
auto& [keyItem, valueItem] = (*unprotectedHeaders)[n];
|
||||
const cppbor::Int* number = keyItem->asInt();
|
||||
if (number == nullptr) {
|
||||
LOG(ERROR) << "Key item in top-level map is not a number";
|
||||
|
@ -2335,9 +2142,9 @@ optional<vector<uint8_t>> calcMac(const vector<uint8_t>& sessionTranscriptEncode
|
|||
.add("DeviceAuthentication")
|
||||
.add(std::move(sessionTranscriptItem))
|
||||
.add(docType)
|
||||
.add(cppbor::Semantic(kSemanticTagEncodedCbor, deviceNameSpacesEncoded));
|
||||
.add(cppbor::SemanticTag(kSemanticTagEncodedCbor, deviceNameSpacesEncoded));
|
||||
vector<uint8_t> deviceAuthenticationBytes =
|
||||
cppbor::Semantic(kSemanticTagEncodedCbor, deviceAuthentication.encode()).encode();
|
||||
cppbor::SemanticTag(kSemanticTagEncodedCbor, deviceAuthentication.encode()).encode();
|
||||
optional<vector<uint8_t>> calculatedMac =
|
||||
support::coseMac0(eMacKey, {}, // payload
|
||||
deviceAuthenticationBytes); // detached content
|
||||
|
|
|
@ -55,99 +55,6 @@ TEST(IdentityCredentialSupport, decodeHex) {
|
|||
EXPECT_FALSE(support::decodeHex("012"));
|
||||
}
|
||||
|
||||
TEST(IdentityCredentialSupport, CborPrettyPrint) {
|
||||
EXPECT_EQ("'Some text'", support::cborPrettyPrint(cppbor::Tstr("Some text").encode()));
|
||||
|
||||
EXPECT_EQ("''", support::cborPrettyPrint(cppbor::Tstr("").encode()));
|
||||
|
||||
EXPECT_EQ("{0x01, 0x00, 0x02, 0xf0, 0xff, 0x40}",
|
||||
support::cborPrettyPrint(
|
||||
cppbor::Bstr(vector<uint8_t>({1, 0, 2, 240, 255, 64})).encode()));
|
||||
|
||||
EXPECT_EQ("{}", support::cborPrettyPrint(cppbor::Bstr(vector<uint8_t>()).encode()));
|
||||
|
||||
EXPECT_EQ("true", support::cborPrettyPrint(cppbor::Bool(true).encode()));
|
||||
|
||||
EXPECT_EQ("false", support::cborPrettyPrint(cppbor::Bool(false).encode()));
|
||||
|
||||
EXPECT_EQ("42", support::cborPrettyPrint(cppbor::Uint(42).encode()));
|
||||
|
||||
EXPECT_EQ("9223372036854775807", // 0x7fff ffff ffff ffff
|
||||
support::cborPrettyPrint(cppbor::Uint(std::numeric_limits<int64_t>::max()).encode()));
|
||||
|
||||
EXPECT_EQ("-42", support::cborPrettyPrint(cppbor::Nint(-42).encode()));
|
||||
|
||||
EXPECT_EQ("-9223372036854775808", // -0x8000 0000 0000 0000
|
||||
support::cborPrettyPrint(cppbor::Nint(std::numeric_limits<int64_t>::min()).encode()));
|
||||
}
|
||||
|
||||
TEST(IdentityCredentialSupport, CborPrettyPrintCompound) {
|
||||
cppbor::Array array = cppbor::Array("foo", "bar", "baz");
|
||||
EXPECT_EQ("['foo', 'bar', 'baz', ]", support::cborPrettyPrint(array.encode()));
|
||||
|
||||
cppbor::Map map = cppbor::Map().add("foo", 42).add("bar", 43).add("baz", 44);
|
||||
EXPECT_EQ(
|
||||
"{\n"
|
||||
" 'foo' : 42,\n"
|
||||
" 'bar' : 43,\n"
|
||||
" 'baz' : 44,\n"
|
||||
"}",
|
||||
support::cborPrettyPrint(map.encode()));
|
||||
|
||||
cppbor::Array array2 = cppbor::Array(cppbor::Tstr("Some text"), cppbor::Nint(-42));
|
||||
EXPECT_EQ("['Some text', -42, ]", support::cborPrettyPrint(array2.encode()));
|
||||
|
||||
cppbor::Map map2 = cppbor::Map().add(42, "foo").add(43, "bar").add(44, "baz");
|
||||
EXPECT_EQ(
|
||||
"{\n"
|
||||
" 42 : 'foo',\n"
|
||||
" 43 : 'bar',\n"
|
||||
" 44 : 'baz',\n"
|
||||
"}",
|
||||
support::cborPrettyPrint(map2.encode()));
|
||||
|
||||
cppbor::Array deeplyNestedArrays =
|
||||
cppbor::Array(cppbor::Array(cppbor::Array("a", "b", "c")),
|
||||
cppbor::Array(cppbor::Array("d", "e", cppbor::Array("f", "g"))));
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" ['a', 'b', 'c', ],\n"
|
||||
" [\n 'd',\n"
|
||||
" 'e',\n"
|
||||
" ['f', 'g', ],\n"
|
||||
" ],\n"
|
||||
"]",
|
||||
support::cborPrettyPrint(deeplyNestedArrays.encode()));
|
||||
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
" {0x0a, 0x0b},\n"
|
||||
" 'foo',\n"
|
||||
" 42,\n"
|
||||
" ['foo', 'bar', 'baz', ],\n"
|
||||
" {\n"
|
||||
" 'foo' : 42,\n"
|
||||
" 'bar' : 43,\n"
|
||||
" 'baz' : 44,\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" 'deep1' : ['Some text', -42, ],\n"
|
||||
" 'deep2' : {\n"
|
||||
" 42 : 'foo',\n"
|
||||
" 43 : 'bar',\n"
|
||||
" 44 : 'baz',\n"
|
||||
" },\n"
|
||||
" },\n"
|
||||
"]",
|
||||
support::cborPrettyPrint(cppbor::Array(cppbor::Bstr(vector<uint8_t>{10, 11}),
|
||||
cppbor::Tstr("foo"), cppbor::Uint(42),
|
||||
std::move(array), std::move(map),
|
||||
(cppbor::Map()
|
||||
.add("deep1", std::move(array2))
|
||||
.add("deep2", std::move(map2))))
|
||||
.encode()));
|
||||
}
|
||||
|
||||
TEST(IdentityCredentialSupport, Signatures) {
|
||||
vector<uint8_t> data = {1, 2, 3};
|
||||
|
||||
|
@ -219,7 +126,7 @@ TEST(IdentityCredentialSupport, CoseSignatures) {
|
|||
ASSERT_EQ(data, payload.value());
|
||||
|
||||
// Finally, check that |coseSign1| are the bytes of a valid COSE_Sign1 message
|
||||
string out = support::cborPrettyPrint(coseSign1.value());
|
||||
string out = cppbor::prettyPrint(coseSign1.value());
|
||||
out = replaceLine(out, -2, " [] // Signature Removed");
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
|
@ -250,7 +157,7 @@ TEST(IdentityCredentialSupport, CoseSignaturesAdditionalData) {
|
|||
ASSERT_EQ(0, payload.value().size());
|
||||
|
||||
// Finally, check that |coseSign1| are the bytes of a valid COSE_Sign1 message
|
||||
string out = support::cborPrettyPrint(coseSign1.value());
|
||||
string out = cppbor::prettyPrint(coseSign1.value());
|
||||
out = replaceLine(out, -2, " [] // Signature Removed");
|
||||
EXPECT_EQ(
|
||||
"[\n"
|
||||
|
@ -411,7 +318,7 @@ TEST(IdentityCredentialSupport, CoseMac0) {
|
|||
"0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, 0x5e, 0xbb, "
|
||||
"0xe2, 0x2d, 0x42, 0xbe, 0x53},\n"
|
||||
"]",
|
||||
support::cborPrettyPrint(mac.value()));
|
||||
cppbor::prettyPrint(mac.value()));
|
||||
}
|
||||
|
||||
TEST(IdentityCredentialSupport, CoseMac0DetachedContent) {
|
||||
|
@ -433,7 +340,7 @@ TEST(IdentityCredentialSupport, CoseMac0DetachedContent) {
|
|||
"0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, 0x5e, 0xbb, "
|
||||
"0xe2, 0x2d, 0x42, 0xbe, 0x53},\n"
|
||||
"]",
|
||||
support::cborPrettyPrint(mac.value()));
|
||||
cppbor::prettyPrint(mac.value()));
|
||||
}
|
||||
|
||||
// Generates a private key in DER format for a small value of 'd'.
|
||||
|
@ -460,8 +367,8 @@ std::pair<vector<uint8_t>, vector<uint8_t>> p256PrivateKeyGetXandY(
|
|||
|
||||
const cppbor::Item* findValueForTstr(const cppbor::Map* map, const string& keyValue) {
|
||||
// TODO: Need cast until libcppbor's Map::get() is marked as const
|
||||
auto [item, found] = ((cppbor::Map*)map)->get(keyValue);
|
||||
if (!found) {
|
||||
const auto& item = map->get(keyValue);
|
||||
if (!item) {
|
||||
return nullptr;
|
||||
}
|
||||
return item.get();
|
||||
|
@ -483,12 +390,13 @@ const cppbor::Map* findMapValueForTstr(const cppbor::Map* map, const string& key
|
|||
return item->asMap();
|
||||
}
|
||||
|
||||
const cppbor::Semantic* findSemanticValueForTstr(const cppbor::Map* map, const string& keyValue) {
|
||||
const cppbor::SemanticTag* findSemanticValueForTstr(const cppbor::Map* map,
|
||||
const string& keyValue) {
|
||||
const cppbor::Item* item = findValueForTstr(map, keyValue);
|
||||
if (item == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return item->asSemantic();
|
||||
return item->asSemanticTag();
|
||||
}
|
||||
|
||||
const std::string findStringValueForTstr(const cppbor::Map* map, const string& keyValue) {
|
||||
|
@ -576,11 +484,11 @@ TEST(IdentityCredentialSupport, testVectors_18013_5) {
|
|||
auto [sessionEstablishmentItem, _se, _se2] = cppbor::parse(sessionEstablishmentEncoded.value());
|
||||
const cppbor::Map* sessionEstablishment = sessionEstablishmentItem->asMap();
|
||||
ASSERT_NE(sessionEstablishment, nullptr);
|
||||
const cppbor::Semantic* eReaderKeyBytes =
|
||||
const cppbor::SemanticTag* eReaderKeyBytes =
|
||||
findSemanticValueForTstr(sessionEstablishment, "eReaderKeyBytes");
|
||||
ASSERT_NE(eReaderKeyBytes, nullptr);
|
||||
ASSERT_EQ(eReaderKeyBytes->value(), 24);
|
||||
const cppbor::Bstr* eReaderKeyBstr = eReaderKeyBytes->child()->asBstr();
|
||||
ASSERT_EQ(eReaderKeyBytes->semanticTag(), 24);
|
||||
const cppbor::Bstr* eReaderKeyBstr = eReaderKeyBytes->asBstr();
|
||||
ASSERT_NE(eReaderKeyBstr, nullptr);
|
||||
vector<uint8_t> eReaderKeyEncoded = eReaderKeyBstr->value();
|
||||
// TODO: verify this agrees with ephemeralReaderKeyX and ephemeralReaderKeyY
|
||||
|
@ -605,12 +513,12 @@ TEST(IdentityCredentialSupport, testVectors_18013_5) {
|
|||
// SessionTranscriptBytes = #6.24(bstr .cbor SessionTranscript)
|
||||
//
|
||||
cppbor::Array sessionTranscript;
|
||||
sessionTranscript.add(cppbor::Semantic(24, deviceEngagementEncoded));
|
||||
sessionTranscript.add(cppbor::Semantic(24, eReaderKeyEncoded));
|
||||
sessionTranscript.add(cppbor::SemanticTag(24, deviceEngagementEncoded));
|
||||
sessionTranscript.add(cppbor::SemanticTag(24, eReaderKeyEncoded));
|
||||
sessionTranscript.add(cppbor::Null());
|
||||
vector<uint8_t> sessionTranscriptEncoded = sessionTranscript.encode();
|
||||
vector<uint8_t> sessionTranscriptBytes =
|
||||
cppbor::Semantic(24, sessionTranscriptEncoded).encode();
|
||||
cppbor::SemanticTag(24, sessionTranscriptEncoded).encode();
|
||||
|
||||
// The expected EMacKey is 4c1ebb8aacc633465390fa44edfdb49cb57f2e079aaa771d812584699c0b97e2
|
||||
//
|
||||
|
@ -696,11 +604,11 @@ TEST(IdentityCredentialSupport, testVectors_18013_5) {
|
|||
|
||||
// Dig out the encoded form of DeviceNameSpaces
|
||||
//
|
||||
const cppbor::Semantic* deviceNameSpacesBytes =
|
||||
const cppbor::SemanticTag* deviceNameSpacesBytes =
|
||||
findSemanticValueForTstr(deviceSigned, "nameSpaces");
|
||||
ASSERT_NE(deviceNameSpacesBytes, nullptr);
|
||||
ASSERT_EQ(deviceNameSpacesBytes->value(), 24);
|
||||
const cppbor::Bstr* deviceNameSpacesBstr = deviceNameSpacesBytes->child()->asBstr();
|
||||
ASSERT_EQ(deviceNameSpacesBytes->semanticTag(), 24);
|
||||
const cppbor::Bstr* deviceNameSpacesBstr = deviceNameSpacesBytes->asBstr();
|
||||
ASSERT_NE(deviceNameSpacesBstr, nullptr);
|
||||
vector<uint8_t> deviceNameSpacesEncoded = deviceNameSpacesBstr->value();
|
||||
|
||||
|
|
Loading…
Reference in a new issue