Browse Source

add `dsa_import_pkcs8()`

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel 3 years ago
parent
commit
464c9b1986

+ 3 - 0
src/headers/tomcrypt_pk.h

@@ -483,6 +483,9 @@ int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen,
                     const dsa_key       *key);
                     const dsa_key       *key);
 
 
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
+int dsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                     const password_ctx  *pw_ctx,
+                     dsa_key *key);
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key);
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key);
 int dsa_verify_key(const dsa_key *key, int *stat);
 int dsa_verify_key(const dsa_key *key, int *stat);
 int dsa_shared_secret(void          *private_key, void *base,
 int dsa_shared_secret(void          *private_key, void *base,

+ 4 - 0
src/headers/tomcrypt_private.h

@@ -432,9 +432,13 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
 #endif /* LTC_MECC */
 #endif /* LTC_MECC */
 
 
 #ifdef LTC_MDSA
 #ifdef LTC_MDSA
+int dsa_int_init(dsa_key *key);
+int dsa_int_validate(const dsa_key *key, int *stat);
 int dsa_int_validate_xy(const dsa_key *key, int *stat);
 int dsa_int_validate_xy(const dsa_key *key, int *stat);
 int dsa_int_validate_pqg(const dsa_key *key, int *stat);
 int dsa_int_validate_pqg(const dsa_key *key, int *stat);
 int dsa_int_validate_primes(const dsa_key *key, int *stat);
 int dsa_int_validate_primes(const dsa_key *key, int *stat);
+int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key);
+int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key);
 #endif /* LTC_MDSA */
 #endif /* LTC_MDSA */
 
 
 
 

+ 2 - 7
src/pk/dsa/dsa_generate_pqg.c

@@ -209,13 +209,8 @@ int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_si
 {
 {
    int err;
    int err;
 
 
-   LTC_ARGCHK(key         != NULL);
-   LTC_ARGCHK(ltc_mp.name != NULL);
-
-   /* init mp_ints */
-   if ((err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL)) != CRYPT_OK) {
-      return err;
-   }
+   /* init key */
+   if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
    /* generate params */
    /* generate params */
    err = s_dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
    err = s_dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
    if (err != CRYPT_OK) {
    if (err != CRYPT_OK) {

+ 33 - 37
src/pk/dsa/dsa_import.c

@@ -9,6 +9,25 @@
 
 
 #ifdef LTC_MDSA
 #ifdef LTC_MDSA
 
 
+int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key)
+{
+   int           err;
+   unsigned long zero = 0;
+   /* get key type */
+   if ((err = der_decode_sequence_multi(in, inlen,
+                          LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
+                          LTC_ASN1_INTEGER,      1UL, key->p,
+                          LTC_ASN1_INTEGER,      1UL, key->q,
+                          LTC_ASN1_INTEGER,      1UL, key->g,
+                          LTC_ASN1_INTEGER,      1UL, key->y,
+                          LTC_ASN1_INTEGER,      1UL, key->x,
+                          LTC_ASN1_EOL,          0UL, NULL)) == CRYPT_OK) {
+
+       key->type = PK_PRIVATE;
+   }
+   return err;
+}
+
 /**
 /**
    Import a DSA key
    Import a DSA key
    @param in       The binary packet to import from
    @param in       The binary packet to import from
@@ -19,18 +38,13 @@
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
 {
 {
    int           err, stat;
    int           err, stat;
-   unsigned long zero = 0, len;
    unsigned char* tmpbuf = NULL;
    unsigned char* tmpbuf = NULL;
    unsigned char flags[1];
    unsigned char flags[1];
 
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(in  != NULL);
-   LTC_ARGCHK(key != NULL);
-   LTC_ARGCHK(ltc_mp.name != NULL);
 
 
    /* init key */
    /* init key */
-   if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL) != CRYPT_OK) {
-      return CRYPT_MEM;
-   }
+   if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
 
 
    /* try to match the old libtomcrypt format */
    /* try to match the old libtomcrypt format */
    err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
    err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
@@ -71,62 +85,44 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
           goto LBL_ERR;
           goto LBL_ERR;
        }
        }
    }
    }
