/* Returns a requested by the peer signature algorithm that * matches the given certificate's public key algorithm. */ gnutls_sign_algorithm_t _gnutls_session_get_sign_algo(gnutls_session_t session, gnutls_pcert_st * cert) { unsigned i; int ret; const version_entry_st *ver = get_version(session); sig_ext_st *priv; extension_priv_data_t epriv; unsigned int cert_algo; if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); cert_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL); ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, &epriv); priv = epriv; if (ret < 0 || !_gnutls_version_has_selectable_sighash(ver) || priv->sign_algorithms_size == 0) /* none set, allow SHA-1 only */ { ret = gnutls_pk_to_sign(cert_algo, GNUTLS_DIG_SHA1); if (_gnutls_session_sign_algo_enabled(session, ret) < 0) goto fail; return ret; } for (i = 0; i < priv->sign_algorithms_size; i++) { if (gnutls_sign_get_pk_algorithm(priv->sign_algorithms[i]) == cert_algo) { if (_gnutls_pubkey_compatible_with_sig (session, cert->pubkey, ver, priv->sign_algorithms[i]) < 0) continue; if (_gnutls_session_sign_algo_enabled (session, priv->sign_algorithms[i]) < 0) continue; return priv->sign_algorithms[i]; } } fail: return GNUTLS_SIGN_UNKNOWN; }
/* Returns a requested by the peer signature algorithm that * matches the given certificate's public key algorithm. */ gnutls_sign_algorithm_t _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_pcert_st* cert) { unsigned i; int ret; gnutls_protocol_t ver = gnutls_protocol_get_version (session); sig_ext_st *priv; extension_priv_data_t epriv; unsigned int cert_algo; cert_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL); ret = _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, &epriv); priv = epriv.ptr; if (ret < 0 || !_gnutls_version_has_selectable_sighash (ver) || priv->sign_algorithms_size == 0) /* none set, allow SHA-1 only */ { return gnutls_pk_to_sign (cert_algo, GNUTLS_DIG_SHA1); } for (i = 0; i < priv->sign_algorithms_size; i++) { if (_gnutls_sign_get_pk_algorithm (priv->sign_algorithms[i]) == cert_algo) { if (_gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, priv->sign_algorithms[i]) < 0) continue; if (_gnutls_session_sign_algo_enabled(session, priv->sign_algorithms[i]) < 0) continue; return priv->sign_algorithms[i]; } } return GNUTLS_SIGN_UNKNOWN; }
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(); }
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); } }