EVP_DSA_Signature_demo.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*-
  2. * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * An example that uses the EVP_PKEY*, EVP_DigestSign* and EVP_DigestVerify*
  11. * methods to calculate public/private DSA keypair and to sign and verify
  12. * two static buffers.
  13. */
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include <openssl/err.h>
  17. #include <openssl/evp.h>
  18. #include <openssl/decoder.h>
  19. #include <openssl/dsa.h>
  20. /*
  21. * This demonstration will calculate and verify a signature of data using
  22. * the soliloquy from Hamlet scene 1 act 3
  23. */
  24. static const char *hamlet_1 =
  25. "To be, or not to be, that is the question,\n"
  26. "Whether tis nobler in the minde to suffer\n"
  27. "The slings and arrowes of outragious fortune,\n"
  28. "Or to take Armes again in a sea of troubles,\n"
  29. ;
  30. static const char *hamlet_2 =
  31. "And by opposing, end them, to die to sleep;\n"
  32. "No more, and by a sleep, to say we end\n"
  33. "The heart-ache, and the thousand natural shocks\n"
  34. "That flesh is heir to? tis a consumation\n"
  35. ;
  36. static const char ALG[] = "DSA";
  37. static const char DIGEST[] = "SHA256";
  38. static const int NUMBITS = 2048;
  39. static const char * const PROPQUERY = NULL;
  40. static int generate_dsa_params(OSSL_LIB_CTX *libctx,
  41. EVP_PKEY **p_params)
  42. {
  43. int ret = 0;
  44. EVP_PKEY_CTX *pkey_ctx = NULL;
  45. EVP_PKEY *params = NULL;
  46. pkey_ctx = EVP_PKEY_CTX_new_from_name(libctx, ALG, PROPQUERY);
  47. if (pkey_ctx == NULL)
  48. goto end;
  49. if (EVP_PKEY_paramgen_init(pkey_ctx) <= 0)
  50. goto end;
  51. if (EVP_PKEY_CTX_set_dsa_paramgen_bits(pkey_ctx, NUMBITS) <= 0)
  52. goto end;
  53. if (EVP_PKEY_paramgen(pkey_ctx, &params) <= 0)
  54. goto end;
  55. if (params == NULL)
  56. goto end;
  57. ret = 1;
  58. end:
  59. if(ret != 1) {
  60. EVP_PKEY_free(params);
  61. params = NULL;
  62. }
  63. EVP_PKEY_CTX_free(pkey_ctx);
  64. *p_params = params;
  65. fprintf(stdout, "Params:\n");
  66. EVP_PKEY_print_params_fp(stdout, params, 4, NULL);
  67. fprintf(stdout, "\n");
  68. return ret;
  69. }
  70. static int generate_dsa_key(OSSL_LIB_CTX *libctx,
  71. EVP_PKEY *params,
  72. EVP_PKEY **p_pkey)
  73. {
  74. int ret = 0;
  75. EVP_PKEY_CTX *ctx = NULL;
  76. EVP_PKEY *pkey = NULL;
  77. ctx = EVP_PKEY_CTX_new_from_pkey(libctx, params,
  78. NULL);
  79. if (ctx == NULL)
  80. goto end;
  81. if (EVP_PKEY_keygen_init(ctx) <= 0)
  82. goto end;
  83. if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
  84. goto end;
  85. if (pkey == NULL)
  86. goto end;
  87. ret = 1;
  88. end:
  89. if(ret != 1) {
  90. EVP_PKEY_free(pkey);
  91. pkey = NULL;
  92. }
  93. EVP_PKEY_CTX_free(ctx);
  94. *p_pkey = pkey;
  95. fprintf(stdout, "Generating public/private key pair:\n");
  96. EVP_PKEY_print_public_fp(stdout, pkey, 4, NULL);
  97. fprintf(stdout, "\n");
  98. EVP_PKEY_print_private_fp(stdout, pkey, 4, NULL);
  99. fprintf(stdout, "\n");
  100. EVP_PKEY_print_params_fp(stdout, pkey, 4, NULL);
  101. fprintf(stdout, "\n");
  102. return ret;
  103. }
  104. static int extract_public_key(const EVP_PKEY *pkey,
  105. OSSL_PARAM **p_public_key)
  106. {
  107. int ret = 0;
  108. OSSL_PARAM *public_key = NULL;
  109. if (EVP_PKEY_todata(pkey, EVP_PKEY_PUBLIC_KEY, &public_key) != 1)
  110. goto end;
  111. ret = 1;
  112. end:
  113. if (ret != 1) {
  114. OSSL_PARAM_free(public_key);
  115. public_key = NULL;
  116. }
  117. *p_public_key = public_key;
  118. return ret;
  119. }
  120. static int extract_keypair(const EVP_PKEY *pkey,
  121. OSSL_PARAM **p_keypair)
  122. {
  123. int ret = 0;
  124. OSSL_PARAM *keypair = NULL;
  125. if (EVP_PKEY_todata(pkey, EVP_PKEY_KEYPAIR, &keypair) != 1)
  126. goto end;
  127. ret = 1;
  128. end:
  129. if (ret != 1) {
  130. OSSL_PARAM_free(keypair);
  131. keypair = NULL;
  132. }
  133. *p_keypair = keypair;
  134. return ret;
  135. }
  136. static int demo_sign(OSSL_LIB_CTX *libctx,
  137. size_t *p_sig_len, unsigned char **p_sig_value,
  138. OSSL_PARAM keypair[])
  139. {
  140. int ret = 0;
  141. size_t sig_len = 0;
  142. unsigned char *sig_value = NULL;
  143. EVP_MD_CTX *ctx = NULL;
  144. EVP_PKEY_CTX *pkey_ctx = NULL;
  145. EVP_PKEY *pkey = NULL;
  146. pkey_ctx = EVP_PKEY_CTX_new_from_name(libctx, ALG, PROPQUERY);
  147. if (pkey_ctx == NULL)
  148. goto end;
  149. if (EVP_PKEY_fromdata_init(pkey_ctx) != 1)
  150. goto end;
  151. if (EVP_PKEY_fromdata(pkey_ctx, &pkey, EVP_PKEY_KEYPAIR, keypair) != 1)
  152. goto end;
  153. ctx = EVP_MD_CTX_create();
  154. if (ctx == NULL)
  155. goto end;
  156. if (EVP_DigestSignInit_ex(ctx, NULL, DIGEST, libctx, NULL, pkey, NULL) != 1)
  157. goto end;
  158. if (EVP_DigestSignUpdate(ctx, hamlet_1, sizeof(hamlet_1)) != 1)
  159. goto end;
  160. if (EVP_DigestSignUpdate(ctx, hamlet_2, sizeof(hamlet_2)) != 1)
  161. goto end;
  162. /* Calculate the signature size */
  163. if (EVP_DigestSignFinal(ctx, NULL, &sig_len) != 1)
  164. goto end;
  165. if (sig_len == 0)
  166. goto end;
  167. sig_value = OPENSSL_malloc(sig_len);
  168. if (sig_value == NULL)
  169. goto end;
  170. /* Calculate the signature */
  171. if (EVP_DigestSignFinal(ctx, sig_value, &sig_len) != 1)
  172. goto end;
  173. ret = 1;
  174. end:
  175. EVP_MD_CTX_free(ctx);
  176. if (ret != 1) {
  177. OPENSSL_free(sig_value);
  178. sig_len = 0;
  179. sig_value = NULL;
  180. }
  181. *p_sig_len = sig_len;
  182. *p_sig_value = sig_value;
  183. EVP_PKEY_free(pkey);
  184. EVP_PKEY_CTX_free(pkey_ctx);
  185. fprintf(stdout, "Generating signature:\n");
  186. BIO_dump_indent_fp(stdout, sig_value, sig_len, 2);
  187. fprintf(stdout, "\n");
  188. return ret;
  189. }
  190. static int demo_verify(OSSL_LIB_CTX *libctx,
  191. size_t sig_len, unsigned char *sig_value,
  192. OSSL_PARAM public_key[])
  193. {
  194. int ret = 0;
  195. EVP_MD_CTX *ctx = NULL;
  196. EVP_PKEY_CTX *pkey_ctx = NULL;
  197. EVP_PKEY *pkey = NULL;
  198. pkey_ctx = EVP_PKEY_CTX_new_from_name(libctx, ALG, PROPQUERY);
  199. if (pkey_ctx == NULL)
  200. goto end;
  201. if (EVP_PKEY_fromdata_init(pkey_ctx) != 1)
  202. goto end;
  203. if (EVP_PKEY_fromdata(pkey_ctx, &pkey, EVP_PKEY_PUBLIC_KEY, public_key) != 1)
  204. goto end;
  205. ctx = EVP_MD_CTX_create();
  206. if(ctx == NULL)
  207. goto end;
  208. if (EVP_DigestVerifyInit_ex(ctx, NULL, DIGEST, libctx, NULL, pkey, NULL) != 1)
  209. goto end;
  210. if (EVP_DigestVerifyUpdate(ctx, hamlet_1, sizeof(hamlet_1)) != 1)
  211. goto end;
  212. if (EVP_DigestVerifyUpdate(ctx, hamlet_2, sizeof(hamlet_2)) != 1)
  213. goto end;
  214. if (EVP_DigestVerifyFinal(ctx, sig_value, sig_len) != 1)
  215. goto end;
  216. ret = 1;
  217. end:
  218. EVP_PKEY_free(pkey);
  219. EVP_PKEY_CTX_free(pkey_ctx);
  220. EVP_MD_CTX_free(ctx);
  221. return ret;
  222. }
  223. int main(void)
  224. {
  225. int ret = EXIT_FAILURE;
  226. OSSL_LIB_CTX *libctx = NULL;
  227. EVP_PKEY *params = NULL;
  228. EVP_PKEY *pkey = NULL;
  229. OSSL_PARAM *public_key = NULL;
  230. OSSL_PARAM *keypair = NULL;
  231. size_t sig_len = 0;
  232. unsigned char *sig_value = NULL;
  233. libctx = OSSL_LIB_CTX_new();
  234. if (libctx == NULL)
  235. goto end;
  236. if (generate_dsa_params(libctx, &params) != 1)
  237. goto end;
  238. if (generate_dsa_key(libctx, params, &pkey) != 1)
  239. goto end;
  240. if (extract_public_key(pkey, &public_key) != 1)
  241. goto end;
  242. if (extract_keypair(pkey, &keypair) != 1)
  243. goto end;
  244. /* The signer signs with his private key, and distributes his public key */
  245. if (demo_sign(libctx, &sig_len, &sig_value, keypair) != 1)
  246. goto end;
  247. /* A verifier uses the signers public key to verify the signature */
  248. if (demo_verify(libctx, sig_len, sig_value, public_key) != 1)
  249. goto end;
  250. ret = EXIT_SUCCESS;
  251. end:
  252. if (ret != EXIT_SUCCESS)
  253. ERR_print_errors_fp(stderr);
  254. OPENSSL_free(sig_value);
  255. EVP_PKEY_free(params);
  256. EVP_PKEY_free(pkey);
  257. OSSL_PARAM_free(public_key);
  258. OSSL_PARAM_free(keypair);
  259. OSSL_LIB_CTX_free(libctx);
  260. return ret;
  261. }