/** * gnutls_certificate_set_x509_key_file2: * @res: is a #gnutls_certificate_credentials_t type. * @certfile: is a file that containing the certificate list (path) for * the specified private key, in PKCS7 format, or a list of certificates * @keyfile: is a file that contains the private key * @type: is PEM or DER * @pass: is the password of the key * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t * * This function sets a certificate/private key pair in the * gnutls_certificate_credentials_t type. This function may be * called more than once, in case multiple keys/certificates exist for * the server. For clients that need to send more than its own end * entity certificate, e.g., also an intermediate CA cert, then the * @certfile must contain the ordered certificate chain. * * Note that the names in the certificate provided will be considered * when selecting the appropriate certificate to use (in case of multiple * certificate/key pairs). * * This function can also accept URLs at @keyfile and @certfile. In that case it * will use the private key and certificate indicated by the URLs. Note * that the supported URLs are the ones indicated by gnutls_url_is_supported(). * Before GnuTLS 3.4.0 when a URL was specified, the @pass part was ignored and a * PIN callback had to be registered, this is no longer the case in current releases. * * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its * present issuers in the token are imported (i.e., forming the required trust chain). * * If that function fails to load the @res structure is at an undefined state, it must * not be reused to load other keys or certificates. * * Note that, this function by default returns zero on success and a negative value on error. * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags() * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair. * * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior). * **/ int gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res, const char *certfile, const char *keyfile, gnutls_x509_crt_fmt_t type, const char *pass, unsigned int flags) { int ret; gnutls_privkey_t rkey; /* this should be first */ if ((ret = _gnutls_read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0) return ret; if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) { gnutls_privkey_deinit(rkey); return ret; } res->ncerts++; if ((ret = _gnutls_check_key_cert_match(res)) < 0) { gnutls_assert(); return ret; } CRED_RET_SUCCESS(res); }
/* Reads a private key from a token. */ static int read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey) { int ret; gnutls_privkey_t pkey = NULL; /* allocate space for the pkey list */ ret = gnutls_privkey_init(&pkey); if (ret < 0) { gnutls_assert(); goto cleanup; } if (res->pin.cb) gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data); ret = gnutls_privkey_import_url(pkey, url, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } *rkey = pkey; return 0; cleanup: if (pkey) gnutls_privkey_deinit(pkey); return ret; }
/** * gnutls_certificate_free_keys: * @sc: is a #gnutls_certificate_credentials_t structure. * * This function will delete all the keys and the certificates associated * with the given credentials. This function must not be called when a * TLS negotiation that uses the credentials is in progress. * **/ void gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc) { unsigned i, j; for (i = 0; i < sc->ncerts; i++) { for (j = 0; j < sc->certs[i].cert_list_length; j++) { gnutls_pcert_deinit (&sc->certs[i].cert_list[j]); } gnutls_free (sc->certs[i].cert_list); _gnutls_str_array_clear (&sc->certs[i].names); } gnutls_free (sc->certs); sc->certs = NULL; for (i = 0; i < sc->ncerts; i++) { gnutls_privkey_deinit (sc->pkey[i]); } gnutls_free (sc->pkey); sc->pkey = NULL; sc->ncerts = 0; }
/** * gnutls_certificate_set_x509_key_mem2: * @res: is a #gnutls_certificate_credentials_t type. * @cert: contains a certificate list (path) for the specified private key * @key: is the private key, or %NULL * @type: is PEM or DER * @pass: is the key's password * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t * * This function sets a certificate/private key pair in the * gnutls_certificate_credentials_t type. This function may be called * more than once, in case multiple keys/certificates exist for the * server. * * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates * is supported. This means that certificates intended for signing cannot * be used for ciphersuites that require encryption. * * If the certificate and the private key are given in PEM encoding * then the strings that hold their values must be null terminated. * * The @key may be %NULL if you are using a sign callback, see * gnutls_sign_callback_set(). * * Note that, this function by default returns zero on success and a negative value on error. * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags() * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair. * * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior). **/ int gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res, const gnutls_datum_t * cert, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type, const char *pass, unsigned int flags) { int ret; gnutls_privkey_t rkey; /* this should be first */ if ((ret = _gnutls_read_key_mem(res, key ? key->data : NULL, key ? key->size : 0, type, pass, flags, &rkey)) < 0) return ret; if ((ret = read_cert_mem(res, rkey, cert->data, cert->size, type)) < 0) { gnutls_privkey_deinit(rkey); return ret; } res->ncerts++; if (key && (ret = _gnutls_check_key_cert_match(res)) < 0) { gnutls_assert(); return ret; } CRED_RET_SUCCESS(res); }
static void check_other_work(sec_mod_st *sec) { if (need_exit) { unsigned i; for (i = 0; i < sec->key_size; i++) { gnutls_privkey_deinit(sec->key[i]); } sec_mod_client_db_deinit(sec); tls_cache_deinit(&sec->tls_db); talloc_free(sec); exit(0); } if (need_reload) { seclog(sec, LOG_DEBUG, "reloading configuration"); reload_cfg_file(sec, sec->perm_config, 0); sec->config = sec->perm_config->config; load_keys(sec, 0); need_reload = 0; } if (need_maintainance) { seclog(sec, LOG_DEBUG, "performing maintenance"); cleanup_client_entries(sec); expire_tls_sessions(sec); seclog(sec, LOG_DEBUG, "active sessions %d", sec_mod_client_db_elems(sec)); alarm(MAINTAINANCE_TIME); need_maintainance = 0; } }
/*! * Create GnuTLS private key from unencrypted PEM data. */ int pem_to_privkey(const dnssec_binary_t *data, gnutls_privkey_t *key, char **id_ptr) { assert(data); assert(key); assert(id_ptr); // create abstract private key gnutls_x509_privkey_t key_x509 = NULL; int r = pem_to_x509(data, &key_x509); if (r != DNSSEC_EOK) { return r; } gnutls_privkey_t key_abs = NULL; r = gnutls_privkey_init(&key_abs); if (r != GNUTLS_E_SUCCESS) { gnutls_x509_privkey_deinit(key_x509); return DNSSEC_ENOMEM; } int flags = GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE; r = gnutls_privkey_import_x509(key_abs, key_x509, flags); if (r != GNUTLS_E_SUCCESS) { gnutls_x509_privkey_deinit(key_x509); gnutls_privkey_deinit(key_abs); return DNSSEC_ENOMEM; } // extract keytag char *id = gnutls_x509_privkey_hex_key_id(key_x509); if (id == NULL) { gnutls_privkey_deinit(key_abs); return DNSSEC_ENOMEM; } *key = key_abs; *id_ptr = id; return DNSSEC_EOK; }
PrivateKey::~PrivateKey() { if (key) { gnutls_privkey_deinit(key); key = nullptr; } if (x509_key) { gnutls_x509_privkey_deinit(x509_key); x509_key = nullptr; } gnutls_global_deinit(); }
void doit(void) { int ret, status; const char *lib; gnutls_privkey_t pkey; pid_t pid; signal(SIGPIPE, SIG_IGN); gnutls_pkcs11_set_pin_function(pin_func, NULL); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); lib = getenv("P11MOCKLIB1"); if (lib == NULL) lib = P11LIB; ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_add_provider(lib, NULL); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } assert(gnutls_privkey_init(&pkey) == 0); ret = gnutls_privkey_import_url(pkey, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN); if (ret < 0) { fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } /* fork to force PKCS#11 reinitialization */ pid = fork(); if (pid == -1) { exit(1); } else if (pid) { waitpid(pid, &status, 0); check_wait_status(status); goto cleanup; } do_thread_stuff(pkey); cleanup: gnutls_privkey_deinit(pkey); }
void doit(void) { server_check(); reset_buffers(); client_check(); if (g_pcert) { gnutls_pcert_deinit(g_pcert); gnutls_free(g_pcert); } if (g_pkey) { gnutls_privkey_deinit(g_pkey); } }
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; }
/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type * indicates the certificate format. * * It returns the private key read in @rkey. */ int _gnutls_read_key_mem(gnutls_certificate_credentials_t res, const void *key, int key_size, gnutls_x509_crt_fmt_t type, const char *pass, unsigned int flags, gnutls_privkey_t *rkey) { int ret; gnutls_datum_t tmp; gnutls_privkey_t privkey; if (key) { tmp.data = (uint8_t *) key; tmp.size = key_size; ret = gnutls_privkey_init(&privkey); if (ret < 0) { gnutls_assert(); return ret; } if (res->pin.cb) { gnutls_privkey_set_pin_function(privkey, res->pin.cb, res->pin.data); } else if (pass != NULL) { snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s", pass); gnutls_privkey_set_pin_function(privkey, tmp_pin_cb, res->pin_tmp); } ret = gnutls_privkey_import_x509_raw(privkey, &tmp, type, pass, flags); if (ret < 0) { gnutls_assert(); gnutls_privkey_deinit(privkey); return ret; } *rkey = privkey; } else { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } return 0; }
PrivateKey& PrivateKey::operator=(PrivateKey&& o) noexcept { if (key) { gnutls_privkey_deinit(key); key = nullptr; } if (x509_key) { gnutls_x509_privkey_deinit(x509_key); x509_key = nullptr; } key = o.key; x509_key = o.x509_key; o.key = nullptr; o.x509_key = nullptr; return *this; }
static int dcrypt_gnutls_generate_keypair(struct dcrypt_keypair *pair_r, enum dcrypt_key_type kind, unsigned int bits, const char *curve, const char **error_r) { gnutls_pk_algorithm_t pk_algo; gnutls_ecc_curve_t pk_curve; if (kind == DCRYPT_KEY_EC) { pk_curve = gnutls_ecc_curve_get_id(curve); if (pk_curve == GNUTLS_ECC_CURVE_INVALID) { *error_r = "Invalid curve"; return -1; } bits = GNUTLS_CURVE_TO_BITS(pk_curve); #if GNUTLS_VERSION_NUMBER >= 0x030500 pk_algo = gnutls_curve_get_pk(pk_curve); #else pk_algo = GNUTLS_PK_EC; #endif } else if (kind == DCRYPT_KEY_RSA) { pk_algo = gnutls_pk_get_id("RSA"); } else { *error_r = "Unsupported key type"; return -1; } int ec; gnutls_privkey_t priv; if ((ec = gnutls_privkey_init(&priv)) != GNUTLS_E_SUCCESS) return dcrypt_gnutls_error(ec, error_r); #if GNUTLS_VERSION_NUMBER >= 0x030500 gnutls_privkey_set_flags(priv, GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT); #endif ec = gnutls_privkey_generate(priv, pk_algo, bits, 0); if (ec != GNUTLS_E_SUCCESS) { gnutls_privkey_deinit(priv); return dcrypt_gnutls_error(ec, error_r); } pair_r->priv = (struct dcrypt_private_key*)priv; return dcrypt_gnutls_private_to_public_key(pair_r->priv, &pair_r->pub, error_r); }
/** * gnutls_x509_crt_sign2: * @crt: a certificate of type #gnutls_x509_crt_t * @issuer: is the certificate of the certificate issuer * @issuer_key: holds the issuer's private key * @dig: The message digest to use, %GNUTLS_DIG_SHA1 is a safe choice * @flags: must be 0 * * This function will sign the certificate with the issuer's private key, and * will copy the issuer's information into the certificate. * * This must be the last step in a certificate generation since all * the previously set parameters are now signed. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_crt_sign2(gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer, gnutls_x509_privkey_t issuer_key, gnutls_digest_algorithm_t dig, unsigned int flags) { int result; gnutls_privkey_t privkey; if (crt == NULL || issuer == NULL || issuer_key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_privkey_init(&privkey); if (result < 0) { gnutls_assert(); return result; } result = gnutls_privkey_import_x509(privkey, issuer_key, 0); if (result < 0) { gnutls_assert(); goto fail; } result = gnutls_x509_crt_privkey_sign(crt, issuer, privkey, dig, flags); if (result < 0) { gnutls_assert(); goto fail; } result = 0; fail: gnutls_privkey_deinit(privkey); return result; }
void doit (void) { gnutls_x509_privkey_t pkey; gnutls_privkey_t abs_pkey; gnutls_x509_crq_t crq; size_t pkey_key_id_len; unsigned char *pkey_key_id = NULL; size_t crq_key_id_len; unsigned char *crq_key_id = NULL; gnutls_pk_algorithm_t algorithm; int ret; ret = global_init (); if (ret < 0) fail ("global_init: %d\n", ret); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (4711); for (algorithm = GNUTLS_PK_RSA; algorithm <= GNUTLS_PK_DSA; algorithm++) { ret = gnutls_x509_crq_init (&crq); if (ret < 0) fail ("gnutls_x509_crq_init: %d\n", ret); ret = gnutls_x509_privkey_init (&pkey); if (ret < 0) { fail ("gnutls_x509_privkey_init: %d\n", ret); } ret = gnutls_privkey_init (&abs_pkey); if (ret < 0) { fail ("gnutls_privkey_init: %d\n", ret); } ret = gnutls_x509_privkey_generate (pkey, algorithm, 1024, 0); if (ret < 0) { fail ("gnutls_x509_privkey_generate (rsa): %d\n", ret); } else if (debug) { success ("Key[%s] generation ok: %d\n", gnutls_pk_algorithm_get_name (algorithm), ret); } pkey_key_id_len = 0; ret = gnutls_x509_privkey_get_key_id (pkey, 0, pkey_key_id, &pkey_key_id_len); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { fail ("gnutls_x509_privkey_get_key_id incorrectly returns %d\n", ret); } pkey_key_id = malloc (sizeof (unsigned char) * pkey_key_id_len); ret = gnutls_x509_privkey_get_key_id (pkey, 0, pkey_key_id, &pkey_key_id_len); if (ret != GNUTLS_E_SUCCESS) { fail ("gnutls_x509_privkey_get_key_id incorrectly returns %d\n", ret); } ret = gnutls_x509_crq_set_version (crq, 1); if (ret < 0) { fail ("gnutls_x509_crq_set_version: %d\n", ret); } ret = gnutls_x509_crq_set_key (crq, pkey); if (ret < 0) { fail ("gnutls_x509_crq_set_key: %d\n", ret); } ret = gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME, 0, "CN-Test", 7); if (ret < 0) { fail ("gnutls_x509_crq_set_dn_by_oid: %d\n", ret); } ret = gnutls_privkey_import_x509( abs_pkey, pkey, 0); if (ret < 0) { fail ("gnutls_privkey_import_x509: %d\n", ret); } ret = gnutls_x509_crq_privkey_sign (crq, abs_pkey, GNUTLS_DIG_SHA1, 0); if (ret < 0) { fail ("gnutls_x509_crq_sign: %d\n", ret); } ret = gnutls_x509_crq_verify (crq, 0); if (ret < 0) { fail ("gnutls_x509_crq_verify: %d\n", ret); } crq_key_id_len = 0; ret = gnutls_x509_crq_get_key_id (crq, 0, crq_key_id, &crq_key_id_len); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { fail ("gnutls_x509_crq_get_key_id incorrectly returns %d\n", ret); } crq_key_id = malloc (sizeof (unsigned char) * crq_key_id_len); ret = gnutls_x509_crq_get_key_id (crq, 0, crq_key_id, &crq_key_id_len); if (ret != GNUTLS_E_SUCCESS) { fail ("gnutls_x509_crq_get_key_id incorrectly returns %d\n", ret); } if (crq_key_id_len == pkey_key_id_len) { ret = memcmp (crq_key_id, pkey_key_id, crq_key_id_len); if (ret == 0) { if (debug) success ("Key ids are identical. OK.\n"); } else { fail ("Key ids differ incorrectly: %d\n", ret); } } else { fail ("Key_id lengths differ incorrectly: %d - %d\n", (int) crq_key_id_len, (int) pkey_key_id_len); } if (pkey_key_id) { free (pkey_key_id); pkey_key_id = NULL; } if (crq_key_id) { free (crq_key_id); crq_key_id = NULL; } gnutls_x509_crq_deinit (crq); gnutls_x509_privkey_deinit (pkey); gnutls_privkey_deinit (abs_pkey); } gnutls_global_deinit (); }
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) */ }
void doit(void) { int ret; const char *lib; gnutls_privkey_t key; gnutls_pkcs11_obj_t obj; gnutls_datum_t sig = {NULL, 0}, data; unsigned flags = 0; lib = getenv("P11MOCKLIB1"); if (lib == NULL) lib = P11LIB; { void *dl; unsigned int *pflags; dl = dlopen(lib, RTLD_NOW); if (dl == NULL) { fail("could not dlopen %s\n", lib); exit(1); } pflags = dlsym(dl, "pkcs11_mock_flags"); if (pflags == NULL) { fail("could find pkcs11_mock_flags\n"); exit(1); } *pflags = MOCK_FLAG_ALWAYS_AUTH; } data.data = (void*)"\x38\x17\x0c\x08\xcb\x45\x8f\xd4\x87\x9c\x34\xb6\xf6\x08\x29\x4c\x50\x31\x2b\xbb"; data.size = 20; ret = global_init(); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_add_provider(lib, NULL); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_obj_init(&obj); assert(ret>=0); gnutls_pkcs11_obj_set_pin_function(obj, pin_func, NULL); ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:object=test;type=private", GNUTLS_PKCS11_OBJ_FLAG_LOGIN); assert(ret>=0); ret = gnutls_pkcs11_obj_get_flags(obj, &flags); assert(ret>=0); if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH)) { fail("key object doesn't have the always authenticate flag\n"); } gnutls_pkcs11_obj_deinit(obj); ret = gnutls_privkey_init(&key); assert(ret>=0); gnutls_privkey_set_pin_function(key, pin_func, NULL); ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } pin_called = 0; ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } if (pin_called == 0) { fail("PIN function wasn't called!\n"); } pin_called = 0; gnutls_free(sig.data); /* call again - should re-authenticate */ ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } if (pin_called == 0) { fail("PIN function wasn't called twice!\n"); } pin_called = 0; gnutls_free(sig.data); if (debug) printf("done\n\n\n"); gnutls_privkey_deinit(key); gnutls_pkcs11_deinit(); gnutls_global_deinit(); }
static int load_keys(sec_mod_st *sec, unsigned force) { unsigned i, need_reload = 0; int ret; struct pin_st pins; static time_t last_access = 0; for (i = 0; i < sec->perm_config->key_size; i++) { if (need_file_reload(sec->perm_config->key[i], last_access) != 0) { need_reload = 1; break; } } if (need_reload == 0) return 0; last_access = time(0); ret = load_pins(sec->perm_config, &pins); if (ret < 0) { seclog(sec, LOG_ERR, "error loading PIN files"); exit(1); } /* Reminder: the number of private keys or their filenames cannot be changed on reload */ if (sec->key == NULL) { sec->key_size = sec->perm_config->key_size; sec->key = talloc_zero_size(sec, sizeof(*sec->key) * sec->perm_config->key_size); if (sec->key == NULL) { seclog(sec, LOG_ERR, "error in memory allocation"); exit(1); } } /* read private keys */ for (i = 0; i < sec->key_size; i++) { gnutls_privkey_t p; ret = gnutls_privkey_init(&p); CHECK_LOOP_ERR(ret); /* load the private key */ if (gnutls_url_is_supported(sec->perm_config->key[i]) != 0) { gnutls_privkey_set_pin_function(p, pin_callback, &pins); ret = gnutls_privkey_import_url(p, sec->perm_config->key[i], 0); CHECK_LOOP_ERR(ret); } else { gnutls_datum_t data; ret = gnutls_load_file(sec->perm_config->key[i], &data); if (ret < 0) { seclog(sec, LOG_ERR, "error loading file '%s'", sec->perm_config->key[i]); CHECK_LOOP_ERR(ret); } ret = gnutls_privkey_import_x509_raw(p, &data, GNUTLS_X509_FMT_PEM, NULL, 0); if (ret == GNUTLS_E_DECRYPTION_FAILED && pins.pin[0]) { ret = gnutls_privkey_import_x509_raw(p, &data, GNUTLS_X509_FMT_PEM, pins.pin, 0); } CHECK_LOOP_ERR(ret); gnutls_free(data.data); } if (sec->key[i] != NULL) { gnutls_privkey_deinit(sec->key[i]); } sec->key[i] = p; } return 0; }
void doit(void) { int ret; const char *lib; gnutls_privkey_t key; gnutls_pubkey_t pub; gnutls_datum_t m1, e1; gnutls_datum_t m2, e2; ret = global_init(); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); lib = getenv("P11MOCKLIB1"); if (lib == NULL) lib = P11LIB; ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pkcs11_add_provider(lib, NULL); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_privkey_init(&key); assert(ret>=0); ret = gnutls_pubkey_init(&pub); assert(ret>=0); gnutls_privkey_set_pin_function(key, pin_func, NULL); ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_import_privkey(pub, key, 0, 0); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_export_rsa_raw(pub, &m1, &e1); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } gnutls_pubkey_deinit(pub); gnutls_privkey_deinit(key); /* try again using gnutls_pubkey_import_url */ ret = gnutls_pubkey_init(&pub); assert(ret>=0); ret = gnutls_pubkey_import_url(pub, "pkcs11:object=test;type=public", 0); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_export_rsa_raw(pub, &m2, &e2); if (ret < 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); exit(1); } assert(m1.size == m2.size); assert(e1.size == e2.size); assert(memcmp(e1.data, e2.data, e2.size)==0); assert(memcmp(m1.data, m2.data, m2.size)==0); gnutls_pubkey_deinit(pub); gnutls_free(m1.data); gnutls_free(e1.data); gnutls_free(m2.data); gnutls_free(e2.data); gnutls_pkcs11_deinit(); gnutls_global_deinit(); }
static int check_privkey_import_export(void) { gnutls_privkey_t key; gnutls_datum_t p, q, g, y, x; gnutls_datum_t m, e, u, e1, e2, d; gnutls_ecc_curve_t curve; gnutls_digest_algorithm_t digest; gnutls_gost_paramset_t paramset; int ret; global_init(); ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_dsa_raw(key, &_dsa_p, &_dsa_q, &_dsa_g, &_dsa_y, &_dsa_x); if (ret < 0) fail("error\n"); ret = gnutls_privkey_export_dsa_raw2(key, &p, &q, &g, &y, &x, 0); if (ret < 0) fail("error: %s\n", gnutls_strerror(ret)); CMP("p", &p, dsa_p); CMP("q", &q, dsa_q); CMP("g", &g, dsa_g); CMP("y", &y, dsa_y); CMP("x", &x, dsa_x); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(g.data); gnutls_free(y.data); gnutls_free(x.data); ret = gnutls_privkey_export_dsa_raw2(key, &p, &q, &g, &y, &x, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error: %s\n", gnutls_strerror(ret)); CMP_NO_LZ("p", &p, dsa_p); CMP_NO_LZ("q", &q, dsa_q); CMP_NO_LZ("g", &g, dsa_g); CMP_NO_LZ("y", &y, dsa_y); CMP_NO_LZ("x", &x, dsa_x); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(g.data); gnutls_free(y.data); gnutls_free(x.data); gnutls_privkey_deinit(key); /* RSA */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_rsa_raw(key, &_rsa_m, &_rsa_e, &_rsa_d, &_rsa_p, &_rsa_q, &_rsa_u, &_rsa_e1, &_rsa_e2); if (ret < 0) fail("error\n"); ret = gnutls_privkey_export_rsa_raw2(key, &m, &e, &d, &p, &q, &u, &e1, &e2, 0); if (ret < 0) fail("error\n"); CMP("m", &m, rsa_m); CMP("e", &e, rsa_e); CMP("d", &d, rsa_d); CMP("p", &p, rsa_p); CMP("q", &q, rsa_q); CMP("u", &u, rsa_u); CMP("e1", &e1, rsa_e1); CMP("e2", &e2, rsa_e2); gnutls_free(m.data); gnutls_free(e.data); gnutls_free(d.data); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(u.data); gnutls_free(e1.data); gnutls_free(e2.data); ret = gnutls_privkey_export_rsa_raw2(key, &m, &e, &d, &p, &q, &u, &e1, &e2, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); CMP_NO_LZ("m", &m, rsa_m); CMP_NO_LZ("e", &e, rsa_e); CMP_NO_LZ("d", &d, rsa_d); CMP_NO_LZ("p", &p, rsa_p); CMP_NO_LZ("q", &q, rsa_q); CMP_NO_LZ("u", &u, rsa_u); CMP_NO_LZ("e1", &e1, rsa_e1); CMP_NO_LZ("e2", &e2, rsa_e2); gnutls_free(m.data); gnutls_free(e.data); gnutls_free(d.data); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(u.data); gnutls_free(e1.data); gnutls_free(e2.data); gnutls_privkey_deinit(key); /* ECC */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_SECP256R1, &_ecc_x, &_ecc_y, &_ecc_k); if (ret < 0) fail("error\n"); ret = gnutls_privkey_export_ecc_raw2(key, &curve, &x, &y, &p, 0); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_SECP256R1) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } CMP("x", &x, ecc_x); CMP("y", &y, ecc_y); CMP("k", &p, ecc_k); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(p.data); ret = gnutls_privkey_export_ecc_raw2(key, &curve, &x, &y, &p, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_SECP256R1) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } CMP_NO_LZ("x", &x, ecc_x); CMP_NO_LZ("y", &y, ecc_y); CMP_NO_LZ("k", &p, ecc_k); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(p.data); gnutls_privkey_deinit(key); /* Ed25519 */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); /* test whether an invalid size would fail */ ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_ED25519, &_rsa_m, NULL, &_rsa_m); if (ret != GNUTLS_E_INVALID_REQUEST) fail("error\n"); ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_ED25519, &_ed25519_x, NULL, &_ed25519_k); if (ret < 0) fail("error\n"); ret = gnutls_privkey_verify_params(key); if (ret != 0) fail("error: %s\n", gnutls_strerror(ret)); ret = gnutls_privkey_export_ecc_raw(key, &curve, &x, NULL, &p); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_ED25519) { fail("unexpected curve value: %d\n", (int)curve); } CMP("x", &x, ed25519_x); CMP("k", &p, ed25519_k); gnutls_free(x.data); gnutls_free(p.data); gnutls_privkey_deinit(key); /* Ed25519 with incorrect public key */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_ED25519, &_false_ed25519_x, NULL, &_ed25519_k); if (ret < 0) fail("error\n"); ret = gnutls_privkey_verify_params(key); if (ret != GNUTLS_E_ILLEGAL_PARAMETER) fail("error: %s\n", gnutls_strerror(ret)); gnutls_privkey_deinit(key); /* GOST */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_gost_raw(key, GNUTLS_ECC_CURVE_GOST256CPXA, GNUTLS_DIG_GOSTR_94, GNUTLS_GOST_PARAMSET_CP_A, &_gost_x, &_gost_y, &_gost_k); if (ret < 0) fail("error\n"); ret = gnutls_privkey_export_gost_raw2(key, &curve, &digest, ¶mset, &x, &y, &p, 0); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } if (digest != GNUTLS_DIG_GOSTR_94) { fprintf(stderr, "unexpected digest value: %d\n", (int)digest); exit(1); } if (paramset != GNUTLS_GOST_PARAMSET_CP_A) { fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset); exit(1); } CMP("x", &x, gost_x); CMP("y", &y, gost_y); CMP("k", &p, gost_k); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(p.data); ret = gnutls_privkey_export_gost_raw2(key, &curve, &digest, ¶mset, &x, &y, &p, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } if (digest != GNUTLS_DIG_GOSTR_94) { fprintf(stderr, "unexpected digest value: %d\n", (int)digest); exit(1); } if (paramset != GNUTLS_GOST_PARAMSET_CP_A) { fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset); exit(1); } CMP_NO_LZ("x", &x, gost_x); CMP_NO_LZ("y", &y, gost_y); CMP_NO_LZ("k", &p, gost_k); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(p.data); gnutls_privkey_deinit(key); return 0; }
void doit(void) { char buf[128]; int ret; const char *lib, *bin; gnutls_x509_crt_t crt; gnutls_x509_privkey_t key; gnutls_datum_t tmp, sig; gnutls_privkey_t pkey; gnutls_pubkey_t pubkey; gnutls_pubkey_t pubkey2; unsigned i, sigalgo; bin = softhsm_bin(); lib = softhsm_lib(); ret = global_init(); if (ret != 0) { fail("%d: %s\n", ret, gnutls_strerror(ret)); } gnutls_pkcs11_set_pin_function(pin_func, NULL); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); set_softhsm_conf(CONFIG); snprintf(buf, sizeof(buf), "%s --init-token --slot 0 --label test --so-pin " PIN " --pin " PIN, bin); system(buf); ret = gnutls_pkcs11_add_provider(lib, NULL); if (ret < 0) { fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret)); } if (verify_eddsa_presence() == 0) { fprintf(stderr, "Skipping test as no EDDSA mech is supported\n"); exit(77); } ret = gnutls_x509_crt_init(&crt); if (ret < 0) fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret)); ret = gnutls_x509_crt_import(crt, &server_ca3_eddsa_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret)); if (debug) { gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &tmp); printf("\tCertificate: %.*s\n", tmp.size, tmp.data); gnutls_free(tmp.data); } ret = gnutls_x509_privkey_init(&key); if (ret < 0) { fail("gnutls_x509_privkey_init: %s\n", gnutls_strerror(ret)); } ret = gnutls_x509_privkey_import(key, &server_ca3_eddsa_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("gnutls_x509_privkey_import: %s\n", gnutls_strerror(ret)); } /* initialize softhsm token */ ret = gnutls_pkcs11_token_init(SOFTHSM_URL, PIN, "test"); if (ret < 0) { fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret)); } ret = gnutls_pkcs11_token_set_pin(SOFTHSM_URL, NULL, PIN, GNUTLS_PIN_USER); if (ret < 0) { fail("gnutls_pkcs11_token_set_pin: %s\n", gnutls_strerror(ret)); } ret = gnutls_pkcs11_copy_x509_crt(SOFTHSM_URL, crt, "cert", GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE | GNUTLS_PKCS11_OBJ_FLAG_LOGIN); if (ret < 0) { fail("gnutls_pkcs11_copy_x509_crt: %s\n", gnutls_strerror(ret)); } ret = gnutls_pkcs11_copy_x509_privkey(SOFTHSM_URL, key, "cert", GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE | GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE | GNUTLS_PKCS11_OBJ_FLAG_LOGIN); if (ret < 0) { fail("gnutls_pkcs11_copy_x509_privkey: %s\n", gnutls_strerror(ret)); } gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); gnutls_pkcs11_set_pin_function(NULL, NULL); assert(gnutls_privkey_init(&pkey) == 0); ret = gnutls_privkey_import_pkcs11_url(pkey, SOFTHSM_URL ";object=cert;object-type=private;pin-value=" PIN); if (ret < 0) { fail("error in gnutls_privkey_import_pkcs11_url: %s\n", gnutls_strerror(ret)); } assert(gnutls_pubkey_init(&pubkey) == 0); assert(gnutls_pubkey_import_privkey(pubkey, pkey, 0, 0) == 0); assert(gnutls_pubkey_init(&pubkey2) == 0); assert(gnutls_pubkey_import_x509_raw (pubkey2, &server_ca3_eddsa_cert, GNUTLS_X509_FMT_PEM, 0) == 0); /* this is the algorithm supported by the certificate */ sigalgo = GNUTLS_SIGN_EDDSA_ED25519; for (i = 0; i < 20; i++) { /* check whether privkey and pubkey are operational * by signing and verifying */ ret = gnutls_privkey_sign_data2(pkey, sigalgo, 0, &testdata, &sig); if (ret < 0) myfail("Error signing data %s\n", gnutls_strerror(ret)); /* verify against the pubkey in PKCS #11 */ ret = gnutls_pubkey_verify_data2(pubkey, sigalgo, 0, &testdata, &sig); if (ret < 0) myfail("Error verifying data1: %s\n", gnutls_strerror(ret)); /* verify against the raw pubkey */ ret = gnutls_pubkey_verify_data2(pubkey2, sigalgo, 0, &testdata, &sig); if (ret < 0) myfail("Error verifying data2: %s\n", gnutls_strerror(ret)); gnutls_free(sig.data); } gnutls_pubkey_deinit(pubkey2); gnutls_pubkey_deinit(pubkey); gnutls_privkey_deinit(pkey); gnutls_global_deinit(); remove(CONFIG); }
static int check_dsa(void) { gnutls_privkey_t key; gnutls_pubkey_t pub; gnutls_datum_t p, q, g, y, x; int ret; global_init(); success("Checking DSA key operations\n"); ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_init(&pub); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_x509_raw(key, &dsa_key, GNUTLS_X509_FMT_PEM, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_import_privkey(pub, key, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_export_dsa_raw2(pub, &p, &q, &g, &y, 0); if (ret < 0) fail("error\n"); CMP("p", &p, dsa_p); CMP("q", &q, dsa_q); CMP("g", &g, dsa_g); CMP("y", &y, dsa_y); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(g.data); gnutls_free(y.data); ret = gnutls_pubkey_export_dsa_raw2(pub, &p, &q, &g, &y, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); CMP_NO_LZ("p", &p, dsa_p); CMP_NO_LZ("q", &q, dsa_q); CMP_NO_LZ("g", &g, dsa_g); CMP_NO_LZ("y", &y, dsa_y); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(g.data); gnutls_free(y.data); ret = gnutls_privkey_export_dsa_raw(key, &p, &q, &g, &y, &x); if (ret < 0) fail("error\n"); CMP("p", &p, dsa_p); CMP("q", &q, dsa_q); CMP("g", &g, dsa_g); CMP("y", &y, dsa_y); CMP("x", &x, dsa_x); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(g.data); gnutls_free(y.data); gnutls_free(x.data); ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x); if (ret < 0 || x.size == 0) fail("error in pkcs8 export\n"); gnutls_free(x.data); gnutls_privkey_deinit(key); gnutls_pubkey_deinit(pub); return 0; }
static int check_rsa(void) { gnutls_privkey_t key; gnutls_pubkey_t pub; gnutls_datum_t m, e, d, p, q, u, e1, e2; int ret; success("Checking RSA key operations\n"); /* RSA */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_init(&pub); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_x509_raw(key, &rsa_key, GNUTLS_X509_FMT_PEM, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_import_privkey(pub, key, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_export_rsa_raw2(pub, &m, &e, 0); if (ret < 0) fail("error\n"); CMP("m", &m, rsa_m); CMP("e", &e, rsa_e); gnutls_free(m.data); gnutls_free(e.data); ret = gnutls_pubkey_export_rsa_raw2(pub, &m, &e, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); CMP_NO_LZ("m", &m, rsa_m); CMP_NO_LZ("e", &e, rsa_e); gnutls_free(m.data); gnutls_free(e.data); ret = gnutls_privkey_export_rsa_raw(key, &m, &e, &d, &p, &q, &u, &e1, &e2); if (ret < 0) fail("error\n"); CMP("m", &m, rsa_m); CMP("e", &e, rsa_e); CMP("d", &d, rsa_d); CMP("p", &p, rsa_p); CMP("q", &q, rsa_q); CMP("u", &u, rsa_u); CMP("e1", &e1, rsa_e1); CMP("e2", &e2, rsa_e2); gnutls_free(m.data); gnutls_free(e.data); gnutls_free(d.data); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(u.data); gnutls_free(e1.data); gnutls_free(e2.data); ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &m); if (ret < 0 || m.size == 0) fail("error in pkcs8 export\n"); gnutls_free(m.data); gnutls_privkey_deinit(key); gnutls_pubkey_deinit(pub); return 0; }
static int check_ecc(void) { gnutls_privkey_t key; gnutls_pubkey_t pub; gnutls_datum_t y, x, k; gnutls_ecc_curve_t curve; int ret; success("Checking SECP256R1 key operations\n"); /* ECC */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_init(&pub); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_x509_raw(key, &server_ecc_key, GNUTLS_X509_FMT_PEM, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_import_privkey(pub, key, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, &y, 0); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_SECP256R1) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } CMP("x", &x, ecc_x); CMP("y", &y, ecc_y); gnutls_free(x.data); gnutls_free(y.data); ret = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, &y, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_SECP256R1) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } CMP_NO_LZ("x", &x, ecc_x); CMP_NO_LZ("y", &y, ecc_y); gnutls_free(x.data); gnutls_free(y.data); /* check the private key export */ ret = gnutls_privkey_export_ecc_raw(key, &curve, &x, &y, &k); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_SECP256R1) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } CMP("x", &x, ecc_x); CMP("y", &y, ecc_y); CMP("k", &k, ecc_k); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(k.data); ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x); if (ret < 0 || x.size == 0) fail("error in pkcs8 export\n"); gnutls_free(x.data); gnutls_privkey_deinit(key); /* More public key ops */ ret = gnutls_pubkey_export_ecc_x962(pub, &x, &y); if (ret < 0) fail("error\n"); CMP("parameters", &x, ecc_params); CMP("ecpoint", &y, ecc_point); ret = gnutls_pubkey_import_ecc_x962(pub, &x, &y); if (ret < 0) fail("error\n"); gnutls_free(x.data); gnutls_free(y.data); /* check again */ ret = gnutls_pubkey_export_ecc_raw(pub, &curve, &x, &y); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_SECP256R1) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); fail("error\n"); } CMP("x", &x, ecc_x); CMP("y", &y, ecc_y); gnutls_free(x.data); gnutls_free(y.data); gnutls_pubkey_deinit(pub); return 0; }
static int check_ed25519(void) { gnutls_privkey_t key; gnutls_pubkey_t pub; gnutls_datum_t y, x, k; gnutls_ecc_curve_t curve; int ret; success("Checking ed25519 key operations\n"); /* ECC */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_init(&pub); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_x509_raw(key, &server_ca3_eddsa_key, GNUTLS_X509_FMT_PEM, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_import_privkey(pub, key, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_export_ecc_raw(pub, &curve, &x, NULL); if (ret < 0) fail("error\n"); gnutls_free(x.data); ret = gnutls_pubkey_export_ecc_raw(pub, &curve, &x, &y); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_ED25519) { fail("unexpected curve value: %d\n", (int)curve); } CMP("x", &x, ed25519_x); if (y.data != NULL) { fail("expected NULL value in Y\n"); } gnutls_free(x.data); /* check the private key export */ ret = gnutls_privkey_export_ecc_raw(key, &curve, &x, NULL, &k); if (ret < 0) fail("error\n"); gnutls_free(x.data); gnutls_free(k.data); ret = gnutls_privkey_export_ecc_raw(key, &curve, &x, &y, &k); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_ED25519) { fail("unexpected curve value: %d\n", (int)curve); } CMP("x", &x, ed25519_x); CMP("k", &k, ed25519_k); gnutls_free(x.data); gnutls_free(k.data); if (y.data != NULL) { fail("expected NULL value in Y\n"); } ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x); if (ret < 0 || x.size == 0) fail("error in pkcs8 export\n"); gnutls_free(x.data); gnutls_privkey_deinit(key); /* More public key ops */ ret = gnutls_pubkey_export_ecc_x962(pub, &x, &y); if (ret != GNUTLS_E_INVALID_REQUEST) fail("error\n"); gnutls_pubkey_deinit(pub); return 0; }
static int check_gost(void) { gnutls_privkey_t key; gnutls_pubkey_t pub; gnutls_datum_t y, x, k; gnutls_ecc_curve_t curve; gnutls_digest_algorithm_t digest; gnutls_gost_paramset_t paramset; int ret; success("Checking GOST key operations\n"); /* ECC */ ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_init(&pub); if (ret < 0) fail("error\n"); ret = gnutls_privkey_import_x509_raw(key, &server_ca3_gost01_key, GNUTLS_X509_FMT_PEM, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_import_privkey(pub, key, 0, 0); if (ret < 0) fail("error\n"); ret = gnutls_pubkey_export_gost_raw2(pub, &curve, &digest, ¶mset, &x, &y, 0); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } if (digest != GNUTLS_DIG_GOSTR_94) { fprintf(stderr, "unexpected digest value: %d\n", (int)digest); exit(1); } if (paramset != GNUTLS_GOST_PARAMSET_CP_A) { fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset); exit(1); } CMP("x", &x, gost_x); CMP("y", &y, gost_y); gnutls_free(x.data); gnutls_free(y.data); ret = gnutls_pubkey_export_gost_raw2(pub, &curve, &digest, ¶mset, &x, &y, GNUTLS_EXPORT_FLAG_NO_LZ); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } if (digest != GNUTLS_DIG_GOSTR_94) { fprintf(stderr, "unexpected digest value: %d\n", (int)digest); exit(1); } if (paramset != GNUTLS_GOST_PARAMSET_CP_A) { fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset); exit(1); } CMP_NO_LZ("x", &x, gost_x); CMP_NO_LZ("y", &y, gost_y); gnutls_free(x.data); gnutls_free(y.data); /* check the private key export */ ret = gnutls_privkey_export_gost_raw2(key, &curve, &digest, ¶mset, &x, &y, &k, 0); if (ret < 0) fail("error\n"); if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) { fprintf(stderr, "unexpected curve value: %d\n", (int)curve); exit(1); } if (digest != GNUTLS_DIG_GOSTR_94) { fprintf(stderr, "unexpected digest value: %d\n", (int)digest); exit(1); } if (paramset != GNUTLS_GOST_PARAMSET_CP_A) { fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset); exit(1); } CMP("x", &x, gost_x); CMP("y", &y, gost_y); CMP("k", &k, gost_k); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(k.data); ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x); if (ret < 0 || x.size == 0) fail("error in pkcs8 export\n"); gnutls_free(x.data); gnutls_privkey_deinit(key); gnutls_pubkey_deinit(pub); return 0; }
void doit(void) { gnutls_x509_privkey_t key; gnutls_x509_crt_t crt; gnutls_pubkey_t pubkey; gnutls_privkey_t privkey; gnutls_sign_algorithm_t sign_algo; gnutls_datum_t signature; gnutls_datum_t signature2; int ret; size_t i; global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); for (i = 0; i < sizeof(key_dat) / sizeof(key_dat[0]); i++) { if (debug) success("loop %d\n", (int) 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_pubkey_init(&pubkey); if (ret < 0) fail("gnutls_privkey_init\n"); ret = gnutls_privkey_init(&privkey); if (ret < 0) fail("gnutls_pubkey_init\n"); ret = gnutls_privkey_import_x509(privkey, key, 0); if (ret < 0) fail("gnutls_privkey_import_x509\n"); ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, 0, &hash_data, &signature2); if (ret < 0) fail("gnutls_privkey_sign_hash\n"); ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &raw_data, &signature); 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"); ret = gnutls_pubkey_import_x509(pubkey, crt, 0); if (ret < 0) fail("gnutls_x509_pubkey_import\n"); ret = gnutls_x509_crt_get_signature_algorithm(crt); if (ret != GNUTLS_SIGN_RSA_SHA1) fail("gnutls_crt_get_signature_algorithm\n"); ret = gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &hash_data, &signature); if (ret < 0) fail("gnutls_x509_pubkey_verify_hash2\n"); ret = gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &hash_data, &signature2); if (ret < 0) fail("gnutls_x509_pubkey_verify_hash-1 (hashed data)\n"); /* should fail */ ret = gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &invalid_hash_data, &signature2); if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) fail("gnutls_x509_pubkey_verify_hash-2 (hashed data)\n"); sign_algo = gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm (pubkey, NULL), GNUTLS_DIG_SHA1); ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0, &hash_data, &signature2); if (ret < 0) fail("gnutls_x509_pubkey_verify_hash2-1 (hashed data)\n"); /* should fail */ ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0, &invalid_hash_data, &signature2); if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) fail("gnutls_x509_pubkey_verify_hash2-2 (hashed data)\n"); /* test the raw interface */ gnutls_free(signature.data); signature.data = NULL; if (gnutls_pubkey_get_pk_algorithm(pubkey, NULL) == GNUTLS_PK_RSA) { ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, &hash_data, &signature); if (ret < 0) fail("gnutls_privkey_sign_hash: %s\n", gnutls_strerror(ret)); sign_algo = gnutls_pk_to_sign (gnutls_pubkey_get_pk_algorithm(pubkey, NULL), GNUTLS_DIG_SHA1); ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA, &hash_data, &signature); if (ret < 0) fail("gnutls_pubkey_verify_hash-3 (raw hashed data)\n"); gnutls_free(signature.data); /* test the legacy API */ ret = gnutls_privkey_sign_raw_data(privkey, 0, &hash_data, &signature); if (ret < 0) fail("gnutls_privkey_sign_raw_data: %s\n", gnutls_strerror(ret)); ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA, &hash_data, &signature); if (ret < 0) fail("gnutls_pubkey_verify_hash-4 (legacy raw hashed data)\n"); } gnutls_free(signature.data); gnutls_free(signature2.data); gnutls_x509_privkey_deinit(key); gnutls_x509_crt_deinit(crt); gnutls_privkey_deinit(privkey); gnutls_pubkey_deinit(pubkey); } gnutls_global_deinit(); }
void pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags, common_info_st * info) { gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; int ret; gnutls_datum_t data, sig = {NULL, 0}; int pk; pkcs11_common(info); FIX(url, outfile, 0, info); data.data = (void*)TEST_DATA; data.size = sizeof(TEST_DATA)-1; ret = gnutls_privkey_init(&privkey); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_init(&pubkey); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_privkey_import_url(privkey, url, flags); if (ret < 0) { fprintf(stderr, "Cannot import private key: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags); if (ret < 0) { fprintf(stderr, "Cannot import public key: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig); if (ret < 0) { fprintf(stderr, "Cannot sign data: %s\n", gnutls_strerror(ret)); exit(1); } pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL); fprintf(stderr, "Verifying against private key parameters... "); ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1), 0, &data, &sig); if (ret < 0) { fprintf(stderr, "Cannot verify signed data: %s\n", gnutls_strerror(ret)); exit(1); } fprintf(stderr, "ok\n"); /* now try to verify against a public key within the token */ gnutls_pubkey_deinit(pubkey); ret = gnutls_pubkey_init(&pubkey); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } ret = gnutls_pubkey_import_url(pubkey, url, flags); if (ret < 0) { fprintf(stderr, "Cannot find a corresponding public key object in token: %s\n", gnutls_strerror(ret)); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) exit(0); exit(1); } fprintf(stderr, "Verifying against public key in the token... "); ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1), 0, &data, &sig); if (ret < 0) { fprintf(stderr, "Cannot verify signed data: %s\n", gnutls_strerror(ret)); exit(1); } fprintf(stderr, "ok\n"); gnutls_free(sig.data); gnutls_pubkey_deinit(pubkey); gnutls_privkey_deinit(privkey); UNFIX; }
void doit(void) { int ret; unsigned int mode; gnutls_cipher_hd_t ch; gnutls_hmac_hd_t mh; gnutls_session_t session; gnutls_pubkey_t pubkey; gnutls_x509_privkey_t xprivkey; gnutls_privkey_t privkey; gnutls_datum_t key = { key16, sizeof(key16) }; gnutls_datum_t iv = { iv16, sizeof(iv16) }; fprintf(stderr, "Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n"); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); mode = gnutls_fips140_mode_enabled(); if (mode == 0) { success("We are not in FIPS140 mode\n"); exit(77); } ret = global_init(); if (ret < 0) { fail("Cannot initialize library\n"); } /* Try crypto.h functionality */ ret = gnutls_cipher_init(&ch, GNUTLS_CIPHER_AES_128_CBC, &key, &iv); if (ret < 0) { fail("gnutls_cipher_init failed\n"); } gnutls_cipher_deinit(ch); ret = gnutls_hmac_init(&mh, GNUTLS_MAC_SHA1, key.data, key.size); if (ret < 0) { fail("gnutls_hmac_init failed\n"); } gnutls_hmac_deinit(mh, NULL); ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16)); if (ret < 0) { fail("gnutls_rnd failed\n"); } ret = gnutls_pubkey_init(&pubkey); if (ret < 0) { fail("gnutls_pubkey_init failed\n"); } gnutls_pubkey_deinit(pubkey); ret = gnutls_privkey_init(&privkey); if (ret < 0) { fail("gnutls_privkey_init failed\n"); } gnutls_privkey_deinit(privkey); ret = gnutls_x509_privkey_init(&xprivkey); if (ret < 0) { fail("gnutls_privkey_init failed\n"); } gnutls_x509_privkey_deinit(xprivkey); ret = gnutls_init(&session, 0); if (ret < 0) { fail("gnutls_init failed\n"); } gnutls_deinit(session); /* Test when FIPS140 is set to error state */ _gnutls_lib_simulate_error(); /* Try crypto.h functionality */ ret = gnutls_cipher_init(&ch, GNUTLS_CIPHER_AES_128_CBC, &key, &iv); if (ret >= 0) { fail("gnutls_cipher_init succeeded when in FIPS140 error state\n"); } ret = gnutls_hmac_init(&mh, GNUTLS_MAC_SHA1, key.data, key.size); if (ret >= 0) { fail("gnutls_hmac_init succeeded when in FIPS140 error state\n"); } ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16)); if (ret >= 0) { fail("gnutls_rnd succeeded when in FIPS140 error state\n"); } ret = gnutls_pubkey_init(&pubkey); if (ret >= 0) { fail("gnutls_pubkey_init succeeded when in FIPS140 error state\n"); } ret = gnutls_privkey_init(&privkey); if (ret >= 0) { fail("gnutls_privkey_init succeeded when in FIPS140 error state\n"); } ret = gnutls_x509_privkey_init(&xprivkey); if (ret >= 0) { fail("gnutls_x509_privkey_init succeeded when in FIPS140 error state\n"); } ret = gnutls_init(&session, 0); if (ret >= 0) { fail("gnutls_init succeeded when in FIPS140 error state\n"); } gnutls_global_deinit(); return; }
void Plugin::_loadCertificate() { QFile file(this->crtFile); gnutls_datum_t datum; size_t size = 2048; QByteArray data; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; gnutls_pubkey_t pubkeyCrt; int error; QMap<char *, QByteArray> oid; gnutls_digest_algorithm_t digest; if (!file.open(QIODevice::ReadWrite)) throw Properties("error", "Unable to open the certificate file").add("file", this->crtFile); ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt"); ASSERT(gnutls_privkey_init(&privkey)); ASSERT(gnutls_privkey_import_x509(privkey, this->key, 0)); ASSERT(gnutls_pubkey_init(&pubkey)); ASSERT(gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0)); // Verifies that the certificate is valid if (file.size() > 0) { ASSERT(gnutls_pubkey_init(&pubkeyCrt)); data = file.readAll(); datum.size = data.size(); datum.data = (unsigned char *)data.data(); if (gnutls_x509_crt_import(this->crt, &datum, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) file.resize(0); else if (gnutls_x509_crt_get_expiration_time(this->crt) < ::time(NULL) + CRT_EXPIRATION_REGEN) file.resize(0); else if (gnutls_pubkey_import_x509(pubkeyCrt, this->crt, 0) != GNUTLS_E_SUCCESS) file.resize(0); // Ensures that the public keys of the certificate and the private key match size_t size1 = size, size2 = size; QByteArray pub1((int)size1, 0), pub2((int)size2, 0); if (gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, pub1.data(), &size1) != GNUTLS_E_SUCCESS || gnutls_pubkey_export(pubkeyCrt, GNUTLS_X509_FMT_PEM, pub2.data(), &size2) != GNUTLS_E_SUCCESS || size1 != size2 || pub1 != pub2) file.resize(0); gnutls_pubkey_deinit(pubkeyCrt); } // Generates a new certificate if (file.size() == 0) { gnutls_x509_crt_deinit(this->crt); this->init.removeAll("crt"); ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt"); LOG_INFO("Generating a new certificate", "Plugin", "_generateCertificate"); oid.insert((char *)GNUTLS_OID_X520_COMMON_NAME, "LightBird"); oid.insert((char *)GNUTLS_OID_X520_ORGANIZATION_NAME, "LightBird"); QMapIterator<char *, QByteArray> it(oid); while (it.hasNext()) ASSERT(gnutls_x509_crt_set_dn_by_oid(this->crt, it.key(), 0, it.value().data(), it.next().value().size())); ASSERT(gnutls_x509_crt_set_pubkey(this->crt, pubkey)); data = this->_generateSerial(); ASSERT(gnutls_x509_crt_set_serial(this->crt, data.data(), data.size())); ASSERT(gnutls_x509_crt_set_activation_time(this->crt, ::time(NULL))); ASSERT(gnutls_x509_crt_set_expiration_time(this->crt, ::time(NULL) + CRT_EXPIRATION)); ASSERT(gnutls_x509_crt_set_basic_constraints(this->crt, 0, -1)); ASSERT(gnutls_x509_crt_set_key_purpose_oid(this->crt, GNUTLS_KP_TLS_WWW_SERVER, 0)); ASSERT(gnutls_x509_crt_set_key_usage(this->crt, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT)); data.resize((int)size); ASSERT(gnutls_x509_crt_get_key_id(this->crt, 0, (unsigned char *)data.data(), &size)); ASSERT(gnutls_x509_crt_set_subject_key_id(this->crt, (unsigned char *)data.data(), size)); ASSERT(gnutls_x509_crt_set_version(this->crt, 3)); ASSERT(gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &digest, NULL)); ASSERT(gnutls_x509_crt_privkey_sign(this->crt, this->crt, privkey, digest, 0)); size = data.size(); ASSERT(gnutls_x509_crt_export(this->crt, GNUTLS_X509_FMT_PEM, data.data(), &size)); data.resize((int)size); file.write(data); } gnutls_pubkey_deinit(pubkey); gnutls_privkey_deinit(privkey); }