int rsa_verify_sig(char *sig, int sig_size, u8 *sha1) { MPI public_key[2]; MPI hash; MPI data; int nread; int nframe; if (!rsa_key) { return -EINVAL; } /* initialize our keys */ nread = rsa_key->n_size; public_key[0] = mpi_read_from_buffer((byte *)rsa_key->n, &nread, 0); if (!public_key[0]) { return -EINVAL; } nread = rsa_key->e_size; public_key[1] = mpi_read_from_buffer((byte *)rsa_key->e, &nread, 0); if (!public_key[1]) { return -EINVAL; } /* set up the MPI for the sig */ data = mpi_read_from_buffer(sig, &sig_size, 0); if (!data) { return -EINVAL; } /* set up the MPI for the result */ nframe = mpi_get_nbits(public_key[0]); hash = do_encode_md(sha1, nframe); /* verify the sig */ return rsa_verify(hash, &data, public_key); }
/* Encode the given digest into a pkcs#1 compatible format. */ cdk_error_t _cdk_digest_encode_pkcs1 (byte ** r_md, size_t * r_mdlen, int pk_algo, const byte * md, int digest_algo, unsigned nbits) { size_t dlen; if (!md || !r_md || !r_mdlen) return CDK_Inv_Value; dlen = _gnutls_hash_get_algo_len (digest_algo); if (dlen <= 0) return CDK_Inv_Algo; if (is_DSA (pk_algo)) { /* DSS does not use a special encoding. */ *r_md = cdk_malloc (dlen + 1); if (!*r_md) return CDK_Out_Of_Core; *r_mdlen = dlen; memcpy (*r_md, md, dlen); return 0; } else { const byte *asn; int asnlen; cdk_error_t rc; asnlen = _gnutls_get_digest_oid (digest_algo, &asn); if (asnlen < 0) return asnlen; rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen, nbits, asn, asnlen); return rc; } return 0; }
int digsig_rsa_bsign_verify(unsigned char *hash_format, int length, unsigned char *signed_hash) { int rc = 0, cmp; MPI hash, data; unsigned nread = DIGSIG_ELF_SIG_SIZE; int nframe; unsigned char sig_class; unsigned char sig_timestamp[SIZEOF_UNSIGNED_INT]; int i; SIGCTX *ctx = NULL; unsigned char *new_sig; new_sig = kmalloc(gDigestLength[HASH_SHA1], DIGSIG_SAFE_ALLOC); if (!new_sig) { DSM_ERROR ("kmalloc failed in %s for new_sig\n", __FUNCTION__); return -ENOMEM; } /* Get MPI of signed data from .sig file/section */ nread = DIGSIG_ELF_SIG_SIZE; data = mpi_read_from_buffer(signed_hash + DIGSIG_RSA_DATA_OFFSET, &nread, 0); if (!data) { kfree(new_sig); return -EINVAL; } /* Get MPI for hash */ /* bsign modif - file hash - gpg modif */ /* bsign modif: add bsign greet at beginning */ /* gpg modif: add class and timestamp at end */ ctx = kmalloc(sizeof(SIGCTX), GFP_KERNEL); if (!ctx) { DSM_ERROR("Cannot allocate ctx\n"); mpi_free (data); kfree (new_sig); return -ENOMEM; } ctx->tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); if (!ctx->tvmem) { kfree (ctx); mpi_free(data); kfree (new_sig); DSM_ERROR("Cannot allocate plaintext buffer\n"); return -ENOMEM; } digsig_sha1_init(ctx); sig_class = signed_hash[DIGSIG_RSA_CLASS_OFFSET]; sig_class &= 0xff; for (i = 0; i < SIZEOF_UNSIGNED_INT; i++) { sig_timestamp[i] = signed_hash[DIGSIG_RSA_TIMESTAMP_OFFSET + i] & 0xff; } digsig_sha1_update(ctx, DIGSIG_BSIGN_STRING, DIGSIG_BSIGN_GREET_SIZE); digsig_sha1_update(ctx, hash_format, SHA1_DIGEST_LENGTH); digsig_sha1_update(ctx, &sig_class, 1); digsig_sha1_update(ctx, sig_timestamp, SIZEOF_UNSIGNED_INT); if ((rc = digsig_sha1_final(ctx, new_sig)) < 0) { DSM_ERROR ("internal_rsa_verify_final Cannot finalize hash algorithm\n"); mpi_free(data); kfree(ctx->tvmem); kfree(ctx); return rc; } nframe = mpi_get_nbits(digsig_public_key[0]); hash = do_encode_md(new_sig, nframe); if (hash == MPI_NULL) { DSM_PRINT(DEBUG_SIGN, "mpi creation failed\\n"); } /* Do RSA verification */ cmp = rsa_verify(hash, &data, digsig_public_key); rc = cmp ? -EPERM : 0; mpi_free(hash); mpi_free(data); kfree(ctx->tvmem); kfree(ctx); kfree (new_sig); return rc; }
int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, gcry_md_hd_t md, int mdalgo, int *r_pkalgo) { int rc; ksba_sexp_t p; gcry_mpi_t frame; gcry_sexp_t s_sig, s_hash, s_pkey; size_t n; int pkalgo; if (r_pkalgo) *r_pkalgo = 0; n = gcry_sexp_canon_len (sigval, 0, NULL, NULL); if (!n) { log_error ("libksba did not return a proper S-Exp\n"); return gpg_error (GPG_ERR_BUG); } rc = gcry_sexp_sscan (&s_sig, NULL, (char*)sigval, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); return rc; } p = ksba_cert_get_public_key (cert); n = gcry_sexp_canon_len (p, 0, NULL, NULL); if (!n) { log_error ("libksba did not return a proper S-Exp\n"); ksba_free (p); gcry_sexp_release (s_sig); return gpg_error (GPG_ERR_BUG); } if (DBG_CRYPTO) log_printhex ("public key: ", p, n); rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); ksba_free (p); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); gcry_sexp_release (s_sig); return rc; } pkalgo = pk_algo_from_sexp (s_pkey); if (r_pkalgo) *r_pkalgo = pkalgo; rc = do_encode_md (md, mdalgo, pkalgo, gcry_pk_get_nbits (s_pkey), s_pkey, &frame); if (rc) { gcry_sexp_release (s_sig); gcry_sexp_release (s_pkey); return rc; } /* put hash into the S-Exp s_hash */ if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) BUG (); gcry_mpi_release (frame); rc = gcry_pk_verify (s_sig, s_hash, s_pkey); if (DBG_X509) log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc)); gcry_sexp_release (s_sig); gcry_sexp_release (s_hash); gcry_sexp_release (s_pkey); return rc; }
/* Check the signature on CERT using the ISSUER-CERT. This function does only test the cryptographic signature and nothing else. It is assumed that the ISSUER_CERT is valid. */ int gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) { const char *algoid; gcry_md_hd_t md; int rc, algo; gcry_mpi_t frame; ksba_sexp_t p; size_t n; gcry_sexp_t s_sig, s_hash, s_pkey; algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); if (!algo) { log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?"); if (algoid && ( !strcmp (algoid, "1.2.840.113549.1.1.2") ||!strcmp (algoid, "1.2.840.113549.2.2"))) log_info (_("(this is the MD2 algorithm)\n")); return gpg_error (GPG_ERR_GENERAL); } rc = gcry_md_open (&md, algo, 0); if (rc) { log_error ("md_open failed: %s\n", gpg_strerror (rc)); return rc; } if (DBG_HASHING) gcry_md_debug (md, "hash.cert"); rc = ksba_cert_hash (cert, 1, HASH_FNC, md); if (rc) { log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc)); gcry_md_close (md); return rc; } gcry_md_final (md); p = ksba_cert_get_sig_val (cert); n = gcry_sexp_canon_len (p, 0, NULL, NULL); if (!n) { log_error ("libksba did not return a proper S-Exp\n"); gcry_md_close (md); ksba_free (p); return gpg_error (GPG_ERR_BUG); } if (DBG_CRYPTO) { int j; log_debug ("signature value:"); for (j=0; j < n; j++) log_printf (" %02X", p[j]); log_printf ("\n"); } rc = gcry_sexp_sscan ( &s_sig, NULL, (char*)p, n); ksba_free (p); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); gcry_md_close (md); return rc; } p = ksba_cert_get_public_key (issuer_cert); n = gcry_sexp_canon_len (p, 0, NULL, NULL); if (!n) { log_error ("libksba did not return a proper S-Exp\n"); gcry_md_close (md); ksba_free (p); gcry_sexp_release (s_sig); return gpg_error (GPG_ERR_BUG); } rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); ksba_free (p); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); gcry_md_close (md); gcry_sexp_release (s_sig); return rc; } rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey), gcry_pk_get_nbits (s_pkey), s_pkey, &frame); if (rc) { gcry_md_close (md); gcry_sexp_release (s_sig); gcry_sexp_release (s_pkey); return rc; } /* put hash into the S-Exp s_hash */ if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) BUG (); gcry_mpi_release (frame); rc = gcry_pk_verify (s_sig, s_hash, s_pkey); if (DBG_X509) log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc)); gcry_md_close (md); gcry_sexp_release (s_sig); gcry_sexp_release (s_hash); gcry_sexp_release (s_pkey); return rc; }