Howto use libgrcypt for signature?

Stephan Mueller smueller at chronox.de
Fri May 27 11:53:15 CEST 2016


Am Freitag, 27. Mai 2016, 10:35:08 schrieb Stef Bon:

Hi Stef,

> Hi,
> 
> I'm writing a fuse fs for sftp, and using libgcrypt for encryption,
> hmac, digest and dh.
> 
> Now I m working on the checking of the signature of H send by the
> sender. The client creates also H,
> and has to check the signature of H using the public key.
> 
> I've got the signature of H from the server, H and the public hostkey
> of the server as string (length, buffer).
> 
> How to go futher? I know I have to use the function  gcry_pk_verify, but
> how?
> 
> Do I have to convert the strings to some s-expressions using a format first?

some example code:

static int libgcrypt_rsa_sigver(struct rsa_sigver_data *data)
{
        gcry_sexp_t s_data = NULL;
        gcry_sexp_t s_key = NULL;
        gcry_sexp_t s_sig = NULL;
        int algo = 0;
        int mode = 0;
        int ret = 1;
        gpg_error_t err;
        unsigned char hash[64];
        unsigned int hashsize;
        gcry_mpi_t n = NULL;
        gcry_mpi_t e = NULL;
        gcry_mpi_t sig = NULL;

        libgcrypt_init(1);

        if (libgcrypt_cipher(data->cipher, 0, &algo, &mode))
                return 1;

        hashsize = gcry_md_get_algo_dlen(algo);
        if (!hashsize || hashsize > sizeof hash) {
                dolog(LOG_WARN, "digest too long for buffer or unknown hash 
algorithm\n");
                return 1;
        }

        /* Generate and convert the hash */
        gcry_md_hash_buffer(algo, hash, data->msg.buf, data->msg.len);
        err = gcry_sexp_build (&s_data, NULL,
                               "(data (flags pkcs1)(hash %s %b))",
                               gcry_md_algo_name(algo), (int)hashsize, hash);
        if (err) {
                dolog(LOG_WARN, "gcry_sexp_build failed for RSA data input: 
%s\n",
                      gpg_strerror (err));
                return 1;
        }

        /* Convert public key */
        err = gcry_mpi_scan(&n, GCRYMPI_FMT_USG,
                            data->n.buf, data->n.len, NULL);
        if (err) {
                dolog(LOG_WARN, "error scanning RSA parameter n: %s\n", 
gpg_strerror(err));
                goto out;
        }
        err = gcry_mpi_scan(&e, GCRYMPI_FMT_USG,
                            data->e.buf, data->e.len, NULL);
        if (err) {
                dolog(LOG_WARN, "error scanning RSA parameter e: %s\n", 
gpg_strerror(err));
                goto out;
        }
        err = gcry_sexp_build(&s_key, NULL, "(public-key(rsa(n%m)(e%m)))", n, 
e);
        if (err) {
                dolog(LOG_WARN, "error building S-expression: %s\n", 
gpg_strerror (err));
                goto out;
        }

        /* Convert signature */
        err = gcry_mpi_scan(&sig, GCRYMPI_FMT_USG,
                            data->sig.buf, data->sig.len, NULL);
        if (err) {
                dolog(LOG_WARN, "error scanning RSA parameter signature: 
%s\n", gpg_strerror(err));
                goto out;
        }
        err = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %m)))", sig);
        if (err) {
                dolog(LOG_WARN, "error building S-expression: %s\n", 
gpg_strerror (err));
                goto out;
        }

        /* sig verification */
        err = gcry_pk_verify(s_sig, s_data, s_key);
        if (!err)
                ret = 0;
        else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
                ret = -1;
        else
                ret = 1;

out:
        if (n)
                gcry_mpi_release(n);
        if (e)
                gcry_mpi_release(e);
        if (sig)
                gcry_mpi_release(sig);
        if (s_sig)
                gcry_sexp_release (s_sig);
        if (s_key)
                gcry_sexp_release (s_key);
        if (s_data)
                gcry_sexp_release (s_data);

        return ret;
}
> 
> Thanks in advance,
> 
> Stef
> 
> _______________________________________________
> Gcrypt-devel mailing list
> Gcrypt-devel at gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gcrypt-devel


Ciao
Stephan



More information about the Gcrypt-devel mailing list