-   /* get key type */
-   if (der_decode_sequence_multi(in, inlen,
-                                 LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
-                                 LTC_ASN1_INTEGER,       1UL, key->p,
-                                 LTC_ASN1_INTEGER,       1UL, key->q,
-                                 LTC_ASN1_INTEGER,       1UL, key->g,
-                                 LTC_ASN1_INTEGER,       1UL, key->y,
-                                 LTC_ASN1_INTEGER,       1UL, key->x,
-                                 LTC_ASN1_EOL,           0UL, NULL) == CRYPT_OK) {
 
 
-       key->type = PK_PRIVATE;
-   } else { /* public */
+   if (dsa_import_pkcs1(in, inlen, key) != CRYPT_OK) {
       ltc_asn1_list params[3];
       ltc_asn1_list params[3];
-      unsigned long tmpbuf_len = inlen;
+      unsigned long tmpbuf_len = inlen, len;
 
 
       LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
       LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
       LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
       LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
       LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
       LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
+      len = 3;
 
 
       tmpbuf = XCALLOC(1, tmpbuf_len);
       tmpbuf = XCALLOC(1, tmpbuf_len);
       if (tmpbuf == NULL) {
       if (tmpbuf == NULL) {
-         err = CRYPT_MEM;
-         goto LBL_ERR;
+         return CRYPT_MEM;
       }
       }
 
 
-      len = 3;
-      err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_DSA,
-                                               tmpbuf, &tmpbuf_len,
-                                               LTC_ASN1_SEQUENCE, params, &len);
+      err = x509_decode_subject_public_key_info(in, inlen,
+                                                LTC_OID_DSA,       tmpbuf, &tmpbuf_len,
+                                                LTC_ASN1_SEQUENCE, params, &len);
       if (err != CRYPT_OK) {
       if (err != CRYPT_OK) {
          XFREE(tmpbuf);
          XFREE(tmpbuf);
          goto LBL_ERR;
          goto LBL_ERR;
       }
       }
 
 
-      if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
+      if ((err = der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
          XFREE(tmpbuf);
          XFREE(tmpbuf);
          goto LBL_ERR;
          goto LBL_ERR;
       }
       }
 
 
-      XFREE(tmpbuf);
       key->type = PK_PUBLIC;
       key->type = PK_PUBLIC;
+      XFREE(tmpbuf);
    }
    }
 
 
 LBL_OK:
 LBL_OK:
    key->qord = mp_unsigned_bin_size(key->q);
    key->qord = mp_unsigned_bin_size(key->q);
 
 
-   /* quick p, q, g validation, without primality testing */
-   if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) {
-      goto LBL_ERR;
-   }
-   if (stat == 0) {
-      err = CRYPT_INVALID_PACKET;
-      goto LBL_ERR;
-   }
-   /* validate x, y */
-   if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK) {
+   /* quick p, q, g validation, without primality testing
+    * + x, y validation */
+   if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
       goto LBL_ERR;
       goto LBL_ERR;
    }
    }
    if (stat == 0) {
    if (stat == 0) {
@@ -134,7 +130,7 @@ LBL_OK:
       goto LBL_ERR;
       goto LBL_ERR;
    }
    }
 
 
-  return CRYPT_OK;
+   return CRYPT_OK;
 LBL_ERR:
 LBL_ERR:
    dsa_free(key);
    dsa_free(key);
    return err;
    return err;

+ 88 - 0
src/pk/dsa/dsa_import_pkcs8.c

