1*2974e8f1Sjsing /* $OpenBSD: tls_keypair.c,v 1.5 2018/02/10 04:57:35 jsing Exp $ */ 2bb4cb1b0Sjsing /* 3bb4cb1b0Sjsing * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 4bb4cb1b0Sjsing * 5bb4cb1b0Sjsing * Permission to use, copy, modify, and distribute this software for any 6bb4cb1b0Sjsing * purpose with or without fee is hereby granted, provided that the above 7bb4cb1b0Sjsing * copyright notice and this permission notice appear in all copies. 8bb4cb1b0Sjsing * 9bb4cb1b0Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10bb4cb1b0Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11bb4cb1b0Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12bb4cb1b0Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13bb4cb1b0Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14bb4cb1b0Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15bb4cb1b0Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16bb4cb1b0Sjsing */ 17bb4cb1b0Sjsing 18bb4cb1b0Sjsing #include <openssl/bio.h> 19bb4cb1b0Sjsing #include <openssl/err.h> 20bb4cb1b0Sjsing #include <openssl/pem.h> 21bb4cb1b0Sjsing 22bb4cb1b0Sjsing #include <tls.h> 23bb4cb1b0Sjsing 24bb4cb1b0Sjsing #include "tls_internal.h" 25bb4cb1b0Sjsing 26bb4cb1b0Sjsing struct tls_keypair * 27bb4cb1b0Sjsing tls_keypair_new(void) 28bb4cb1b0Sjsing { 29bb4cb1b0Sjsing return calloc(1, sizeof(struct tls_keypair)); 30bb4cb1b0Sjsing } 31bb4cb1b0Sjsing 32*2974e8f1Sjsing static void 33bb4cb1b0Sjsing tls_keypair_clear_key(struct tls_keypair *keypair) 34bb4cb1b0Sjsing { 35bb4cb1b0Sjsing freezero(keypair->key_mem, keypair->key_len); 36bb4cb1b0Sjsing keypair->key_mem = NULL; 37bb4cb1b0Sjsing keypair->key_len = 0; 38bb4cb1b0Sjsing } 39bb4cb1b0Sjsing 40*2974e8f1Sjsing static int 41*2974e8f1Sjsing tls_keypair_pubkey_hash(struct tls_keypair *keypair, struct tls_error *error) 42*2974e8f1Sjsing { 43*2974e8f1Sjsing X509 *cert = NULL; 44*2974e8f1Sjsing int rv = -1; 45*2974e8f1Sjsing 46*2974e8f1Sjsing free(keypair->pubkey_hash); 47*2974e8f1Sjsing keypair->pubkey_hash = NULL; 48*2974e8f1Sjsing 49*2974e8f1Sjsing if (keypair->cert_mem == NULL) { 50*2974e8f1Sjsing rv = 0; 51*2974e8f1Sjsing goto done; 52*2974e8f1Sjsing } 53*2974e8f1Sjsing 54*2974e8f1Sjsing if (tls_keypair_load_cert(keypair, error, &cert) == -1) 55*2974e8f1Sjsing goto err; 56*2974e8f1Sjsing if (tls_cert_pubkey_hash(cert, &keypair->pubkey_hash) == -1) 57*2974e8f1Sjsing goto err; 58*2974e8f1Sjsing 59*2974e8f1Sjsing rv = 0; 60*2974e8f1Sjsing 61*2974e8f1Sjsing err: 62*2974e8f1Sjsing X509_free(cert); 63*2974e8f1Sjsing done: 64*2974e8f1Sjsing return (rv); 65*2974e8f1Sjsing } 66*2974e8f1Sjsing 67bb4cb1b0Sjsing int 68bb4cb1b0Sjsing tls_keypair_set_cert_file(struct tls_keypair *keypair, struct tls_error *error, 69bb4cb1b0Sjsing const char *cert_file) 70bb4cb1b0Sjsing { 71*2974e8f1Sjsing if (tls_config_load_file(error, "certificate", cert_file, 72*2974e8f1Sjsing &keypair->cert_mem, &keypair->cert_len) == -1) 73*2974e8f1Sjsing return -1; 74*2974e8f1Sjsing return tls_keypair_pubkey_hash(keypair, error); 75bb4cb1b0Sjsing } 76bb4cb1b0Sjsing 77bb4cb1b0Sjsing int 78*2974e8f1Sjsing tls_keypair_set_cert_mem(struct tls_keypair *keypair, struct tls_error *error, 79*2974e8f1Sjsing const uint8_t *cert, size_t len) 80bb4cb1b0Sjsing { 81*2974e8f1Sjsing if (tls_set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len) == -1) 82*2974e8f1Sjsing return -1; 83*2974e8f1Sjsing return tls_keypair_pubkey_hash(keypair, error); 84bb4cb1b0Sjsing } 85bb4cb1b0Sjsing 86bb4cb1b0Sjsing int 87bb4cb1b0Sjsing tls_keypair_set_key_file(struct tls_keypair *keypair, struct tls_error *error, 88bb4cb1b0Sjsing const char *key_file) 89bb4cb1b0Sjsing { 90bb4cb1b0Sjsing tls_keypair_clear_key(keypair); 91bb4cb1b0Sjsing return tls_config_load_file(error, "key", key_file, 92bb4cb1b0Sjsing &keypair->key_mem, &keypair->key_len); 93bb4cb1b0Sjsing } 94bb4cb1b0Sjsing 95bb4cb1b0Sjsing int 96*2974e8f1Sjsing tls_keypair_set_key_mem(struct tls_keypair *keypair, struct tls_error *error, 97*2974e8f1Sjsing const uint8_t *key, size_t len) 98bb4cb1b0Sjsing { 99bb4cb1b0Sjsing tls_keypair_clear_key(keypair); 100bb4cb1b0Sjsing return tls_set_mem(&keypair->key_mem, &keypair->key_len, key, len); 101bb4cb1b0Sjsing } 102bb4cb1b0Sjsing 103bb4cb1b0Sjsing int 104bb4cb1b0Sjsing tls_keypair_set_ocsp_staple_file(struct tls_keypair *keypair, 105bb4cb1b0Sjsing struct tls_error *error, const char *ocsp_file) 106bb4cb1b0Sjsing { 107bb4cb1b0Sjsing return tls_config_load_file(error, "ocsp", ocsp_file, 108bb4cb1b0Sjsing &keypair->ocsp_staple, &keypair->ocsp_staple_len); 109bb4cb1b0Sjsing } 110bb4cb1b0Sjsing 111bb4cb1b0Sjsing int 112bb4cb1b0Sjsing tls_keypair_set_ocsp_staple_mem(struct tls_keypair *keypair, 113*2974e8f1Sjsing struct tls_error *error, const uint8_t *staple, size_t len) 114bb4cb1b0Sjsing { 115bb4cb1b0Sjsing return tls_set_mem(&keypair->ocsp_staple, &keypair->ocsp_staple_len, 116bb4cb1b0Sjsing staple, len); 117bb4cb1b0Sjsing } 118bb4cb1b0Sjsing 119bb4cb1b0Sjsing void 120bb4cb1b0Sjsing tls_keypair_clear(struct tls_keypair *keypair) 121bb4cb1b0Sjsing { 122*2974e8f1Sjsing struct tls_error error; 123*2974e8f1Sjsing 124*2974e8f1Sjsing tls_keypair_set_cert_mem(keypair, &error, NULL, 0); 125*2974e8f1Sjsing tls_keypair_set_key_mem(keypair, &error, NULL, 0); 126*2974e8f1Sjsing tls_keypair_set_ocsp_staple_mem(keypair, &error, NULL, 0); 12705729e6fSjsing 12805729e6fSjsing free(keypair->pubkey_hash); 12905729e6fSjsing keypair->pubkey_hash = NULL; 130bb4cb1b0Sjsing } 131bb4cb1b0Sjsing 132bb4cb1b0Sjsing void 133bb4cb1b0Sjsing tls_keypair_free(struct tls_keypair *keypair) 134bb4cb1b0Sjsing { 135bb4cb1b0Sjsing if (keypair == NULL) 136bb4cb1b0Sjsing return; 137bb4cb1b0Sjsing 138bb4cb1b0Sjsing tls_keypair_clear(keypair); 139bb4cb1b0Sjsing 140bb4cb1b0Sjsing free(keypair); 141bb4cb1b0Sjsing } 142bb4cb1b0Sjsing 143bb4cb1b0Sjsing int 144bb4cb1b0Sjsing tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error, 145bb4cb1b0Sjsing X509 **cert) 146bb4cb1b0Sjsing { 147bb4cb1b0Sjsing char *errstr = "unknown"; 148bb4cb1b0Sjsing BIO *cert_bio = NULL; 149bb4cb1b0Sjsing int ssl_err; 150bb4cb1b0Sjsing int rv = -1; 151bb4cb1b0Sjsing 152bb4cb1b0Sjsing X509_free(*cert); 153bb4cb1b0Sjsing *cert = NULL; 154bb4cb1b0Sjsing 155bb4cb1b0Sjsing if (keypair->cert_mem == NULL) { 156bb4cb1b0Sjsing tls_error_set(error, "keypair has no certificate"); 157bb4cb1b0Sjsing goto err; 158bb4cb1b0Sjsing } 159bb4cb1b0Sjsing if ((cert_bio = BIO_new_mem_buf(keypair->cert_mem, 160bb4cb1b0Sjsing keypair->cert_len)) == NULL) { 161bb4cb1b0Sjsing tls_error_set(error, "failed to create certificate bio"); 162bb4cb1b0Sjsing goto err; 163bb4cb1b0Sjsing } 164bb4cb1b0Sjsing if ((*cert = PEM_read_bio_X509(cert_bio, NULL, tls_password_cb, 165bb4cb1b0Sjsing NULL)) == NULL) { 166bb4cb1b0Sjsing if ((ssl_err = ERR_peek_error()) != 0) 167bb4cb1b0Sjsing errstr = ERR_error_string(ssl_err, NULL); 168bb4cb1b0Sjsing tls_error_set(error, "failed to load certificate: %s", errstr); 169bb4cb1b0Sjsing goto err; 170bb4cb1b0Sjsing } 171bb4cb1b0Sjsing 172bb4cb1b0Sjsing rv = 0; 173bb4cb1b0Sjsing 174bb4cb1b0Sjsing err: 175bb4cb1b0Sjsing BIO_free(cert_bio); 176bb4cb1b0Sjsing 177bb4cb1b0Sjsing return (rv); 178bb4cb1b0Sjsing } 179