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 <android-base/logging.h>
18 #include <android-base/result.h>
19 
20 #include <openssl/bn.h>
21 #include <openssl/crypto.h>
22 #include <openssl/pkcs7.h>
23 #include <openssl/rsa.h>
24 #include <openssl/x509v3.h>
25 
26 #include <fcntl.h>
27 #include <vector>
28 
29 #include "KeyConstants.h"
30 
31 const char kBasicConstraints[] = "CA:TRUE";
32 const char kKeyUsage[] = "critical,keyCertSign,cRLSign,digitalSignature";
33 const char kSubjectKeyIdentifier[] = "hash";
34 constexpr int kCertLifetimeSeconds = 10 * 365 * 24 * 60 * 60;
35 
36 using android::base::Result;
37 // using android::base::ErrnoError;
38 using android::base::Error;
39 
add_ext(X509 * cert,int nid,const char * value)40 static bool add_ext(X509* cert, int nid, const char* value) {
41     size_t len = strlen(value) + 1;
42     std::vector<char> mutableValue(value, value + len);
43     X509V3_CTX context;
44 
45     X509V3_set_ctx_nodb(&context);
46 
47     X509V3_set_ctx(&context, cert, cert, nullptr, nullptr, 0);
48     X509_EXTENSION* ex = X509V3_EXT_nconf_nid(nullptr, &context, nid, mutableValue.data());
49     if (!ex) {
50         return false;
51     }
52 
53     X509_add_ext(cert, ex, -1);
54     X509_EXTENSION_free(ex);
55     return true;
56 }
57 
getRsa(const std::vector<uint8_t> & publicKey)58 Result<bssl::UniquePtr<RSA>> getRsa(const std::vector<uint8_t>& publicKey) {
59     bssl::UniquePtr<RSA> rsaPubkey(RSA_new());
60     rsaPubkey->n = BN_new();
61     rsaPubkey->e = BN_new();
62 
63     BN_bin2bn(publicKey.data(), publicKey.size(), rsaPubkey->n);
64     BN_set_word(rsaPubkey->e, kRsaKeyExponent);
65 
66     return rsaPubkey;
67 }
68 
verifySignature(const std::string & message,const std::string & signature,const std::vector<uint8_t> & publicKey)69 Result<void> verifySignature(const std::string& message, const std::string& signature,
70                              const std::vector<uint8_t>& publicKey) {
71     auto rsaKey = getRsa(publicKey);
72     uint8_t hashBuf[SHA256_DIGEST_LENGTH];
73     SHA256(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(message.c_str())),
74            message.length(), hashBuf);
75 
76     bool success = RSA_verify(NID_sha256, hashBuf, sizeof(hashBuf),
77                               (const uint8_t*)signature.c_str(), signature.length(), rsaKey->get());
78 
79     if (!success) {
80         return Error() << "Failed to verify signature.";
81     }
82     return {};
83 }
84 
createSelfSignedCertificate(const std::vector<uint8_t> & publicKey,const std::function<Result<std::string> (const std::string &)> & signFunction,const std::string & path)85 Result<void> createSelfSignedCertificate(
86     const std::vector<uint8_t>& publicKey,
87     const std::function<Result<std::string>(const std::string&)>& signFunction,
88     const std::string& path) {
89     bssl::UniquePtr<X509> x509(X509_new());
90     if (!x509) {
91         return Error() << "Unable to allocate x509 container";
92     }
93     X509_set_version(x509.get(), 2);
94 
95     ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), 1);
96     X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
97     X509_gmtime_adj(X509_get_notAfter(x509.get()), kCertLifetimeSeconds);
98 
99     // "publicKey" corresponds to the raw public key bytes - need to create
100     // a new RSA key with the correct exponent.
101     auto rsaPubkey = getRsa(publicKey);
102 
103     EVP_PKEY* public_key = EVP_PKEY_new();
104     EVP_PKEY_assign_RSA(public_key, rsaPubkey->release());
105 
106     if (!X509_set_pubkey(x509.get(), public_key)) {
107         return Error() << "Unable to set x509 public key";
108     }
109 
110     X509_NAME* name = X509_get_subject_name(x509.get());
111     if (!name) {
112         return Error() << "Unable to get x509 subject name";
113     }
114     X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
115                                reinterpret_cast<const unsigned char*>("US"), -1, -1, 0);
116     X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
117                                reinterpret_cast<const unsigned char*>("Android"), -1, -1, 0);
118     X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
119                                reinterpret_cast<const unsigned char*>("ODS"), -1, -1, 0);
120     if (!X509_set_issuer_name(x509.get(), name)) {
121         return Error() << "Unable to set x509 issuer name";
122     }
123 
124     add_ext(x509.get(), NID_basic_constraints, kBasicConstraints);
125     add_ext(x509.get(), NID_key_usage, kKeyUsage);
126     add_ext(x509.get(), NID_subject_key_identifier, kSubjectKeyIdentifier);
127     add_ext(x509.get(), NID_authority_key_identifier, "keyid:always");
128 
129     X509_ALGOR_set0(x509->cert_info->signature, OBJ_nid2obj(NID_sha256WithRSAEncryption),
130                     V_ASN1_NULL, NULL);
131     X509_ALGOR_set0(x509->sig_alg, OBJ_nid2obj(NID_sha256WithRSAEncryption), V_ASN1_NULL, NULL);
132 
133     // Get the data to be signed
134     char* to_be_signed_buf(nullptr);
135     size_t to_be_signed_length = i2d_re_X509_tbs(x509.get(), (unsigned char**)&to_be_signed_buf);
136 
137     auto signed_data = signFunction(std::string(to_be_signed_buf, to_be_signed_length));
138     if (!signed_data.ok()) {
139         return signed_data.error();
140     }
141 
142     // This is the only part that doesn't use boringssl default functions - we manually copy in the
143     // signature that was provided to us.
144     x509->signature->data = (unsigned char*)OPENSSL_malloc(signed_data->size());
145     memcpy(x509->signature->data, signed_data->c_str(), signed_data->size());
146     x509->signature->length = signed_data->size();
147 
148     x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
149     x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
150     auto f = fopen(path.c_str(), "wbe");
151     if (f == nullptr) {
152         return Error() << "Failed to open " << path;
153     }
154     i2d_X509_fp(f, x509.get());
155     fclose(f);
156 
157     EVP_PKEY_free(public_key);
158     return {};
159 }
160 
extractPublicKey(EVP_PKEY * pkey)161 Result<std::vector<uint8_t>> extractPublicKey(EVP_PKEY* pkey) {
162     if (pkey == nullptr) {
163         return Error() << "Failed to extract public key from x509 cert";
164     }
165 
166     if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
167         return Error() << "The public key is not an RSA key";
168     }
169 
170     RSA* rsa = EVP_PKEY_get1_RSA(pkey);
171     auto num_bytes = BN_num_bytes(rsa->n);
172     std::vector<uint8_t> pubKey(num_bytes);
173     int res = BN_bn2bin(rsa->n, pubKey.data());
174     RSA_free(rsa);
175 
176     if (!res) {
177         return Error() << "Failed to convert public key to bytes";
178     }
179 
180     return pubKey;
181 }
182 
183 Result<std::vector<uint8_t>>
extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t> & keyData)184 extractPublicKeyFromSubjectPublicKeyInfo(const std::vector<uint8_t>& keyData) {
185     auto keyDataBytes = keyData.data();
186     EVP_PKEY* public_key = d2i_PUBKEY(nullptr, &keyDataBytes, keyData.size());
187 
188     return extractPublicKey(public_key);
189 }
190 
extractPublicKeyFromX509(const std::vector<uint8_t> & keyData)191 Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::vector<uint8_t>& keyData) {
192     auto keyDataBytes = keyData.data();
193     bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &keyDataBytes, keyData.size()));
194     if (decoded_cert.get() == nullptr) {
195         return Error() << "Failed to decode X509 certificate.";
196     }
197     bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
198 
199     return extractPublicKey(decoded_pkey.get());
200 }
201 
extractPublicKeyFromX509(const std::string & path)202 Result<std::vector<uint8_t>> extractPublicKeyFromX509(const std::string& path) {
203     X509* cert;
204     auto f = fopen(path.c_str(), "re");
205     if (f == nullptr) {
206         return Error() << "Failed to open " << path;
207     }
208     if (!d2i_X509_fp(f, &cert)) {
209         fclose(f);
210         return Error() << "Unable to decode x509 cert at " << path;
211     }
212 
213     fclose(f);
214     return extractPublicKey(X509_get_pubkey(cert));
215 }
216 
createPkcs7(const std::vector<uint8_t> & signed_digest)217 Result<std::vector<uint8_t>> createPkcs7(const std::vector<uint8_t>& signed_digest) {
218     CBB out, outer_seq, wrapped_seq, seq, digest_algos_set, digest_algo, null;
219     CBB content_info, issuer_and_serial, signer_infos, signer_info, sign_algo, signature;
220     uint8_t *pkcs7_data, *name_der;
221     size_t pkcs7_data_len, name_der_len;
222     BIGNUM* serial = BN_new();
223     int sig_nid = NID_rsaEncryption;
224 
225     X509_NAME* name = X509_NAME_new();
226     if (!name) {
227         return Error() << "Unable to get x509 subject name";
228     }
229     X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
230                                reinterpret_cast<const unsigned char*>("US"), -1, -1, 0);
231     X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
232                                reinterpret_cast<const unsigned char*>("Android"), -1, -1, 0);
233     X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
234                                reinterpret_cast<const unsigned char*>("ODS"), -1, -1, 0);
235 
236     BN_set_word(serial, 1);
237     name_der_len = i2d_X509_NAME(name, &name_der);
238     CBB_init(&out, 1024);
239 
240     if (!CBB_add_asn1(&out, &outer_seq, CBS_ASN1_SEQUENCE) ||
241         !OBJ_nid2cbb(&outer_seq, NID_pkcs7_signed) ||
242         !CBB_add_asn1(&outer_seq, &wrapped_seq,
243                       CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
244         // See https://tools.ietf.org/html/rfc2315#section-9.1
245         !CBB_add_asn1(&wrapped_seq, &seq, CBS_ASN1_SEQUENCE) ||
246         !CBB_add_asn1_uint64(&seq, 1 /* version */) ||
247         !CBB_add_asn1(&seq, &digest_algos_set, CBS_ASN1_SET) ||
248         !CBB_add_asn1(&digest_algos_set, &digest_algo, CBS_ASN1_SEQUENCE) ||
249         !OBJ_nid2cbb(&digest_algo, NID_sha256) ||
250         !CBB_add_asn1(&digest_algo, &null, CBS_ASN1_NULL) ||
251         !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) ||
252         !OBJ_nid2cbb(&content_info, NID_pkcs7_data) ||
253         !CBB_add_asn1(&seq, &signer_infos, CBS_ASN1_SET) ||
254         !CBB_add_asn1(&signer_infos, &signer_info, CBS_ASN1_SEQUENCE) ||
255         !CBB_add_asn1_uint64(&signer_info, 1 /* version */) ||
256         !CBB_add_asn1(&signer_info, &issuer_and_serial, CBS_ASN1_SEQUENCE) ||
257         !CBB_add_bytes(&issuer_and_serial, name_der, name_der_len) ||
258         !BN_marshal_asn1(&issuer_and_serial, serial) ||
259         !CBB_add_asn1(&signer_info, &digest_algo, CBS_ASN1_SEQUENCE) ||
260         !OBJ_nid2cbb(&digest_algo, NID_sha256) ||
261         !CBB_add_asn1(&digest_algo, &null, CBS_ASN1_NULL) ||
262         !CBB_add_asn1(&signer_info, &sign_algo, CBS_ASN1_SEQUENCE) ||
263         !OBJ_nid2cbb(&sign_algo, sig_nid) || !CBB_add_asn1(&sign_algo, &null, CBS_ASN1_NULL) ||
264         !CBB_add_asn1(&signer_info, &signature, CBS_ASN1_OCTETSTRING) ||
265         !CBB_add_bytes(&signature, signed_digest.data(), signed_digest.size()) ||
266         !CBB_finish(&out, &pkcs7_data, &pkcs7_data_len)) {
267         return Error() << "Failed to create PKCS7 certificate.";
268     }
269 
270     return std::vector<uint8_t>(&pkcs7_data[0], &pkcs7_data[pkcs7_data_len]);
271 }
272