static int dcrypt_gnutls_private_to_public_key(struct dcrypt_private_key *priv_key, struct dcrypt_public_key **pub_key_r, const char **error_r) { int ec; gnutls_privkey_t priv = (gnutls_privkey_t)priv_key; if (gnutls_privkey_get_pk_algorithm(priv, NULL) == GNUTLS_PK_RSA) { gnutls_datum_t m,e; /* do not extract anything we don't need */ ec = gnutls_privkey_export_rsa_raw(priv, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL); if (ec != GNUTLS_E_SUCCESS) return dcrypt_gnutls_error(ec, error_r); gnutls_pubkey_t pub; gnutls_pubkey_init(&pub); ec = gnutls_pubkey_import_rsa_raw(pub, &m, &e); gnutls_free(m.data); gnutls_free(e.data); if (ec < 0) { gnutls_pubkey_deinit(pub); return dcrypt_gnutls_error(ec, error_r); } *pub_key_r = (struct dcrypt_public_key*)pub; return 0; } else if (gnutls_privkey_get_pk_algorithm(priv, NULL) == GNUTLS_PK_EC) { gnutls_ecc_curve_t curve; gnutls_datum_t x,y,k; ec = gnutls_privkey_export_ecc_raw(priv, &curve, &x, &y, NULL); if (ec != GNUTLS_E_SUCCESS) return dcrypt_gnutls_error(ec, error_r); gnutls_pubkey_t pub; gnutls_pubkey_init(&pub); ec = gnutls_pubkey_import_ecc_raw(pub, curve, &x, &y); gnutls_free(x.data); gnutls_free(y.data); if (ec < 0) { gnutls_pubkey_deinit(pub); return dcrypt_gnutls_error(ec, error_r); } *pub_key_r = (struct dcrypt_public_key*)pub; return 0; } return -1; }
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_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_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; }