예제 #1
0
파일: pgp.c 프로젝트: uvbs/SupportCenter
/**
  * gnutls_openpgp_key_get_pk_algorithm - This function returns the key's PublicKey algorithm
  * @key: is an OpenPGP key
  * @bits: if bits is non null it will hold the size of the parameters' in bits
  *
  * This function will return the public key algorithm of an OpenPGP
  * certificate.
  *
  * If bits is non null, it should have enough size to hold the parameters
  * size in bits. For RSA the bits returned is the modulus. 
  * For DSA the bits returned are of the public exponent.
  *
  * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
  * or a negative value on error.
  *
  **/
int
gnutls_openpgp_key_get_pk_algorithm (gnutls_openpgp_key_t key,
				     unsigned int *bits)
{
  cdk_packet_t pkt;
  int algo = 0;

  if (!key)
    return GNUTLS_E_INVALID_REQUEST;

  pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY);
  if (pkt && pkt->pkttype == CDK_PKT_PUBLIC_KEY)
    {
      if (bits)
	*bits = cdk_pk_get_nbits (pkt->pkt.public_key);
      algo = pkt->pkt.public_key->pubkey_algo;
      if (is_RSA (algo))
	algo = GNUTLS_PK_RSA;
      else if (is_DSA (algo))
	algo = GNUTLS_PK_DSA;
      else
	algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  return algo;
}
예제 #2
0
/**
 * gnutls_openpgp_privkey_get_subkey_pk_algorithm:
 * @key: is an OpenPGP key
 * @idx: is the subkey index
 * @bits: if bits is non null it will hold the size of the parameters' in bits
 *
 * This function will return the public key algorithm of a subkey of an OpenPGP
 * certificate.
 *
 * If bits is non null, it should have enough size to hold the parameters
 * size in bits. For RSA the bits returned is the modulus.
 * For DSA the bits returned are of the public exponent.
 *
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
 *   success, or a negative error code on error.
 *
 * Since: 2.4.0
 **/
gnutls_pk_algorithm_t
gnutls_openpgp_privkey_get_subkey_pk_algorithm(gnutls_openpgp_privkey_t
					       key, unsigned int idx,
					       unsigned int *bits)
{
	cdk_packet_t pkt;
	int algo;

	if (!key) {
		gnutls_assert();
		return GNUTLS_PK_UNKNOWN;
	}

	if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX)
		return gnutls_openpgp_privkey_get_pk_algorithm(key, bits);

	pkt = _get_secret_subkey(key, idx);

	algo = 0;
	if (pkt) {
		if (bits)
			*bits = cdk_pk_get_nbits(pkt->pkt.secret_key->pk);
		algo = pkt->pkt.secret_key->pubkey_algo;
		if (is_RSA(algo))
			algo = GNUTLS_PK_RSA;
		else if (is_DSA(algo))
			algo = GNUTLS_PK_DSA;
		else
			algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
	}

	return algo;
}
예제 #3
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;
}
예제 #4
0
/**
 * cdk_pklist_encrypt:
 * @pkl: the keylist
 * @dek: the data encryption key
 * @outp: the stream to write in the data
 *
 * Encrypt the session key with each key of the list and wrap it
 * into a PUBKEY_ENC packet and write it to @outp.
 */
