char *cacertpath;
gnutls_x509_crt_t *cacerts;
unsigned int ncacerts;
+
+ char *certpath;
+ char *keypath;
+ gnutls_x509_crt_t *certs;
+ unsigned int ncerts;
+ gnutls_x509_privkey_t key;
};
static QCryptoTLSCredsX509Files *
}
g_free(files->cacerts);
g_free(files->cacertpath);
+ for (i = 0; i < files->ncerts; i++) {
+ gnutls_x509_crt_deinit(files->certs[i]);
+ }
+ gnutls_x509_privkey_deinit(files->key);
+ g_free(files->certs);
+ g_free(files->certpath);
+ g_free(files->keypath);
g_free(files);
}
const char *certFile,
gnutls_x509_crt_t **certs,
unsigned int *ncerts,
- bool isServer,
- bool isCA,
Error **errp)
{
gnutls_datum_t data;
g_autofree char *buf = NULL;
gsize buflen;
GError *gerr = NULL;
+ int ret;
*ncerts = 0;
trace_qcrypto_tls_creds_x509_load_cert_list(creds, certFile);
data.data = (unsigned char *)buf;
data.size = strlen(buf);
- if (gnutls_x509_crt_list_import2(certs, ncerts, &data,
- GNUTLS_X509_FMT_PEM, 0) < 0) {
- error_setg(errp,
- isCA ? "Unable to import CA certificate list %s" :
- (isServer ? "Unable to import server certificate %s" :
- "Unable to import client certificate %s"),
- certFile);
+ ret = gnutls_x509_crt_list_import2(certs, ncerts, &data,
+ GNUTLS_X509_FMT_PEM, 0);
+ if (ret < 0) {
+ error_setg(errp, "Unable to import certificate %s: %s",
+ certFile, gnutls_strerror(ret));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+qcrypto_tls_creds_load_privkey(QCryptoTLSCredsX509 *creds,
+ const char *keyFile,
+ gnutls_x509_privkey_t *key,
+ Error **errp)
+{
+ gnutls_datum_t data;
+ g_autofree char *buf = NULL;
+ g_autofree char *password = NULL;
+ gsize buflen;
+ GError *gerr = NULL;
+ int ret;
+
+ ret = gnutls_x509_privkey_init(key);
+ if (ret < 0) {
+ error_setg(errp, "Unable to initialize private key: %s",
+ gnutls_strerror(ret));
+ return -1;
+ }
+
+ if (!g_file_get_contents(keyFile, &buf, &buflen, &gerr)) {
+ error_setg(errp, "Cannot load private key %s: %s",
+ keyFile, gerr->message);
+ g_error_free(gerr);
+ return -1;
+ }
+
+ data.data = (unsigned char *)buf;
+ data.size = strlen(buf);
+
+ if (creds->passwordid) {
+ password = qcrypto_secret_lookup_as_utf8(creds->passwordid,
+ errp);
+ if (!password) {
+ return -1;
+ }
+ }
+
+ if (gnutls_x509_privkey_import2(*key, &data,
+ GNUTLS_X509_FMT_PEM,
+ password, 0) < 0) {
+ error_setg(errp, "Unable to import private key %s", keyFile);
return -1;
}
qcrypto_tls_creds_x509_sanity_check(QCryptoTLSCredsX509 *creds,
QCryptoTLSCredsX509Files *files,
bool isServer,
- const char *certFile,
Error **errp)
{
- gnutls_x509_crt_t *certs = NULL;
- unsigned int ncerts = 0;
size_t i;
- int ret = -1;
-
- if (certFile) {
- if (qcrypto_tls_creds_load_cert_list(creds,
- certFile,
- &certs,
- &ncerts,
- isServer,
- false,
- errp) < 0) {
- goto cleanup;
- }
- }
- for (i = 0; i < ncerts; i++) {
+ for (i = 0; i < files->ncerts; i++) {
if (qcrypto_tls_creds_check_cert(creds,
- certs[i], certFile,
+ files->certs[i], files->certpath,
isServer, i != 0, errp) < 0) {
- goto cleanup;
+ return -1;
}
}
- if (ncerts &&
+ if (files->ncerts &&
qcrypto_tls_creds_check_authority_chain(creds, files,
- certs, ncerts,
+ files->certs, files->ncerts,
isServer, errp) < 0) {
- goto cleanup;
- }
-
- if (ncerts &&
- qcrypto_tls_creds_check_cert_pair(files, certs, ncerts, certFile,
- isServer, errp) < 0) {
- goto cleanup;
+ return -1;
}
- ret = 0;
-
- cleanup:
- for (i = 0; i < ncerts; i++) {
- gnutls_x509_crt_deinit(certs[i]);
+ if (files->ncerts &&
+ qcrypto_tls_creds_check_cert_pair(files,
+ files->certs, files->ncerts,
+ files->certpath, isServer,
+ errp) < 0) {
+ return -1;
}
- g_free(certs);
- return ret;
+ return 0;
}
files->cacertpath,
&files->cacerts,
&files->ncacerts,
- isServer,
- true,
errp) < 0) {
return -1;
}
return 0;
}
+
+static int
+qcrypto_tls_creds_x509_load_identity(QCryptoTLSCredsX509 *creds,
+ QCryptoTLSCredsBox *box,
+ QCryptoTLSCredsX509Files *files,
+ bool isServer,
+ Error **errp)
+{
+ int ret;
+
+ if (isServer) {
+ if (qcrypto_tls_creds_get_path(&creds->parent_obj,
+ QCRYPTO_TLS_CREDS_X509_SERVER_CERT,
+ true, &files->certpath, errp) < 0 ||
+ qcrypto_tls_creds_get_path(&creds->parent_obj,
+ QCRYPTO_TLS_CREDS_X509_SERVER_KEY,
+ true, &files->keypath, errp) < 0) {
+ return -1;
+ }
+ } else {
+ if (qcrypto_tls_creds_get_path(&creds->parent_obj,
+ QCRYPTO_TLS_CREDS_X509_CLIENT_CERT,
+ false, &files->certpath, errp) < 0 ||
+ qcrypto_tls_creds_get_path(&creds->parent_obj,
+ QCRYPTO_TLS_CREDS_X509_CLIENT_KEY,
+ false, &files->keypath, errp) < 0) {
+ return -1;
+ }
+ }
+
+ if (!files->certpath &&
+ !files->keypath) {
+ return 0;
+ }
+ if (files->certpath && !files->keypath) {
+ error_setg(errp, "Cert '%s' without corresponding key",
+ files->certpath);
+ return -1;
+ }
+ if (!files->certpath && files->keypath) {
+ error_setg(errp, "Key '%s' without corresponding cert",
+ files->keypath);
+ return -1;
+ }
+
+ if (qcrypto_tls_creds_load_cert_list(creds,
+ files->certpath,
+ &files->certs,
+ &files->ncerts,
+ errp) < 0) {
+ return -1;
+ }
+
+ if (qcrypto_tls_creds_load_privkey(creds,
+ files->keypath,
+ &files->key,
+ errp) < 0) {
+ return -1;
+ }
+
+ ret = gnutls_certificate_set_x509_key(box->data.cert,
+ files->certs,
+ files->ncerts,
+ files->key);
+ if (ret < 0) {
+ error_setg(errp, "Cannot set certificate '%s' & key '%s': %s",
+ files->certpath, files->keypath, gnutls_strerror(ret));
+ return -1;
+ }
+ return 0;
+}
+
+
static int
qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
Error **errp)
g_autoptr(QCryptoTLSCredsBox) box = NULL;
g_autoptr(QCryptoTLSCredsX509Files) files = NULL;
g_autofree char *cacrl = NULL;
- g_autofree char *cert = NULL;
- g_autofree char *key = NULL;
g_autofree char *dhparams = NULL;
bool isServer = (creds->parent_obj.endpoint ==
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER);
return -1;
}
+ if (qcrypto_tls_creds_x509_load_identity(creds, box, files,
+ isServer, errp) < 0) {
+ return -1;
+ }
+
if (isServer) {
if (qcrypto_tls_creds_get_path(&creds->parent_obj,
QCRYPTO_TLS_CREDS_X509_CA_CRL,
false, &cacrl, errp) < 0 ||
- qcrypto_tls_creds_get_path(&creds->parent_obj,
- QCRYPTO_TLS_CREDS_X509_SERVER_CERT,
- true, &cert, errp) < 0 ||
- qcrypto_tls_creds_get_path(&creds->parent_obj,
- QCRYPTO_TLS_CREDS_X509_SERVER_KEY,
- true, &key, errp) < 0 ||
qcrypto_tls_creds_get_path(&creds->parent_obj,
QCRYPTO_TLS_CREDS_DH_PARAMS,
false, &dhparams, errp) < 0) {
return -1;
}
- } else {
- if (qcrypto_tls_creds_get_path(&creds->parent_obj,
- QCRYPTO_TLS_CREDS_X509_CLIENT_CERT,
- false, &cert, errp) < 0 ||
- qcrypto_tls_creds_get_path(&creds->parent_obj,
- QCRYPTO_TLS_CREDS_X509_CLIENT_KEY,
- false, &key, errp) < 0) {
- return -1;
- }
}
if (creds->sanityCheck &&
- qcrypto_tls_creds_x509_sanity_check(creds, files, isServer,
- cert, errp) < 0) {
+ qcrypto_tls_creds_x509_sanity_check(creds, files, isServer, errp) < 0) {
return -1;
}
- if (cert != NULL && key != NULL) {
- g_autofree char *password = NULL;
- if (creds->passwordid) {
- password = qcrypto_secret_lookup_as_utf8(creds->passwordid,
- errp);
- if (!password) {
- return -1;
- }
- }
- ret = gnutls_certificate_set_x509_key_file2(box->data.cert,
- cert, key,
- GNUTLS_X509_FMT_PEM,
- password,
- 0);
- if (ret < 0) {
- error_setg(errp, "Cannot load certificate '%s' & key '%s': %s",
- cert, key, gnutls_strerror(ret));
- return -1;
- }
- }
-
if (cacrl != NULL) {
ret = gnutls_certificate_set_x509_crl_file(box->data.cert,
cacrl,