2 * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
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
11 * An example that uses the EVP_MD*, EVP_DigestSign* and EVP_DigestVerify*
12 * methods to calculate and verify a signature of two static buffers.
17 #include <openssl/err.h>
18 #include <openssl/evp.h>
19 #include <openssl/decoder.h>
20 #include "EVP_Signature_demo.h"
23 * This demonstration will calculate and verify a signature of data using
24 * the soliloquy from Hamlet scene 1 act 3
27 static const char *hamlet_1 =
28 "To be, or not to be, that is the question,\n"
29 "Whether tis nobler in the minde to suffer\n"
30 "The slings and arrowes of outragious fortune,\n"
31 "Or to take Armes again in a sea of troubles,\n"
33 static const char *hamlet_2 =
34 "And by opposing, end them, to die to sleep;\n"
35 "No more, and by a sleep, to say we end\n"
36 "The heart-ache, and the thousand natural shocks\n"
37 "That flesh is heir to? tis a consumation\n"
41 * For demo_sign, load EC private key priv_key from priv_key_der[].
42 * For demo_verify, load EC public key pub_key from pub_key_der[].
44 static EVP_PKEY *get_key(OSSL_LIB_CTX *libctx, const char *propq, int public)
46 OSSL_DECODER_CTX *dctx = NULL;
47 EVP_PKEY *pkey = NULL;
49 const unsigned char *data;
53 selection = EVP_PKEY_PUBLIC_KEY;
55 data_len = sizeof(pub_key_der);
57 selection = EVP_PKEY_KEYPAIR;
59 data_len = sizeof(priv_key_der);
61 dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, "EC",
62 selection, libctx, propq);
63 (void)OSSL_DECODER_from_data(dctx, &data, &data_len);
64 OSSL_DECODER_CTX_free(dctx);
66 fprintf(stderr, "Failed to load %s key.\n", public ? "public" : "private");
70 static int demo_sign(OSSL_LIB_CTX *libctx, const char *sig_name,
71 size_t *sig_out_len, unsigned char **sig_out_value)
73 int result = 0, public = 0;
75 unsigned char *sig_value = NULL;
76 const char *propq = NULL;
77 EVP_MD_CTX *sign_context = NULL;
78 EVP_PKEY *priv_key = NULL;
81 priv_key = get_key(libctx, propq, public);
82 if (priv_key == NULL) {
83 fprintf(stderr, "Get private key failed.\n");
87 * Make a message signature context to hold temporary state
88 * during signature creation
90 sign_context = EVP_MD_CTX_new();
91 if (sign_context == NULL) {
92 fprintf(stderr, "EVP_MD_CTX_new failed.\n");
96 * Initialize the sign context to use the fetched
99 if (!EVP_DigestSignInit_ex(sign_context, NULL, sig_name,
100 libctx, NULL, priv_key, NULL)) {
101 fprintf(stderr, "EVP_DigestSignInit_ex failed.\n");
105 * EVP_DigestSignUpdate() can be called several times on the same context
106 * to include additional data.
108 if (!EVP_DigestSignUpdate(sign_context, hamlet_1, strlen(hamlet_1))) {
109 fprintf(stderr, "EVP_DigestSignUpdate(hamlet_1) failed.\n");
112 if (!EVP_DigestSignUpdate(sign_context, hamlet_2, strlen(hamlet_2))) {
113 fprintf(stderr, "EVP_DigestSignUpdate(hamlet_2) failed.\n");
116 /* Call EVP_DigestSignFinal to get signature length sig_len */
117 if (!EVP_DigestSignFinal(sign_context, NULL, &sig_len)) {
118 fprintf(stderr, "EVP_DigestSignFinal failed.\n");
122 fprintf(stderr, "EVP_DigestSignFinal returned invalid signature length.\n");
125 sig_value = OPENSSL_malloc(sig_len);
126 if (sig_value == NULL) {
127 fprintf(stderr, "No memory.\n");
130 if (!EVP_DigestSignFinal(sign_context, sig_value, &sig_len)) {
131 fprintf(stderr, "EVP_DigestSignFinal failed.\n");
134 *sig_out_len = sig_len;
135 *sig_out_value = sig_value;
136 fprintf(stdout, "Generating signature:\n");
137 BIO_dump_indent_fp(stdout, sig_value, sig_len, 2);
138 fprintf(stdout, "\n");
142 /* OpenSSL free functions will ignore NULL arguments */
144 OPENSSL_free(sig_value);
145 EVP_PKEY_free(priv_key);
146 EVP_MD_CTX_free(sign_context);
150 static int demo_verify(OSSL_LIB_CTX *libctx, const char *sig_name,
151 size_t sig_len, unsigned char *sig_value)
153 int result = 0, public = 1;
154 const char *propq = NULL;
155 EVP_MD_CTX *verify_context = NULL;
156 EVP_PKEY *pub_key = NULL;
159 * Make a verify signature context to hold temporary state
160 * during signature verification
162 verify_context = EVP_MD_CTX_new();
163 if (verify_context == NULL) {
164 fprintf(stderr, "EVP_MD_CTX_new failed.\n");
168 pub_key = get_key(libctx, propq, public);
169 if (pub_key == NULL) {
170 fprintf(stderr, "Get public key failed.\n");
174 if (!EVP_DigestVerifyInit_ex(verify_context, NULL, sig_name,
175 libctx, NULL, pub_key, NULL)) {
176 fprintf(stderr, "EVP_DigestVerifyInit failed.\n");
180 * EVP_DigestVerifyUpdate() can be called several times on the same context
181 * to include additional data.
183 if (!EVP_DigestVerifyUpdate(verify_context, hamlet_1, strlen(hamlet_1))) {
184 fprintf(stderr, "EVP_DigestVerifyUpdate(hamlet_1) failed.\n");
187 if (!EVP_DigestVerifyUpdate(verify_context, hamlet_2, strlen(hamlet_2))) {
188 fprintf(stderr, "EVP_DigestVerifyUpdate(hamlet_2) failed.\n");
191 if (EVP_DigestVerifyFinal(verify_context, sig_value, sig_len) <= 0) {
192 fprintf(stderr, "EVP_DigestVerifyFinal failed.\n");
195 fprintf(stdout, "Signature verified.\n");
199 /* OpenSSL free functions will ignore NULL arguments */
200 EVP_PKEY_free(pub_key);
201 EVP_MD_CTX_free(verify_context);
207 OSSL_LIB_CTX *libctx = NULL;
208 const char *sig_name = "SHA3-512";
210 unsigned char *sig_value = NULL;
213 libctx = OSSL_LIB_CTX_new();
214 if (libctx == NULL) {
215 fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
218 if (!demo_sign(libctx, sig_name, &sig_len, &sig_value)) {
219 fprintf(stderr, "demo_sign failed.\n");
222 if (!demo_verify(libctx, sig_name, sig_len, sig_value)) {
223 fprintf(stderr, "demo_verify failed.\n");
230 ERR_print_errors_fp(stderr);
231 /* OpenSSL free functions will ignore NULL arguments */
232 OSSL_LIB_CTX_free(libctx);
233 OPENSSL_free(sig_value);