예제 #1
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Decode the public key from the data-format back
 * to the "normal", internal format.
 *
 * @param buf the buffer where the public key data is stored
 * @param len the length of the data in @a buf
 * @return NULL on error
 */
struct GNUNET_CRYPTO_rsa_PublicKey *
GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
                                     size_t len)
{
  struct GNUNET_CRYPTO_rsa_PublicKey *key;
  gcry_mpi_t n;
  int ret;

  key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
  if (0 !=
      gcry_sexp_new (&key->sexp,
                     buf,
                     len,
                     0))
  {
    GNUNET_break_op (0);
    GNUNET_free (key);
    return NULL;
  }
  /* verify that this is an RSA public key */
  ret = key_from_sexp (&n, key->sexp, "public-key", "n");
  if (0 != ret)
    ret = key_from_sexp (&n, key->sexp, "rsa", "n");
  if (0 != ret)
  {
    /* this is no public RSA key */
    GNUNET_break (0);
    gcry_sexp_release (key->sexp);
    GNUNET_free (key);
    return NULL;
  }
  gcry_mpi_release (n);
  return key;
}
//build the s-expression of the key reading the file
void retrieve_key_pair(char * filename){

    void* dsa_buf; 
    gcry_error_t err;
    //open the correct file
    FILE * file = fopen(filename, "rb");

    if (!file) {
        puts("fopen() failed");
        exit(0);
    }
    //retrieve the file size
    int size = get_file_size(file);
    //allocate the buffer that will contain the key
    dsa_buf = malloc(size);
    if (!dsa_buf) {
        puts("malloc: could not allocate rsa buffer");
        exit(0);
    }
    //copy the content of the file in the buffer
    if (fread(dsa_buf, size, 1, file) != 1) {
       puts("fread() failed");
       exit(0);
    }
    //build the s-expression
    err = gcry_sexp_new(&dsa_key_pair, dsa_buf, size, 0); 

    if(err){
        puts("Error");
        exit(0);
    }
}
예제 #3
0
static void
get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
{
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  int rc;
  
  rc = gcry_sexp_new (&key_spec,
		      "(genkey (rsa (nbits 4:1024)))", 0, 1);
  if (rc)
    die ("error creating S-expression: %s\n", gpg_strerror (rc));
  rc = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (rc)
    die ("error generating RSA key: %s\n", gpg_strerror (rc));
    
  pub_key = gcry_sexp_find_token (key, "public-key", 0);
  if (! pub_key)
    die ("public part missing in key\n");

  sec_key = gcry_sexp_find_token (key, "private-key", 0);
  if (! sec_key)
    die ("private part missing in key\n");

  gcry_sexp_release (key);
  *pkey = pub_key;
  *skey = sec_key;
}
예제 #4
0
static void
get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
{
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  int rc;

  rc = gcry_sexp_new
    (&key_spec,
     (fixed_x
      ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
      : "(genkey (elg (nbits 3:512)))"),
     0, 1);

  if (rc)
    die ("error creating S-expression: %s\n", gcry_strerror (rc));
  rc = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (rc)
    die ("error generating Elgamal key: %s\n", gcry_strerror (rc));

  if (verbose > 1)
    show_sexp ("generated ELG key:\n", key);

  pub_key = gcry_sexp_find_token (key, "public-key", 0);
  if (!pub_key)
    die ("public part missing in key\n");

  sec_key = gcry_sexp_find_token (key, "private-key", 0);
  if (!sec_key)
    die ("private part missing in key\n");

  gcry_sexp_release (key);
  *pkey = pub_key;
  *skey = sec_key;
}
예제 #5
0
static void
get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
{
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  int rc;

  rc = gcry_sexp_new
    (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))",  0, 1);
  if (rc)
    die ("error creating S-expression: %s\n", gcry_strerror (rc));
  rc = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (rc)
    die ("error generating DSA key: %s\n", gcry_strerror (rc));

  if (verbose > 1)
    show_sexp ("generated DSA key (fips 186):\n", key);

  pub_key = gcry_sexp_find_token (key, "public-key", 0);
  if (!pub_key)
    die ("public part missing in key\n");

  sec_key = gcry_sexp_find_token (key, "private-key", 0);
  if (!sec_key)
    die ("private part missing in key\n");

  gcry_sexp_release (key);
  *pkey = pub_key;
  *skey = sec_key;
}
예제 #6
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Decode the private key from the data-format back
 * to the "normal", internal format.
 *
 * @param buf the buffer where the private key data is stored
 * @param len the length of the data in @a buf
 * @return NULL on error
 */
struct GNUNET_CRYPTO_rsa_PrivateKey *
GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
                                      size_t len)
{
  struct GNUNET_CRYPTO_rsa_PrivateKey *key;
  key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
  if (0 !=
      gcry_sexp_new (&key->sexp,
                     buf,
                     len,
                     0))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         "Decoded private key is not valid\n");
    GNUNET_free (key);
    return NULL;
  }
  if (0 != gcry_pk_testkey (key->sexp))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         "Decoded private key is not valid\n");
    GNUNET_CRYPTO_rsa_private_key_free (key);
    return NULL;
  }
  return key;
}
예제 #7
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Decode the signature from the data-format back to the "normal", internal
 * format.
 *
 * @param buf the buffer where the public key data is stored
 * @param len the length of the data in @a buf
 * @return NULL on error
 */
