static int
convert_rsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
{
  struct rsa_public_key pub;
  struct rsa_private_key priv;
  int res;
  
  rsa_public_key_init(&pub);
  rsa_private_key_init(&priv);

  if (rsa_keypair_from_der(&pub, &priv, 0,
			   length, data))
    {
      /* Reuses the buffer */
      nettle_buffer_reset(buffer);
      res = rsa_keypair_to_sexp(buffer, NULL, &pub, &priv);
    }
  else
    {
      werror("Invalid PKCS#1 private key.\n");
      res = 0;
    }
  rsa_public_key_clear(&pub);
  rsa_private_key_clear(&priv);

  return res;
}
/* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
static int
convert_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
{
  /* SubjectPublicKeyInfo ::= SEQUENCE {
         algorithm		AlgorithmIdentifier,
	 subjectPublicKey 	BIT STRING
     }

     AlgorithmIdentifier ::= SEQUENCE {
         algorithm  	OBJECT IDENTIFIER,
	 parameters 	OPTIONAL
     }
  */
  struct asn1_der_iterator i;
  struct asn1_der_iterator j;
  int res = 0;

  if (asn1_der_iterator_first(&i, length, data) == ASN1_ITERATOR_CONSTRUCTED
      && i.type == ASN1_SEQUENCE
      && asn1_der_decode_constructed_last(&i) == ASN1_ITERATOR_CONSTRUCTED
      && i.type == ASN1_SEQUENCE

      /* Use the j iterator to parse the algorithm identifier */
      && asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE
      && j.type == ASN1_IDENTIFIER
      && asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE
      && i.type == ASN1_BITSTRING

      /* Use i to parse the object wrapped in the bit string.*/
      && asn1_der_decode_bitstring_last(&i))
    {
      /* pkcs-1 {
	     iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
	     modules(0) pkcs-1(1)
	 }

	 --
	 -- When rsaEncryption is used in an AlgorithmIdentifier the
	 -- parameters MUST be present and MUST be NULL.
	 --
	 rsaEncryption    OBJECT IDENTIFIER ::= { pkcs-1 1 }
      */
      static const uint8_t id_rsaEncryption[9] =
	{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
      /*
	 --
	 -- When dsa is used in an AlgorithmIdentifier the
	 -- parameters MUST be present and MUST NOT be NULL.
	 --
	 dsa    OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
      */
      static const uint8_t id_dsa[7] =
	{ 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 };

      switch (j.length)
	{
	unknown:
	default:
	  werror("SubjectPublicKeyInfo: Unsupported algorithm.\n");
	  res = -1;
	  break;
	  
	case 7:
	  if (memcmp(j.data, id_dsa, 7) == 0)
	    {
	      if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_CONSTRUCTED
		  && asn1_der_decode_constructed_last(&j) == ASN1_ITERATOR_PRIMITIVE)
		{
		  struct dsa_public_key pub;

		  dsa_public_key_init(&pub);

		  if (dsa_params_from_der_iterator(&pub, 0, &i)
		      && dsa_public_key_from_der_iterator(&pub, 0, &j))
		    {
		      nettle_buffer_reset(buffer);
		      res = dsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
		    }
		}
	      if (!res)
		werror("SubjectPublicKeyInfo: Invalid DSA key.\n");
	      break;
	    }
	  else goto unknown;
	case 9:
	  if (memcmp(j.data, id_rsaEncryption, 9) == 0)
	    {
	      if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_PRIMITIVE
		  && j.type == ASN1_NULL
		  && j.length == 0
		  && asn1_der_iterator_next(&j) == ASN1_ITERATOR_END)
		{
		  struct rsa_public_key pub;

		  rsa_public_key_init(&pub);

		  if (rsa_public_key_from_der_iterator(&pub, 0, &i))
		    {
		      nettle_buffer_reset(buffer);
		      res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
		    }
		}
	      if (!res)
		werror("SubjectPublicKeyInfo: Invalid RSA key.\n");
	      break;
	    }
	  else goto unknown;
	}
    }
  else
    werror("SubjectPublicKeyInfo: Invalid object.\n");
  
  return res;
}
int main(int argc, char **argv)
{
	FILE *input = stdin;

	RSA *openssl_key = NULL;
	struct rsa_private_key *nettle_key = NULL;
	struct rsa_public_key *nettle_pub_key = NULL;
	struct nettle_buffer *sexp_buffer = NULL;

	OpenSSL_add_all_algorithms();
	
	openssl_key = PEM_read_RSAPrivateKey(input, NULL, NULL, NULL);

	if(!openssl_key)
	{
		fprintf(stderr, "OpenSSL failed to read key: %s\n", ERR_error_string(ERR_get_error(), NULL));
		return 1;
	}

# ifdef DEBUG
	fprintf(stderr, "OpenSSL RSA private key:\n");
	fprintf(stderr, "\tPrivate Exponent: %s\n", BN_bn2hex(openssl_key->d)); // d
	fprintf(stderr, "\tPrime 1: %s\n", BN_bn2hex(openssl_key->p));          // p
	fprintf(stderr, "\tPrime 2: %s\n", BN_bn2hex(openssl_key->q));          // q
	fprintf(stderr, "\tExponent 1: %s\n", BN_bn2hex(openssl_key->dmp1));    // a
	fprintf(stderr, "\tExponent 2: %s\n", BN_bn2hex(openssl_key->dmq1));    // b
	fprintf(stderr, "\tCoefficient: %s\n", BN_bn2hex(openssl_key->iqmp));   // c
# endif

	nettle_key = (struct rsa_private_key*)malloc(sizeof(struct rsa_private_key));
	if(!nettle_key)
	{
		fprintf(stderr, "Failed to malloc %zu bytes\n", sizeof(struct rsa_private_key));
		return 4;
	}
	rsa_private_key_init(nettle_key);
	mpz_set_str(nettle_key->d, BN_bn2hex(openssl_key->d), 16);
	mpz_set_str(nettle_key->p, BN_bn2hex(openssl_key->p), 16);
	mpz_set_str(nettle_key->q, BN_bn2hex(openssl_key->q), 16);
	mpz_set_str(nettle_key->a, BN_bn2hex(openssl_key->dmp1), 16);
	mpz_set_str(nettle_key->b, BN_bn2hex(openssl_key->dmq1), 16);
	mpz_set_str(nettle_key->c, BN_bn2hex(openssl_key->iqmp), 16);

	if(rsa_private_key_prepare(nettle_key) != 1)
	{
		fprintf(stderr, "Nettle failed to prepare key\n");
		return 2;
	}

# ifdef DEBUG
	fprintf(stderr, "\tPrivate Exponent: %s\n", mpz_get_str(NULL, 16, nettle_key->d)); // d
	fprintf(stderr, "\tPrime 1: %s\n", mpz_get_str(NULL, 16, nettle_key->p));          // p
	fprintf(stderr, "\tPrime 2: %s\n", mpz_get_str(NULL, 16, nettle_key->q));          // q
	fprintf(stderr, "\tExponent 1: %s\n", mpz_get_str(NULL, 16, nettle_key->a));    // a
	fprintf(stderr, "\tExponent 2: %s\n", mpz_get_str(NULL, 16, nettle_key->b));    // b
	fprintf(stderr, "\tCoefficient: %s\n", mpz_get_str(NULL, 16, nettle_key->c));   // c
# endif

	nettle_pub_key = (struct rsa_public_key*)malloc(sizeof(struct rsa_public_key));
	if(!nettle_pub_key)
	{
		fprintf(stderr, "Failed to malloc %zu bytes\n", sizeof(struct rsa_public_key));
		return 4;
	}
	rsa_public_key_init(nettle_pub_key);
	mpz_set_str(nettle_pub_key->n, BN_bn2hex(openssl_key->n), 16);
	mpz_set_str(nettle_pub_key->e, BN_bn2hex(openssl_key->e), 16);
	
	if(rsa_public_key_prepare(nettle_pub_key) != 1)
	{
		fprintf(stderr, "Nettle failed to prepare public key\n");
		return 2;
	}

	sexp_buffer = (struct nettle_buffer*)malloc(sizeof(struct nettle_buffer));
	if(!sexp_buffer)
	{
		fprintf(stderr, "Failed to malloc %zu bytes\n", sizeof(struct nettle_buffer));
		return 4;
	}
	nettle_buffer_init(sexp_buffer);

	if(rsa_keypair_to_sexp(sexp_buffer, NULL, nettle_pub_key, nettle_key) == 0)
	{
		fprintf(stderr, "Nettle failed to export key to sexp\n");
		return 3;
	}

	size_t bytes_written = fwrite(sexp_buffer->contents, 1, sexp_buffer->size, stdout);
	if(bytes_written < sexp_buffer->size)
	{
		fprintf(stderr, "Failed to write sexp to stdout\n");
		return 5;
	}

	return 0;
}
int
test_main(void)
{
  struct rsa_public_key pub;
  struct rsa_private_key priv;

  struct nettle_buffer buffer;
  
  rsa_public_key_init(&pub);
  rsa_private_key_init(&priv);

  mpz_set_str(pub.n,
	      "085c3408989acae4faec3cbbad91c90d34c1d259cd74121a"
	      "36f38b0b51424a9b2be514a04377113a6cdafe79dd7d5f2e"
	      "cc8b5e9661189b86a7b22239907c25", 16);
  mpz_set_str(pub.e, "36ad4b1d", 16);

  ASSERT(rsa_public_key_prepare(&pub));
  
  mpz_set_str(priv.d,
	      "06ee6d4ff3c239e408150daf8117abfa36a40ad4455d9059"
	      "a86d52f33a2de07418a0a699594588c64810248c9412d554"
	      "f74af947c73c32007e87c92f0937ed", 16);

  mpz_set_str(priv.p,
	      "03259879b24315e9cf14254824c7935d807cdb6990f414a0"
	      "f65e6065130a611f", 16);

  mpz_set_str(priv.q,
	      "02a81ba73bad45fc73b36deffce52d1b73e0747f4d8a8264"
	      "8cecd310448ea63b", 16);

  mpz_set_str(priv.a,
	      "026cbdad5dd0046e093f060ecd5b4ac918e098b0278bb752"
	      "b7cadd6a8944f0b9", 16);

  mpz_set_str(priv.b,
	      "0148751e622d6d58e3bb094afd6edacf7370351d068e2ce9"
	      "f565c5528c4a7473", 16);

  mpz_set_str(priv.c,
	      "f8a458ea73a018dc6fa56863e3bc6de405f364f77dee6f09"
	      "62679ea1a8282e", 16);

  ASSERT(rsa_private_key_prepare(&priv));
  
  nettle_buffer_init(&buffer);
  ASSERT(rsa_keypair_to_sexp(&buffer, "rsa", &pub, &priv));

  if (verbose)
    {
      printf("private:");
      print_hex(buffer.size, buffer.contents);  
    }
  
  ASSERT(MEMEQH(buffer.size, buffer.contents,
		"2831313a707269766174652d6b657928"
		"333a72736128313a6e36333a085c3408"
		"989acae4faec3cbbad91c90d34c1d259"
		"cd74121a36f38b0b51424a9b2be514a0"
		"4377113a6cdafe79dd7d5f2ecc8b5e96"
		"61189b86a7b22239907c252928313a65"
		"343a36ad4b1d2928313a6436333a06ee"
		"6d4ff3c239e408150daf8117abfa36a4"
		"0ad4455d9059a86d52f33a2de07418a0"
		"a699594588c64810248c9412d554f74a"
		"f947c73c32007e87c92f0937ed292831"
		"3a7033323a03259879b24315e9cf1425"
		"4824c7935d807cdb6990f414a0f65e60"
		"65130a611f2928313a7133323a02a81b"
		"a73bad45fc73b36deffce52d1b73e074"
		"7f4d8a82648cecd310448ea63b292831"
		"3a6133323a026cbdad5dd0046e093f06"
		"0ecd5b4ac918e098b0278bb752b7cadd"
		"6a8944f0b92928313a6233323a014875"
		"1e622d6d58e3bb094afd6edacf737035"
		"1d068e2ce9f565c5528c4a7473292831"
		"3a6333323a00f8a458ea73a018dc6fa5"
		"6863e3bc6de405f364f77dee6f096267"
		"9ea1a8282e292929"));

  nettle_buffer_clear(&buffer);
  ASSERT(rsa_keypair_to_sexp(&buffer, NULL, &pub, NULL));

  if (verbose)
    {
      printf("public:");
      print_hex(buffer.size, buffer.contents);  
    }
  ASSERT(MEMEQH(buffer.size, buffer.contents,
		"2831303a7075626c69632d6b65792839"
		"3a7273612d706b63733128313a6e3633"
		"3a085c3408989acae4faec3cbbad91c9"
		"0d34c1d259cd74121a36f38b0b51424a"
		"9b2be514a04377113a6cdafe79dd7d5f"
		"2ecc8b5e9661189b86a7b22239907c25"
		"2928313a65343a36ad4b1d292929"));

  rsa_public_key_clear(&pub);
  rsa_private_key_clear(&priv);
  
  SUCCESS();
}