New file.
authorNiels Möller <nisse@lysator.liu.se>
Sun, 20 Nov 2005 17:06:47 +0000 (18:06 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Sun, 20 Nov 2005 17:06:47 +0000 (18:06 +0100)
Rev: src/nettle/der2rsa.c:1.1
Rev: src/nettle/testsuite/pkcs1-conv-test:1.1

der2rsa.c [new file with mode: 0644]
testsuite/pkcs1-conv-test [new file with mode: 0755]

diff --git a/der2rsa.c b/der2rsa.c
new file mode 100644 (file)
index 0000000..9d8b437
--- /dev/null
+++ b/der2rsa.c
@@ -0,0 +1,137 @@
+/* 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 */
diff --git a/testsuite/pkcs1-conv-test b/testsuite/pkcs1-conv-test
new file mode 100755 (executable)
index 0000000..5ac3657
--- /dev/null
@@ -0,0 +1,49 @@
+#! /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