struct GNUNET_CRYPTO_rsa_Signature *
GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
                                    size_t len)
{
  struct GNUNET_CRYPTO_rsa_Signature *sig;
  int ret;
  gcry_mpi_t s;

  sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
  if (0 !=
      gcry_sexp_new (&sig->sexp,
                     buf,
                     len,
                     0))
  {
    GNUNET_break_op (0);
    GNUNET_free (sig);
    return NULL;
  }
  /* verify that this is an RSA signature */
  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  if (0 != ret)
    ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  if (0 != ret)
  {
    /* this is no RSA Signature */
    GNUNET_break_op (0);
    gcry_sexp_release (sig->sexp);
    GNUNET_free (sig);
    return NULL;
  }
  gcry_mpi_release (s);
  return sig;
}
예제 #8
0
파일: keygen.c 프로젝트: ifzz/libgcrypt
static void
check_dsa_keys (void)
{
    gcry_sexp_t keyparm, key;
    int rc;
    int i;

    /* Check that DSA generation works and that it can grok the qbits
       argument. */
    if (verbose)
        show ("creating 5 1024 bit DSA keys\n");
    for (i=0; i < 5; i++)
    {
        rc = gcry_sexp_new (&keyparm,
                            "(genkey\n"
                            " (dsa\n"
                            "  (nbits 4:1024)\n"
                            " ))", 0, 1);
        if (rc)
            die ("error creating S-expression: %s\n", gpg_strerror (rc));
        rc = gcry_pk_genkey (&key, keyparm);
        gcry_sexp_release (keyparm);
        if (rc)
            die ("error generating DSA key: %s\n", gpg_strerror (rc));
        if (!i && verbose > 1)
            show_sexp ("1024 bit DSA key:\n", key);
        gcry_sexp_release (key);
    }

    if (verbose)
        show ("creating 1536 bit DSA key\n");
    rc = gcry_sexp_new (&keyparm,
                        "(genkey\n"
                        " (dsa\n"
                        "  (nbits 4:1536)\n"
                        "  (qbits 3:224)\n"
                        " ))", 0, 1);
    if (rc)
        die ("error creating S-expression: %s\n", gpg_strerror (rc));
    rc = gcry_pk_genkey (&key, keyparm);
    gcry_sexp_release (keyparm);
    if (rc)
        die ("error generating DSA key: %s\n", gpg_strerror (rc));
    if (verbose > 1)
        show_sexp ("1536 bit DSA key:\n", key);
    gcry_sexp_release (key);
}
예제 #9
0
gcry_sexp_t sexp_new(const char *str) {
	gcry_error_t error;

	gcry_sexp_t sexp;
	size_t len = strlen(str);
	if ((error = gcry_sexp_new(&sexp, str, len, 1))) {
		printf("Error in sexp_new(%s): %s\nSource: %s\n", str, gcry_strerror(error), gcry_strsource(error));
		exit(1);
	}

	return sexp;
}
예제 #10
0
static void
check_matching (void)
{
  gpg_error_t err;
  gcry_sexp_t key;
  const char *name;
  unsigned int nbits;

  err = gcry_sexp_new (&key, sample_key_1, 0, 1);
  if (err)
    die ("parsing s-expression string failed: %s\n", gpg_strerror (err));
  name = gcry_pk_get_curve (key, 0, &nbits);
  if (!name)
    fail ("curve name not found for sample_key_1\n");
  else if (strcmp (name, sample_key_1_curve))
    fail ("expected curve name %s but got %s for sample_key_1\n",
          sample_key_1_curve, name);
  else if (nbits != sample_key_1_nbits)
    fail ("expected curve size %u but got %u for sample_key_1\n",
          sample_key_1_nbits, nbits);

  gcry_sexp_release (key);

  err = gcry_sexp_new (&key, sample_key_2, 0, 1);
  if (err)
    die ("parsing s-expression string failed: %s\n", gpg_strerror (err));
  name = gcry_pk_get_curve (key, 0, &nbits);
  if (!name)
    fail ("curve name not found for sample_key_2\n");
  else if (strcmp (name, sample_key_2_curve))
    fail ("expected curve name %s but got %s for sample_key_2\n",
          sample_key_2_curve, name);
  else if (nbits != sample_key_2_nbits)
    fail ("expected curve size %u but got %u for sample_key_2\n",
          sample_key_2_nbits, nbits);

  gcry_sexp_release (key);
}
예제 #11
0
/* Generate a private DSA key for a given account, storing it into a
 * FILE*, and loading it into the given OtrlUserState.  Overwrite any
 * previously generated keys for that account in that OtrlUserState.
 * The FILE* must be open for reading and writing. */
