diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2021-09-16 15:06:27 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2021-09-16 15:06:27 +0900 |
commit | 117f5c3f8028efc18a0b20d854b6b2b8babcb1d6 (patch) | |
tree | 9e41cb405657f4838337eb1db9c3df051239e129 | |
parent | 722604169704dd4c5d322eaef6dfd165ddd50fd0 (diff) | |
download | libgcrypt-117f5c3f8028efc18a0b20d854b6b2b8babcb1d6.tar.gz |
experiment-pk_hash_sign/verify: Implement pk_hash_sign/verify.
--
GnuPG-bug-id: 4894
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r-- | cipher/pubkey.c | 104 | ||||
-rw-r--r-- | src/gcrypt-int.h | 4 | ||||
-rw-r--r-- | src/gcrypt.h.in | 31 | ||||
-rw-r--r-- | src/visibility.c | 16 |
4 files changed, 142 insertions, 13 deletions
diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 3ca09932..fcc9fb29 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -438,6 +438,59 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) } +gcry_err_code_t +_gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl, gcry_md_hd_t hd_orig, + gcry_sexp_t s_skey) +{ + gcry_err_code_t rc; + gcry_pk_spec_t *spec; + gcry_sexp_t keyparms = NULL; + gcry_sexp_t s_hash = NULL; + int algo; + const unsigned char *digest; + gcry_error_t err; + gcry_md_hd_t hd; + + *r_sig = NULL; + + err = _gcry_md_copy (&hd, hd_orig); + if (err) + return gpg_err_code (err); + + algo = _gcry_md_get_algo (hd); + + digest = _gcry_md_read (hd, 0); + if (!digest) + { + _gcry_md_close (hd); + return GPG_ERR_DIGEST_ALGO; + } + + rc = _gcry_sexp_build (&s_hash, NULL, tmpl, + _gcry_md_algo_name (algo), + (int) _gcry_md_get_algo_dlen (algo), + digest); + + _gcry_md_close (hd); + if (rc) + goto leave; + + rc = spec_from_sexp (s_skey, 1, &spec, &keyparms); + if (rc) + goto leave; + + if (spec->sign) + rc = spec->sign (r_sig, s_hash, keyparms); + else + rc = GPG_ERR_NOT_IMPLEMENTED; + + leave: + sexp_release (s_hash); + sexp_release (keyparms); + return rc; +} + + /* Verify a signature. @@ -467,6 +520,57 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey) } +gcry_err_code_t +_gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl, gcry_md_hd_t hd_orig, + gcry_sexp_t s_pkey) +{ + gcry_err_code_t rc; + gcry_pk_spec_t *spec; + gcry_sexp_t keyparms = NULL; + gcry_sexp_t s_hash = NULL; + int algo; + const unsigned char *digest; + gcry_error_t err; + gcry_md_hd_t hd; + + err = _gcry_md_copy (&hd, hd_orig); + if (err) + return gpg_err_code (err); + + algo = _gcry_md_get_algo (hd); + + digest = _gcry_md_read (hd, 0); + if (!digest) + { + _gcry_md_close (hd); + return GPG_ERR_DIGEST_ALGO; + } + + rc = _gcry_sexp_build (&s_hash, NULL, tmpl, + _gcry_md_algo_name (algo), + (int) _gcry_md_get_algo_dlen (algo), + digest); + + _gcry_md_close (hd); + if (rc) + goto leave; + + rc = spec_from_sexp (s_pkey, 1, &spec, &keyparms); + if (rc) + goto leave; + + if (spec->verify) + rc = spec->verify (s_sig, s_hash, keyparms); + else + rc = GPG_ERR_NOT_IMPLEMENTED; + + leave: + sexp_release (s_hash); + sexp_release (keyparms); + return rc; +} + + /* Test a key. diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h index 5bfa9a81..6829a427 100644 --- a/src/gcrypt-int.h +++ b/src/gcrypt-int.h @@ -113,6 +113,10 @@ unsigned int _gcry_ecc_get_algo_keylen (int algo); gpg_error_t _gcry_ecc_mul_point (int algo, unsigned char *result, const unsigned char *scalar, const unsigned char *point); +gcry_err_code_t _gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl, + gcry_md_hd_t hd, gcry_sexp_t s_skey); +gcry_err_code_t _gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl, + gcry_md_hd_t hd, gcry_sexp_t s_pkey); gcry_error_t _gcry_pkey_vopen (gcry_pkey_hd_t *h, int algo, unsigned int flags, va_list arg_ptr); diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 11225031..5eafed91 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1160,19 +1160,6 @@ gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, gcry_error_t gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey); -/* Variant of gcry_pk_sign which takes as additional parameter a HASH - * handle and an optional context. The hash algorithm used by the - * handle needs to have the algorithm given by the DATA parameter - * enabled. The hash handle must not yet been finalized; the function - * takes a copy of the state and does a finalize on the copy. This - * function shall be used if a policy requires that hashing and signing - * is done by the same function. CTX is currently not used and should - * be passed as NULL. */ -gcry_error_t gcry_pk_hash_sign (gcry_sexp_t *result, - gcry_sexp_t data, gcry_sexp_t skey, - gcry_md_hd_t hash, - gcry_ctx_t ctx); - /* Check the signature SIGVAL on DATA using the public key PKEY. */ gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey); @@ -1904,6 +1891,24 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; /* Return true if Libgcrypt is in FIPS mode. */ #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) +/* Variant of gcry_pk_sign which takes as additional parameter a HD + * handle for hash and an optional context. The hash algorithm used by the + * handle needs to be enabled and input needs to be supplied beforehand. + * DATA-TMPL specifies a template to compose an S-expression to be signed. + * The hash handle must not yet been finalized; the function + * takes a copy of the state and does a finalize on the copy. This + * function shall be used if a policy requires that hashing and signing + * is done by the same function. CTX is currently not used and should + * be passed as NULL. */ +gcry_error_t gcry_pk_hash_sign (gcry_sexp_t *result, + const char *data_tmpl, gcry_sexp_t skey, + gcry_md_hd_t hd, gcry_ctx_t ctx); + +/* Variant of gcry_pk_verify which takes as additional parameter a HD + * handle for hash and an optional context. Similar to gcry_pk_hash_sign. */ +gcry_error_t gcry_pk_hash_verify (gcry_sexp_t sigval, + const char *data_tmpl, gcry_sexp_t pkey, + gcry_md_hd_t hd, gcry_ctx_t ctx); #if 0 /* (Keep Emacsens' auto-indent happy.) */ { diff --git a/src/visibility.c b/src/visibility.c index 86ec3786..3f0514f7 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -1028,6 +1028,14 @@ gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) } gcry_error_t +gcry_pk_hash_sign (gcry_sexp_t *result, const char *data_tmpl, gcry_sexp_t skey, + gcry_md_hd_t hd, gcry_ctx_t ctx) +{ + (void)ctx; + return gpg_error (_gcry_pk_sign_md (result, data_tmpl, hd, skey)); +} + +gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) { if (!fips_is_operational ()) @@ -1036,6 +1044,14 @@ gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) } gcry_error_t +gcry_pk_hash_verify (gcry_sexp_t sigval, const char *data_tmpl, gcry_sexp_t pkey, + gcry_md_hd_t hd, gcry_ctx_t ctx) +{ + (void)ctx; + return gpg_error (_gcry_pk_verify_md (sigval, data_tmpl, hd, pkey)); +} + +gcry_error_t gcry_pk_testkey (gcry_sexp_t key) { if (!fips_is_operational ()) |