--- /dev/null
+/* der2rsa.c
+ *
+ * Decoding of keys in PKCS#1 format.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2005 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if WITH_PUBLIC_KEY
+
+#include "rsa.h"
+
+#include "bignum.h"
+#include "asn1.h"
+
+#define GET(i, x, l) \
+(asn1_der_iterator_next((i)) == ASN1_ITERATOR_PRIMITIVE \
+ && (i)->type == ASN1_INTEGER \
+ && asn1_der_get_bignum((i), (x), (l)) \
+ && mpz_sgn((x)) > 0)
+
+int
+rsa_public_key_from_der_iterator(struct rsa_public_key *pub,
+ unsigned limit,
+ struct asn1_der_iterator *i)
+{
+ /* RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER, -- n
+ publicExponent INTEGER -- e
+ }
+ */
+
+ return (i->type == ASN1_SEQUENCE
+ && asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE
+ && asn1_der_get_bignum(i, pub->n, limit)
+ && mpz_sgn(pub->n) > 0
+ && GET(i, pub->e, limit)
+ && asn1_der_iterator_next(i) == ASN1_ITERATOR_END
+ && rsa_public_key_prepare(pub));
+}
+
+int
+rsa_private_key_from_der_iterator(struct rsa_public_key *pub,
+ struct rsa_private_key *priv,
+ unsigned limit,
+ struct asn1_der_iterator *i)
+{
+ /* RSAPrivateKey ::= SEQUENCE {
+ version Version,
+ modulus INTEGER, -- n
+ publicExponent INTEGER, -- e
+ privateExponent INTEGER, -- d
+ prime1 INTEGER, -- p
+ prime2 INTEGER, -- q
+ exponent1 INTEGER, -- d mod (p-1)
+ exponent2 INTEGER, -- d mod (q-1)
+ coefficient INTEGER, -- (inverse of q) mod p
+ otherPrimeInfos OtherPrimeInfos OPTIONAL
+ }
+ */
+
+ uint32_t version;
+
+ if (i->type != ASN1_SEQUENCE)
+ return 0;
+
+ if (asn1_der_decode_constructed_last(i) == ASN1_ITERATOR_PRIMITIVE
+ && i->type == ASN1_INTEGER
+ && asn1_der_get_uint32(i, &version)
+ && version <= 1
+ && GET(i, pub->n, limit)
+ && GET(i, pub->e, limit)
+ && rsa_public_key_prepare(pub)
+ && GET(i, priv->d, limit)
+ && GET(i, priv->p, limit)
+ && GET(i, priv->q, limit)
+ && GET(i, priv->a, limit)
+ && GET(i, priv->b, limit)
+ && GET(i, priv->c, limit)
+ && rsa_private_key_prepare(priv))
+ {
+ if (version == 1)
+ {
+ /* otherPrimeInfos must be present. We ignore the contents */
+ if (!(asn1_der_iterator_next(i) == ASN1_ITERATOR_CONSTRUCTED
+ && i->type == ASN1_SEQUENCE))
+ return 0;
+ }
+
+ return (asn1_der_iterator_next(i) == ASN1_ITERATOR_END);
+ }
+
+ return 0;
+}
+
+int
+rsa_keypair_from_der(struct rsa_public_key *pub,
+ struct rsa_private_key *priv,
+ unsigned limit,
+ unsigned length, const uint8_t *data)
+{
+ struct asn1_der_iterator i;
+ enum asn1_iterator_result res;
+
+ res = asn1_der_iterator_first(&i, length, data);
+
+ if (res != ASN1_ITERATOR_CONSTRUCTED)
+ return 0;
+
+ if (priv)
+ return rsa_private_key_from_der_iterator(pub, priv, limit, &i);
+ else
+ return rsa_public_key_from_der_iterator(pub, limit, &i);
+}
+
+#endif /* WITH_PUBLIC_KEY */
--- /dev/null
+#! /bin/sh
+
+if [ -z "$srcdir" ] ; then
+ srcdir=`pwd`
+fi
+
+# Private RSA key, generated by openssl
+../tools/pkcs1-conv >testkey.priv <<EOF || exit 1
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC3792bBgQ/mc8aYOFaLEJES/JipmLAeVgznob/Vrzvdcx+bl6L
+6gTphctU9ToOLC049dZYW3DJ53owUmbQgqB0vvLTjM9lGSEw4oXLrp7x/XVo/fZM
+UcRWq5H8Z0l6KANXHwcVcsjjqPBJ6WD/Is3o9rb58GU9GZcsMO2Zoh8z6wIDAQAB
+AoGABP+iwRS/xs6yPyBE34N2ZY6+zomBA4QIrpZvSr8bsVI9NW5gaWL5sTLunKdx
+ZXMz42li4tHRVdtRicCjhKUYIShH6J3ACKnBsCHwK6MgEyuDifxhmVt/b5xQNdOL
+bckwBXCL/XwkIkSgrvgUk/cXcvDXSdf7cRX+tgEHlbGjWGkCQQDaS9Xm3ZTIJ1CO
+/chlET2Cf/e5GzC79njzeg5oDyTG7qlXZudpZv5D6NatVoIDF4gfey6NKB7DNehT
+ff+v9wztAkEA17TN+cuFBuZX+KT3K7J1uavGqWOypDUy/h7PINODJLzoWAWnw94H
+NSu6/pXo1Q1WBMQa1jB1qxJaLpBp56iBNwJAUp6JIouSl/5pOvVKNxZDVXThaSml
+VD6AoIX9ldzFapVBelb0FqxoZ4NkXM50/n6VgnS4tawNmIx6lb8GWq8CMQJBAM5S
+lMofzyggX3jnYbycQFrOYYFYaWEDubi0A27koYYcYyj+j8+bqc1D/OLSxRg0X1jD
+st+5DnQJY9UyMPpyhNUCQQChMjCAamJP3xC7bOoza//k7E9kvx5IZcEsQWqok5BO
+PSVKy/gGBeN1Q7Rj+XoybQ/SqLpfgTYRI9UpbKmpkNuq
+-----END RSA PRIVATE KEY-----
+EOF
+
+../tools/pkcs1-conv >testkey.pub <<EOF || exit 1
+# Corresponding public key
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3792bBgQ/mc8aYOFaLEJES/Ji
+pmLAeVgznob/Vrzvdcx+bl6L6gTphctU9ToOLC049dZYW3DJ53owUmbQgqB0vvLT
+jM9lGSEw4oXLrp7x/XVo/fZMUcRWq5H8Z0l6KANXHwcVcsjjqPBJ6WD/Is3o9rb5
+8GU9GZcsMO2Zoh8z6wIDAQAB
+-----END PUBLIC KEY-----
+EOF
+
+../examples/rsa-sign testkey.priv >testsignature <<EOF || exit 1
+gazonk
+EOF
+
+# Signature on the data "gazonk\n", using sha1 and the above key
+cat > testsignature2 <<EOF && diff testsignature testsignature2 || exit 1
+5c96ffe7e925224ce6e98648bf2ed3193cab2fc82af9c7fa7fdc5b623bde1d77c5409129d16d1127ae4fad519c24059fe85f4a4360a900f3dee906e6de2ecd010fa56c02d3f7d0772d43439464a91b025722a6f0b6cb65aee1017b29aff4511f90315caae0be74c2ac496474896e7e3ad200cb7c609ddef5c674272964e4b780
+EOF
+
+../examples/rsa-verify testkey.pub testsignature <<EOF || exit 1
+gazonk
+EOF
+
+exit 0