@@ -0,0 +1,88 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+#include "tomcrypt_private.h"
+
+/**
+  @file dsa_import_pkcs8.c
+  Import a PKCS DSA key
+*/
+
+#ifdef LTC_MDSA
+
+int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key)
+{
+   int err, stat;
+
+   LTC_UNUSED_PARAM(alg_id);
+
+   if (!alg_id->child
+         || !LTC_ASN1_IS_TYPE(alg_id->child->next, LTC_ASN1_SEQUENCE)
+         || !LTC_ASN1_IS_TYPE(priv_key, LTC_ASN1_OCTET_STRING)) {
+      return CRYPT_INVALID_PACKET;
+   }
+   if ((err = dsa_set_pqg_dsaparam(alg_id->child->next->data, alg_id->child->next->size, key)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = der_decode_integer(priv_key->data, priv_key->size, key->x)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+   if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   /* quick p, q, g validation, without primality testing
+    * + x, y validation */
+   if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+   if (stat == 0) {
+      err = CRYPT_INVALID_PACKET;
+      goto LBL_ERR;
+   }
+
+   key->qord = mp_unsigned_bin_size(key->q);
+   key->type = PK_PRIVATE;
+
+   return err;
+LBL_ERR:
+   dsa_free(key);
+   return err;
+}
+/**
+  Import an RSAPrivateKey in PKCS#8 format
+  @param in        The packet to import from
+  @param inlen     It's length (octets)
+  @param pw_ctx    The password context when decrypting the private key
+  @param key       [out] Destination for newly imported key
+  @return CRYPT_OK if successful, upon error allocated memory is freed
+*/
+int dsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                     const password_ctx  *pw_ctx,
+                     dsa_key *key)
+{
+   int           err;
+   ltc_asn1_list *l = NULL;
+   ltc_asn1_list *alg_id, *priv_key;
+   enum ltc_oid_id pka;
+
+   LTC_ARGCHK(in != NULL);
+
+   if ((err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
+      goto LBL_DER_FREE;
+   }
+   if (pka != LTC_OID_DSA) {
+      err = CRYPT_INVALID_PACKET;
+      goto LBL_DER_FREE;
+   }
+
+   err = dsa_import_pkcs8_asn1(alg_id, priv_key, key);
+
+LBL_DER_FREE:
+   der_free_sequence_flexi(l);
+   return err;
+}
+
+#endif /* LTC_MRSA */

+ 22 - 0
src/pk/dsa/dsa_init.c

@@ -0,0 +1,22 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+#include "tomcrypt_private.h"
+
+
+#ifdef LTC_MDSA
+
+/**
+  Init DSA key
+  @param key     [out] the key to init
+  @return CRYPT_OK if successful.
+*/
+int dsa_int_init(dsa_key *key)
+{
+   LTC_ARGCHK(key         != NULL);
+   LTC_ARGCHK(ltc_mp.name != NULL);
+
+   /* init key */
+   return mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
+}
+
+#endif

+ 1 - 4
src/pk/dsa/dsa_set.c

@@ -26,12 +26,9 @@ int dsa_set_pqg(const unsigned char *p,  unsigned long plen,
    LTC_ARGCHK(p           != NULL);
    LTC_ARGCHK(p           != NULL);
    LTC_ARGCHK(q           != NULL);
    LTC_ARGCHK(q           != NULL);
    LTC_ARGCHK(g           != NULL);
    LTC_ARGCHK(g           != NULL);
-   LTC_ARGCHK(key         != NULL);
-   LTC_ARGCHK(ltc_mp.name != NULL);
 
 
    /* init key */
    /* init key */
-   err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
-   if (err != CRYPT_OK) return err;
+   if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
 
 
    if ((err = mp_read_unsigned_bin(key->p, (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; }
    if ((err = mp_read_unsigned_bin(key->p, (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; }
    if ((err = mp_read_unsigned_bin(key->g, (unsigned char *)g , glen)) != CRYPT_OK) { goto LBL_ERR; }
    if ((err = mp_read_unsigned_bin(key->g, (unsigned char *)g , glen)) != CRYPT_OK) { goto LBL_ERR; }

+ 1 - 2
src/pk/dsa/dsa_set_pqg_dsaparam.c

@@ -25,8 +25,7 @@ int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamle
    LTC_ARGCHK(ltc_mp.name != NULL);
    LTC_ARGCHK(ltc_mp.name != NULL);
 
 
    /* init key */
    /* init key */
-   err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
-   if (err != CRYPT_OK) return err;
+   if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
 
 
    if ((err = der_decode_sequence_multi(dsaparam, dsaparamlen,
    if ((err = der_decode_sequence_multi(dsaparam, dsaparamlen,
                                         LTC_ASN1_INTEGER, 1UL, key->p,
                                         LTC_ASN1_INTEGER, 1UL, key->p,

+ 19 - 4
src/pk/dsa/dsa_verify_key.c

@@ -27,10 +27,7 @@ int dsa_verify_key(const dsa_key *key, int *stat)
    err = dsa_int_validate_primes(key, stat);
    err = dsa_int_validate_primes(key, stat);
    if (err != CRYPT_OK || *stat == 0) return err;
    if (err != CRYPT_OK || *stat == 0) return err;
 
 
-   err = dsa_int_validate_pqg(key, stat);
-   if (err != CRYPT_OK || *stat == 0) return err;
-
-   return dsa_int_validate_xy(key, stat);
+   return dsa_int_validate(key, stat);
 }
 }
 
 
 /**
 /**
@@ -186,4 +183,22 @@ error:
    return err;
    return err;
 }
 }
 
 
+/**
+   Validation of DSA params (p, q, g) and DSA key (x and y)
+
+   @param key   The key to validate
+   @param stat  [out]  Result of test, 1==valid, 0==invalid
+   @return CRYPT_OK if successful
+*/
+int dsa_int_validate(const dsa_key *key, int *stat)
+{
+   int err;
+
+   err = dsa_int_validate_pqg(key, stat);
+   if (err != CRYPT_OK || *stat == 0) return err;
+
+   return dsa_int_validate_xy(key, stat);
+
+}
+
 #endif
 #endif