• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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