/* * Demo on how to use /dev/crypto device for HMAC. * * Placed under public domain. * */ #include #include #include #include #include #include #include #include #include #if GNUTLS_VERSION_NUMBER >= 0x020b00 # include #endif #define DATA_SIZE 4096 #define DIAGNOSTIC_CALL(f,p...) \ if ((output_size = f(p)) < 0) { \ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); \ perror(#f); \ return 1; \ } #define DIAGNOSTIC_ERROR(p...) \ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); \ fprintf(stderr, p); #define DIAGNOSTIC_DUMP(d,l) \ { \ int out_index; \ \ for (out_index = 0; out_index < l; out_index++) \ fprintf(stderr, "%.2x:", (int)d[out_index]); \ fprintf(stderr, "\n"); \ } static void print_hex_datum (gnutls_datum_t * dat) { unsigned int j; #define SPACE "\t" fprintf (stdout, "\n" SPACE); for (j = 0; j < dat->size; j++) { fprintf (stdout, "%.2x:", (unsigned char) dat->data[j]); if ((j + 1) % 15 == 0) fprintf (stdout, "\n" SPACE); } fprintf (stdout, "\n"); } static void print_dsa_pkey (gnutls_datum_t * x, gnutls_datum_t * y, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g) { if (x) { fprintf (stdout, "private key:"); print_hex_datum (x); } fprintf (stdout, "public key:"); print_hex_datum (y); fprintf (stdout, "p:"); print_hex_datum (p); fprintf (stdout, "q:"); print_hex_datum (q); fprintf (stdout, "g:"); print_hex_datum (g); } static void print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, gnutls_datum_t * exp1, gnutls_datum_t *exp2) { fprintf (stdout, "modulus:"); print_hex_datum (m); fprintf (stdout, "public exponent:"); print_hex_datum (e); if (d) { fprintf (stdout, "private exponent:"); print_hex_datum (d); fprintf (stdout, "prime1:"); print_hex_datum (p); fprintf (stdout, "prime2:"); print_hex_datum (q); fprintf (stdout, "coefficient:"); print_hex_datum (u); if (exp1 && exp2) { fprintf (stdout, "exp1:"); print_hex_datum (exp1); fprintf (stdout, "exp2:"); print_hex_datum (exp2); } } } static const char * raw_to_string (const unsigned char *raw, size_t raw_size) { static char buf[1024]; size_t i; if (raw_size == 0) return NULL; if (raw_size * 3 + 1 >= sizeof (buf)) return NULL; for (i = 0; i < raw_size; i++) { sprintf (&(buf[i * 3]), "%02X%s", raw[i], (i == raw_size - 1) ? "" : ":"); } buf[sizeof (buf) - 1] = '\0'; return buf; } int privkey_info (void* data, int data_size, int verbose) { gnutls_x509_privkey_t key; size_t size; int ret; gnutls_datum_t der; unsigned char buffer[5*1024]; const char *cprint; ret = gnutls_x509_privkey_init (&key); if (ret < 0) { fprintf(stderr, "error in privkey_init\n"); return 1; } der.data = data; der.size = data_size; ret = gnutls_x509_privkey_import (key, &der, GNUTLS_X509_FMT_DER); if (ret < 0) { fprintf(stderr, "unable to import privkey\n"); return 1; } if (verbose > 0) { /* Public key algorithm */ fprintf (stdout, "Public Key Info:\n"); ret = gnutls_x509_privkey_get_pk_algorithm (key); fprintf (stdout, "\tPublic Key Algorithm: "); cprint = gnutls_pk_algorithm_get_name (ret); fprintf (stdout, "%s\n", cprint ? cprint : "Unknown"); /* Print the raw public and private keys */ if (ret == GNUTLS_PK_RSA) { gnutls_datum_t m, e, d, p, q, u, exp1={NULL,0}, exp2={NULL,0}; #if GNUTLS_VERSION_NUMBER >= 0x020b00 ret = gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u, &exp1, &exp2); #else ret = gnutls_x509_privkey_export_rsa_raw (key, &m, &e, &d, &p, &q, &u); #endif if (ret < 0) fprintf (stderr, "Error in key RSA data export: %s\n", gnutls_strerror (ret)); else { print_rsa_pkey (&m, &e, &d, &p, &q, &u, &exp1, &exp2); 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 (exp1.data); gnutls_free (exp2.data); } } else if (ret == GNUTLS_PK_DSA) { gnutls_datum_t p, q, g, y, x; ret = gnutls_x509_privkey_export_dsa_raw (key, &p, &q, &g, &y, &x); if (ret < 0) fprintf (stderr, "Error in key DSA data export: %s\n", gnutls_strerror (ret)); else { print_dsa_pkey (&x, &y, &p, &q, &g); gnutls_free (x.data); gnutls_free (y.data); gnutls_free (p.data); gnutls_free (q.data); gnutls_free (g.data); } } fprintf (stdout, "\n"); size = sizeof (buffer); if ((ret = gnutls_x509_privkey_get_key_id (key, 0, buffer, &size)) < 0) { fprintf (stderr, "Error in key id calculation: %s\n", gnutls_strerror (ret)); } else { fprintf (stdout, "Public Key ID: %s\n", raw_to_string (buffer, size)); } size = sizeof (buffer); ret = gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf(stderr, "Error in privkey_export\n"); return 1; } fprintf (stdout, "\n%s\n", buffer); } gnutls_x509_privkey_deinit (key); return 0; } int pubkey_info(void* data, int data_size, int verbose) { #if GNUTLS_VERSION_NUMBER >= 0x020b00 gnutls_pubkey_t key; size_t size; int ret; gnutls_datum_t der; unsigned char buffer[5*1024]; const char *cprint; ret = gnutls_pubkey_init (&key); if (ret < 0) { fprintf(stderr, "error in pubkey_init\n"); return 1; } der.data = data; der.size = data_size; ret = gnutls_pubkey_import (key, &der, GNUTLS_X509_FMT_DER); if (ret < 0) { fprintf(stderr, "unable to import pubkey\n"); return 1; } if (verbose > 0) { /* Public key algorithm */ fprintf (stdout, "Public Key Info:\n"); ret = gnutls_pubkey_get_pk_algorithm (key, NULL); fprintf (stdout, "\tPublic Key Algorithm: "); cprint = gnutls_pk_algorithm_get_name (ret); fprintf (stdout, "%s\n", cprint ? cprint : "Unknown"); /* Print the raw public and private keys */ if (ret == GNUTLS_PK_RSA) { gnutls_datum_t m, e; ret = gnutls_pubkey_get_pk_rsa_raw (key, &m, &e); if (ret < 0) fprintf (stderr, "Error in key RSA data export: %s\n", gnutls_strerror (ret)); else { print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL, NULL, NULL); gnutls_free (m.data); gnutls_free (e.data); } } else if (ret == GNUTLS_PK_DSA) { gnutls_datum_t p, q, g, y; ret = gnutls_pubkey_get_pk_dsa_raw (key, &p, &q, &g, &y); if (ret < 0) fprintf (stderr, "Error in key DSA data export: %s\n", gnutls_strerror (ret)); else { print_dsa_pkey (NULL, &y, &p, &q, &g); gnutls_free (y.data); gnutls_free (p.data); gnutls_free (q.data); gnutls_free (g.data); } } fprintf (stdout, "\n"); size = sizeof (buffer); if ((ret = gnutls_pubkey_get_key_id (key, 0, buffer, &size)) < 0) { fprintf (stderr, "Error in key id calculation: %s\n", gnutls_strerror (ret)); } else { fprintf (stdout, "Public Key ID: %s\n", raw_to_string (buffer, size)); } size = sizeof (buffer); ret = gnutls_pubkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf(stderr, "Error in privkey_export\n"); return 1; } fprintf (stdout, "\n%s\n", buffer); } gnutls_pubkey_deinit (key); #endif return 0; } /* Diffie Hellman */ const char dh_params_txt[] = "-----BEGIN DH PARAMETERS-----\n"\ "MIGHAoGBAKMox0/IjuGqSaGMJESYMhdmXiTe1pY8gkSzWZ/ktWaUdaYAzgAZp7r3\n"\ "OCh68YslS9Oi7/UQjmBbgGuOucMKgq3tYeYzY8G2epIuIzM4TAogaEqwkdSrXlth\n"\ "MMsP2FhLhHg8m6V6iItitnMOz9r8t3BEf04GRlfzgZraM0gUUwTjAgEF\n"\ "-----END DH PARAMETERS-----\n"; static int test_ncr_dh(void) { ncr_key_generate_params_t kgen; ncr_key_t private1, public1, public2, private2; ncr_key_t z1, z2; int ret; gnutls_datum g, p, params; gnutls_dh_params_t dhp; unsigned char y1[1024], y2[1024]; size_t y1_size, y2_size; ncr_key_params_t kderive; ssize_t output_size; fprintf(stdout, "Tests on DH key exchange:"); fflush(stdout); params.data = (void*)dh_params_txt; params.size = sizeof(dh_params_txt)-1; ret = gnutls_dh_params_init(&dhp); if (ret < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "gnutls: %s\n", gnutls_strerror(ret)); return 1; } ret = gnutls_dh_params_import_pkcs3(dhp, ¶ms, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "gnutls: %s\n", gnutls_strerror(ret)); return 1; } ret = gnutls_dh_params_export_raw(dhp, &p, &g, NULL); if (ret < 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "gnutls: %s\n", gnutls_strerror(ret)); return 1; } /* generate a DH key */ DIAGNOSTIC_CALL(ncr_key_init, &private1); DIAGNOSTIC_CALL(ncr_key_init, &public1); DIAGNOSTIC_CALL(ncr_key_generate_params_init, &kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_set_algorithm, kgen, NCR_ALG_DH); DIAGNOSTIC_CALL(ncr_key_generate_params_set_keyflags, kgen, NCR_KEY_FLAG_EXPORTABLE); DIAGNOSTIC_CALL(ncr_key_generate_params_set_dh, kgen, p.data, p.size, g.data, g.size); DIAGNOSTIC_CALL(ncr_key_generate_pair, private1, public1, kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_deinit, kgen); /* generate another DH key */ DIAGNOSTIC_CALL(ncr_key_init, &private2); DIAGNOSTIC_CALL(ncr_key_init, &public2); DIAGNOSTIC_CALL(ncr_key_generate_params_init, &kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_set_algorithm, kgen, NCR_ALG_DH); DIAGNOSTIC_CALL(ncr_key_generate_params_set_keyflags, kgen, NCR_KEY_FLAG_EXPORTABLE); DIAGNOSTIC_CALL(ncr_key_generate_params_set_dh, kgen, p.data, p.size, g.data, g.size); DIAGNOSTIC_CALL(ncr_key_generate_pair, private2, public2, kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_deinit, kgen); /* export y1=g^x1 */ DIAGNOSTIC_CALL(ncr_key_export, public1, y1, sizeof(y1)); y1_size = output_size; DIAGNOSTIC_CALL(ncr_key_deinit, public1); /* export y2=g^x2 */ DIAGNOSTIC_CALL(ncr_key_export, public2, y2, sizeof(y2)); y2_size = output_size; DIAGNOSTIC_CALL(ncr_key_deinit, public2); /* z1=y1^x2 */ DIAGNOSTIC_CALL(ncr_key_init, &z1); DIAGNOSTIC_CALL(ncr_key_params_init, &kderive); DIAGNOSTIC_CALL(ncr_key_params_set_dh_pub, kderive, y2, y2_size); DIAGNOSTIC_CALL(ncr_key_derive, z1, NCR_KEY_FLAG_EXPORTABLE, private1, NCR_DERIVE_DH, kderive); ncr_key_params_deinit(kderive); DIAGNOSTIC_CALL(ncr_key_deinit, private1); /* z2=y2^x1 */ DIAGNOSTIC_CALL(ncr_key_init, &z2); DIAGNOSTIC_CALL(ncr_key_params_init, &kderive); DIAGNOSTIC_CALL(ncr_key_params_set_dh_pub, kderive, y1, y1_size); DIAGNOSTIC_CALL(ncr_key_derive, z2, NCR_KEY_FLAG_EXPORTABLE, private2, NCR_DERIVE_DH, kderive); ncr_key_params_deinit(kderive); DIAGNOSTIC_CALL(ncr_key_deinit, private2); /* z1==z2 */ DIAGNOSTIC_CALL(ncr_key_export, z1, y1, sizeof(y1)); y1_size = output_size; DIAGNOSTIC_CALL(ncr_key_deinit, z1); DIAGNOSTIC_CALL(ncr_key_export, z2, y2, sizeof(y2)); y2_size = output_size; DIAGNOSTIC_CALL(ncr_key_deinit, z2); if (y1_size == 0 || y1_size != y2_size || memcmp(y1, y2, y1_size) != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); DIAGNOSTIC_ERROR("Output in DH does not match (%d, %d)!\n", (int)y1_size, (int)y2_size); fprintf(stderr, "Key1[%d]: ", (int) y1_size); DIAGNOSTIC_DUMP(y1, y1_size); fprintf(stderr, "Key2[%d]: ", (int) y2_size); DIAGNOSTIC_DUMP(y2, y2_size); return 1; } fprintf(stdout, " Success\n"); return 0; } /* check whether wrapping of long keys is not allowed with * shorted wrapping keys */ static int test_ncr_wrap_key3(void) { int i; ncr_key_t key; size_t data_size; ncr_key_generate_params_t kgen; ncr_key_t pubkey, privkey; uint8_t data[DATA_SIZE]; /* only the first two should be allowed to be wrapped. * the latter shouldn't because it has security level larger * then 128 bits (the size of the wrapping key). */ const int sizes[] = {1024, 3248, 5200}; ssize_t output_size; fprintf(stdout, "Tests on key wrapping (might take long): "); fflush(stdout); /* convert it to key */ DIAGNOSTIC_CALL(ncr_key_init, &privkey); DIAGNOSTIC_CALL(ncr_key_init, &pubkey); if (geteuid() != 0) { /* cannot test further */ fprintf(stdout, "\t(Wrapping test not completed. Run as root)\n"); return 0; } /* make a wrapping key */ DIAGNOSTIC_CALL(ncr_key_init, &key); DIAGNOSTIC_CALL(ncr_key_import, key, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, "ab", 2, NCR_ALG_AES_CBC, NCR_KEY_TYPE_SECRET, NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPING); for (i=0;i= 0 && i == 2) { DIAGNOSTIC_ERROR("[%d-%d]\n", i, sizes[i]); /* wrapping shouldn't have been allowed */ return 1; } if (output_size >= 0) { data_size = output_size; /* try unwrapping */ DIAGNOSTIC_CALL(ncr_key_unwrap, key, NCR_WALG_AES_RFC5649, NULL, privkey, data, data_size, NCR_ALG_RSA, NCR_KEY_TYPE_PRIVATE, 0); } fprintf(stdout, "*"); fflush(stdout); } fprintf(stdout, " Success\n"); return 0; } #define RSA_ENCRYPT_SIZE 32 static int rsa_key_encrypt(ncr_key_t privkey, ncr_key_t pubkey, int oaep) { ncr_key_params_t params; uint8_t data[DATA_SIZE]; uint8_t vdata[RSA_ENCRYPT_SIZE]; int enc_size; ssize_t output_size; fprintf(stdout, "Tests on RSA (%s) key encryption:", (oaep!=0)?"OAEP":"PKCS V1.5"); fflush(stdout); memset(data, 0x3, sizeof(data)); memcpy(vdata, data, sizeof(vdata)); /* do encryption */ DIAGNOSTIC_CALL(ncr_key_params_init, ¶ms); if (oaep) { DIAGNOSTIC_CALL(ncr_key_params_set_rsa_type, params, RSA_PKCS1_OAEP); DIAGNOSTIC_CALL(ncr_key_params_set_rsa_oaep_hash, params, NCR_ALG_SHA1); } else { DIAGNOSTIC_CALL(ncr_key_params_set_rsa_type, params, RSA_PKCS1_V1_5); } DIAGNOSTIC_CALL(ncr_session_once_direct_data, pubkey, params, NCR_OP_ENCRYPT, NCR_ALG_RSA, data, RSA_ENCRYPT_SIZE, data, sizeof(data)); enc_size = output_size; /* decrypt data */ DIAGNOSTIC_CALL(ncr_session_once_direct_data, privkey, params, NCR_OP_DECRYPT, NCR_ALG_RSA, data, enc_size, data, sizeof(data)); if (memcmp(vdata, data, sizeof(vdata)) != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); fprintf(stderr, "Decrypted data do not match!\n"); return 1; } ncr_key_params_deinit(params); fprintf(stdout, " Success\n"); return 0; } #define DATA_TO_SIGN 52 static int rsa_key_sign_verify(ncr_key_t privkey, ncr_key_t pubkey, int pss) { ncr_key_params_t params; uint8_t data[DATA_SIZE]; uint8_t sig[DATA_SIZE]; int sig_size; ssize_t output_size; fprintf(stdout, "Tests on RSA (%s) key signature:", (pss!=0)?"PSS":"PKCS V1.5"); fflush(stdout); memset(data, 0x3, sizeof(data)); /* sign datad */ DIAGNOSTIC_CALL(ncr_key_params_init, ¶ms); DIAGNOSTIC_CALL(ncr_key_params_set_rsa_type, params, (pss != 0) ? RSA_PKCS1_PSS : RSA_PKCS1_V1_5); DIAGNOSTIC_CALL(ncr_key_params_set_rsa_sign_hash, params, NCR_ALG_SHA1); DIAGNOSTIC_CALL(ncr_session_once_direct_data, privkey, params, NCR_OP_SIGN, NCR_ALG_RSA, data, DATA_TO_SIGN, sig, sizeof(sig)); sig_size = output_size; /* verify signature */ memset(data, 0x3, sizeof(data)); DIAGNOSTIC_CALL(ncr_session_once_direct_data, pubkey, params, NCR_OP_VERIFY, NCR_ALG_RSA, data, DATA_TO_SIGN, sig, sig_size); ncr_key_params_deinit(params); fprintf(stdout, " Success\n"); return 0; } static int dsa_key_sign_verify(ncr_key_t privkey, ncr_key_t pubkey) { ncr_key_params_t params; uint8_t data[DATA_SIZE]; uint8_t sig[DATA_SIZE]; int sig_size; ssize_t output_size; fprintf(stdout, "Tests on DSA key signature:"); fflush(stdout); memset(data, 0x3, sizeof(data)); /* sign datad */ DIAGNOSTIC_CALL(ncr_key_params_init, ¶ms); DIAGNOSTIC_CALL(ncr_key_params_set_dsa_sign_hash, params, NCR_ALG_SHA1); DIAGNOSTIC_CALL(ncr_session_once_direct_data, privkey, params, NCR_OP_SIGN, NCR_ALG_DSA, data, DATA_TO_SIGN, sig, sizeof(sig)); sig_size = output_size; /* verify signature */ DIAGNOSTIC_CALL(ncr_session_once_direct_data, pubkey, params, NCR_OP_VERIFY, NCR_ALG_DSA, data, DATA_TO_SIGN, sig, sig_size); ncr_key_params_deinit(params); fprintf(stdout, " Success\n"); return 0; } static int test_ncr_rsa(void) { int ret; ncr_key_generate_params_t kgen; ncr_key_t pubkey, privkey; uint8_t data[DATA_SIZE]; ssize_t output_size; fprintf(stdout, "Tests on RSA key generation:"); fflush(stdout); /* convert it to key */ DIAGNOSTIC_CALL(ncr_key_init, &privkey); DIAGNOSTIC_CALL(ncr_key_init, &pubkey); DIAGNOSTIC_CALL(ncr_key_generate_params_init, &kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_set_algorithm, kgen, NCR_ALG_RSA); DIAGNOSTIC_CALL(ncr_key_generate_params_set_keyflags, kgen, NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE); DIAGNOSTIC_CALL(ncr_key_generate_params_set_rsa_bits, kgen, 1024); DIAGNOSTIC_CALL(ncr_key_generate_pair, privkey, pubkey, kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_deinit, kgen); /* export the private key */ memset(data, 0, sizeof(data)); DIAGNOSTIC_CALL(ncr_key_export, privkey, data, sizeof(data)); ret = privkey_info(data, output_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } /* export the public key */ memset(data, 0, sizeof(data)); DIAGNOSTIC_CALL(ncr_key_export, pubkey, data, sizeof(data)); ret = pubkey_info(data, output_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } fprintf(stdout, " Success\n"); ret = rsa_key_sign_verify(privkey, pubkey, 1); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } ret = rsa_key_sign_verify(privkey, pubkey, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } ret = rsa_key_encrypt(privkey, pubkey, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } ret = rsa_key_encrypt(privkey, pubkey, 1); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } return 0; } static int test_ncr_dsa(void) { int ret; ncr_key_generate_params_t kgen; ncr_key_t pubkey, privkey; uint8_t data[DATA_SIZE]; ssize_t output_size; fprintf(stdout, "Tests on DSA key generation:"); fflush(stdout); /* convert it to key */ DIAGNOSTIC_CALL(ncr_key_init, &privkey); DIAGNOSTIC_CALL(ncr_key_init, &pubkey); DIAGNOSTIC_CALL(ncr_key_generate_params_init, &kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_set_algorithm, kgen, NCR_ALG_DSA); DIAGNOSTIC_CALL(ncr_key_generate_params_set_keyflags, kgen, NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE); DIAGNOSTIC_CALL(ncr_key_generate_params_set_dsa_q_bits, kgen, 160); DIAGNOSTIC_CALL(ncr_key_generate_params_set_dsa_p_bits, kgen, 1024); DIAGNOSTIC_CALL(ncr_key_generate_pair, privkey, pubkey, kgen); DIAGNOSTIC_CALL(ncr_key_generate_params_deinit, kgen); memset(data, 0, sizeof(data)); DIAGNOSTIC_CALL(ncr_key_export, privkey, data, sizeof(data)); ret = privkey_info(data, output_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } /* export the public key */ memset(data, 0, sizeof(data)); DIAGNOSTIC_CALL(ncr_key_export, pubkey, data, sizeof(data)); ret = pubkey_info(data, output_size, 0); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } fprintf(stdout, " Success\n"); ret = dsa_key_sign_verify(privkey, pubkey); if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } return 0; } int main() { gnutls_global_init(); /* actually test if the initial close * will really delete all used lists */ ncr_global_init(0); if (test_ncr_dh()) return 1; if (test_ncr_rsa()) return 1; if (test_ncr_dsa()) return 1; if (test_ncr_wrap_key3()) return 1; /* Close the original descriptor */ ncr_global_deinit(); return 0; }