gcry_error_t otrl_privkey_generate_FILEp(OtrlUserState us, FILE *privf,
	const char *accountname, const char *protocol)
{
    gcry_error_t err;
    gcry_sexp_t key, parms, privkey;
    static const char *parmstr = "(genkey (dsa (nbits 4:1024)))";
    OtrlPrivKey *p;

    if (!privf) return gcry_error(GPG_ERR_NO_ERROR);

    /* Create a DSA key */
    err = gcry_sexp_new(&parms, parmstr, strlen(parmstr), 0);
    if (err) {
	return err;
    }
    err = gcry_pk_genkey(&key, parms);
    gcry_sexp_release(parms);
    if (err) {
	return err;
    }

    /* Extract the privkey */
    privkey = gcry_sexp_find_token(key, "private-key", 0);
    gcry_sexp_release(key);

    /* Output the other keys we know */
    fprintf(privf, "(privkeys\n");

    for (p=us->privkey_root; p; p=p->next) {
	/* Skip this one if our new key replaces it */
	if (!strcmp(p->accountname, accountname) &&
		!strcmp(p->protocol, protocol)) {
	    continue;
	}

	account_write(privf, p->accountname, p->protocol, p->privkey);
    }
    account_write(privf, accountname, protocol, privkey);
    gcry_sexp_release(privkey);
    fprintf(privf, ")\n");

    fseek(privf, 0, SEEK_SET);

    return otrl_privkey_read_FILEp(us, privf);
}
예제 #12
0
static void
get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
{
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  int rc;

  rc = gcry_sexp_new
    (&key_spec,
     "(genkey (dsa (transient-key)(use-fips186)(domain"
     "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
     "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
     "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
     "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
     "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
     "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
     "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
     "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
     "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
     ")))", 0, 1);
  if (rc)
    die ("error creating S-expression: %s\n", gcry_strerror (rc));
  rc = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (rc)
    die ("error generating DSA key: %s\n", gcry_strerror (rc));

  if (verbose > 1)
    show_sexp ("generated DSA key:\n", key);

  pub_key = gcry_sexp_find_token (key, "public-key", 0);
  if (!pub_key)
    die ("public part missing in key\n");

  sec_key = gcry_sexp_find_token (key, "private-key", 0);
  if (!sec_key)
    die ("private part missing in key\n");

  gcry_sexp_release (key);
  *pkey = pub_key;
  *skey = sec_key;
}
예제 #13
0
static void
get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
{
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  int rc;

  rc = gcry_sexp_new
    (&key_spec,
     "(genkey"
     "  (dsa"
     "    (nbits 4:1024)"
     "    (use-fips186)"
     "    (transient-key)"
     "    (derive-parms"
     "      (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
     0, 1);
  if (rc)
    die ("error creating S-expression: %s\n", gcry_strerror (rc));
  rc = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (rc)
    die ("error generating DSA key: %s\n", gcry_strerror (rc));

  if (verbose > 1)
    show_sexp ("generated DSA key (fips 186 with seed):\n", key);

  pub_key = gcry_sexp_find_token (key, "public-key", 0);
  if (!pub_key)
    die ("public part missing in key\n");

  sec_key = gcry_sexp_find_token (key, "private-key", 0);
  if (!sec_key)
    die ("private part missing in key\n");

  gcry_sexp_release (key);
  *pkey = pub_key;
  *skey = sec_key;
}
예제 #14
0
파일: keygen.c 프로젝트: ifzz/libgcrypt
static void
check_elg_keys (void)
{
    gcry_sexp_t keyparm, key;
    int rc;

    if (verbose)
        show ("creating 1024 bit Elgamal key\n");
    rc = gcry_sexp_new (&keyparm,
                        "(genkey\n"
                        " (elg\n"
                        "  (nbits 4:1024)\n"
                        " ))", 0, 1);
    if (rc)
        die ("error creating S-expression: %s\n", gpg_strerror (rc));
    rc = gcry_pk_genkey (&key, keyparm);
    gcry_sexp_release (keyparm);
    if (rc)
        die ("error generating Elgamal key: %s\n", gpg_strerror (rc));
    if (verbose > 1)
        show_sexp ("1024 bit Elgamal key:\n", key);
    gcry_sexp_release (key);
}
예제 #15
0
static void
check_ed25519ecdsa_sample_key (void)
{
  static const char ecc_private_key[] =
    "(private-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
    "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
    "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
    "))";
  static const char ecc_private_key_wo_q[] =
    "(private-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
    "))";
  static const char ecc_public_key[] =
    "(public-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
    "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
    "))";
  static const char ecc_public_key_comp[] =
    "(public-key\n"
    " (ecc\n"
    "  (curve \"Ed25519\")\n"
    "  (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
    "))";
  static const char hash_string[] =
    "(data (flags ecdsa rfc6979)\n"
    " (hash sha256 #00112233445566778899AABBCCDDEEFF"
    /* */          "000102030405060708090A0B0C0D0E0F#))";

  gpg_error_t err;
  gcry_sexp_t key, hash, sig;

  if (verbose)
    fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");

  /* Sign.  */
  if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign failed: %s", gpg_strerror (err));

  /* Verify.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify failed: %s", gpg_strerror (err));

  /* Verify again using a compressed public key.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));

  /* Sign without a Q parameter.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  gcry_sexp_release (sig);
  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));

  /* Verify.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));

  /* Verify again using a compressed public key.  */
  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));
  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));

  extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
                               "655d0179e22199bf63691fd88eb64e15"));
  extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
                               "623ddaf5d02fa65ca5056cb6bd0f16f1"));

  gcry_sexp_release (sig);
  gcry_sexp_release (key);
  gcry_sexp_release (hash);
}
예제 #16
0
파일: keygen.c 프로젝트: ifzz/libgcrypt
static void
check_rsa_keys (void)
{
    gcry_sexp_t keyparm, key;
    int rc;

    if (verbose)
        show ("creating 1024 bit RSA key\n");
    rc = gcry_sexp_new (&keyparm,
                        "(genkey\n"
                        " (rsa\n"
                        "  (nbits 4:1024)\n"
                        " ))", 0, 1);
    if (rc)
        die ("error creating S-expression: %s\n", gpg_strerror (rc));
    rc = gcry_pk_genkey (&key, keyparm);
    gcry_sexp_release (keyparm);
    if (rc)
        die ("error generating RSA key: %s\n", gpg_strerror (rc));
    if (verbose > 1)
        show_sexp ("1024 bit RSA key:\n", key);
    check_generated_rsa_key (key, 65537);
    gcry_sexp_release (key);


    if (verbose)
        show ("creating 512 bit RSA key with e=257\n");
    rc = gcry_sexp_new (&keyparm,
                        "(genkey\n"
                        " (rsa\n"
                        "  (nbits 3:512)\n"
                        "  (rsa-use-e 3:257)\n"
                        " ))", 0, 1);
    if (rc)
        die ("error creating S-expression: %s\n", gpg_strerror (rc));
    rc = gcry_pk_genkey (&key, keyparm);
    gcry_sexp_release (keyparm);
    if (rc)
        die ("error generating RSA key: %s\n", gpg_strerror (rc));

    check_generated_rsa_key (key, 257);
    gcry_sexp_release (key);

    if (verbose)
        show ("creating 512 bit RSA key with default e\n");
    rc = gcry_sexp_new (&keyparm,
                        "(genkey\n"
                        " (rsa\n"
                        "  (nbits 3:512)\n"
                        "  (rsa-use-e 1:0)\n"
                        " ))", 0, 1);
    if (rc)
        die ("error creating S-expression: %s\n", gpg_strerror (rc));
    rc = gcry_pk_genkey (&key, keyparm);
    gcry_sexp_release (keyparm);
    if (rc)
        die ("error generating RSA key: %s\n", gpg_strerror (rc));

    check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
    gcry_sexp_release (key);
}
예제 #17
0
static void
check_extract_param (void)
{
  /* This sample data is a real key but with some parameters of the
     public key modified.  */
  static char sample1[] =
    "(key-data"
    " (public-key"
    "  (ecc"
    "   (curve Ed25519)"
    "   (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
    "   (a #EF#)"
    "   (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
    "   (g #14"
    "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "       6666666666666666666666666666666666666666666666666666666666666658#)"
    "   (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
    "   (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
    "))"
    " (private-key"
    "  (ecc"
    "   (curve Ed25519)"
    "   (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
    "   (a #FF#)"
    "   (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
    "   (g #04"
    "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "       6666666666666666666666666666666666666666666666666666666666666658#)"
    "   (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
    "   (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
    "   (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
    ")))";

  static char sample1_p[] =
    "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
  static char sample1_px[] =
    "6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
  static char sample1_a[] = "FF";
  static char sample1_ax[] = "EF";
  static char sample1_b[] =
    "D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
  static char sample1_bx[] =
    "C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
  static char sample1_g[] =
    "04"
    "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "6666666666666666666666666666666666666666666666666666666666666658";
  static char sample1_gx[] =
    "14"
    "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "6666666666666666666666666666666666666666666666666666666666666658";
  static char sample1_n[] =
    "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
  static char sample1_nx[] =
    "0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
  static char sample1_q[] =
    "30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
  static char sample1_qx[] =
    "20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
  static char sample1_d[] =
    "56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";

  static struct {
    const char *sexp_str;
    const char *path;
    const char *list;
    int nparam;
    gpg_err_code_t expected_err;
    const char *exp_p;
    const char *exp_a;
    const char *exp_b;
    const char *exp_g;
    const char *exp_n;
    const char *exp_q;
    const char *exp_d;
  } tests[] = {
    {
      sample1,
      NULL,
      "pabgnqd", 6,
      GPG_ERR_MISSING_VALUE,
    },
    {
      sample1,
      NULL,
      "pabgnq", 7,
      GPG_ERR_INV_ARG
    },
    {
      sample1,
      NULL,
      "pab'gnq", 7,
      GPG_ERR_SYNTAX
    },
    {
      sample1,
      NULL,
      "pab''gnq", 7,
      GPG_ERR_SYNTAX
    },
    {
      sample1,
      NULL,
      "pabgnqd", 7,
      0,
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      NULL,
      "  pab\tg nq\nd  ", 7,
      0,
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      NULL,
      "abg", 3,
      0,
      sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "ab'g'", 3,
      0,
      sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "x?abg", 4,
      0,
      NULL, sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "p?abg", 4,
      GPG_ERR_USER_1,
      NULL, sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "pax?gnqd", 7,
      0,
      sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      "public-key",
      "pabgnqd", 7,
      GPG_ERR_NO_OBJ,  /* d is not in public key.  */
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      "private-key",
      "pabgnqd", 7,
      0,
      sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
      sample1_q, sample1_d
    },
    {
      sample1,
      "public-key!ecc",
      "pabgnq", 6,
      0,
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx
    },
    {
      sample1,
      "public-key!ecc!foo",
      "pabgnq", 6,
      GPG_ERR_NOT_FOUND
    },
    {
      sample1,
      "public-key!!ecc",
      "pabgnq", 6,
      GPG_ERR_NOT_FOUND
    },
    {
      sample1,
      "private-key",
      "pa/bgnqd", 7,
      0,
      sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
      sample1_q, sample1_d
    },
    {
      sample1,
      "private-key",
      "p-a+bgnqd", 7,
      0,
      sample1_p, "-01", sample1_b, sample1_g, sample1_n,
      sample1_q, sample1_d
    },
    {NULL}
  };
  int idx, i;
  const char *paramstr;
  int paramidx;
  gpg_error_t err;
  gcry_sexp_t sxp;
  gcry_mpi_t mpis[7];
  gcry_buffer_t ioarray[7];
  char iobuffer[200];

  info ("checking gcry_sexp_extract_param\n");
  for (idx=0; tests[idx].sexp_str; idx++)
    {
      err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
      if (err)
        die ("converting string to sexp failed: %s", gpg_strerror (err));

      memset (mpis, 0, sizeof mpis);
      switch (tests[idx].nparam)
        {
        case 0:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         NULL);
          break;
        case 1:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, NULL);
          break;
        case 2:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, NULL);
          break;
        case 3:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, NULL);
          break;
        case 4:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, NULL);
          break;
        case 5:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
                                         NULL);
          break;
        case 6:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
                                         mpis+5, NULL);
          break;
        case 7:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
                                         mpis+5, mpis+6, NULL);
          break;
        default:
          die ("test %d: internal error", idx);
        }

      if (tests[idx].expected_err
          && tests[idx].expected_err != GPG_ERR_USER_1)
        {
          if (tests[idx].expected_err != gpg_err_code (err))
            fail ("gcry_sexp_extract_param test %d failed: "
                  "expected error '%s' - got '%s'", idx,
                  gpg_strerror (tests[idx].expected_err),gpg_strerror (err));

        }
      else if (err)
        {
          fail ("gcry_sexp_extract_param test %d failed: %s",
                idx, gpg_strerror (err));
        }
      else /* No error - check the extracted values.  */
        {
          for (paramidx=0; paramidx < DIM (mpis); paramidx++)
            {
              switch (paramidx)
                {
                case 0: paramstr = tests[idx].exp_p; break;
                case 1: paramstr = tests[idx].exp_a; break;
                case 2: paramstr = tests[idx].exp_b; break;
                case 3: paramstr = tests[idx].exp_g; break;
                case 4: paramstr = tests[idx].exp_n; break;
                case 5: paramstr = tests[idx].exp_q; break;
                case 6: paramstr = tests[idx].exp_d; break;
                default:
                  die ("test %d: internal error: bad param %d",
                       idx, paramidx);
                }

              if (tests[idx].expected_err == GPG_ERR_USER_1
                  && mpis[paramidx] && !paramstr && paramidx == 0)
                ; /* Okay  Special case error for param 0.  */
              else if (!mpis[paramidx] && !paramstr)
                ; /* Okay.  */
              else if (!mpis[paramidx] && paramstr)
                fail ("test %d: value for param %d expected but not returned",
                      idx, paramidx);
              else if (mpis[paramidx] && !paramstr)
                fail ("test %d: value for param %d not expected",
                      idx, paramidx);
              else if (cmp_mpihex (mpis[paramidx], paramstr))
                {
                  fail ("test %d: param %d mismatch", idx, paramidx);
                  gcry_log_debug    ("expected: %s\n", paramstr);
                  gcry_log_debugmpi ("     got", mpis[paramidx]);
                }
              else if (tests[idx].expected_err && paramidx == 0)
                fail ("test %d: param %d: expected error '%s' - got 'Success'",
                      idx, paramidx, gpg_strerror (tests[idx].expected_err));
            }

        }

      for (i=0; i < DIM (mpis); i++)
        gcry_mpi_release (mpis[i]);
      gcry_sexp_release (sxp);
    }

  info ("checking gcry_sexp_extract_param/desc\n");

  memset (ioarray, 0, sizeof ioarray);

  err = gcry_sexp_new (&sxp, sample1, 0, 1);
  if (err)
    die ("converting string to sexp failed: %s", gpg_strerror (err));

  ioarray[1].size = sizeof iobuffer;
  ioarray[1].data = iobuffer;
  ioarray[1].off  = 0;
  ioarray[2].size = sizeof iobuffer;
  ioarray[2].data = iobuffer;
  ioarray[2].off  = 50;
  assert (ioarray[2].off < sizeof iobuffer);
  err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
                                 ioarray+0, ioarray+1, ioarray+2, NULL);
  if (err)
    fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
  else
    {
      if (!ioarray[0].data)
        fail ("gcry_sexp_extract_param/desc failed: no P");
      else if (ioarray[0].size != 32)
        fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
      else if (ioarray[0].len != 32)
        fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
      else if (ioarray[0].off)
        fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
      else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
        {
          fail ("gcry_sexp_extract_param/desc failed: P mismatch");
          gcry_log_debug    ("expected: %s\n", sample1_p);
          gcry_log_debughex ("     got", ioarray[0].data, ioarray[0].len);
        }

      if (!ioarray[1].data)
        fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
      else if (ioarray[1].size != sizeof iobuffer)
        fail ("gcry_sexp_extract_param/desc failed: A size changed");
      else if (ioarray[1].off != 0)
        fail ("gcry_sexp_extract_param/desc failed: A off changed");
      else if (ioarray[1].len != 1)
        fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
      else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
                           ioarray[1].len, sample1_a))
        {
          fail ("gcry_sexp_extract_param/desc failed: A mismatch");
          gcry_log_debug    ("expected: %s\n", sample1_a);
          gcry_log_debughex ("     got",
                             (char *)ioarray[1].data + ioarray[1].off,
                             ioarray[1].len);
        }

      if (!ioarray[2].data)
        fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
      else if (ioarray[2].size != sizeof iobuffer)
        fail ("gcry_sexp_extract_param/desc failed: B size changed");
      else if (ioarray[2].off != 50)
        fail ("gcry_sexp_extract_param/desc failed: B off changed");
      else if (ioarray[2].len != 32)
        fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
      else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
                           ioarray[2].len, sample1_b))
        {
          fail ("gcry_sexp_extract_param/desc failed: B mismatch");
          gcry_log_debug    ("expected: %s\n", sample1_b);
          gcry_log_debughex ("     got",
                             (char *)ioarray[2].data + ioarray[2].off,
                             ioarray[2].len);
        }

      xfree (ioarray[0].data);
    }

  gcry_sexp_release (sxp);

  info ("checking gcry_sexp_extract_param long name\n");

  memset (ioarray, 0, sizeof ioarray);
  memset (mpis, 0, sizeof mpis);

  err = gcry_sexp_new (&sxp, sample1, 0, 1);
  if (err)
    die ("converting string to sexp failed: %s", gpg_strerror (err));

  err = gcry_sexp_extract_param (sxp, "key-data!private-key",
                                 "&'curve'+p",
                                 ioarray+0, mpis+0, NULL);
  if (err)
    fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));

  if (!ioarray[0].data)
    fail ("gcry_sexp_extract_param long name failed: no curve");
  else if (ioarray[0].size != 7)
    fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
  else if (ioarray[0].len != 7)
    fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
  else if (ioarray[0].off)
    fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
  else if (strncmp (ioarray[0].data, "Ed25519", 7))
    {
      fail ("gcry_sexp_extract_param long name failed: curve mismatch");
      gcry_log_debug ("expected: %s\n", "Ed25519");
      gcry_log_debug ("     got: %.*s\n",
                      (int)ioarray[0].len, (char*)ioarray[0].data);
    }

  if (!mpis[0])
    fail ("gcry_sexp_extract_param long name failed: p not returned");
  else if (cmp_mpihex (mpis[0], sample1_p))
    {
      fail ("gcry_sexp_extract_param long name failed: p mismatch");
      gcry_log_debug    ("expected: %s\n", sample1_p);
      gcry_log_debugmpi ("     got", mpis[0]);
    }

  gcry_free (ioarray[0].data);
  gcry_mpi_release (mpis[0]);

  gcry_sexp_release (sxp);

}
예제 #18
0
static void
back_and_forth_one (int testno, const char *buffer, size_t length)
{
  gcry_error_t rc;
  gcry_sexp_t se, se1;
  unsigned char *canon;
  size_t canonlen;  /* Including the hidden nul suffix.  */
  size_t n, n1;
  char *p1;

  rc = gcry_sexp_new (&se, buffer, length, 1);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
      return;
    }
  n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
  if (!n1)
    {
      fail ("baf %d: get required length for canon failed\n", testno);
      return;
    }
  p1 = gcry_xmalloc (n1);
  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
  if (n1 != n+1) /* sprints adds an extra 0 but does not return it. */
    {
      fail ("baf %d: length mismatch for canon\n", testno);
      return;
    }
  canonlen = n1;
  canon = gcry_malloc (canonlen);
  memcpy (canon, p1, canonlen);
  rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_create failed: %s\n",
            testno, gpg_strerror (rc));
      return;
    }
  gcry_sexp_release (se1);

  /* Again but with memory checking. */
  p1 = gcry_xmalloc (n1+2);
  *p1 = '\x55';
  p1[n1+1] = '\xaa';
  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
  if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
    {
      fail ("baf %d: length mismatch for canon\n", testno);
      return;
    }
  if (*p1 != '\x55' || p1[n1+1] != '\xaa')
    fail ("baf %d: memory corrupted (1)\n", testno);
  rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_create failed: %s\n",
            testno, gpg_strerror (rc));
      return;
    }
  if (*p1 != '\x55' || p1[n1+1] != '\xaa')
    fail ("baf %d: memory corrupted (2)\n", testno);
  gcry_sexp_release (se1);
  if (*p1 != '\x55' || p1[n1+1] != '\xaa')
    fail ("baf %d: memory corrupted (3)\n", testno);
  gcry_free (p1);

  /* Check converting to advanced format.  */
  n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, NULL, 0);
  if (!n1)
    {
      fail ("baf %d: get required length for advanced failed\n", testno);
      return;
    }
  p1 = gcry_xmalloc (n1);
  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, p1, n1);
  if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
    {
      fail ("baf %d: length mismatch for advanced\n", testno);
      return;
    }
  rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_create failed: %s\n",
            testno, gpg_strerror (rc));
      return;
    }
  if (compare_to_canon (se1, canon, canonlen))
    {
      fail ("baf %d: converting to advanced failed: %s\n",
            testno, gpg_strerror (rc));
      return;
    }
  gcry_sexp_release (se1);


  /* FIXME: we need a lot more tests */

  gcry_sexp_release (se);
  xfree (canon);
}
예제 #19
0
/* A test based on bug 1594.  */
static void
bug_1594 (void)
{
static char thing[] =
  "(signature"
  " (public-key"
  "  (rsa"
  "   (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
  "       6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
  "       6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
  "       C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
  "       CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
  "       54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
  "       13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
  "       A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
  "       F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
  "       A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
  "       E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
  "       E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
  "       923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
  "       EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
  "       2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
  "       95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
  "       67#)"
  "   (e #010001#))))";
  gcry_sexp_t sig, pubkey, n, n_val;

  info ("checking fix for bug 1594\n");

  if (gcry_sexp_new (&sig, thing, 0, 1))
    die ("scanning fixed string failed\n");
  pubkey = gcry_sexp_find_token (sig, "public-key", 0);
  gcry_sexp_release (sig);
  if (!pubkey)
    {
      fail ("'public-key' token not found");
      return;
    }
  n = gcry_sexp_find_token (pubkey, "n", 0);
  if (!n)
    {
      fail ("'n' token not found");
      gcry_sexp_release (pubkey);
      return;
    }
  n_val = gcry_sexp_nth (n, 1);
  /* Bug 1594 would require the following test:
   *   if (n_val)
   *     fail ("extracting 1-th of 'n' list did not fail");
   * However, we meanwhile modified the S-expression functions to
   * behave like Scheme to allow the access of any element of a list.
   */
  if (!n_val)
    fail ("extracting 1-th of 'n' list failed");
  /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)"  */
  gcry_sexp_release (n_val);
  n_val = gcry_sexp_nth (n, 2);
  if (n_val)
    fail ("extracting 2-th of 'n' list did not fail");
  n_val = gcry_sexp_nth (n, 0);
  if (!n_val)
    fail ("extracting 0-th of 'n' list failed");
  /*gcry_log_debugsxp ("0-th", n_val); => "(n)"  */
  if (gcry_sexp_nth (n_val, 1))
    fail ("extracting 1-th of car of 'n' list did not fail");
  gcry_sexp_release (n_val);
  gcry_sexp_release (n);
  gcry_sexp_release (pubkey);
}
예제 #20
0
static void
check_x931_derived_key (int what)
{
  static struct {
    const char *param;
    const char *expected_d;
  } testtable[] = {
    { /* First example from X9.31 (D.1.1).  */
      "(genkey\n"
      "  (rsa\n"
      "    (nbits 4:1024)\n"
      "    (rsa-use-e 1:3)\n"
      "    (derive-parms\n"
      "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
      "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
      "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
      "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
      "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
      "            B98BD984#)\n"
      "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
      "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
      "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
      "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
      "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
      "            321DE34A#))))\n",
      "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
      "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
      "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
      "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
      "241D3C4B"
    },

    { /* Second example from X9.31 (D.2.1).  */
      "(genkey\n"
      "  (rsa\n"
      "    (nbits 4:1536)\n"
      "    (rsa-use-e 1:3)\n"
      "    (derive-parms\n"
      "      (Xp1 #18272558B61316348297EACA74#)\n"
      "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
      "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
      "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
      "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
      "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
      "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
      "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
      "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
      "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
      "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
      "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
      "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
      "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
      "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
      "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
      "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
      "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
      "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
      "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
      "BBCCB9F65C83"
      /* Note that this example in X9.31 gives this value for D:

        "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
        "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
        "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
        "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
        "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
        "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
        "EF32E7D9720B"

        This is a bug in X9.31, obviously introduced by using

           d = e^{-1} mod (p-1)(q-1)

         instead of using the universal exponent as required by 4.1.3:

           d = e^{-1} mod lcm(p-1,q-1)

         The examples in X9.31 seem to be pretty buggy, see
         cipher/primegen.c for another bug.  Not only that I had to
         spend 100 USD for the 66 pages of the document, it also took
         me several hours to figure out that the bugs are in the
         document and not in my code.
       */
    },

    { /* First example from NIST RSAVS (B.1.1).  */
      "(genkey\n"
      "  (rsa\n"
      "    (nbits 4:1024)\n"
      "    (rsa-use-e 1:3)\n"
      "    (derive-parms\n"
      "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
      "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
      "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
      "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
      "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
      "            cab44595#)\n"
      "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
      "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
      "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
      "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
      "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
      "            2f389eda#))))\n",
      "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
      "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
      "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
      "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
      "dc7e8feb"
    },

    { /* Second example from NIST RSAVS (B.1.1).  */
      "(genkey\n"
      "  (rsa\n"
      "    (nbits 4:1536)\n"
      "    (rsa-use-e 1:3)\n"
      "    (derive-parms\n"
      "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
      "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
      "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
      "            d7bc71d412511cd93981ddde8f91b967da404056\n"
      "            c39f105f7f239abdaff92923859920f6299e82b9\n"
      "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
      "            26974eb7bb1f14843841281b363b9cdb#)\n"
      "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
      "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
      "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
      "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
      "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
      "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
      "            9e3cb308cc655aebd766340da8921383#))))\n",
      "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
      "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
      "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
      "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
      "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
      "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
      "2ccf8a84835b"
    }
  };
  gpg_error_t err;
  gcry_sexp_t key_spec, key, pub_key, sec_key;
  gcry_mpi_t d_expected, d_have;

  if (what < 0 && what >= sizeof testtable)
    die ("invalid WHAT value\n");

  err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
  if (err)
    die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));

  err = gcry_pk_genkey (&key, key_spec);
  gcry_sexp_release (key_spec);
  if (err)
    die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));

  pub_key = gcry_sexp_find_token (key, "public-key", 0);
  if (!pub_key)
    die ("public part missing in key [%d]\n", what);

  sec_key = gcry_sexp_find_token (key, "private-key", 0);
  if (!sec_key)
    die ("private part missing in key [%d]\n", what);

  err = gcry_mpi_scan
    (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
  if (err)
    die ("error converting string [%d]\n", what);

  if (verbose > 1)
    show_sexp ("generated key:\n", key);

  d_have = key_param_from_sexp (sec_key, "rsa", "d");
  if (!d_have)
    die ("parameter d not found in RSA secret key [%d]\n", what);
  if (gcry_mpi_cmp (d_expected, d_have))
    {
      show_sexp (NULL, sec_key);
      die ("parameter d does match expected value [%d]\n", what);
    }
  gcry_mpi_release (d_expected);
  gcry_mpi_release (d_have);

  gcry_sexp_release (key);
  gcry_sexp_release (pub_key);
  gcry_sexp_release (sec_key);
}
예제 #21
0
static void
check_ecc_sample_key (void)
{
  static const char ecc_private_key[] =
    "(private-key\n"
    " (ecdsa\n"
    "  (curve \"NIST P-256\")\n"
    "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
    "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
    "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
    "))";
  static const char ecc_private_key_wo_q[] =
    "(private-key\n"
    " (ecdsa\n"
    "  (curve \"NIST P-256\")\n"
    "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
    "))";
  static const char ecc_public_key[] =
    "(public-key\n"
    " (ecdsa\n"
    "  (curve \"NIST P-256\")\n"
    "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
    "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
    "))";
  static const char hash_string[] =
    "(data (flags raw)\n"
    " (value #00112233445566778899AABBCCDDEEFF"
    /* */    "000102030405060708090A0B0C0D0E0F#))";

  gpg_error_t err;
  gcry_sexp_t key, hash, sig;

  if (verbose)
    fprintf (stderr, "Checking sample ECC key.\n");

  if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign failed: %s", gpg_strerror (err));

  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify failed: %s", gpg_strerror (err));

  /* Now try signing without the Q parameter.  */

  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  gcry_sexp_release (sig);
  if ((err = gcry_pk_sign (&sig, hash, key)))
    die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));

  gcry_sexp_release (key);
  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    die ("line %d: %s", __LINE__, gpg_strerror (err));

  if ((err = gcry_pk_verify (sig, hash, key)))
    die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));

  gcry_sexp_release (sig);
  gcry_sexp_release (key);
  gcry_sexp_release (hash);
}
예제 #22
0
파일: tsexp.c 프로젝트: Greenchik/libgcrypt
static void
back_and_forth_one (int testno, const char *buffer, size_t length)
{
  gcry_error_t rc;
  gcry_sexp_t se, se1;
  size_t n, n1;
  char *p1;

  rc = gcry_sexp_new (&se, buffer, length, 1);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
      return;
    }
  n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
  if (!n1)
    {
      fail ("baf %d: get required length for canon failed\n", testno);
      return;
    }
  p1 = gcry_xmalloc (n1);
  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
  if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */
    {
      fail ("baf %d: length mismatch for canon\n", testno);
      return;
    }
  rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_create failed: %s\n",
            testno, gpg_strerror (rc));
      return;
    }
  gcry_sexp_release (se1);

  /* Again but with memory checking. */
  p1 = gcry_xmalloc (n1+2);
  *p1 = '\x55';
  p1[n1+1] = '\xaa';
  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
  if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
    {
      fail ("baf %d: length mismatch for canon\n", testno);
      return;
    }
  if (*p1 != '\x55' || p1[n1+1] != '\xaa')
    fail ("baf %d: memory corrupted (1)\n", testno);
  rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
  if (rc)
    {
      fail ("baf %d: gcry_sexp_create failed: %s\n",
            testno, gpg_strerror (rc));
      return;
    }
  if (*p1 != '\x55' || p1[n1+1] != '\xaa')
    fail ("baf %d: memory corrupted (2)\n", testno);
  gcry_sexp_release (se1);
  if (*p1 != '\x55' || p1[n1+1] != '\xaa')
    fail ("baf %d: memory corrupted (3)\n", testno);
  gcry_free (p1);

  /* FIXME: we need a lot more tests */

  gcry_sexp_release (se);
}
예제 #23
0
파일: tsexp.c 프로젝트: Greenchik/libgcrypt
/* fixme: we need better tests */
static void
basic (void)
{
  int pass;
  gcry_sexp_t sexp;
  int idx;
  char *secure_buffer;
  size_t secure_buffer_len;
  const char *string;
  static struct {
    const char *token;
    const char *parm;
  } values[] = {
    { "public-key", NULL },
    { "dsa", NULL },
    { "dsa", "p" },
    { "dsa", "y" },
    { "dsa", "q" },
    { "dsa", "g" },
    { NULL }
  };

  info ("doing some pretty pointless tests\n");

  secure_buffer_len = 99;
  secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
  memset (secure_buffer, 'G', secure_buffer_len);

  for (pass=0;;pass++)
    {
      gcry_mpi_t m;

      switch (pass)
        {
        case 0:
          string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                    "(q #61626364656667#) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 42);
          if ( gcry_sexp_build (&sexp, NULL, string, m ) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          break;

        case 1:
          string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                    "(q %b) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 42);
          if ( gcry_sexp_build (&sexp, NULL, string,
                                15, "foo\0\x01\0x02789012345", m) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          break;

        case 2:
          string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
                    "(q %b) (g %m)))");

          m = gcry_mpi_set_ui (NULL, 17);
          if ( gcry_sexp_build (&sexp, NULL, string,
                                secure_buffer_len, secure_buffer, m) )
            {
              gcry_mpi_release (m);
              fail (" scanning `%s' failed\n", string);
              return;
            }
          gcry_mpi_release (m);
          if (!gcry_is_secure (sexp))
            fail ("gcry_sexp_build did not switch to secure memory\n");
          break;

        case 3:
          {
            gcry_sexp_t help_sexp;

            if (gcry_sexp_new (&help_sexp,
                               "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
              {
                fail (" scanning fixed string failed\n");
                return;
              }

            string = ("(public-key (dsa (p #41424344#) (parm %S) "
                      "(y dummy)(q %b) (g %m)))");
            m = gcry_mpi_set_ui (NULL, 17);
            if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
                                  secure_buffer_len, secure_buffer, m) )
              {
                gcry_mpi_release (m);
                fail (" scanning `%s' failed\n", string);
                return;
              }
            gcry_mpi_release (m);
            gcry_sexp_release (help_sexp);
          }
          break;


        default:
          return; /* Ready. */
        }


      /* now find something */
      for (idx=0; values[idx].token; idx++)
        {
          const char *token = values[idx].token;
          const char *parm = values[idx].parm;
          gcry_sexp_t s1, s2;
          gcry_mpi_t a;
          const char *p;
          size_t n;

          s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
          if (!s1)
            {
              fail ("didn't found `%s'\n", token);
              continue;
            }

          p = gcry_sexp_nth_data (s1, 0, &n);
          if (!p)
            {
              gcry_sexp_release (s1);
              fail ("no car for `%s'\n", token);
              continue;
            }
          info ("car=`%.*s'\n", (int)n, p);

          s2 = gcry_sexp_cdr (s1);
          if (!s2)
            {
              gcry_sexp_release (s1);
              fail ("no cdr for `%s'\n", token);
              continue;
            }

          p = gcry_sexp_nth_data (s2, 0, &n);
          gcry_sexp_release (s2);
          if (p)
            {
              gcry_sexp_release (s1);
              fail ("data at car of `%s'\n", token);
              continue;
            }

          if (parm)
            {
              s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
              gcry_sexp_release (s1);
              if (!s2)
                {
                  fail ("didn't found `%s'\n", parm);
                  continue;
                }
              p = gcry_sexp_nth_data (s2, 0, &n);
              if (!p)
                {
                  gcry_sexp_release (s2);
                  fail("no car for `%s'\n", parm );
                  continue;
                }
              info ("car=`%.*s'\n", (int)n, p);
              p = gcry_sexp_nth_data (s2, 1, &n);
              if (!p)
                {
                  gcry_sexp_release (s2);
                  fail("no cdr for `%s'\n", parm );
                  continue;
                }
              info ("cdr=`%.*s'\n", (int)n, p);

              a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
              gcry_sexp_release (s2);
              if (!a)
                {
                  fail("failed to cdr the mpi for `%s'\n", parm);
                  continue;
                }
              gcry_mpi_release (a);
            }
          else
            gcry_sexp_release (s1);
        }

      gcry_sexp_release (sexp);
      sexp = NULL;
    }
  gcry_free (secure_buffer);
}
예제 #24
0
/* Read a sets of private DSA keys from a FILE* into the given
 * OtrlUserState.  The FILE* must be open for reading. */
gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf)
{
    int privfd;
    struct stat st;
    char *buf;
    const char *token;
    size_t tokenlen;
    gcry_error_t err;
    gcry_sexp_t allkeys;
    size_t i;

    if (!privf) return gcry_error(GPG_ERR_NO_ERROR);

    /* Release any old ideas we had about our keys */
    otrl_privkey_forget_all(us);

    /* Load the data into a buffer */
    privfd = fileno(privf);
    if (fstat(privfd, &st)) {
	err = gcry_error_from_errno(errno);
	return err;
    }
    buf = malloc(st.st_size);
    if (!buf && st.st_size > 0) {
	return gcry_error(GPG_ERR_ENOMEM);
    }
    if (fread(buf, st.st_size, 1, privf) != 1) {
	err = gcry_error_from_errno(errno);
	free(buf);
	return err;
    }

    err = gcry_sexp_new(&allkeys, buf, st.st_size, 0);
    free(buf);
    if (err) {
	return err;
    }

    token = gcry_sexp_nth_data(allkeys, 0, &tokenlen);
    if (tokenlen != 8 || strncmp(token, "privkeys", 8)) {
	gcry_sexp_release(allkeys);
	return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
    }

    /* Get each account */
    for(i=1; i<gcry_sexp_length(allkeys); ++i) {
	gcry_sexp_t names, protos, privs;
	char *name, *proto;
	gcry_sexp_t accounts;
	OtrlPrivKey *p;
	
	/* Get the ith "account" S-exp */
	accounts = gcry_sexp_nth(allkeys, i);
	
	/* It's really an "account" S-exp? */
	token = gcry_sexp_nth_data(accounts, 0, &tokenlen);
	if (tokenlen != 7 || strncmp(token, "account", 7)) {
	    gcry_sexp_release(accounts);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	}
	/* Extract the name, protocol, and privkey S-exps */
	names = gcry_sexp_find_token(accounts, "name", 0);
	protos = gcry_sexp_find_token(accounts, "protocol", 0);
	privs = gcry_sexp_find_token(accounts, "private-key", 0);
	gcry_sexp_release(accounts);
	if (!names || !protos || !privs) {
	    gcry_sexp_release(names);
	    gcry_sexp_release(protos);
	    gcry_sexp_release(privs);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	}
	/* Extract the actual name and protocol */
	token = gcry_sexp_nth_data(names, 1, &tokenlen);
	if (!token) {
	    gcry_sexp_release(names);
	    gcry_sexp_release(protos);
	    gcry_sexp_release(privs);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	}
	name = malloc(tokenlen + 1);
	if (!name) {
	    gcry_sexp_release(names);
	    gcry_sexp_release(protos);
	    gcry_sexp_release(privs);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_ENOMEM);
	}
	memmove(name, token, tokenlen);
	name[tokenlen] = '\0';
	gcry_sexp_release(names);

	token = gcry_sexp_nth_data(protos, 1, &tokenlen);
	if (!token) {
	    free(name);
	    gcry_sexp_release(protos);
	    gcry_sexp_release(privs);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	}
	proto = malloc(tokenlen + 1);
	if (!proto) {
	    free(name);
	    gcry_sexp_release(protos);
	    gcry_sexp_release(privs);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_ENOMEM);
	}
	memmove(proto, token, tokenlen);
	proto[tokenlen] = '\0';
	gcry_sexp_release(protos);

	/* Make a new OtrlPrivKey entry */
	p = malloc(sizeof(*p));
	if (!p) {
	    free(name);
	    free(proto);
	    gcry_sexp_release(privs);
	    gcry_sexp_release(allkeys);
	    return gcry_error(GPG_ERR_ENOMEM);
	}

	/* Fill it in and link it up */
	p->accountname = name;
	p->protocol = proto;
	p->pubkey_type = OTRL_PUBKEY_TYPE_DSA;
	p->privkey = privs;
	p->next = us->privkey_root;
	if (p->next) {
	    p->next->tous = &(p->next);
	}
	p->tous = &(us->privkey_root);
	us->privkey_root = p;
	err = make_pubkey(&(p->pubkey_data), &(p->pubkey_datalen), p->privkey);
	if (err) {
	    gcry_sexp_release(allkeys);
	    otrl_privkey_forget(p);
	    return gcry_error(GPG_ERR_UNUSABLE_SECKEY);
	}
    }
    gcry_sexp_release(allkeys);

    return gcry_error(GPG_ERR_NO_ERROR);
}