/* Load a public key. * @mand should be non zero if it is required to read a public key. */ gnutls_pubkey_t load_pubkey(int mand, common_info_st * info) { gnutls_pubkey_t key; int ret; gnutls_datum_t dat; size_t size; if (!info->pubkey && !mand) return NULL; if (info->pubkey == NULL) { fprintf(stderr, "missing --load-pubkey\n"); exit(1); } if (gnutls_url_is_supported(info->pubkey) != 0) return _load_url_pubkey(info->pubkey); ret = gnutls_pubkey_init(&key); if (ret < 0) { fprintf(stderr, "privkey_init: %s\n", gnutls_strerror(ret)); exit(1); } dat.data = (void *) read_binary_file(info->pubkey, &size); dat.size = size; if (!dat.data) { fprintf(stderr, "error reading --load-pubkey: %s\n", info->pubkey); exit(1); } ret = gnutls_pubkey_import(key, &dat, info->incert_format); if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { ret = gnutls_pubkey_import_x509_raw(key, &dat, info->incert_format, 0); if (ret < 0) { fprintf(stderr, "import error: could not find a valid PEM header; " "check if your key has the PUBLIC KEY header\n"); exit(1); } } else if (ret < 0) { fprintf(stderr, "importing --load-pubkey: %s: %s\n", info->pubkey, gnutls_strerror(ret)); exit(1); } free(dat.data); return key; }
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); }