/** * gnutls_rsa_params_import_pkcs1 - This function will import RSA params from a pkcs1 structure * @params: A structure where the parameters will be copied to * @pkcs1_params: should contain a PKCS1 RSAPublicKey structure PEM or DER encoded * @format: the format of params. PEM or DER. * * This function will extract the RSAPublicKey found in a PKCS1 formatted * structure. * * If the structure is PEM encoded, it should have a header * of "BEGIN RSA PRIVATE KEY". * * In case of failure a negative value will be returned, and * 0 on success. * **/ int gnutls_rsa_params_import_pkcs1 (gnutls_rsa_params_t params, const gnutls_datum_t * pkcs1_params, gnutls_x509_crt_fmt_t format) { return gnutls_x509_privkey_import (params, pkcs1_params, format); }
void SslContext::setKeyFile(const std::string& filename) { if (error_) return; if (!enabled) return; TRACE("SslContext::setKeyFile: \"%s\"", filename.c_str()); gnutls_datum_t data; if ((error_ = loadFile(data, filename))) { log(x0::Severity::error, "Error loading private key file(%s): %s", filename.c_str(), error_.message().c_str()); return; } int rv; if ((rv = gnutls_x509_privkey_init(&x509PrivateKey_)) < 0) { freeFile(data); return; } if ((rv = gnutls_x509_privkey_import(x509PrivateKey_, &data, GNUTLS_X509_FMT_PEM)) < 0) { TRACE("setKeyFile: failed to import key as x509-fmt-pem. trying pkcs-plain."); rv = gnutls_x509_privkey_import_pkcs8(x509PrivateKey_, &data, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN); } if (rv < 0) { log(x0::Severity::error, "Error loading private key file(%s): %s", filename.c_str(), gnutls_strerror(rv)); freeFile(data); return; } freeFile(data); TRACE("setKeyFile: success."); }
/** * FIXME Replace this with a tls_load_key function and use it * in tls_connection_create. * * Most probably we only need one context and key for all connections */ int tls_check_keyfile(const char *keyfile) { gnutls_x509_privkey_t key; gnutls_datum_t keycontent = { NULL, 0 }; FILE *keyfp; size_t br; SSL_library_init(); OpenSSL_add_all_algorithms(); if (access(capture_get_keyfile(), R_OK) != 0) return 0; if (!(keyfp = fopen(capture_get_keyfile(), "rb"))) return 0; fseek(keyfp, 0, SEEK_END); keycontent.size = ftell(keyfp); fseek(keyfp, 0, SEEK_SET); keycontent.data = sng_malloc(keycontent.size); br = fread(keycontent.data, 1, keycontent.size, keyfp); fclose(keyfp); gnutls_x509_privkey_init(&key); if (gnutls_x509_privkey_import(key, &keycontent, GNUTLS_X509_FMT_PEM) < 0) return 0; sng_free(keycontent.data); return 1; }
gnutls_x509_privkey tls_load_privkey(requiem_client_profile_t *cp) { int ret; size_t size; gnutls_datum data; char filename[256]; gnutls_x509_privkey key; requiem_client_profile_get_tls_key_filename(cp, filename, sizeof(filename)); ret = access(filename, F_OK); if ( ret < 0 ) return gen_crypto(cp, filename, requiem_client_profile_get_uid(cp), requiem_client_profile_get_gid(cp)); ret = _requiem_load_file(filename, &data.data, &size); if ( ret < 0 ) { fprintf(stderr, "could not load '%s': %s.\n", filename, requiem_strerror(ret)); return NULL; } data.size = (unsigned int) size; gnutls_x509_privkey_init(&key); gnutls_x509_privkey_import(key, &data, GNUTLS_X509_FMT_PEM); _requiem_unload_file(data.data, size); return key; }
int mailstream_ssl_set_client_private_key_data(struct mailstream_ssl_context * ssl_context, unsigned char *pkey_der, size_t len) { #ifdef USE_SSL #ifndef USE_GNUTLS EVP_PKEY *pkey = NULL; if (pkey_der != NULL && len > 0) pkey = d2i_AutoPrivateKey(NULL, (const unsigned char **)&pkey_der, len); ssl_context->client_pkey = (EVP_PKEY *)pkey; return 0; #else gnutls_datum tmp; int r; ssl_context->client_pkey = NULL; if (len == 0) return 0; gnutls_x509_privkey_init(&(ssl_context->client_pkey)); tmp.data = pkey_der; tmp.size = len; if ((r = gnutls_x509_privkey_import(ssl_context->client_pkey, &tmp, GNUTLS_X509_FMT_DER)) < 0) { gnutls_x509_privkey_deinit(ssl_context->client_pkey); ssl_context->client_pkey = NULL; return -1; } return 0; #endif #endif return -1; }
/*- * gnutls_x509_extract_key_pk_algorithm - This function returns the keys's PublicKey algorithm * @cert: is a DER encoded private key * * This function will return the public key algorithm of a DER encoded private * key. * * Returns a member of the gnutls_pk_algorithm_t enumeration on success, * or GNUTLS_E_UNKNOWN_PK_ALGORITHM on error. * -*/ int gnutls_x509_extract_key_pk_algorithm (const gnutls_datum_t * key) { gnutls_x509_privkey_t pkey; int ret, pk; ret = gnutls_x509_privkey_init (&pkey); if (ret < 0) { gnutls_assert (); return ret; } ret = gnutls_x509_privkey_import (pkey, key, GNUTLS_X509_FMT_DER); if (ret < 0) { gnutls_assert (); return ret; } pk = gnutls_x509_privkey_get_pk_algorithm (pkey); gnutls_x509_privkey_deinit (pkey); return pk; }
void doit (void) { gnutls_x509_privkey_t key; gnutls_x509_crt_t crt; gnutls_digest_algorithm_t hash_algo; unsigned char _signature[128]; size_t _signature_size = sizeof (_signature); gnutls_datum signature; int ret; size_t i; gnutls_global_init (); for (i = 0; i < sizeof (key_dat) / sizeof (key_dat[0]); i++) { success ("loop %d\n", i); ret = gnutls_x509_privkey_init (&key); if (ret < 0) fail ("gnutls_x509_privkey_init\n"); ret = gnutls_x509_privkey_import (key, &key_dat[i], GNUTLS_X509_FMT_PEM); if (ret < 0) fail ("gnutls_x509_privkey_import\n"); ret = gnutls_x509_privkey_sign_data (key, GNUTLS_DIG_SHA1, 0, &raw_data, _signature, &_signature_size); if (ret < 0) fail ("gnutls_x509_privkey_sign_hash\n"); ret = gnutls_x509_crt_init (&crt); if (ret < 0) fail ("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_import (crt, &cert_dat[i], GNUTLS_X509_FMT_PEM); if (ret < 0) fail ("gnutls_x509_crt_import\n"); signature.data = _signature; signature.size = _signature_size; ret = gnutls_x509_crt_get_verify_algorithm (crt, &signature, &hash_algo); if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1) fail ("gnutls_x509_crt_get_verify_algorithm\n"); ret = gnutls_x509_crt_verify_hash (crt, 0, &hash_data, &signature); if (ret < 0) fail ("gnutls_x509_privkey_verify_hash\n"); gnutls_x509_privkey_deinit (key); gnutls_x509_crt_deinit (crt); } gnutls_global_deinit (); }
static int import_key(gnutls_certificate_credentials_t xcred, const gnutls_datum_t *skey, const gnutls_datum_t *cert) { gnutls_x509_privkey_t key; gnutls_x509_crt_t *crt_list; unsigned crt_list_size, idx, i; gnutls_datum_t tcert; int ret; assert(gnutls_x509_privkey_init(&key)>=0); ret = gnutls_x509_crt_list_import2(&crt_list, &crt_list_size, cert, GNUTLS_X509_FMT_PEM, 0); if (ret < 0) { fail("error in gnutls_x509_crt_list_import2: %s\n", gnutls_strerror(ret)); } ret = gnutls_x509_privkey_import(key, skey, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("error in key import: %s\n", gnutls_strerror(ret)); } ret = gnutls_certificate_set_x509_key(xcred, crt_list, crt_list_size, key); if (ret < 0) { success("error in gnutls_certificate_set_x509_key: %s\n", gnutls_strerror(ret)); idx = ret; goto cleanup; } /* return index */ idx = ret; /* verify whether the stored certificate match the ones we have */ for (i=0;i<MIN(2, crt_list_size);i++) { ret = gnutls_certificate_get_crt_raw(xcred, idx, i, &tcert); if (ret < 0) { fail("error in %d: cert: %d: %s\n", __LINE__, i, gnutls_strerror(ret)); exit(1); } compare(&tcert, cert->data+i); } cleanup: gnutls_x509_privkey_deinit(key); for (i=0;i<crt_list_size;i++) { gnutls_x509_crt_deinit(crt_list[i]); } gnutls_free(crt_list); return idx; }
static gchar* _make_rsasha1_base64_signature(const gchar* base_string, const gchar* key) { gnutls_privkey_t pkey; gnutls_x509_privkey_t x509_pkey; gnutls_datum_t pkey_data; gnutls_datum_t signature; gchar* out = NULL; pkey_data.data = (guchar*)key; pkey_data.size = strlen(key); gnutls_privkey_init(&pkey); gnutls_x509_privkey_init(&x509_pkey); int res = gnutls_x509_privkey_import(x509_pkey, &pkey_data, GNUTLS_X509_FMT_PEM); if (res != GNUTLS_E_SUCCESS) { goto out; } res = gnutls_privkey_import_x509(pkey, x509_pkey, 0); if (res != GNUTLS_E_SUCCESS) { goto out; } res = gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, &pkey_data, &signature); if (res != GNUTLS_E_SUCCESS) { goto out; } out = g_malloc0((signature.size / 3 + 1) * 4 + 4); gint state = 0; gint save = 0; gchar* p = out; p += g_base64_encode_step(signature.data, signature.size, FALSE, p, &state, &save); g_base64_encode_close(FALSE, p, &state, &save); gnutls_free(signature.data); out: gnutls_x509_privkey_deinit(x509_pkey); gnutls_privkey_deinit(pkey); return out; }
/** * gnutls_x509_privkey_import2: * @key: The structure to store the parsed key * @data: The DER or PEM encoded key. * @format: One of DER or PEM * @password: A password (optional) * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t * * This function will import the given DER or PEM encoded key, to * the native #gnutls_x509_privkey_t format, irrespective of the * input format. The input format is auto-detected. * * The supported formats are basic unencrypted key, PKCS8, PKCS12, * and the openssl format. * * If the provided key is encrypted but no password was given, then * %GNUTLS_E_DECRYPTION_FAILED is returned. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_import2(gnutls_x509_privkey_t key, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format, const char *password, unsigned int flags) { int ret = 0; if (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) { ret = gnutls_x509_privkey_import(key, data, format); if (ret < 0) { gnutls_assert(); } } if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD)) || ret < 0) { ret = gnutls_x509_privkey_import_pkcs8(key, data, format, password, flags); if (ret < 0) { if (ret == GNUTLS_E_DECRYPTION_FAILED) goto cleanup; ret = import_pkcs12_privkey(key, data, format, password, flags); if (ret < 0 && format == GNUTLS_X509_FMT_PEM) { if (ret == GNUTLS_E_DECRYPTION_FAILED) goto cleanup; ret = gnutls_x509_privkey_import_openssl(key, data, password); if (ret < 0) { gnutls_assert(); goto cleanup; } } else { gnutls_assert(); goto cleanup; } } } ret = 0; cleanup: return ret; }
/** Private function which import the given key into a gnutls structure. * * @param key_name The filename of the private key to import. * @param key the gnutls key structure. * * @return 1 if the key was successfully imported. */ static userpref_error_t userpref_import_key(const char* key_name, gnutls_x509_privkey_t key) { userpref_error_t ret = USERPREF_E_INVALID_CONF; gnutls_datum_t pem_key = { NULL, 0 }; if (userpref_get_file_contents(key_name, &pem_key)) { if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM)) ret = USERPREF_E_SUCCESS; else ret = USERPREF_E_SSL_ERROR; } gnutls_free(pem_key.data); return ret; }
/* Load the private key. * @mand should be non zero if it is required to read a private key. */ gnutls_x509_privkey_t load_x509_private_key (int mand, common_info_st * info) { gnutls_x509_privkey_t key; int ret; gnutls_datum_t dat; size_t size; if (!info->privkey && !mand) return NULL; if (info->privkey == NULL) error (EXIT_FAILURE, 0, "missing --load-privkey"); ret = gnutls_x509_privkey_init (&key); if (ret < 0) error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); dat.data = read_binary_file (info->privkey, &size); dat.size = size; if (!dat.data) error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info->privkey); if (info->pkcs8) { const char *pass = get_pass (); ret = gnutls_x509_privkey_import_pkcs8 (key, &dat, info->incert_format, pass, 0); } else ret = gnutls_x509_privkey_import (key, &dat, info->incert_format); free (dat.data); if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { error (EXIT_FAILURE, 0, "import error: could not find a valid PEM header; " "check if your key is PKCS #8 or PKCS #12 encoded"); } if (ret < 0) error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s", info->privkey, gnutls_strerror (ret)); return key; }
void doit(void) { gnutls_dh_params_t dh_params; gnutls_x509_privkey_t privkey; gnutls_datum_t p1, g1, p2, g2, q; unsigned bits = 0; int ret; /* import DH parameters from DSA key and verify they are the same */ gnutls_dh_params_init(&dh_params); gnutls_x509_privkey_init(&privkey); ret = gnutls_x509_privkey_import(privkey, &dsa_key, GNUTLS_X509_FMT_PEM); if (ret < 0) fail("error in %s: %d\n", __FILE__, __LINE__); ret = gnutls_dh_params_import_dsa(dh_params, privkey); if (ret < 0) fail("error in %s: %d\n", __FILE__, __LINE__); ret = gnutls_dh_params_export_raw(dh_params, &p1, &g1, &bits); if (ret < 0) fail("error in %s: %d\n", __FILE__, __LINE__); ret = gnutls_x509_privkey_export_dsa_raw(privkey, &p2, &q, &g2, NULL, NULL); if (ret < 0) fail("error in %s: %d\n", __FILE__, __LINE__); if (bits > q.size*8 || bits < q.size*8-8) fail("error in %s: %d\n", __FILE__, __LINE__); if (compare(&p1, &p2) != 0) fail("error in %s: %d\n", __FILE__, __LINE__); if (compare(&g1, &g2) != 0) fail("error in %s: %d\n", __FILE__, __LINE__); gnutls_free(p1.data); gnutls_free(g1.data); gnutls_free(p2.data); gnutls_free(g2.data); gnutls_free(q.data); gnutls_dh_params_deinit(dh_params); gnutls_x509_privkey_deinit(privkey); success("all ok\n"); }
struct SSLConnection * tls_connection_create(struct in_addr caddr, uint16_t cport, struct in_addr saddr, uint16_t sport) { struct SSLConnection *conn = NULL; gnutls_datum_t keycontent = { NULL, 0 }; FILE *keyfp; gnutls_x509_privkey_t spkey; size_t br; // Allocate memory for this connection conn = sng_malloc(sizeof(struct SSLConnection)); memcpy(&conn->client_addr, &caddr, sizeof(struct in_addr)); memcpy(&conn->server_addr, &saddr, sizeof(struct in_addr)); memcpy(&conn->client_port, &cport, sizeof(uint16_t)); memcpy(&conn->server_port, &sport, sizeof(uint16_t)); SSL_library_init(); OpenSSL_add_all_algorithms(); if (!(conn->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) return NULL; if (!(conn->ssl = SSL_new(conn->ssl_ctx))) return NULL; if (!(keyfp = fopen(capture_get_keyfile(), "rb"))) return NULL; fseek(keyfp, 0, SEEK_END); keycontent.size = ftell(keyfp); fseek(keyfp, 0, SEEK_SET); keycontent.data = sng_malloc(keycontent.size); br = fread(keycontent.data, 1, keycontent.size, keyfp); fclose(keyfp); gnutls_x509_privkey_init(&spkey); gnutls_x509_privkey_import(spkey, &keycontent, GNUTLS_X509_FMT_PEM); sng_free(keycontent.data); gnutls_privkey_init(&conn->server_private_key); gnutls_privkey_import_x509(conn->server_private_key, spkey, 0); // Add this connection to the list conn->next = connections; connections = conn; return conn; }
static int import_Key(QWidget * w, gnutls_x509_privkey_t * privkey, gnutls_datum_t * raw) { int ret; if (raw->size == 0) return -1; gnutls_x509_privkey_init(privkey); ret = gnutls_x509_privkey_import2(*privkey, raw, GNUTLS_X509_FMT_PEM, NULL, 0); if (ret == GNUTLS_E_DECRYPTION_FAILED && w != NULL) { bool ok; QString text; text = QInputDialog::getText(w, QLatin1String ("This file requires a password"), QLatin1String("Please enter your password"), QLineEdit::Password, QString(), &ok); if (!ok) { ret = -1; goto fail; } ret = gnutls_x509_privkey_import2(*privkey, raw, GNUTLS_X509_FMT_PEM, text.toAscii().data(), 0); } if (ret == GNUTLS_E_BASE64_DECODING_ERROR || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) ret = gnutls_x509_privkey_import(*privkey, raw, GNUTLS_X509_FMT_DER); if (ret < 0) { goto fail; } return 0; fail: gnutls_x509_privkey_deinit(*privkey); *privkey = NULL; return ret; }
/* Load the certificate and the private key. */ static void load_keys (void) { int ret; gnutls_datum_t data; data = load_file (CERT_FILE); if (data.data == NULL) { fprintf (stderr, "*** Error loading cert file.\n"); exit (1); } gnutls_x509_crt_init (&crt); ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf (stderr, "*** Error loading key file: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (data); data = load_file (KEY_FILE); if (data.data == NULL) { fprintf (stderr, "*** Error loading key file.\n"); exit (1); } gnutls_x509_privkey_init (&key); ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf (stderr, "*** Error loading key file: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (data); }
int _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey, const gnutls_datum_t * raw_key, gnutls_x509_crt_fmt_t type) { gnutls_x509_privkey_t tmpkey; int ret; ret = gnutls_x509_privkey_init (&tmpkey); if (ret < 0) { gnutls_assert (); return ret; } ret = gnutls_x509_privkey_import (tmpkey, raw_key, type); #ifdef ENABLE_PKI /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */ if (ret < 0) ret = gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type, NULL, GNUTLS_PKCS_PLAIN); #endif if (ret < 0) { gnutls_assert (); gnutls_x509_privkey_deinit (tmpkey); return ret; } ret = _gnutls_x509_privkey_to_gkey (privkey, tmpkey); if (ret < 0) { gnutls_assert (); gnutls_x509_privkey_deinit (tmpkey); return ret; } gnutls_x509_privkey_deinit (tmpkey); return 0; }
static gnutls_privkey_t _load_privkey(gnutls_datum_t *dat, common_info_st * info) { int ret; gnutls_privkey_t key; gnutls_x509_privkey_t xkey; ret = gnutls_x509_privkey_init (&xkey); if (ret < 0) error (EXIT_FAILURE, 0, "x509_privkey_init: %s", gnutls_strerror (ret)); ret = gnutls_privkey_init (&key); if (ret < 0) error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); if (info->pkcs8) { const char *pass = get_pass (); ret = gnutls_x509_privkey_import_pkcs8 (xkey, dat, info->incert_format, pass, 0); } else ret = gnutls_x509_privkey_import (xkey, dat, info->incert_format); if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { error (EXIT_FAILURE, 0, "import error: could not find a valid PEM header; " "check if your key is PKCS #8 or PKCS #12 encoded"); } if (ret < 0) error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s", info->privkey, gnutls_strerror (ret)); ret = gnutls_privkey_import_x509(key, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_privkey_import_x509: %s", gnutls_strerror (ret)); return key; }
static int import_dsa_dh(gnutls_dh_params_t dh_params, gnutls_datum_t *params, gnutls_x509_crt_fmt_t format) { gnutls_x509_privkey_t pkey; int ret; ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) return ret; ret = gnutls_x509_privkey_import(pkey, params, format); if (ret < 0) return ret; ret = gnutls_dh_params_import_dsa(dh_params, pkey); gnutls_x509_privkey_deinit(pkey); return ret; }
/** * epc_tls_private_key_load: * @filename: name of a file to read the key from, in the GLib file name encoding * @error: return location for a #GError, or %NULL * * Reads a PEM encoded private X.509 key. * * If the call was successful, the newly created private key object is * returned. This key can be used with functions of the <citetitle>GNU * TLS</citetitle> library. If the call was not successful, it returns %NULL * and sets @error. The error domain is #EPC_TLS_ERROR. Error codes are taken * from the <citetitle>GNU TLS</citetitle> library. * * Returns: The newly created key object, or %NULL. */ gnutls_x509_privkey_t epc_tls_private_key_load (const gchar *filename, GError **error) { gnutls_x509_privkey_t key = NULL; gint rc = GNUTLS_E_SUCCESS; gchar *contents = NULL; gnutls_datum_t buffer; g_return_val_if_fail (NULL != filename, NULL); if (g_file_get_contents (filename, &contents, (gsize*) &buffer.size, error)) { if (EPC_DEBUG_LEVEL (1)) g_debug ("%s: Loading private key `%s'", G_STRLOC, filename); buffer.data = (guchar*) contents; epc_tls_check (rc = gnutls_x509_privkey_init (&key)); epc_tls_check (rc = gnutls_x509_privkey_import (key, &buffer, GNUTLS_X509_FMT_PEM)); } out: if (GNUTLS_E_SUCCESS != rc) { g_set_error (error, EPC_TLS_ERROR, rc, _("Cannot import private server key '%s': %s"), filename, gnutls_strerror (rc)); if (key) gnutls_x509_privkey_deinit (key); key = NULL; } g_free (contents); return key; }
/* Load the certificate and the private key. */ static void load_keys (void) { unsigned int crt_num; int ret; gnutls_datum_t data; if (x509_certfile != NULL && x509_keyfile != NULL) { data = load_file (x509_certfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading cert file.\n"); exit (1); } crt_num = MAX_CRT; ret = gnutls_x509_crt_list_import (x509_crt, &crt_num, &data, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); if (ret < 0) { if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { fprintf (stderr, "*** Error loading cert file: Too many certs %d\n", crt_num); } else { fprintf (stderr, "*** Error loading cert file: %s\n", gnutls_strerror (ret)); } exit (1); } x509_crt_size = ret; fprintf (stderr, "Processed %d client certificates...\n", ret); unload_file (data); data = load_file (x509_keyfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading key file.\n"); exit (1); } gnutls_x509_privkey_init (&x509_key); ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf (stderr, "*** Error loading key file: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (data); fprintf (stderr, "Processed %d client X.509 certificates...\n", x509_crt_size); } #ifdef ENABLE_OPENPGP if (pgp_certfile != NULL && pgp_keyfile != NULL) { data = load_file (pgp_certfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading PGP cert file.\n"); exit (1); } gnutls_openpgp_crt_init (&pgp_crt); ret = gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64); if (ret < 0) { fprintf (stderr, "*** Error loading PGP cert file: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (data); data = load_file (pgp_keyfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading PGP key file.\n"); exit (1); } gnutls_openpgp_privkey_init (&pgp_key); ret = gnutls_openpgp_privkey_import (pgp_key, &data, GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); if (ret < 0) { fprintf (stderr, "*** Error loading PGP key file: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (data); if (info.pgp_subkey != NULL) { gnutls_openpgp_keyid_t keyid; if (strcasecmp (info.pgp_subkey, "auto") == 0) { ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1); if (ret < 0) { fprintf (stderr, "*** Error setting preferred sub key id (%s): %s\n", info.pgp_subkey, gnutls_strerror (ret)); exit (1); } } else get_keyid (keyid, info.pgp_subkey); ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid); if (ret >= 0) ret = gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid); if (ret < 0) { fprintf (stderr, "*** Error setting preferred sub key id (%s): %s\n", info.pgp_subkey, gnutls_strerror (ret)); exit (1); } } fprintf (stderr, "Processed 1 client PGP certificate...\n"); } #endif }
void doit(void) { gnutls_x509_privkey_t pkey; gnutls_x509_crt_t crt; gnutls_x509_crt_t crt2; const char *err = NULL; gnutls_datum_t out; size_t s = 0; int ret; ret = global_init(); if (ret < 0) fail("global_init\n"); gnutls_global_set_time_function(mytime); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); ret = gnutls_x509_crt_init(&crt); if (ret != 0) fail("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_init(&crt2); if (ret != 0) fail("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM); if (ret != 0) fail("gnutls_x509_crt_import\n"); ret = gnutls_x509_privkey_init(&pkey); if (ret != 0) fail("gnutls_x509_privkey_init\n"); ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM); if (ret != 0) fail("gnutls_x509_privkey_import\n"); /* Setup CRT */ ret = gnutls_x509_crt_set_version(crt, 3); if (ret != 0) fail("gnutls_x509_crt_set_version\n"); ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3); if (ret != 0) fail("gnutls_x509_crt_set_serial\n"); ret = gnutls_x509_crt_set_expiration_time(crt, -1); if (ret != 0) fail("error\n"); ret = gnutls_x509_crt_set_activation_time(crt, mytime(0)); if (ret != 0) fail("error\n"); ret = gnutls_x509_crt_set_key(crt, pkey); if (ret != 0) fail("gnutls_x509_crt_set_key\n"); ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1); if (ret < 0) { fail("error\n"); } ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE); if (ret != 0) fail("gnutls_x509_crt_set_key_usage %d\n", ret); ret = gnutls_x509_crt_set_dn(crt, "o = none to\\, mention,cn = nikos", &err); if (ret < 0) { fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err); } ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "foo", 3, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "*****@*****.**", strlen("*****@*****.**"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "ινβάλιντ@bar.org", strlen("ινβάλιντ@bar.org"), 1); if (ret != GNUTLS_E_INVALID_UTF8_EMAIL) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS, "\xc1\x5c\x96\x3", 4, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "apa", 3, 0); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "απαλό.com", strlen("απαλό.com"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); #ifdef HAVE_LIBIDN ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "test@νίκο.org", strlen("test@νίκο.org"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); #endif s = 0; ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); if (ret != 0) fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_CLIENT, 1); if (ret != 0) fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret); ret = gnutls_x509_crt_set_issuer_dn(crt, "cn = my CA, o = big\\, and one", &err); if (ret < 0) { fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err); } ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0); if (ret < 0) fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret)); ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out); if (ret != 0) fail("gnutls_x509_crt_print\n"); if (debug) printf("crt: %.*s\n", out.size, out.data); gnutls_free(out.data); s = 0; ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret)); s = 0; ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s); if (ret != 0) fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret)); ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out); if (ret < 0 || out.size == 0) fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret)); if (out.size != 45 || memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) { hexprint(out.data, out.size); fail("issuer DN comparison failed\n"); } gnutls_free(out.data); ret = gnutls_x509_crt_get_raw_dn(crt, &out); if (ret < 0 || out.size == 0) fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret)); if (out.size != 45 || memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) { fail("DN comparison failed\n"); } gnutls_free(out.data); ret = gnutls_x509_crt_equals(crt, crt); if (ret == 0) { fail("equality test failed\n"); } ret = gnutls_x509_crt_equals(crt, crt2); if (ret != 0) { fail("equality test failed\n"); } assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0); #ifdef HAVE_LIBIDN assert(out.size == saved_crt.size); assert(memcmp(out.data, saved_crt.data, out.size)==0); #endif gnutls_free(out.data); gnutls_x509_crt_deinit(crt); gnutls_x509_crt_deinit(crt2); gnutls_x509_privkey_deinit(pkey); gnutls_global_deinit(); }
EAPI Eet_Key * eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb) { #ifdef HAVE_SIGNATURE /* Signature declarations */ Eet_Key *key = NULL; # ifdef HAVE_GNUTLS /* Gnutls private declarations */ Eina_File *f = NULL; void *data = NULL; gnutls_datum_t load_file = { NULL, 0 }; char pass[1024]; if (!emile_cipher_init()) return NULL; /* Init */ if (!(key = malloc(sizeof(Eet_Key)))) goto on_error; key->references = 1; if (gnutls_x509_crt_init(&(key->certificate))) goto on_error; if (gnutls_x509_privkey_init(&(key->private_key))) goto on_error; /* Mmap certificate_file */ f = eina_file_open(certificate_file, 0); if (!f) goto on_error; /* let's make mmap safe and just get 0 pages for IO erro */ eina_mmap_safety_enabled_set(EINA_TRUE); data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!data) goto on_error; /* Import the certificate in Eet_Key structure */ load_file.data = data; load_file.size = eina_file_size_get(f); if (gnutls_x509_crt_import(key->certificate, &load_file, GNUTLS_X509_FMT_PEM) < 0) goto on_error; eina_file_map_free(f, data); /* Reset values */ eina_file_close(f); f = NULL; data = NULL; load_file.data = NULL; load_file.size = 0; /* Mmap private_key_file */ f = eina_file_open(private_key_file, 0); if (!f) goto on_error; /* let's make mmap safe and just get 0 pages for IO erro */ eina_mmap_safety_enabled_set(EINA_TRUE); data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!data) goto on_error; /* Import the private key in Eet_Key structure */ load_file.data = data; load_file.size = eina_file_size_get(f); /* Try to directly import the PEM encoded private key */ if (gnutls_x509_privkey_import(key->private_key, &load_file, GNUTLS_X509_FMT_PEM) < 0) { /* Else ask for the private key pass */ if (cb && cb(pass, 1024, 0, NULL)) { /* If pass then try to decode the pkcs 8 private key */ if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file, GNUTLS_X509_FMT_PEM, pass, 0)) goto on_error; } else /* Else try to import the pkcs 8 private key without pass */ if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file, GNUTLS_X509_FMT_PEM, NULL, 1)) goto on_error; } eina_file_map_free(f, data); eina_file_close(f); return key; on_error: if (data) eina_file_map_free(f, data); if (f) eina_file_close(f); if (key) { if (key->certificate) gnutls_x509_crt_deinit(key->certificate); if (key->private_key) gnutls_x509_privkey_deinit(key->private_key); free(key); } # else /* ifdef HAVE_GNUTLS */ /* Openssl private declarations */ FILE *fp; EVP_PKEY *pkey = NULL; X509 *cert = NULL; if (!emile_cipher_init()) return NULL; /* Load the X509 certificate in memory. */ fp = fopen(certificate_file, "rb"); if (!fp) return NULL; cert = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); if (!cert) goto on_error; /* Check the presence of the public key. Just in case. */ pkey = X509_get_pubkey(cert); if (!pkey) goto on_error; /* Load the private key in memory. */ fp = fopen(private_key_file, "rb"); if (!fp) goto on_error; pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL); fclose(fp); if (!pkey) goto on_error; /* Load the certificate and the private key in Eet_Key structure */ key = malloc(sizeof(Eet_Key)); if (!key) goto on_error; key->references = 1; key->certificate = cert; key->private_key = pkey; return key; on_error: if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); # endif /* ifdef HAVE_GNUTLS */ #else (void) certificate_file; (void) private_key_file; (void) cb; #endif /* ifdef HAVE_SIGNATURE */ return NULL; }
/* Load the certificate and the private key. */ static void load_keys (void) { unsigned int crt_num; int ret, i; gnutls_datum_t data = { NULL, 0 }; gnutls_x509_crt_t crt_list[MAX_CRT]; #ifdef ENABLE_PKCS11 gnutls_pkcs11_privkey_t pkcs11_key; #endif gnutls_x509_privkey_t tmp_key; unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE]; if (x509_certfile != NULL && x509_keyfile != NULL) { #ifdef ENABLE_PKCS11 if (strncmp (x509_certfile, "pkcs11:", 7) == 0) { crt_num = 1; gnutls_x509_crt_init (&crt_list[0]); ret = gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) ret = gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, GNUTLS_PKCS11_OBJ_FLAG_LOGIN); if (ret < 0) { fprintf (stderr, "*** Error loading cert file.\n"); exit (1); } x509_crt_size = 1; } else #endif /* ENABLE_PKCS11 */ { data = load_file (x509_certfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading cert file.\n"); exit (1); } crt_num = MAX_CRT; ret = gnutls_x509_crt_list_import (crt_list, &crt_num, &data, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); if (ret < 0) { if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { fprintf (stderr, "*** Error loading cert file: Too many certs %d\n", crt_num); } else { fprintf (stderr, "*** Error loading cert file: %s\n", gnutls_strerror (ret)); } exit (1); } x509_crt_size = ret; } for (i=0;i<x509_crt_size;i++) { ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0); if (ret < 0) { fprintf(stderr, "*** Error importing crt to pcert: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt_list[i]); } unload_file (&data); ret = gnutls_privkey_init(&x509_key); if (ret < 0) { fprintf (stderr, "*** Error initializing key: %s\n", gnutls_strerror (ret)); exit (1); } #ifdef ENABLE_PKCS11 if (strncmp (x509_keyfile, "pkcs11:", 7) == 0) { gnutls_pkcs11_privkey_init (&pkcs11_key); ret = gnutls_pkcs11_privkey_import_url (pkcs11_key, x509_keyfile, 0); if (ret < 0) { fprintf (stderr, "*** Error loading url: %s\n", gnutls_strerror (ret)); exit (1); } ret = gnutls_privkey_import_pkcs11( x509_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); if (ret < 0) { fprintf (stderr, "*** Error loading url: %s\n", gnutls_strerror (ret)); exit (1); } } else #endif /* ENABLE_PKCS11 */ { data = load_file (x509_keyfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading key file.\n"); exit (1); } gnutls_x509_privkey_init (&tmp_key); ret = gnutls_x509_privkey_import (tmp_key, &data, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf (stderr, "*** Error loading key file: %s\n", gnutls_strerror (ret)); exit (1); } ret = gnutls_privkey_import_x509( x509_key, tmp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); if (ret < 0) { fprintf (stderr, "*** Error loading url: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (&data); } fprintf (stdout, "Processed %d client X.509 certificates...\n", x509_crt_size); } #ifdef ENABLE_OPENPGP if (info.pgp_subkey != NULL) { get_keyid (keyid, info.pgp_subkey); } if (pgp_certfile != NULL && pgp_keyfile != NULL) { gnutls_openpgp_crt_t tmp_pgp_crt; data = load_file (pgp_certfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading PGP cert file.\n"); exit (1); } gnutls_openpgp_crt_init (&tmp_pgp_crt); ret = gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64, info.pgp_subkey!=NULL?keyid:NULL, 0); if (ret < 0) { fprintf (stderr, "*** Error loading PGP cert file: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (&data); ret = gnutls_privkey_init(&pgp_key); if (ret < 0) { fprintf (stderr, "*** Error initializing key: %s\n", gnutls_strerror (ret)); exit (1); } #ifdef ENABLE_PKCS11 if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0) { gnutls_pkcs11_privkey_init (&pkcs11_key); ret = gnutls_pkcs11_privkey_import_url (pkcs11_key, pgp_keyfile, 0); if (ret < 0) { fprintf (stderr, "*** Error loading url: %s\n", gnutls_strerror (ret)); exit (1); } ret = gnutls_privkey_import_pkcs11( pgp_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); if (ret < 0) { fprintf (stderr, "*** Error loading url: %s\n", gnutls_strerror (ret)); exit (1); } } else #endif /* ENABLE_PKCS11 */ { gnutls_openpgp_privkey_t tmp_pgp_key; data = load_file (pgp_keyfile); if (data.data == NULL) { fprintf (stderr, "*** Error loading PGP key file.\n"); exit (1); } gnutls_openpgp_privkey_init (&tmp_pgp_key); ret = gnutls_openpgp_privkey_import (tmp_pgp_key, &data, GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); if (ret < 0) { fprintf (stderr, "*** Error loading PGP key file: %s\n", gnutls_strerror (ret)); exit (1); } if (info.pgp_subkey != NULL) { ret = gnutls_openpgp_privkey_set_preferred_key_id (tmp_pgp_key, keyid); if (ret < 0) { fprintf (stderr, "*** Error setting preferred sub key id (%s): %s\n", info.pgp_subkey, gnutls_strerror (ret)); exit (1); } } ret = gnutls_privkey_import_openpgp( pgp_key, tmp_pgp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); if (ret < 0) { fprintf (stderr, "*** Error loading url: %s\n", gnutls_strerror (ret)); exit (1); } unload_file (&data); } fprintf (stdout, "Processed 1 client PGP certificate...\n"); } #endif }
static void test_failure(const char *name, const char *prio) { int ret; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN; gnutls_x509_crt_t *crts; unsigned int crts_size; unsigned i; gnutls_typed_vdata_st vdata[2]; gnutls_x509_privkey_t pkey; unsigned status; success("testing cert verification failure for %s\n", name); to_server_len = 0; to_client_len = 0; ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_import(pkey, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey); gnutls_x509_privkey_deinit(pkey); for (i=0;i<crts_size;i++) gnutls_x509_crt_deinit(crts[i]); gnutls_free(crts); gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); assert(gnutls_priority_set_direct(server, prio, NULL) >= 0); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); /* Init client */ /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_key_mem(clientx509cred, &cli_cert, &cli_key, GNUTLS_X509_FMT_PEM); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); assert(gnutls_priority_set_direct(client, prio, NULL) >= 0); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); memset(vdata, 0, sizeof(vdata)); /* check with wrong hostname */ vdata[0].type = GNUTLS_DT_DNS_HOSTNAME; vdata[0].data = (void*)"localhost1"; vdata[1].type = GNUTLS_DT_KEY_PURPOSE_OID; vdata[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; gnutls_session_set_verify_cert2(client, vdata, 2, 0); HANDSHAKE_EXPECT(client, server, GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR, GNUTLS_E_AGAIN); status = gnutls_session_get_verify_cert_status(client); if (status == 0) { fail("should not have accepted!\n"); exit(1); } gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); }
/* * initialize a new TLS context */ static int tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) { tlsg_ctx *ctx = lo->ldo_tls_ctx; int rc; if ( lo->ldo_tls_ciphersuite && tlsg_parse_ciphers( ctx, lt->lt_ciphersuite )) { Debug( LDAP_DEBUG_ANY, "TLS: could not set cipher list %s.\n", lo->ldo_tls_ciphersuite, 0, 0 ); return -1; } if (lo->ldo_tls_cacertdir != NULL) { Debug( LDAP_DEBUG_ANY, "TLS: warning: cacertdir not implemented for gnutls\n", NULL, NULL, NULL ); } if (lo->ldo_tls_cacertfile != NULL) { rc = gnutls_certificate_set_x509_trust_file( ctx->cred, lt->lt_cacertfile, GNUTLS_X509_FMT_PEM ); if ( rc < 0 ) return -1; } if ( lo->ldo_tls_certfile && lo->ldo_tls_keyfile ) { gnutls_x509_privkey_t key; gnutls_datum_t buf; gnutls_x509_crt_t certs[VERIFY_DEPTH]; unsigned int max = VERIFY_DEPTH; rc = gnutls_x509_privkey_init( &key ); if ( rc ) return -1; /* OpenSSL builds the cert chain for us, but GnuTLS * expects it to be present in the certfile. If it's * not, we have to build it ourselves. So we have to * do some special checks here... */ rc = tlsg_getfile( lt->lt_keyfile, &buf ); if ( rc ) return -1; rc = gnutls_x509_privkey_import( key, &buf, GNUTLS_X509_FMT_PEM ); LDAP_FREE( buf.data ); if ( rc < 0 ) return rc; rc = tlsg_getfile( lt->lt_certfile, &buf ); if ( rc ) return -1; rc = gnutls_x509_crt_list_import( certs, &max, &buf, GNUTLS_X509_FMT_PEM, 0 ); LDAP_FREE( buf.data ); if ( rc < 0 ) return rc; /* If there's only one cert and it's not self-signed, * then we have to build the cert chain. */ if ( max == 1 && !gnutls_x509_crt_check_issuer( certs[0], certs[0] )) { gnutls_x509_crt_t *cas; unsigned int i, j, ncas; gnutls_certificate_get_x509_cas( ctx->cred, &cas, &ncas ); for ( i = 1; i<VERIFY_DEPTH; i++ ) { for ( j = 0; j<ncas; j++ ) { if ( gnutls_x509_crt_check_issuer( certs[i-1], cas[j] )) { certs[i] = cas[j]; max++; /* If this CA is self-signed, we're done */ if ( gnutls_x509_crt_check_issuer( cas[j], cas[j] )) j = ncas; break; } } /* only continue if we found a CA and it was not self-signed */ if ( j == ncas ) break; } } rc = gnutls_certificate_set_x509_key( ctx->cred, certs, max, key ); if ( rc ) return -1; } else if ( lo->ldo_tls_certfile || lo->ldo_tls_keyfile ) { Debug( LDAP_DEBUG_ANY, "TLS: only one of certfile and keyfile specified\n", NULL, NULL, NULL ); return -1; } if ( lo->ldo_tls_dhfile ) { Debug( LDAP_DEBUG_ANY, "TLS: warning: ignoring dhfile\n", NULL, NULL, NULL ); } if ( lo->ldo_tls_crlfile ) { rc = gnutls_certificate_set_x509_crl_file( ctx->cred, lt->lt_crlfile, GNUTLS_X509_FMT_PEM ); if ( rc < 0 ) return -1; rc = 0; } /* FIXME: ITS#5992 - this should go be configurable, * and V1 CA certs should be phased out ASAP. */ gnutls_certificate_set_verify_flags( ctx->cred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT ); if ( is_server ) { gnutls_dh_params_init(&ctx->dh_params); gnutls_dh_params_generate2(ctx->dh_params, DH_BITS); } return 0; }
void doit(void) { int exit_code = EXIT_SUCCESS; int ret; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN; gnutls_x509_crt_t *crts; unsigned int crts_size; unsigned i; gnutls_x509_privkey_t pkey; /* General init. */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(2); ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_import(pkey, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey); gnutls_x509_privkey_deinit(pkey); for (i=0;i<crts_size;i++) gnutls_x509_crt_deinit(crts[i]); gnutls_free(crts); gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); gnutls_priority_set_direct(server, "NORMAL:-CIPHER-ALL:+AES-128-GCM", NULL); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); /* Init client */ /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); gnutls_certificate_set_retrieve_function2(clientx509cred, cert_callback); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); gnutls_priority_set_direct(client, "NORMAL", NULL); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); HANDSHAKE(client, server); if (gnutls_certificate_get_ours(client) == NULL) { fail("client certificate was not sent!\n"); exit(1); } /* check gnutls_certificate_get_ours() - server side */ { const gnutls_datum_t *mcert; gnutls_datum_t scert; gnutls_x509_crt_t crt; mcert = gnutls_certificate_get_ours(server); if (mcert == NULL) { fail("gnutls_certificate_get_ours(): failed\n"); exit(1); } gnutls_x509_crt_init(&crt); ret = gnutls_x509_crt_import(crt, &server_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &scert); if (ret < 0) { fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt); if (scert.size != mcert->size || memcmp(scert.data, mcert->data, mcert->size) != 0) { fail("gnutls_certificate_get_ours output doesn't match cert\n"); exit(1); } gnutls_free(scert.data); } /* check gnutls_certificate_get_ours() - client side */ { const gnutls_datum_t *mcert; gnutls_datum_t ccert; gnutls_x509_crt_t crt; mcert = gnutls_certificate_get_ours(client); if (mcert == NULL) { fail("gnutls_certificate_get_ours(): failed\n"); exit(1); } gnutls_x509_crt_init(&crt); ret = gnutls_x509_crt_import(crt, &cli_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &ccert); if (ret < 0) { fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt); if (ccert.size != mcert->size || memcmp(ccert.data, mcert->data, mcert->size) != 0) { fail("gnutls_certificate_get_ours output doesn't match cert\n"); exit(1); } gnutls_free(ccert.data); } /* check the number of certificates received */ { unsigned cert_list_size = 0; gnutls_typed_vdata_st data[2]; unsigned status; memset(data, 0, sizeof(data)); /* check with wrong hostname */ data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)"localhost1"; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; gnutls_certificate_get_peers(client, &cert_list_size); if (cert_list_size < 2) { fprintf(stderr, "received a certificate list of %d!\n", cert_list_size); exit(1); } ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status == 0) { fprintf(stderr, "should not have accepted!\n"); exit(1); } /* check with wrong purpose */ data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)"localhost"; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_CLIENT; gnutls_certificate_get_peers(client, &cert_list_size); if (cert_list_size < 2) { fprintf(stderr, "received a certificate list of %d!\n", cert_list_size); exit(1); } ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status == 0) { fprintf(stderr, "should not have accepted!\n"); exit(1); } /* check with correct purpose */ data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)"localhost"; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status != 0) { fprintf(stderr, "could not verify certificate: %.4x\n", status); exit(1); } } if (gnutls_certificate_client_get_request_status(client) == 0) { fail("gnutls_certificate_client_get_request_status - 2 failed\n"); exit(1); } gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); gnutls_global_deinit(); if (debug > 0) { if (exit_code == 0) puts("Self-test successful"); else puts("Self-test failed"); } }
void doit (void) { gnutls_x509_privkey_t pkey; gnutls_x509_crt_t crt; gnutls_x509_crq_t crq; gnutls_datum_t out; size_t s = 0; char smallbuf[10]; int ret; ret = gnutls_global_init (); if (ret < 0) fail ("gnutls_global_init\n"); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (4711); ret = gnutls_x509_crq_init (&crq); if (ret != 0) fail ("gnutls_x509_crq_init\n"); ret = gnutls_x509_privkey_init (&pkey); if (ret != 0) fail ("gnutls_x509_privkey_init\n"); ret = gnutls_x509_crt_init (&crt); if (ret != 0) fail ("gnutls_x509_crt_init\n"); ret = gnutls_x509_privkey_import (pkey, &key, GNUTLS_X509_FMT_PEM); if (ret != 0) fail ("gnutls_x509_privkey_import\n"); ret = gnutls_x509_crq_set_version (crq, 0); if (ret != 0) fail ("gnutls_x509_crq_set_version\n"); ret = gnutls_x509_crq_set_key (crq, pkey); if (ret != 0) fail ("gnutls_x509_crq_set_key\n"); s = 0; ret = gnutls_x509_crq_get_extension_info (crq, 0, NULL, &s, NULL); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) fail ("gnutls_x509_crq_get_extension_info\n"); ret = gnutls_x509_crq_set_basic_constraints (crq, 0, 0); if (ret != 0) fail ("gnutls_x509_crq_set_basic_constraints %d\n", ret); ret = gnutls_x509_crq_set_key_usage (crq, 0); if (ret != 0) fail ("gnutls_x509_crq_set_key_usage %d\n", ret); ret = gnutls_x509_crq_get_challenge_password (crq, NULL, &s); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) fail ("gnutls_x509_crq_get_challenge_password %d\n", ret); ret = gnutls_x509_crq_set_challenge_password (crq, "foo"); if (ret != 0) fail ("gnutls_x509_crq_set_challenge_password %d\n", ret); s = 0; ret = gnutls_x509_crq_get_challenge_password (crq, NULL, &s); if (ret != 0 || s != 3) fail ("gnutls_x509_crq_get_challenge_password2 %d/%d\n", ret, (int) s); s = 10; ret = gnutls_x509_crq_get_challenge_password (crq, smallbuf, &s); if (ret != 0 || s != 3 || strcmp (smallbuf, "foo") != 0) fail ("gnutls_x509_crq_get_challenge_password3 %d/%d/%s\n", ret, (int) s, smallbuf); s = 0; ret = gnutls_x509_crq_get_extension_info (crq, 0, NULL, &s, NULL); if (ret != 0) fail ("gnutls_x509_crq_get_extension_info2\n"); s = 0; ret = gnutls_x509_crq_get_extension_data (crq, 0, NULL, &s); if (ret != 0) fail ("gnutls_x509_crq_get_extension_data\n"); ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME, "foo", 3, 1); if (ret != 0) fail ("gnutls_x509_crq_set_subject_alt_name\n"); ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME, "bar", 3, 1); if (ret != 0) fail ("gnutls_x509_crq_set_subject_alt_name\n"); ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME, "apa", 3, 0); if (ret != 0) fail ("gnutls_x509_crq_set_subject_alt_name\n"); ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME, "foo", 3, 1); if (ret != 0) fail ("gnutls_x509_crq_set_subject_alt_name\n"); s = 0; ret = gnutls_x509_crq_get_key_purpose_oid (crq, 0, NULL, &s, NULL); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) fail ("gnutls_x509_crq_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crq_set_key_purpose_oid (crq, GNUTLS_KP_TLS_WWW_SERVER, 0); if (ret != 0) fail ("gnutls_x509_crq_set_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crq_get_key_purpose_oid (crq, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail ("gnutls_x509_crq_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crq_set_key_purpose_oid (crq, GNUTLS_KP_TLS_WWW_CLIENT, 1); if (ret != 0) fail ("gnutls_x509_crq_set_key_purpose_oid2 %d\n", ret); ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &out); if (ret != 0) fail ("gnutls_x509_crq_print\n"); if (debug) printf ("crq: %.*s\n", out.size, out.data); gnutls_free (out.data); ret = gnutls_x509_crt_set_version (crt, 3); if (ret != 0) fail ("gnutls_x509_crt_set_version\n"); ret = gnutls_x509_crt_set_crq_extensions (crt, crq); if (ret != 0) fail ("gnutls_x509_crt_set_crq_extensions\n"); ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &out); if (ret != 0) fail ("gnutls_x509_crt_print\n"); if (debug) printf ("crt: %.*s\n", out.size, out.data); gnutls_free (out.data); gnutls_x509_crq_deinit (crq); gnutls_x509_crt_deinit (crt); gnutls_x509_privkey_deinit (pkey); gnutls_global_deinit (); }
static void test_success2(const char *name, const char *prio) { int ret; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN; gnutls_x509_crt_t *crts; unsigned int crts_size; unsigned i; gnutls_x509_privkey_t pkey; unsigned status; success("testing cert verification success2 for %s\n", name); to_server_len = 0; to_client_len = 0; ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_import(pkey, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey); gnutls_x509_privkey_deinit(pkey); for (i=0;i<crts_size;i++) gnutls_x509_crt_deinit(crts[i]); gnutls_free(crts); gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); assert(gnutls_priority_set_direct(server, prio, NULL)>=0); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); /* Init client */ /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_key_mem(clientx509cred, &cli_cert, &cli_key, GNUTLS_X509_FMT_PEM); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); assert(gnutls_priority_set_direct(client, prio, NULL)>=0); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); gnutls_session_set_verify_cert(client, "localhost", 0); HANDSHAKE(client, server); status = gnutls_session_get_verify_cert_status(client); if (status != 0) { fail("%s: should have accepted: %u!\n", __func__, status); exit(1); } gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); }
char * irc_sasl_mechanism_ecdsa_nist256p_challenge (struct t_irc_server *server, const char *data_base64, const char *sasl_username, const char *sasl_key) { #if defined(HAVE_GNUTLS) && (LIBGNUTLS_VERSION_NUMBER >= 0x030015) /* 3.0.21 */ char *data, *string, *answer_base64; int length_data, length_username, length, ret; char *str_privkey; gnutls_x509_privkey_t x509_privkey; gnutls_privkey_t privkey; gnutls_datum_t filedatum, decoded_data, signature; #if LIBGNUTLS_VERSION_NUMBER >= 0x030300 /* 3.3.0 */ gnutls_ecc_curve_t curve; gnutls_datum_t x, y, k; char *pubkey, *pubkey_base64; #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x030300 */ answer_base64 = NULL; string = NULL; length = 0; if (strcmp (data_base64, "+") == 0) { /* send "username" + '\0' + "username" */ answer_base64 = NULL; length_username = strlen (sasl_username); length = length_username + 1 + length_username; string = malloc (length + 1); if (string) { snprintf (string, length + 1, "%s|%s", sasl_username, sasl_username); string[length_username] = '\0'; } } else { /* sign the challenge with the private key and return the result */ /* decode the challenge */ data = malloc (strlen (data_base64) + 1); if (!data) return NULL; length_data = dogechat_string_decode_base64 (data_base64, data); /* read file with private key */ str_privkey = irc_sasl_get_key_content (server, sasl_key); if (!str_privkey) { free (data); return NULL; } /* import key */ gnutls_x509_privkey_init (&x509_privkey); gnutls_privkey_init (&privkey); filedatum.data = (unsigned char *)str_privkey; filedatum.size = strlen (str_privkey); ret = gnutls_x509_privkey_import (x509_privkey, &filedatum, GNUTLS_X509_FMT_PEM); free (str_privkey); if (ret != GNUTLS_E_SUCCESS) { dogechat_printf ( server->buffer, _("%sgnutls: invalid private key file: error %d %s"), dogechat_prefix ("error"), ret, gnutls_strerror (ret)); gnutls_x509_privkey_deinit (x509_privkey); gnutls_privkey_deinit (privkey); free (data); return NULL; } #if LIBGNUTLS_VERSION_NUMBER >= 0x030300 /* 3.3.0 */ /* read raw values in key, to display public key */ ret = gnutls_x509_privkey_export_ecc_raw (x509_privkey, &curve, &x, &y, &k); if (ret == GNUTLS_E_SUCCESS) { pubkey = malloc (x.size + 1); if (pubkey) { pubkey[0] = (y.data[y.size - 1] & 1) ? 0x03 : 0x02; memcpy (pubkey + 1, x.data, x.size); pubkey_base64 = malloc ((x.size + 1 + 1) * 4); if (pubkey_base64) { dogechat_string_encode_base64 (pubkey, x.size + 1, pubkey_base64); dogechat_printf ( server->buffer, _("%s%s: signing the challenge with ECC public key: " "%s"), dogechat_prefix ("network"), IRC_PLUGIN_NAME, pubkey_base64); free (pubkey_base64); } free (pubkey); } gnutls_free (x.data); gnutls_free (y.data); gnutls_free (k.data); } #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x030300 */ /* import private key in an abstract key structure */ ret = gnutls_privkey_import_x509 (privkey, x509_privkey, 0); /* gnutls >= 2.11.0 */ if (ret != GNUTLS_E_SUCCESS) { dogechat_printf ( server->buffer, _("%sgnutls: unable to import the private key: error %d %s"), dogechat_prefix ("error"), ret, gnutls_strerror (ret)); gnutls_x509_privkey_deinit (x509_privkey); gnutls_privkey_deinit (privkey); free (data); return NULL; } decoded_data.data = (unsigned char *)data; decoded_data.size = length_data; ret = gnutls_privkey_sign_hash (privkey, GNUTLS_DIG_SHA256, 0, /* gnutls >= 2.11.0 */ &decoded_data, &signature); if (ret != GNUTLS_E_SUCCESS) { dogechat_printf ( server->buffer, _("%sgnutls: unable to sign the hashed data: error %d %s"), dogechat_prefix ("error"), ret, gnutls_strerror (ret)); gnutls_x509_privkey_deinit (x509_privkey); gnutls_privkey_deinit (privkey); free (data); return NULL; } gnutls_x509_privkey_deinit (x509_privkey); gnutls_privkey_deinit (privkey); string = malloc (signature.size); if (string) memcpy (string, signature.data, signature.size); length = signature.size; gnutls_free (signature.data); free (data); } if (string && (length > 0)) { answer_base64 = malloc ((length + 1) * 4); if (answer_base64) dogechat_string_encode_base64 (string, length, answer_base64); free (string); } return answer_base64; #else /* no gnutls or gnutls < 3.0.21 */ /* make C compiler happy */ (void) data_base64; (void) sasl_username; (void) sasl_key; dogechat_printf (server->buffer, _("%sgnutls: version >= 3.0.21 is required for SASL " "\"ecdsa-nist256p-challenge\""), dogechat_prefix ("error")); return NULL; #endif /* defined(HAVE_GNUTLS) && (LIBGNUTLS_VERSION_NUMBER >= 0x030015) */ }