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/rsa.h>
25 #include <openssl/x509.h>
26 #include <openssl/x509v3.h>
27 
28 #include <vector>
29 
30 #include "KeyConstants.h"
31 
32 // Common properties for all of our certificates.
33 constexpr int kCertLifetimeSeconds = 10 * 365 * 24 * 60 * 60;
34 const char* const kIssuerCountry = "US";
35 const char* const kIssuerOrg = "Android";
36 
37 using android::base::ErrnoError;
38 using android::base::Error;
39 using android::base::Result;
40 
loadX509(const std::string & path)41 static Result<bssl::UniquePtr<X509>> loadX509(const std::string& path) {
42     X509* rawCert;
43     auto f = fopen(path.c_str(), "re");
44     if (f == nullptr) {
45         return Error() << "Failed to open " << path;
46     }
47     if (!d2i_X509_fp(f, &rawCert)) {
48         fclose(f);
49         return Error() << "Unable to decode x509 cert at " << path;
50     }
51     bssl::UniquePtr<X509> cert(rawCert);
52 
53     fclose(f);
54     return cert;
55 }
56 
add_ext(X509V3_CTX * context,X509 * cert,int nid,const char * value)57 static bool add_ext(X509V3_CTX* context, X509* cert, int nid, const char* value) {
58     bssl::UniquePtr<X509_EXTENSION> ex(X509V3_EXT_nconf_nid(nullptr, context, nid, value));
59     if (!ex) {
60         return false;
61     }
62 
63     X509_add_ext(cert, ex.get(), -1);
64     return true;
65 }
66 
addNameEntry(X509_NAME * name,const char * field,const char * value)67 static void addNameEntry(X509_NAME* name, const char* field, const char* value) {
68     X509_NAME_add_entry_by_txt(name, field, MBSTRING_ASC,
69                                reinterpret_cast<const unsigned char*>(value), -1, -1, 0);
70 }
71 
getRsaFromModulus(const std::vector<uint8_t> & publicKey)72 static Result<bssl::UniquePtr<RSA>> getRsaFromModulus(const std::vector<uint8_t>& publicKey) {
73     bssl::UniquePtr<BIGNUM> n(BN_new());
74     bssl::UniquePtr<BIGNUM> e(BN_new());
75     bssl::UniquePtr<RSA> rsaPubkey(RSA_new());
76     if (!n || !e || !rsaPubkey || !BN_bin2bn(publicKey.data(), publicKey.size(), n.get()) ||
77         !BN_set_word(e.get(), kRsaKeyExponent) ||
78         !RSA_set0_key(rsaPubkey.get(), n.get(), e.get(), /*d=*/nullptr)) {
79         return Error() << "Failed to create RSA key";
80     }
81     // RSA_set0_key takes ownership of |n| and |e| on success.
82     (void)n.release();
83     (void)e.release();
84 
85     return rsaPubkey;
86 }
87 
modulusToRsaPkey(const std::vector<uint8_t> & publicKey)88 static Result<bssl::UniquePtr<EVP_PKEY>> modulusToRsaPkey(const std::vector<uint8_t>& publicKey) {
89     // "publicKey" corresponds to the raw public key bytes - need to create
90     // a new RSA key with the correct exponent.
91     auto rsaPubkey = getRsaFromModulus(publicKey);
92     if (!rsaPubkey.ok()) {
93         return rsaPubkey.error();
94     }
95 
96     bssl::UniquePtr<EVP_PKEY> public_key(EVP_PKEY_new());
97     if (!EVP_PKEY_assign_RSA(public_key.get(), rsaPubkey->release())) {
98         return Error() << "Failed to assign key";
99     }
100     return public_key;
101 }
102 
verifySignature(const std::string & message,const std::string & signature,const std::vector<uint8_t> & publicKey)103 Result<void> verifySignature(const std::string& message, const std::string& signature,
104                              const std::vector<uint8_t>& publicKey) {
105     auto rsaKey = getRsaFromModulus(publicKey);
106     if (!rsaKey.ok()) {
107         return rsaKey.error();
108     }
109     uint8_t hashBuf[SHA256_DIGEST_LENGTH];
110     SHA256(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(message.c_str())),
111            message.length(), hashBuf);
112 
113     bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf),
114                               (const uint8_t*)signature.c_str(), signature.length(), rsaKey->get());
115 
116     if (!success) {
117         return Error() << "Failed to verify signature";
118     }
119     return {};
120 }
121 
createSelfSignedCertificate(const std::vector<uint8_t> & publicKey,const std::function<Result<std::string> (const std::string &)> & signFunction,const std::string & path)122 Result<void> createSelfSignedCertificate(
123     const std::vector<uint8_t>& publicKey,
124     const std::function<Result<std::string>(const std::string&)>& signFunction,
125     const std::string& path) {
126     auto rsa_pkey = modulusToRsaPkey(publicKey);
127     if (!rsa_pkey.ok()) {
128         return rsa_pkey.error();
129     }
130     bssl::UniquePtr<X509> x509(X509_new());
131     if (!x509) {
132         return Error() << "Unable to allocate x509 container";
133     }
134     X509_set_version(x509.get(), 2);
135     X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
136     X509_gmtime_adj(X509_get_notAfter(x509.get()), kCertLifetimeSeconds);
137     ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), kRootSubject.serialNumber);
138 
139     bssl::UniquePtr<X509_ALGOR> algor(X509_ALGOR_new());
140     if (!algor ||
141         !X509_ALGOR_set0(algor.get(), OBJ_nid2obj(NID_sha256WithRSAEncryption), V_ASN1_NULL,
142                          NULL) ||
143         !X509_set1_signature_algo(x509.get(), algor.get())) {
144         return Error() << "Unable to set x509 signature algorithm";
145     }
146 
147     if (!X509_set_pubkey(x509.get(), rsa_pkey.value().get())) {
148         return Error() << "Unable to set x509 public key";
149     }
150 
151     X509_NAME* subjectName = X509_get_subject_name(x509.get());
152     if (!subjectName) {
153         return Error() << "Unable to get x509 subject name";
154     }
155     addNameEntry(subjectName, "C", kIssuerCountry);
156     addNameEntry(subjectName, "O", kIssuerOrg);
157     addNameEntry(subjectName, "CN", kRootSubject.commonName);
158     if (!X509_set_issuer_name(x509.get(), subjectName)) {
159         return Error() << "Unable to set x509 issuer name";
160     }
161 
162     X509V3_CTX context = {};
163     X509V3_set_ctx(&context, x509.get(), x509.get(), nullptr, nullptr, 0);
164     add_ext(&context, x509.get(), NID_basic_constraints, "CA:TRUE");
165     add_ext(&context, x509.get(), NID_key_usage, "critical,keyCertSign,cRLSign,digitalSignature");
166     add_ext(&context, x509.get(), NID_subject_key_identifier, "hash");
167     add_ext(&context, x509.get(), NID_authority_key_identifier, "keyid:always");
168 
169     // Get the data to be signed
170     unsigned char* to_be_signed_buf(nullptr);
171     size_t to_be_signed_length = i2d_re_X509_tbs(x509.get(), &to_be_signed_buf);
172 
173     auto signed_data = signFunction(
174         std::string(reinterpret_cast<const char*>(to_be_signed_buf), to_be_signed_length));
175     if (!signed_data.ok()) {
176         return signed_data.error();
177     }
178 
179     if (!X509_set1_signature_value(x509.get(),
180                                    reinterpret_cast<const uint8_t*>(signed_data->data()),
181                                    signed_data->size())) {
182         return Error() << "Unable to set x509 signature";
183     }
184 
185     auto f = fopen(path.c_str(), "wbe");
186     if (f == nullptr) {
187         return ErrnoError() << "Failed to open " << path;
188     }
189     i2d_X509_fp(f, x509.get());
190     if (fclose(f) != 0) {
191         return ErrnoError() << "Failed to close " << path;
192     }
193 
194     return {};
195 }
196 
extractPublicKey(EVP_PKEY * pkey)197 static Result<std::vector<uint8_t>> extractPublicKey(EVP_PKEY* pkey) {
198     if (pkey == nullptr) {
199         return Error() << "Failed to extract public key from x509 cert";
200     }
201 
202     if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
203         return Error() << "The public key is not an RSA key";
204     }
205 
206     RSA* rsa = EVP_PKEY_get0_RSA(pkey);
207     auto num_bytes = BN_num_bytes(RSA_get0_n(rsa));
208     std::vector<uint8_t> pubKey(num_bytes);
209     int res = BN_bn2bin(RSA_get0_n(rsa), pubKey.data());
210 
211     if (!res) {
212         return Error() << "Failed to convert public key to bytes";
213     }
214 
215     return pubKey;
216 }
217 
extractPublicKeyFromX509(const std::vector<uint8_t> & derCert)218 Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::vector<uint8_t>& derCert) {
219     auto derCertBytes = derCert.data();
220     bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &derCertBytes, derCert.size()));
221     if (decoded_cert.get() == nullptr) {
222         return Error() << "Failed to decode X509 certificate.";
223     }
224     bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
225 
226     return extractPublicKey(decoded_pkey.get());
227 }
228 
extractPublicKeyFromX509(const std::string & path)229 Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path) {
230     auto cert = loadX509(path);
231     if (!cert.ok()) {
232         return cert.error();
233     }
234     return extractPublicKey(X509_get_pubkey(cert.value().get()));
235 }
236