void pkcs11_write(FILE * outfile, const char *url, const char *label, const char *id, unsigned flags, common_info_st * info) { gnutls_x509_crt_t xcrt; gnutls_x509_privkey_t xkey; gnutls_pubkey_t xpubkey; int ret; gnutls_datum_t *secret_key; unsigned key_usage = 0; unsigned char raw_id[128]; size_t raw_id_size; gnutls_datum_t cid = {NULL, 0}; pkcs11_common(info); FIX(url, outfile, 0, info); CHECK_LOGIN_FLAG(flags); if (label == NULL && info->batch == 0) { label = read_str("warning: The object's label was not specified.\nLabel: "); } if (id != NULL) { raw_id_size = sizeof(raw_id); ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size); if (ret < 0) { fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret)); exit(1); } cid.data = raw_id; cid.size = raw_id_size; } secret_key = load_secret_key(0, info); if (secret_key != NULL) { ret = gnutls_pkcs11_copy_secret_key(url, secret_key, label, info->key_usage, flags | GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } } xcrt = load_cert(0, info); if (xcrt != NULL) { ret = gnutls_pkcs11_copy_x509_crt2(url, xcrt, label, &cid, flags); if (ret < 0) { fprintf(stderr, "Error writing certificate: %s\n", gnutls_strerror(ret)); if (((flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) || (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED)) && (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO) == 0) fprintf(stderr, "note: some tokens may require security officer login for this operation\n"); exit(1); } gnutls_x509_crt_get_key_usage(xcrt, &key_usage, NULL); gnutls_x509_crt_deinit(xcrt); } xkey = load_x509_private_key(0, info); if (xkey != NULL) { ret = gnutls_pkcs11_copy_x509_privkey2(url, xkey, label, &cid, key_usage|info->key_usage, flags | GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_x509_privkey_deinit(xkey); } xpubkey = load_pubkey(0, info); if (xpubkey != NULL) { ret = gnutls_pkcs11_copy_pubkey(url, xpubkey, label, &cid, 0, flags); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_pubkey_deinit(xpubkey); } if (xkey == NULL && xcrt == NULL && secret_key == NULL && xpubkey == NULL) { fprintf(stderr, "You must use --load-privkey, --load-certificate, --load-pubkey or --secret-key to load the file to be copied\n"); exit(1); } UNFIX; return; }
/** * gnutls_tpm_privkey_generate: * @pk: the public key algorithm * @bits: the security bits * @srk_password: a password to protect the exported key (optional) * @key_password: the password for the TPM (optional) * @format: the format of the private key * @pub_format: the format of the public key * @privkey: the generated key * @pubkey: the corresponding public key (may be null) * @flags: should be a list of GNUTLS_TPM_* flags * * This function will generate a private key in the TPM * chip. The private key will be generated within the chip * and will be exported in a wrapped with TPM's master key * form. Furthermore the wrapped key can be protected with * the provided @password. * * Note that bits in TPM is quantized value. If the input value * is not one of the allowed values, then it will be quantized to * one of 512, 1024, 2048, 4096, 8192 and 16384. * * Allowed flags are: * * %GNUTLS_TPM_KEY_SIGNING: Generate a signing key instead of a legacy, * * %GNUTLS_TPM_REGISTER_KEY: Register the generate key in TPM. In that * case @privkey would contain a URL with the UUID. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.1.0 **/ int gnutls_tpm_privkey_generate(gnutls_pk_algorithm_t pk, unsigned int bits, const char *srk_password, const char *key_password, gnutls_tpmkey_fmt_t format, gnutls_x509_crt_fmt_t pub_format, gnutls_datum_t * privkey, gnutls_datum_t * pubkey, unsigned int flags) { TSS_FLAG tpm_flags = TSS_KEY_VOLATILE; TSS_HKEY key_ctx; TSS_RESULT tssret; int ret; void *tdata; UINT32 tint; gnutls_datum_t tmpkey = { NULL, 0 }; TSS_HPOLICY key_policy; gnutls_pubkey_t pub; struct tpm_ctx_st s; TSS_FLAG storage_type; TSS_HTPM htpm; uint8_t buf[32]; CHECK_INIT; privkey->data = NULL; if (pubkey != NULL) pubkey->data = NULL; if (flags & GNUTLS_TPM_KEY_SIGNING) tpm_flags |= TSS_KEY_TYPE_SIGNING; else tpm_flags |= TSS_KEY_TYPE_LEGACY; if (flags & GNUTLS_TPM_KEY_USER) storage_type = TSS_PS_TYPE_USER; else storage_type = TSS_PS_TYPE_SYSTEM; if (bits <= 512) tpm_flags |= TSS_KEY_SIZE_512; else if (bits <= 1024) tpm_flags |= TSS_KEY_SIZE_1024; else if (bits <= 2048) tpm_flags |= TSS_KEY_SIZE_2048; else if (bits <= 4096) tpm_flags |= TSS_KEY_SIZE_4096; else if (bits <= 8192) tpm_flags |= TSS_KEY_SIZE_8192; else tpm_flags |= TSS_KEY_SIZE_16384; ret = tpm_open_session(&s, srk_password, 0); if (ret < 0) return gnutls_assert_val(ret); /* put some randomness into TPM. * Let's not trust it completely. */ tssret = pTspi_Context_GetTpmObject(s.tpm_ctx, &htpm); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_cc; } ret = gnutls_rnd(GNUTLS_RND_RANDOM, buf, sizeof(buf)); if (ret < 0) { gnutls_assert(); goto err_cc; } tssret = pTspi_TPM_StirRandom(htpm, sizeof(buf), buf); if (tssret) { gnutls_assert(); } tssret = pTspi_Context_CreateObject(s.tpm_ctx, TSS_OBJECT_TYPE_RSAKEY, tpm_flags, &key_ctx); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_cc; } tssret = pTspi_SetAttribUint32(key_ctx, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, TSS_SS_RSASSAPKCS1V15_DER); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_sa; } /* set the password of the actual key */ if (key_password) { gnutls_datum_t pout; char *password = NULL; tssret = pTspi_GetPolicyObject(key_ctx, TSS_POLICY_USAGE, &key_policy); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_sa; } ret = _gnutls_utf8_password_normalize(key_password, strlen(key_password), &pout, 0); if (ret < 0) { gnutls_assert(); goto err_sa; } password = (char*)pout.data; tssret = myTspi_Policy_SetSecret(key_policy, SAFE_LEN(password), (void *)password); gnutls_free(password); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_sa; } } tssret = pTspi_Key_CreateKey(key_ctx, s.srk, 0); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_sa; } if (flags & GNUTLS_TPM_REGISTER_KEY) { TSS_UUID key_uuid; ret = randomize_uuid(&key_uuid); if (ret < 0) { gnutls_assert(); goto err_sa; } tssret = pTspi_Context_RegisterKey(s.tpm_ctx, key_ctx, storage_type, key_uuid, TSS_PS_TYPE_SYSTEM, srk_uuid); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_sa; } ret = encode_tpmkey_url((char **) &privkey->data, &key_uuid, storage_type); if (ret < 0) { TSS_HKEY tkey; pTspi_Context_UnregisterKey(s.tpm_ctx, storage_type, key_uuid, &tkey); gnutls_assert(); goto err_sa; } privkey->size = strlen((char *) privkey->data); } else { /* get the key as blob */ tssret = pTspi_GetAttribData(key_ctx, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_BLOB, &tint, (void *) &tdata); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto err_sa; } if (format == GNUTLS_TPMKEY_FMT_CTK_PEM) { ret = _gnutls_x509_encode_string (ASN1_ETYPE_OCTET_STRING, tdata, tint, &tmpkey); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_fbase64_encode("TSS KEY BLOB", tmpkey.data, tmpkey.size, privkey); if (ret < 0) { gnutls_assert(); goto cleanup; } } else { UINT32 tint2; tmpkey.size = tint + 32; /* spec says no more than 20 */ tmpkey.data = gnutls_malloc(tmpkey.size); if (tmpkey.data == NULL) { gnutls_assert(); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } tint2 = tmpkey.size; tssret = pTspi_EncodeDER_TssBlob(tint, tdata, TSS_BLOB_TYPE_PRIVATEKEY, &tint2, tmpkey.data); if (tssret != 0) { gnutls_assert(); ret = tss_err(tssret); goto cleanup; } tmpkey.size = tint2; privkey->data = tmpkey.data; privkey->size = tmpkey.size; tmpkey.data = NULL; } } /* read the public key */ if (pubkey != NULL) { size_t psize = 0; ret = gnutls_pubkey_init(&pub); if (ret < 0) { gnutls_assert(); goto privkey_cleanup; } ret = read_pubkey(pub, key_ctx, &psize); if (ret < 0) { gnutls_assert(); goto privkey_cleanup; } psize += 512; pubkey->data = gnutls_malloc(psize); if (pubkey->data == NULL) { gnutls_assert(); ret = GNUTLS_E_MEMORY_ERROR; goto pubkey_cleanup; } ret = gnutls_pubkey_export(pub, pub_format, pubkey->data, &psize); if (ret < 0) { gnutls_assert(); goto pubkey_cleanup; } pubkey->size = psize; gnutls_pubkey_deinit(pub); } ret = 0; goto cleanup; pubkey_cleanup: gnutls_pubkey_deinit(pub); privkey_cleanup: gnutls_free(privkey->data); cleanup: gnutls_free(tmpkey.data); err_sa: pTspi_Context_CloseObject(s.tpm_ctx, key_ctx); err_cc: tpm_close_session(&s); return ret; }
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) { 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(); }
static void dane_info(const char *host, const char *proto, unsigned int port, unsigned int ca, unsigned int domain, common_info_st * cinfo) { gnutls_pubkey_t pubkey; gnutls_x509_crt_t crt; unsigned char digest[64]; gnutls_datum_t t; int ret; unsigned int usage, selector, type; size_t size; if (proto == NULL) proto = "tcp"; if (port == 0) port = 443; crt = load_cert(0, cinfo); if (crt != NULL && HAVE_OPT(X509)) { selector = 0; /* X.509 */ size = buffer_size; ret = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER, buffer, &size); if (ret < 0) { fprintf(stderr, "export error: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt); } else { /* use public key only */ selector = 1; ret = gnutls_pubkey_init(&pubkey); if (ret < 0) { fprintf(stderr, "pubkey_init: %s\n", gnutls_strerror(ret)); exit(1); } if (crt != NULL) { ret = gnutls_pubkey_import_x509(pubkey, crt, 0); if (ret < 0) { fprintf(stderr, "pubkey_import_x509: %s\n", gnutls_strerror(ret)); exit(1); } size = buffer_size; ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, buffer, &size); if (ret < 0) { fprintf(stderr, "pubkey_export: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt); } else { pubkey = load_pubkey(1, cinfo); size = buffer_size; ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, buffer, &size); if (ret < 0) { fprintf(stderr, "export error: %s\n", gnutls_strerror(ret)); exit(1); } } gnutls_pubkey_deinit(pubkey); } if (default_dig != GNUTLS_DIG_SHA256 && default_dig != GNUTLS_DIG_SHA512) { if (default_dig != GNUTLS_DIG_UNKNOWN) fprintf(stderr, "Unsupported digest. Assuming SHA256.\n"); default_dig = GNUTLS_DIG_SHA256; } ret = gnutls_hash_fast(default_dig, buffer, size, digest); if (ret < 0) { fprintf(stderr, "hash error: %s\n", gnutls_strerror(ret)); exit(1); } if (default_dig == GNUTLS_DIG_SHA256) type = 1; else type = 2; /* DANE certificate classification crap */ if (domain == 0) { if (ca) usage = 0; else usage = 1; } else { if (ca) usage = 2; else usage = 3; } t.data = digest; t.size = gnutls_hash_get_len(default_dig); size = buffer_size; ret = gnutls_hex_encode(&t, (void *) buffer, &size); if (ret < 0) { fprintf(stderr, "hex encode error: %s\n", gnutls_strerror(ret)); exit(1); } fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", port, proto, host, usage, selector, type, buffer); }
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 void dcrypt_gnutls_free_public_key(struct dcrypt_public_key **key) { gnutls_pubkey_deinit((gnutls_pubkey_t)*key); *key = NULL; }
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_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; }
void doit (void) { gnutls_x509_privkey_t key; gnutls_x509_crt_t crt; gnutls_pubkey_t pubkey; gnutls_privkey_t privkey; gnutls_digest_algorithm_t hash_algo; gnutls_sign_algorithm_t sign_algo; gnutls_datum_t signature; gnutls_datum_t signature2; int ret; size_t i; gnutls_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_pubkey_get_verify_algorithm (pubkey, &signature, &hash_algo); if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1) fail ("gnutls_x509_crt_get_verify_algorithm\n"); ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature); if (ret < 0) fail ("gnutls_x509_pubkey_verify_hash\n"); ret = gnutls_pubkey_get_verify_algorithm (pubkey, &signature2, &hash_algo); if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1) fail ("gnutls_x509_crt_get_verify_algorithm (hashed data)\n"); ret = gnutls_pubkey_verify_hash (pubkey, 0, &hash_data, &signature2); if (ret < 0) fail ("gnutls_x509_pubkey_verify_hash-1 (hashed data)\n"); /* should fail */ ret = gnutls_pubkey_verify_hash (pubkey, 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"); 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 (); }
static void test_sig(gnutls_pk_algorithm_t pk, unsigned hash, unsigned bits) { gnutls_pubkey_t pubkey; gnutls_privkey_t privkey; gnutls_sign_algorithm_t sign_algo; gnutls_datum_t signature; const gnutls_datum_t *hash_data; int ret; unsigned j; if (hash == GNUTLS_DIG_SHA1) hash_data = &sha1_data; else if (hash == GNUTLS_DIG_SHA256) hash_data = &sha256_data; else abort(); sign_algo = gnutls_pk_to_sign(pk, hash); for (j = 0; j < 100; j++) { ret = gnutls_pubkey_init(&pubkey); if (ret < 0) ERR(__LINE__); ret = gnutls_privkey_init(&privkey); if (ret < 0) ERR(__LINE__); ret = gnutls_privkey_generate(privkey, pk, bits, 0); if (ret < 0) ERR(__LINE__); ret = gnutls_privkey_sign_hash(privkey, hash, 0, hash_data, &signature); if (ret < 0) ERR(__LINE__); ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, 0); if (ret < 0) ERR(__LINE__); ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0, hash_data, &signature); if (ret < 0) ERR(__LINE__); /* should fail */ ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0, &invalid_hash_data, &signature); if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) ERR(__LINE__); sign_algo = gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm (pubkey, NULL), hash); ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0, hash_data, &signature); if (ret < 0) ERR(__LINE__); /* should fail */ ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0, &invalid_hash_data, &signature); if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) ERR(__LINE__); /* test the raw interface */ gnutls_free(signature.data); signature.data = NULL; if (pk == GNUTLS_PK_RSA) { ret = gnutls_privkey_sign_hash(privkey, hash, GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, hash_data, &signature); if (ret < 0) ERR(__LINE__); sign_algo = gnutls_pk_to_sign (gnutls_pubkey_get_pk_algorithm (pubkey, NULL), hash); ret = gnutls_pubkey_verify_hash2(pubkey, sign_algo, GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA, hash_data, &signature); if (ret < 0) ERR(__LINE__); } gnutls_free(signature.data); gnutls_privkey_deinit(privkey); gnutls_pubkey_deinit(pubkey); } }
static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t * rpubkey) { #ifdef ENABLE_OPENPGP gnutls_openpgp_crt_t crt = NULL; gnutls_pubkey_t pubkey = NULL; size_t size; int ret; ret = gnutls_openpgp_crt_init(&crt); if (ret < 0) return gnutls_assert_val(ret); ret = gnutls_pubkey_init(&pubkey); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_openpgp_crt_import(crt, cert, GNUTLS_OPENPGP_FMT_RAW); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_pubkey_import_openpgp(pubkey, crt, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } size = 0; ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert(); goto cleanup; } rpubkey->data = gnutls_malloc(size); if (rpubkey->data == NULL) if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { ret = GNUTLS_E_MEMORY_ERROR; gnutls_assert(); goto cleanup; } ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, rpubkey->data, &size); if (ret < 0) { gnutls_free(rpubkey->data); gnutls_assert(); goto cleanup; } rpubkey->size = size; ret = 0; cleanup: gnutls_openpgp_crt_deinit(crt); gnutls_pubkey_deinit(pubkey); return ret; #else return GNUTLS_E_UNIMPLEMENTED_FEATURE; #endif }
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); }
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; }
static gnutls_pubkey_t create_rsa_from_modulus(unsigned char *modulus, unsigned int modulus_len, uint32_t exponent) { unsigned char exp_array[4]; uint32_t exponent_no = htonl(exponent); gnutls_pubkey_t rsa = NULL; gnutls_datum_t mod; gnutls_datum_t exp = { .data = exp_array, .size = sizeof(exp_array), }; int err; memcpy(exp_array, &exponent_no, sizeof(exp_array)); err = gnutls_pubkey_init(&rsa); if (err < 0) { fprintf(stderr, "Could not initialized public key structure : %s\n", gnutls_strerror(err)); return NULL; } mod.data = modulus; mod.size = modulus_len; err = gnutls_pubkey_import_rsa_raw(rsa, &mod, &exp); if (err < 0) { fprintf(stderr, "Could not set modulus and exponent on RSA key : %s\n", gnutls_strerror(err)); gnutls_pubkey_deinit(rsa); rsa = NULL; } return rsa; } static int asn_init() { static bool inited; int err; if (inited) return ASN1_SUCCESS; err = asn1_array2tree(tpm_asn1_tab, &_tpm_asn, NULL); if (err != ASN1_SUCCESS) { fprintf(stderr, "array2tree error: %d", err); goto cleanup; } inited = true; cleanup: return err; } static int create_tpm_manufacturer_info(const char *manufacturer, const char *tpm_model, const char *tpm_version, gnutls_datum_t *asn1) { ASN1_TYPE at = ASN1_TYPE_EMPTY; int err; err = asn_init(); if (err != ASN1_SUCCESS) { goto cleanup; } err = asn1_create_element(_tpm_asn, "TPM.TPMManufacturerInfo", &at); if (err != ASN1_SUCCESS) { fprintf(stderr, "asn1_create_element error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmManufacturer.id", "2.23.133.2.1", 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "1. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmManufacturer.manufacturer", manufacturer, 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "2. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmModel.id", "2.23.133.2.2", 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "3. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmModel.model", manufacturer, 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "4. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmVersion.id", "2.23.133.2.3", 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "5. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmVersion.version", manufacturer, 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "6. asn1_write_value error: %d\n", err); goto cleanup; } /* determine needed size of byte array */ asn1->size = 0; err = asn1_der_coding(at, "", NULL, (int *)&asn1->size, NULL); if (err != ASN1_MEM_ERROR) { fprintf(stderr, "1. asn1_der_coding error: %d\n", err); goto cleanup; } //fprintf(stderr, "size=%d\n", asn1->size); asn1->data = gnutls_malloc(asn1->size + 16); err = asn1_der_coding(at, "", asn1->data, (int *)&asn1->size, NULL); if (err != ASN1_SUCCESS) { fprintf(stderr, "2. asn1_der_coding error: %d\n", err); gnutls_free(asn1->data); asn1->data = NULL; goto cleanup; } #if 0 fprintf(stderr, "size=%d\n", asn1->size); unsigned int i = 0; for (i = 0; i < asn1->size; i++) { fprintf(stderr, "%02x ", asn1->data[i]); } fprintf(stderr, "\n"); #endif cleanup: asn1_delete_structure(&at); return err; }
void pkcs11_export (FILE * outfile, const char *url, unsigned int login, common_info_st * info) { gnutls_pkcs11_obj_t crt; gnutls_x509_crt_t xcrt; gnutls_pubkey_t pubkey; int ret; size_t size; unsigned int obj_flags = 0; if (login) obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; pkcs11_common (); if (url == NULL) url = "pkcs11:"; ret = gnutls_pkcs11_obj_init (&crt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_pkcs11_obj_import_url (crt, url, obj_flags); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } switch (gnutls_pkcs11_obj_get_type (crt)) { case GNUTLS_PKCS11_OBJ_X509_CRT: ret = gnutls_x509_crt_init (&xcrt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } size = buffer_size; ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (buffer, 1, size, outfile); gnutls_x509_crt_deinit (xcrt); break; case GNUTLS_PKCS11_OBJ_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_pkcs11 (pubkey, crt, 0); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } size = buffer_size; ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (buffer, 1, size, outfile); gnutls_pubkey_deinit (pubkey); break; default: { gnutls_datum_t data, enc; size = buffer_size; ret = gnutls_pkcs11_obj_export (crt, buffer, &size); if (ret < 0) { break; } data.data = buffer; data.size = size; ret = gnutls_pem_base64_encode_alloc ("DATA", &data, &enc); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (enc.data, 1, enc.size, outfile); gnutls_free (enc.data); break; } } fputs ("\n\n", outfile); gnutls_pkcs11_obj_deinit (crt); return; }
static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t * rpubkey) { gnutls_x509_crt_t crt = NULL; gnutls_pubkey_t pubkey = NULL; size_t size; int ret; ret = gnutls_x509_crt_init(&crt); if (ret < 0) return gnutls_assert_val(ret); ret = gnutls_pubkey_init(&pubkey); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_x509_crt_import(crt, cert, GNUTLS_X509_FMT_DER); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = gnutls_pubkey_import_x509(pubkey, crt, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } size = 0; ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert(); goto cleanup; } rpubkey->data = gnutls_malloc(size); if (rpubkey->data == NULL) if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { ret = GNUTLS_E_MEMORY_ERROR; gnutls_assert(); goto cleanup; } ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, rpubkey->data, &size); if (ret < 0) { gnutls_free(rpubkey->data); gnutls_assert(); goto cleanup; } rpubkey->size = size; ret = 0; cleanup: gnutls_x509_crt_deinit(crt); gnutls_pubkey_deinit(pubkey); return ret; }
void doit(void) { gnutls_x509_privkey_t key; gnutls_x509_crt_t crt; gnutls_pubkey_t pubkey; gnutls_privkey_t privkey; gnutls_datum_t out, out2; int ret; size_t i; global_init(); 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_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_pubkey_encrypt_data(pubkey, 0, &hash_data, &out); if (ret < 0) fail("gnutls_pubkey_encrypt_data\n"); ret = gnutls_privkey_decrypt_data(privkey, 0, &out, &out2); if (ret < 0) fail("gnutls_privkey_decrypt_data\n"); if (out2.size != hash_data.size) fail("Decrypted data don't match original (1)\n"); if (memcmp(out2.data, hash_data.data, hash_data.size) != 0) fail("Decrypted data don't match original (2)\n"); gnutls_free(out.data); gnutls_free(out2.data); ret = gnutls_pubkey_encrypt_data(pubkey, 0, &raw_data, &out); if (ret < 0) fail("gnutls_pubkey_encrypt_data\n"); ret = gnutls_privkey_decrypt_data(privkey, 0, &out, &out2); if (ret < 0) fail("gnutls_privkey_decrypt_data\n"); if (out2.size != raw_data.size) fail("Decrypted data don't match original (3)\n"); if (memcmp(out2.data, raw_data.data, raw_data.size) != 0) fail("Decrypted data don't match original (4)\n"); if (debug) success("ok\n"); gnutls_free(out.data); gnutls_free(out2.data); gnutls_x509_privkey_deinit(key); gnutls_x509_crt_deinit(crt); gnutls_privkey_deinit(privkey); gnutls_pubkey_deinit(pubkey); } gnutls_global_deinit(); }