1 /*
2 * Copyright (C) 2020 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 #include "CertUtils.h"
18
19 #include <android-base/logging.h>
20 #include <android-base/result.h>
21
22 #include <openssl/bn.h>
23 #include <openssl/crypto.h>
24 #include <openssl/pkcs7.h>
25 #include <openssl/rsa.h>
26 #include <openssl/x509.h>
27 #include <openssl/x509v3.h>
28
29 #include <optional>
30 #include <vector>
31
32 #include "KeyConstants.h"
33
34 // Common properties for all of our certificates.
35 constexpr int kCertLifetimeSeconds = 10 * 365 * 24 * 60 * 60;
36 const char* const kIssuerCountry = "US";
37 const char* const kIssuerOrg = "Android";
38
39 using android::base::ErrnoError;
40 using android::base::Error;
41 using android::base::Result;
42
loadX509(const std::string & path)43 static Result<bssl::UniquePtr<X509>> loadX509(const std::string& path) {
44 X509* rawCert;
45 auto f = fopen(path.c_str(), "re");
46 if (f == nullptr) {
47 return Error() << "Failed to open " << path;
48 }
49 if (!d2i_X509_fp(f, &rawCert)) {
50 fclose(f);
51 return Error() << "Unable to decode x509 cert at " << path;
52 }
53 bssl::UniquePtr<X509> cert(rawCert);
54
55 fclose(f);
56 return cert;
57 }
58
makeContext(X509 * issuer,X509 * subject)59 static X509V3_CTX makeContext(X509* issuer, X509* subject) {
60 X509V3_CTX context = {};
61 X509V3_set_ctx(&context, issuer, subject, nullptr, nullptr, 0);
62 return context;
63 }
64
add_ext(X509V3_CTX * context,X509 * cert,int nid,const char * value)65 static bool add_ext(X509V3_CTX* context, X509* cert, int nid, const char* value) {
66 bssl::UniquePtr<X509_EXTENSION> ex(X509V3_EXT_nconf_nid(nullptr, context, nid, value));
67 if (!ex) {
68 return false;
69 }
70
71 X509_add_ext(cert, ex.get(), -1);
72 return true;
73 }
74
addNameEntry(X509_NAME * name,const char * field,const char * value)75 static void addNameEntry(X509_NAME* name, const char* field, const char* value) {
76 X509_NAME_add_entry_by_txt(name, field, MBSTRING_ASC,
77 reinterpret_cast<const unsigned char*>(value), -1, -1, 0);
78 }
79
getRsaFromModulus(const std::vector<uint8_t> & publicKey)80 static Result<bssl::UniquePtr<RSA>> getRsaFromModulus(const std::vector<uint8_t>& publicKey) {
81 bssl::UniquePtr<BIGNUM> n(BN_new());
82 bssl::UniquePtr<BIGNUM> e(BN_new());
83 bssl::UniquePtr<RSA> rsaPubkey(RSA_new());
84 if (!n || !e || !rsaPubkey || !BN_bin2bn(publicKey.data(), publicKey.size(), n.get()) ||
85 !BN_set_word(e.get(), kRsaKeyExponent) ||
86 !RSA_set0_key(rsaPubkey.get(), n.get(), e.get(), /*d=*/nullptr)) {
87 return Error() << "Failed to create RSA key";
88 }
89 // RSA_set0_key takes ownership of |n| and |e| on success.
90 (void)n.release();
91 (void)e.release();
92
93 return rsaPubkey;
94 }
95
96 static Result<bssl::UniquePtr<RSA>>
getRsaFromRsaPublicKey(const std::vector<uint8_t> & rsaPublicKey)97 getRsaFromRsaPublicKey(const std::vector<uint8_t>& rsaPublicKey) {
98 auto derBytes = rsaPublicKey.data();
99 bssl::UniquePtr<RSA> rsaKey(d2i_RSAPublicKey(nullptr, &derBytes, rsaPublicKey.size()));
100 if (rsaKey.get() == nullptr) {
101 return Error() << "Failed to parse RsaPublicKey";
102 }
103 if (derBytes != rsaPublicKey.data() + rsaPublicKey.size()) {
104 return Error() << "Key has unexpected trailing data";
105 }
106
107 return rsaKey;
108 }
109
modulusToRsaPkey(const std::vector<uint8_t> & publicKey)110 static Result<bssl::UniquePtr<EVP_PKEY>> modulusToRsaPkey(const std::vector<uint8_t>& publicKey) {
111 // "publicKey" corresponds to the raw public key bytes - need to create
112 // a new RSA key with the correct exponent.
113 auto rsaPubkey = getRsaFromModulus(publicKey);
114 if (!rsaPubkey.ok()) {
115 return rsaPubkey.error();
116 }
117
118 bssl::UniquePtr<EVP_PKEY> public_key(EVP_PKEY_new());
119 if (!EVP_PKEY_assign_RSA(public_key.get(), rsaPubkey->release())) {
120 return Error() << "Failed to assign key";
121 }
122 return public_key;
123 }
124
125 static Result<bssl::UniquePtr<EVP_PKEY>>
rsaPublicKeyToRsaPkey(const std::vector<uint8_t> & rsaPublicKey)126 rsaPublicKeyToRsaPkey(const std::vector<uint8_t>& rsaPublicKey) {
127 // rsaPublicKey contains both modulus and exponent, DER-encoded.
128 auto rsaKey = getRsaFromRsaPublicKey(rsaPublicKey);
129 if (!rsaKey.ok()) {
130 return rsaKey.error();
131 }
132
133 bssl::UniquePtr<EVP_PKEY> public_key(EVP_PKEY_new());
134 if (!EVP_PKEY_assign_RSA(public_key.get(), rsaKey->release())) {
135 return Error() << "Failed to assign key";
136 }
137 return public_key;
138 }
139
verifySignature(const std::string & message,const std::string & signature,const std::vector<uint8_t> & publicKey)140 Result<void> verifySignature(const std::string& message, const std::string& signature,
141 const std::vector<uint8_t>& publicKey) {
142 auto rsaKey = getRsaFromModulus(publicKey);
143 if (!rsaKey.ok()) {
144 return rsaKey.error();
145 }
146 uint8_t hashBuf[SHA256_DIGEST_LENGTH];
147 SHA256(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(message.c_str())),
148 message.length(), hashBuf);
149
150 bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf),
151 (const uint8_t*)signature.c_str(), signature.length(), rsaKey->get());
152
153 if (!success) {
154 return Error() << "Failed to verify signature";
155 }
156 return {};
157 }
158
verifyRsaPublicKeySignature(const std::string & message,const std::string & signature,const std::vector<uint8_t> & rsaPublicKey)159 Result<void> verifyRsaPublicKeySignature(const std::string& message, const std::string& signature,
160 const std::vector<uint8_t>& rsaPublicKey) {
161 auto rsaKey = getRsaFromRsaPublicKey(rsaPublicKey);
162 if (!rsaKey.ok()) {
163 return rsaKey.error();
164 }
165
166 uint8_t hashBuf[SHA256_DIGEST_LENGTH];
167 SHA256(reinterpret_cast<const uint8_t*>(message.data()), message.size(), hashBuf);
168
169 bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf),
170 reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
171 rsaKey->get());
172 if (!success) {
173 return Error() << "Failed to verify signature";
174 }
175 return {};
176 }
177
createCertificate(const CertSubject & subject,EVP_PKEY * publicKey,const std::function<android::base::Result<std::string> (const std::string &)> & signFunction,const std::optional<std::string> & issuerCertPath,const std::string & path)178 static Result<void> createCertificate(
179 const CertSubject& subject, EVP_PKEY* publicKey,
180 const std::function<android::base::Result<std::string>(const std::string&)>& signFunction,
181 const std::optional<std::string>& issuerCertPath, const std::string& path) {
182
183 // If an issuer cert is specified, we are signing someone else's key.
184 // Otherwise we are signing our key - a self-signed certificate.
185 bool selfSigned = !issuerCertPath;
186
187 bssl::UniquePtr<X509> x509(X509_new());
188 if (!x509) {
189 return Error() << "Unable to allocate x509 container";
190 }
191 X509_set_version(x509.get(), 2);
192 X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
193 X509_gmtime_adj(X509_get_notAfter(x509.get()), kCertLifetimeSeconds);
194 ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), subject.serialNumber);
195
196 bssl::UniquePtr<X509_ALGOR> algor(X509_ALGOR_new());
197 if (!algor ||
198 !X509_ALGOR_set0(algor.get(), OBJ_nid2obj(NID_sha256WithRSAEncryption), V_ASN1_NULL,
199 NULL) ||
200 !X509_set1_signature_algo(x509.get(), algor.get())) {
201 return Error() << "Unable to set x509 signature algorithm";
202 }
203
204 if (!X509_set_pubkey(x509.get(), publicKey)) {
205 return Error() << "Unable to set x509 public key";
206 }
207
208 X509_NAME* subjectName = X509_get_subject_name(x509.get());
209 if (!subjectName) {
210 return Error() << "Unable to get x509 subject name";
211 }
212 addNameEntry(subjectName, "C", kIssuerCountry);
213 addNameEntry(subjectName, "O", kIssuerOrg);
214 addNameEntry(subjectName, "CN", subject.commonName);
215
216 if (selfSigned) {
217 if (!X509_set_issuer_name(x509.get(), subjectName)) {
218 return Error() << "Unable to set x509 issuer name";
219 }
220 } else {
221 X509_NAME* issuerName = X509_get_issuer_name(x509.get());
222 if (!issuerName) {
223 return Error() << "Unable to get x509 issuer name";
224 }
225 addNameEntry(issuerName, "C", kIssuerCountry);
226 addNameEntry(issuerName, "O", kIssuerOrg);
227 addNameEntry(issuerName, "CN", kRootSubject.commonName);
228 }
229
230 // Beware: context contains a pointer to issuerCert, so we need to keep it alive.
231 bssl::UniquePtr<X509> issuerCert;
232 X509V3_CTX context;
233
234 if (selfSigned) {
235 context = makeContext(x509.get(), x509.get());
236 } else {
237 auto certStatus = loadX509(*issuerCertPath);
238 if (!certStatus.ok()) {
239 return Error() << "Unable to load issuer cert: " << certStatus.error();
240 }
241 issuerCert = std::move(certStatus.value());
242 context = makeContext(issuerCert.get(), x509.get());
243 }
244
245 // If it's a self-signed cert we use it for signing certs, otherwise only for signing data.
246 const char* basicConstraints = selfSigned ? "CA:TRUE" : "CA:FALSE";
247 const char* keyUsage =
248 selfSigned ? "critical,keyCertSign,cRLSign,digitalSignature" : "critical,digitalSignature";
249
250 add_ext(&context, x509.get(), NID_basic_constraints, basicConstraints);
251 add_ext(&context, x509.get(), NID_key_usage, keyUsage);
252 add_ext(&context, x509.get(), NID_subject_key_identifier, "hash");
253 add_ext(&context, x509.get(), NID_authority_key_identifier, "keyid:always");
254
255 // Get the data to be signed
256 unsigned char* to_be_signed_buf(nullptr);
257 size_t to_be_signed_length = i2d_re_X509_tbs(x509.get(), &to_be_signed_buf);
258
259 auto signed_data = signFunction(
260 std::string(reinterpret_cast<const char*>(to_be_signed_buf), to_be_signed_length));
261 if (!signed_data.ok()) {
262 return signed_data.error();
263 }
264
265 if (!X509_set1_signature_value(x509.get(),
266 reinterpret_cast<const uint8_t*>(signed_data->data()),
267 signed_data->size())) {
268 return Error() << "Unable to set x509 signature";
269 }
270
271 auto f = fopen(path.c_str(), "wbe");
272 if (f == nullptr) {
273 return ErrnoError() << "Failed to open " << path;
274 }
275 i2d_X509_fp(f, x509.get());
276 if (fclose(f) != 0) {
277 return ErrnoError() << "Failed to close " << path;
278 }
279
280 return {};
281 }
282
createSelfSignedCertificate(const std::vector<uint8_t> & publicKey,const std::function<Result<std::string> (const std::string &)> & signFunction,const std::string & path)283 Result<void> createSelfSignedCertificate(
284 const std::vector<uint8_t>& publicKey,
285 const std::function<Result<std::string>(const std::string&)>& signFunction,
286 const std::string& path) {
287 auto rsa_pkey = modulusToRsaPkey(publicKey);
288 if (!rsa_pkey.ok()) {
289 return rsa_pkey.error();
290 }
291
292 return createCertificate(kRootSubject, rsa_pkey.value().get(), signFunction, {}, path);
293 }
294
createLeafCertificate(const CertSubject & subject,const std::vector<uint8_t> & rsaPublicKey,const std::function<android::base::Result<std::string> (const std::string &)> & signFunction,const std::string & issuerCertPath,const std::string & path)295 android::base::Result<void> createLeafCertificate(
296 const CertSubject& subject, const std::vector<uint8_t>& rsaPublicKey,
297 const std::function<android::base::Result<std::string>(const std::string&)>& signFunction,
298 const std::string& issuerCertPath, const std::string& path) {
299 auto rsa_pkey = rsaPublicKeyToRsaPkey(rsaPublicKey);
300 if (!rsa_pkey.ok()) {
301 return rsa_pkey.error();
302 }
303
304 return createCertificate(subject, rsa_pkey.value().get(), signFunction, issuerCertPath, path);
305 }
306
extractPublicKey(EVP_PKEY * pkey)307 Result<std::vector<uint8_t>> extractPublicKey(EVP_PKEY* pkey) {
308 if (pkey == nullptr) {
309 return Error() << "Failed to extract public key from x509 cert";
310 }
311
312 if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
313 return Error() << "The public key is not an RSA key";
314 }
315
316 RSA* rsa = EVP_PKEY_get0_RSA(pkey);
317 auto num_bytes = BN_num_bytes(RSA_get0_n(rsa));
318 std::vector<uint8_t> pubKey(num_bytes);
319 int res = BN_bn2bin(RSA_get0_n(rsa), pubKey.data());
320
321 if (!res) {
322 return Error() << "Failed to convert public key to bytes";
323 }
324
325 return pubKey;
326 }
327
328 Result<std::vector<uint8_t>>
extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t> & keyData)329 extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t>& keyData) {
330 auto keyDataBytes = keyData.data();
331 bssl::UniquePtr<EVP_PKEY> public_key(d2i_PUBKEY(nullptr, &keyDataBytes, keyData.size()));
332
333 return extractPublicKey(public_key.get());
334 }
335
extractPublicKeyFromX509(const std::vector<uint8_t> & derCert)336 Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::vector<uint8_t>& derCert) {
337 auto derCertBytes = derCert.data();
338 bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &derCertBytes, derCert.size()));
339 if (decoded_cert.get() == nullptr) {
340 return Error() << "Failed to decode X509 certificate.";
341 }
342 bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
343
344 return extractPublicKey(decoded_pkey.get());
345 }
346
extractPublicKeyFromX509(const std::string & path)347 Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path) {
348 auto cert = loadX509(path);
349 if (!cert.ok()) {
350 return cert.error();
351 }
352 return extractPublicKey(X509_get_pubkey(cert.value().get()));
353 }
354
extractRsaPublicKey(EVP_PKEY * pkey)355 static Result<std::vector<uint8_t>> extractRsaPublicKey(EVP_PKEY* pkey) {
356 RSA* rsa = EVP_PKEY_get0_RSA(pkey);
357 if (rsa == nullptr) {
358 return Error() << "The public key is not an RSA key";
359 }
360
361 uint8_t* out = nullptr;
362 int size = i2d_RSAPublicKey(rsa, &out);
363 if (size < 0 || !out) {
364 return Error() << "Failed to convert to RSAPublicKey";
365 }
366
367 bssl::UniquePtr<uint8_t> buffer(out);
368 std::vector<uint8_t> result(out, out + size);
369 return result;
370 }
371
verifyAndExtractCertInfoFromX509(const std::string & path,const std::vector<uint8_t> & publicKey)372 Result<CertInfo> verifyAndExtractCertInfoFromX509(const std::string& path,
373 const std::vector<uint8_t>& publicKey) {
374 auto public_key = modulusToRsaPkey(publicKey);
375 if (!public_key.ok()) {
376 return public_key.error();
377 }
378
379 auto cert = loadX509(path);
380 if (!cert.ok()) {
381 return cert.error();
382 }
383 X509* x509 = cert.value().get();
384
385 // Make sure we signed it.
386 if (X509_verify(x509, public_key.value().get()) != 1) {
387 return Error() << "Failed to verify certificate.";
388 }
389
390 bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(x509));
391 auto subject_key = extractRsaPublicKey(pkey.get());
392 if (!subject_key.ok()) {
393 return subject_key.error();
394 }
395
396 // The pointers here are all owned by x509, and each function handles an
397 // error return from the previous call correctly.
398 X509_NAME* name = X509_get_subject_name(x509);
399 int index = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
400 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index);
401 ASN1_STRING* asn1cn = X509_NAME_ENTRY_get_data(entry);
402 unsigned char* utf8cn;
403 int length = ASN1_STRING_to_UTF8(&utf8cn, asn1cn);
404 if (length < 0) {
405 return Error() << "Failed to read subject CN";
406 }
407
408 bssl::UniquePtr<unsigned char> utf8owner(utf8cn);
409 std::string cn(reinterpret_cast<char*>(utf8cn), static_cast<size_t>(length));
410
411 CertInfo cert_info{std::move(cn), std::move(subject_key.value())};
412 return cert_info;
413 }
414
createPkcs7(const std::vector<uint8_t> & signed_digest,const CertSubject & signer)415 Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signed_digest,
416 const CertSubject& signer) {
417 CBB out, outer_seq, wrapped_seq, seq, digest_algos_set, digest_algo, null;
418 CBB content_info, issuer_and_serial, signer_infos, signer_info, sign_algo, signature;
419 uint8_t *pkcs7_data, *name_der;
420 size_t pkcs7_data_len, name_der_len;
421 BIGNUM* serial = BN_new();
422 int sig_nid = NID_rsaEncryption;
423
424 X509_NAME* issuer_name = X509_NAME_new();
425 if (!issuer_name) {
426 return Error() << "Unable to create x509 subject name";
427 }
428 X509_NAME_add_entry_by_txt(issuer_name, "C", MBSTRING_ASC,
429 reinterpret_cast<const unsigned char*>(kIssuerCountry), -1, -1, 0);
430 X509_NAME_add_entry_by_txt(issuer_name, "O", MBSTRING_ASC,
431 reinterpret_cast<const unsigned char*>(kIssuerOrg), -1, -1, 0);
432 X509_NAME_add_entry_by_txt(issuer_name, "CN", MBSTRING_ASC,
433 reinterpret_cast<const unsigned char*>(kRootSubject.commonName), -1,
434 -1, 0);
435
436 BN_set_word(serial, signer.serialNumber);
437 name_der_len = i2d_X509_NAME(issuer_name, &name_der);
438 CBB_init(&out, 1024);
439
440 if (!CBB_add_asn1(&out, &outer_seq, CBS_ASN1_SEQUENCE) ||
441 !OBJ_nid2cbb(&outer_seq, NID_pkcs7_signed) ||
442 !CBB_add_asn1(&outer_seq, &wrapped_seq,
443 CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
444 // See https://tools.ietf.org/html/rfc2315#section-9.1
445 !CBB_add_asn1(&wrapped_seq, &seq, CBS_ASN1_SEQUENCE) ||
446 !CBB_add_asn1_uint64(&seq, 1 /* version */) ||
447 !CBB_add_asn1(&seq, &digest_algos_set, CBS_ASN1_SET) ||
448 !CBB_add_asn1(&digest_algos_set, &digest_algo, CBS_ASN1_SEQUENCE) ||
449 !OBJ_nid2cbb(&digest_algo, NID_sha256) ||
450 !CBB_add_asn1(&digest_algo, &null, CBS_ASN1_NULL) ||
451 !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) ||
452 !OBJ_nid2cbb(&content_info, NID_pkcs7_data) ||
453 !CBB_add_asn1(&seq, &signer_infos, CBS_ASN1_SET) ||
454 !CBB_add_asn1(&signer_infos, &signer_info, CBS_ASN1_SEQUENCE) ||
455 !CBB_add_asn1_uint64(&signer_info, 1 /* version */) ||
456 !CBB_add_asn1(&signer_info, &issuer_and_serial, CBS_ASN1_SEQUENCE) ||
457 !CBB_add_bytes(&issuer_and_serial, name_der, name_der_len) ||
458 !BN_marshal_asn1(&issuer_and_serial, serial) ||
459 !CBB_add_asn1(&signer_info, &digest_algo, CBS_ASN1_SEQUENCE) ||
460 !OBJ_nid2cbb(&digest_algo, NID_sha256) ||
461 !CBB_add_asn1(&digest_algo, &null, CBS_ASN1_NULL) ||
462 !CBB_add_asn1(&signer_info, &sign_algo, CBS_ASN1_SEQUENCE) ||
463 !OBJ_nid2cbb(&sign_algo, sig_nid) || !CBB_add_asn1(&sign_algo, &null, CBS_ASN1_NULL) ||
464 !CBB_add_asn1(&signer_info, &signature, CBS_ASN1_OCTETSTRING) ||
465 !CBB_add_bytes(&signature, signed_digest.data(), signed_digest.size()) ||
466 !CBB_finish(&out, &pkcs7_data, &pkcs7_data_len)) {
467 return Error() << "Failed to create PKCS7 certificate.";
468 }
469
470 return std::vector<uint8_t>(&pkcs7_data[0], &pkcs7_data[pkcs7_data_len]);
471 }
472