cdk_error_t
cdk_pklist_encrypt( cdk_keylist_t pk_list, cdk_dek_t dek, cdk_stream_t outp )
{
    cdk_pkt_pubkey_t pk = NULL;
    cdk_pkt_pubkey_enc_t enc = NULL;
    cdk_packet_t pkt;
    cdk_sesskey_t frame = NULL;
    int nbits = 0;
    int rc = 0;

    if( !pk_list || !dek || !outp )
        return CDK_Inv_Value;

    if( pk_list->type != CDK_PKT_PUBLIC_KEY )
        return CDK_Inv_Mode;

    pkt = cdk_calloc( 1, sizeof * pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    for( ; pk_list; pk_list = pk_list->next ) {
        pk = pk_list->key.pk;
        cdk_free( enc );
        enc = cdk_calloc( 1, sizeof *enc );
        if( !enc )
            return CDK_Out_Of_Core;
        enc->version = 3;
        enc->pubkey_algo = pk->pubkey_algo;
        cdk_pk_get_keyid( pk, enc->keyid );
        nbits = cdk_pk_get_nbits( pk );
        rc = cdk_dek_encode_pkcs1( dek, nbits, &frame );
        if( rc )
            break;
        rc = cdk_pk_encrypt( pk, enc, frame );
        cdk_sesskey_free( frame );
        if( rc )
            break;
        else {
            cdk_pkt_init( pkt );
            pkt->old_ctb = dek->rfc1991? 1 : 0;
            pkt->pkttype = CDK_PKT_PUBKEY_ENC;
            pkt->pkt.pubkey_enc = enc;
            rc = cdk_pkt_write( outp, pkt );
            cdk_pkt_free( pkt );
            if( rc )
                break;
	}
    }
    cdk_free( pkt );
    cdk_free( enc );
    return rc;
}
예제 #5
0
파일: privkey.c 프로젝트: nobled/gnutls
/**
 * gnutls_openpgp_privkey_get_pk_algorithm:
 * @key: is an OpenPGP key
 * @bits: if bits is non null it will hold the size of the parameters' in bits
 *
 * This function will return the public key algorithm of an OpenPGP
 * certificate.
 *
 * If bits is non null, it should have enough size to hold the parameters
 * size in bits. For RSA the bits returned is the modulus.
 * For DSA the bits returned are of the public exponent.
 *
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
 *   success, or a negative error code on error.
 *
 * Since: 2.4.0
 **/
gnutls_pk_algorithm_t
gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
                                         unsigned int *bits)
{
  cdk_packet_t pkt;
  int algo = 0, ret;
  uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];

  if (!key)
    {
      gnutls_assert ();
      return GNUTLS_PK_UNKNOWN;
    }

  ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
  if (ret == 0)
    {
      int idx;

      idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
      if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX)
        {
          algo =
            gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, bits);
          return algo;
        }
    }

  pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
  if (pkt)
    {
      if (bits)
        *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
      algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
    }

  return algo;
}
예제 #6
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;
}
예제 #7
0
/**
 * gnutls_openpgp_privkey_get_pk_algorithm:
 * @key: is an OpenPGP key
 * @bits: if bits is non null it will hold the size of the parameters' in bits
 *
 * This function will return the public key algorithm of an OpenPGP
 * certificate.
 *
 * If bits is non null, it should have enough size to hold the parameters
 * size in bits. For RSA the bits returned is the modulus.
 * For DSA the bits returned are of the public exponent.
 *
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
 *   success, or a negative value on error.
 *
 * Since: 2.4.0
 **/
gnutls_pk_algorithm_t
gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
					 unsigned int *bits)
{
  cdk_packet_t pkt;
  int algo;

  if (!key)
    {
      gnutls_assert ();
      return GNUTLS_PK_UNKNOWN;
    }

  algo = 0;
  pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
  if (pkt)
    {
      if (bits)
	*bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk);
      algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo);
    }

  return algo;
}
예제 #8
0
파일: xml.c 프로젝트: uvbs/SupportCenter
static int
xml_add_key (gnutls_string * xmlkey, int ext, cdk_pkt_pubkey_t pk, int sub)
{
  const char *algo, *s;
  char keyid[16], fpr[41], tmp[32];
  uint8_t fingerpr[20];
  unsigned int kid[2];
  int i = 0, rc = 0;

  if (!xmlkey || !pk)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  s = sub ? "  <SUBKEY>\n" : "  <MAINKEY>\n";
  _gnutls_string_append_str (xmlkey, s);

  cdk_pk_get_keyid (pk, kid);
  snprintf (keyid, 16, "%08lX%08lX", kid[0], kid[1]);
  rc = xml_add_tag (xmlkey, "KEYID", keyid);
  if (rc)
    return rc;

  cdk_pk_get_fingerprint (pk, fingerpr);
  for (i = 0; i < 20; i++)
    sprintf (fpr + 2 * i, "%02X", fingerpr[i]);
  fpr[40] = '\0';
  rc = xml_add_tag (xmlkey, "FINGERPRINT", fpr);
  if (rc)
    return rc;

  if (is_DSA (pk->pubkey_algo))
    algo = "DSA";
  else if (is_RSA (pk->pubkey_algo))
    algo = "RSA";
  else if (is_ELG (pk->pubkey_algo))
    algo = "ELG";
  else
    algo = "???";
  rc = xml_add_tag (xmlkey, "PKALGO", algo);
  if (rc)
    return rc;

  sprintf (tmp, "%d", cdk_pk_get_nbits (pk));
  rc = xml_add_tag (xmlkey, "KEYLEN", tmp);
  if (rc)
    return rc;

  sprintf (tmp, "%lu", pk->timestamp);
  rc = xml_add_tag (xmlkey, "CREATED", tmp);
  if (rc)
    return rc;

  if (pk->expiredate > 0)
    {
      sprintf (tmp, "%lu", (unsigned long) pk->expiredate);
      rc = xml_add_tag (xmlkey, "EXPIREDATE", tmp);
      if (rc)
	return rc;
    }

  sprintf (tmp, "%d", pk->is_revoked);
  rc = xml_add_tag (xmlkey, "REVOKED", tmp);
  if (rc)
    return rc;

  if (ext)
    {
      rc = xml_add_key_mpi (xmlkey, pk);
      if (rc)
	return rc;
    }

  s = sub ? "  </SUBKEY>\n" : "  </MAINKEY>\n";
  _gnutls_string_append_str (xmlkey, s);

  return 0;
}
예제 #9
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;
}