blob: fb5a7d2f185fd03683b06d3273156b4373fad441 [file] [log] [blame]
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +00001#include "ffi_test_utils.hpp"
2
3#include <iostream>
4
5#include <KeyMintAidlTestBase.h>
6#include <aidl/android/hardware/security/keymint/ErrorCode.h>
7
8#include <vector>
9
10using aidl::android::hardware::security::keymint::ErrorCode;
11
12#define TAG_SEQUENCE 0x30
13#define LENGTH_MASK 0x80
14#define LENGTH_VALUE_MASK 0x7F
15
16/* This function extracts a certificate from the certs_chain_buffer at the given
17 * offset. Each DER encoded certificate starts with TAG_SEQUENCE followed by the
18 * total length of the certificate. The length of the certificate is determined
19 * as per ASN.1 encoding rules for the length octets.
20 *
21 * @param certs_chain_buffer: buffer containing DER encoded X.509 certificates
22 * arranged sequentially.
23 * @data_size: Length of the DER encoded X.509 certificates buffer.
24 * @index: DER encoded X.509 certificates buffer offset.
25 * @cert: Encoded certificate to be extracted from buffer as outcome.
26 * @return: ErrorCode::OK on success, otherwise ErrorCode::UNKNOWN_ERROR.
27 */
28ErrorCode
29extractCertFromCertChainBuffer(uint8_t* certs_chain_buffer, int certs_chain_buffer_size, int& index,
30 aidl::android::hardware::security::keymint::Certificate& cert) {
31 if (index >= certs_chain_buffer_size) {
32 return ErrorCode::UNKNOWN_ERROR;
33 }
34
35 uint32_t length = 0;
36 std::vector<uint8_t> cert_bytes;
37 if (certs_chain_buffer[index] == TAG_SEQUENCE) {
38 // Short form. One octet. Bit 8 has value "0" and bits 7-1 give the length.
39 if (0 == (certs_chain_buffer[index + 1] & LENGTH_MASK)) {
40 length = (uint32_t)certs_chain_buffer[index];
41 // Add SEQ and Length fields
42 length += 2;
43 } else {
44 // Long form. Two to 127 octets. Bit 8 of first octet has value "1" and
45 // bits 7-1 give the number of additional length octets. Second and following
46 // octets give the actual length.
47 int additionalBytes = certs_chain_buffer[index + 1] & LENGTH_VALUE_MASK;
48 if (additionalBytes == 0x01) {
49 length = certs_chain_buffer[index + 2];
50 // Add SEQ and Length fields
51 length += 3;
52 } else if (additionalBytes == 0x02) {
53 length = (certs_chain_buffer[index + 2] << 8 | certs_chain_buffer[index + 3]);
54 // Add SEQ and Length fields
55 length += 4;
56 } else if (additionalBytes == 0x04) {
57 length = certs_chain_buffer[index + 2] << 24;
58 length |= certs_chain_buffer[index + 3] << 16;
59 length |= certs_chain_buffer[index + 4] << 8;
60 length |= certs_chain_buffer[index + 5];
61 // Add SEQ and Length fields
62 length += 6;
63 } else {
64 // Length is larger than uint32_t max limit.
65 return ErrorCode::UNKNOWN_ERROR;
66 }
67 }
68 cert_bytes.insert(cert_bytes.end(), (certs_chain_buffer + index),
69 (certs_chain_buffer + index + length));
70 index += length;
71
72 for (int i = 0; i < cert_bytes.size(); i++) {
73 cert.encodedCertificate = std::move(cert_bytes);
74 }
75 } else {
76 // SEQUENCE TAG MISSING.
77 return ErrorCode::UNKNOWN_ERROR;
78 }
79
80 return ErrorCode::OK;
81}
82
83ErrorCode getCertificateChain(
84 rust::Vec<rust::u8>& chainBuffer,
85 std::vector<aidl::android::hardware::security::keymint::Certificate>& certChain) {
86 uint8_t* data = chainBuffer.data();
87 int index = 0;
88 int data_size = chainBuffer.size();
89
90 while (index < data_size) {
91 aidl::android::hardware::security::keymint::Certificate cert =
92 aidl::android::hardware::security::keymint::Certificate();
93 if (extractCertFromCertChainBuffer(data, data_size, index, cert) != ErrorCode::OK) {
94 return ErrorCode::UNKNOWN_ERROR;
95 }
96 certChain.push_back(std::move(cert));
97 }
98 return ErrorCode::OK;
99}
100
101bool validateCertChain(rust::Vec<rust::u8> cert_buf, uint32_t cert_len, bool strict_issuer_check) {
102 std::vector<aidl::android::hardware::security::keymint::Certificate> cert_chain =
103 std::vector<aidl::android::hardware::security::keymint::Certificate>();
104 if (cert_len <= 0) {
105 return false;
106 }
107 if (getCertificateChain(cert_buf, cert_chain) != ErrorCode::OK) {
108 return false;
109 }
110
111 for (int i = 0; i < cert_chain.size(); i++) {
112 std::cout << cert_chain[i].toString() << "\n";
113 }
114 auto result = aidl::android::hardware::security::keymint::test::ChainSignaturesAreValid(
115 cert_chain, strict_issuer_check);
116
117 if (result == testing::AssertionSuccess()) return true;
118
119 return false;
120}