Exemplo n.º 1
0
/**
 * cdk_pk_sign:
 * @sk: secret key
 * @sig: signature
 * @md: the message digest
 *
 * Sign the message digest from @md and write the result into @sig.
 **/
cdk_error_t
cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte *md)
{
  gcry_sexp_t s_skey = NULL, s_sig = NULL, s_hash = NULL;
  byte *encmd = NULL;
  size_t enclen = 0;
  int nbits;
  cdk_error_t rc;
  gcry_error_t err;
  
  if (!sk || !sk->pk || !sig || !md)
    return CDK_Inv_Value;
  
  if (!is_unprotected (sk))
    return CDK_Inv_Mode;
  
  if (!KEY_CAN_SIGN (sig->pubkey_algo))
    return CDK_Inv_Algo;
  
  nbits = cdk_pk_get_nbits (sk->pk);
  rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, sk->pk->pubkey_algo, md,
				 sig->digest_algo, nbits);
  if (rc)
    return rc;

  rc = seckey_to_sexp (&s_skey, sk);
  if (!rc)
    rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen);
  if (rc)
    {
      cdk_free (encmd);
      gcry_sexp_release (s_skey);
      return rc;
    }  
  
  err = gcry_pk_sign (&s_sig, s_hash, s_skey);
  if (err)
    rc = map_gcry_error (err);
  else
    {      
      rc = sexp_to_sig (sig, s_sig);
      if (!rc)
	{
	  sig->digest_start[0] = md[0];
	  sig->digest_start[1] = md[1];
	}
    }
  
  gcry_sexp_release (s_skey);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_sig);
  cdk_free (encmd);
  return rc;
}
Exemplo n.º 2
0
/**
 * cdk_pk_verify:
 * @pk: the public key
 * @sig: signature
 * @md: the message digest
 *
 * Verify the signature in @sig and compare it with the message digest in @md.
 **/
cdk_error_t
cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte *md)
{
  gcry_sexp_t s_pkey = NULL, s_sig = NULL, s_hash = NULL;
  byte *encmd = NULL;
  size_t enclen;
  cdk_error_t rc;
  
  if (!pk || !sig || !md)
    return CDK_Inv_Value;
  
  rc = pubkey_to_sexp (&s_pkey, pk);
  if (rc)
    return rc;
  
  rc = sig_to_sexp (&s_sig, sig);
  if (rc)
    goto leave;
  
  rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, pk->pubkey_algo, md,
				 sig->digest_algo, cdk_pk_get_nbits (pk));
  if (rc)
    goto leave;
  
  rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen);
  if (rc)
    goto leave;
  
  if (gcry_pk_verify (s_sig, s_hash, s_pkey))
    rc = CDK_Bad_Sig;

  leave:
  gcry_sexp_release (s_sig);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_pkey);
  cdk_free (encmd);
  return rc;
}
Exemplo n.º 3
0
/**
 * cdk_pk_verify:
 * @pk: the public key
 * @sig: signature
 * @md: the message digest
 *
 * Verify the signature in @sig and compare it with the message digest in @md.
 **/
cdk_error_t
cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md)
{
    gnutls_datum_t s_sig;
    byte *encmd = NULL;
    size_t enclen;
    cdk_error_t rc;
    int ret, algo;
    unsigned int i;
    gnutls_datum_t data;
    gnutls_pk_params_st params;

    if (!pk || !sig || !md)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    if (is_DSA (pk->pubkey_algo))
        algo = GNUTLS_PK_DSA;
    else if (is_RSA (pk->pubkey_algo))
        algo = GNUTLS_PK_RSA;
    else
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    rc = sig_to_datum (&s_sig, sig);
    if (rc)
    {
        gnutls_assert ();
        goto leave;
    }

    rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, pk->pubkey_algo, md,
                                   sig->digest_algo, cdk_pk_get_nbits (pk));
    if (rc)
    {
        gnutls_assert ();
        goto leave;
    }

    data.data = encmd;
    data.size = enclen;

    params.params_nr = cdk_pk_get_npkey (pk->pubkey_algo);
    for (i = 0; i < params.params_nr; i++)
        params.params[i] = pk->mpi[i];
    params.flags = 0;
    ret = _gnutls_pk_verify (algo, &data, &s_sig, &params);

    if (ret < 0)
    {
        gnutls_assert ();
        rc = map_gnutls_error (ret);
        goto leave;
    }

    rc = 0;

leave:
    _gnutls_free_datum (&s_sig);
    cdk_free (encmd);
    return rc;
}