1 /* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include <openssl/conf.h> 12 #include <openssl/err.h> 13 #include <openssl/opensslv.h> 14 #include <openssl/pem.h> 15 #include <openssl/sha.h> 16 #include <openssl/x509v3.h> 17 18 #if USE_TBBR_DEFS 19 #include <tbbr_oid.h> 20 #else 21 #include <platform_oid.h> 22 #endif 23 24 #include "cert.h" 25 #include "cmd_opt.h" 26 #include "debug.h" 27 #include "key.h" 28 #include "sha.h" 29 30 #define SERIAL_RAND_BITS 64 31 #define RSA_SALT_LEN 32 32 33 int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) 34 { 35 BIGNUM *btmp; 36 int ret = 0; 37 if (b) 38 btmp = b; 39 else 40 btmp = BN_new(); 41 42 if (!btmp) 43 return 0; 44 45 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) 46 goto error; 47 if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) 48 goto error; 49 50 ret = 1; 51 52 error: 53 54 if (!b) 55 BN_free(btmp); 56 57 return ret; 58 } 59 60 int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value) 61 { 62 X509_EXTENSION *ex; 63 X509V3_CTX ctx; 64 65 /* No configuration database */ 66 X509V3_set_ctx_nodb(&ctx); 67 68 /* Set issuer and subject certificates in the context */ 69 X509V3_set_ctx(&ctx, issuer, subject, NULL, NULL, 0); 70 ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value); 71 if (!ex) { 72 ERR_print_errors_fp(stdout); 73 return 0; 74 } 75 76 X509_add_ext(subject, ex, -1); 77 X509_EXTENSION_free(ex); 78 79 return 1; 80 } 81 82 int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) 83 { 84 EVP_PKEY *pkey = keys[cert->key].key; 85 cert_t *issuer_cert = &certs[cert->issuer]; 86 EVP_PKEY *ikey = keys[issuer_cert->key].key; 87 X509 *issuer = issuer_cert->x; 88 X509 *x; 89 X509_EXTENSION *ex; 90 X509_NAME *name; 91 ASN1_INTEGER *sno; 92 int i, num, rc = 0; 93 EVP_MD_CTX *mdCtx; 94 EVP_PKEY_CTX *pKeyCtx = NULL; 95 96 /* Create the certificate structure */ 97 x = X509_new(); 98 if (!x) { 99 return 0; 100 } 101 102 /* If we do not have a key, use the issuer key (the certificate will 103 * become self signed). This happens in content certificates. */ 104 if (!pkey) { 105 pkey = ikey; 106 } 107 108 /* If we do not have an issuer certificate, use our own (the certificate 109 * will become self signed) */ 110 if (!issuer) { 111 issuer = x; 112 } 113 114 mdCtx = EVP_MD_CTX_create(); 115 if (mdCtx == NULL) { 116 ERR_print_errors_fp(stdout); 117 goto END; 118 } 119 120 /* Sign the certificate with the issuer key */ 121 if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, EVP_sha256(), NULL, ikey)) { 122 ERR_print_errors_fp(stdout); 123 goto END; 124 } 125 126 /* 127 * Set additional parameters if algorithm is RSA PSS. This is not 128 * required for RSA 1.5 or ECDSA. 129 */ 130 if (key_alg == KEY_ALG_RSA) { 131 if (!EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING)) { 132 ERR_print_errors_fp(stdout); 133 goto END; 134 } 135 136 if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN)) { 137 ERR_print_errors_fp(stdout); 138 goto END; 139 } 140 141 if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256())) { 142 ERR_print_errors_fp(stdout); 143 goto END; 144 } 145 } 146 147 /* x509.v3 */ 148 X509_set_version(x, 2); 149 150 /* Random serial number */ 151 sno = ASN1_INTEGER_new(); 152 rand_serial(NULL, sno); 153 X509_set_serialNumber(x, sno); 154 ASN1_INTEGER_free(sno); 155 156 X509_gmtime_adj(X509_get_notBefore(x), 0); 157 X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days); 158 X509_set_pubkey(x, pkey); 159 160 /* Subject name */ 161 name = X509_get_subject_name(x); 162 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, 163 (const unsigned char *)cert->cn, -1, -1, 0); 164 X509_set_subject_name(x, name); 165 166 /* Issuer name */ 167 name = X509_get_issuer_name(x); 168 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, 169 (const unsigned char *)issuer_cert->cn, -1, -1, 0); 170 X509_set_issuer_name(x, name); 171 172 /* Add various extensions: standard extensions */ 173 cert_add_ext(issuer, x, NID_subject_key_identifier, "hash"); 174 cert_add_ext(issuer, x, NID_authority_key_identifier, "keyid:always"); 175 if (ca) { 176 cert_add_ext(issuer, x, NID_basic_constraints, "CA:TRUE"); 177 cert_add_ext(issuer, x, NID_key_usage, "keyCertSign"); 178 } else { 179 cert_add_ext(issuer, x, NID_basic_constraints, "CA:FALSE"); 180 } 181 182 /* Add custom extensions */ 183 if (sk != NULL) { 184 num = sk_X509_EXTENSION_num(sk); 185 for (i = 0; i < num; i++) { 186 ex = sk_X509_EXTENSION_value(sk, i); 187 X509_add_ext(x, ex, -1); 188 } 189 } 190 191 if (!X509_sign_ctx(x, mdCtx)) { 192 ERR_print_errors_fp(stdout); 193 goto END; 194 } 195 196 /* X509 certificate signed successfully */ 197 rc = 1; 198 cert->x = x; 199 200 END: 201 EVP_MD_CTX_destroy(mdCtx); 202 return rc; 203 } 204 205 int cert_init(void) 206 { 207 cmd_opt_t cmd_opt; 208 cert_t *cert; 209 unsigned int i; 210 211 for (i = 0; i < num_certs; i++) { 212 cert = &certs[i]; 213 cmd_opt.long_opt.name = cert->opt; 214 cmd_opt.long_opt.has_arg = required_argument; 215 cmd_opt.long_opt.flag = NULL; 216 cmd_opt.long_opt.val = CMD_OPT_CERT; 217 cmd_opt.help_msg = cert->help_msg; 218 cmd_opt_add(&cmd_opt); 219 } 220 221 return 0; 222 } 223 224 cert_t *cert_get_by_opt(const char *opt) 225 { 226 cert_t *cert; 227 unsigned int i; 228 229 for (i = 0; i < num_certs; i++) { 230 cert = &certs[i]; 231 if (0 == strcmp(cert->opt, opt)) { 232 return cert; 233 } 234 } 235 236 return NULL; 237 } 238