Преглед на файлове

Add SubjectPublicKeyInfo support to `dsa_import()`

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel преди 3 месеца
родител
ревизия
9abf12305a
променени са 2 файла, в които са добавени 74 реда и са изтрити 30 реда
  1. 3 0
      src/pk/asn1/x509/x509_import_spki.c
  2. 71 30
      src/pk/dsa/dsa_import.c

+ 3 - 0
src/pk/asn1/x509/x509_import_spki.c

@@ -15,6 +15,9 @@ static const import_fn s_import_x509_fns[LTC_PKA_NUM] = {
 #ifdef LTC_MRSA
                                                 [LTC_PKA_RSA] = (import_fn)rsa_import_x509,
 #endif
+#ifdef LTC_MDSA
+                                                [LTC_PKA_DSA] = (import_fn)dsa_import,
+#endif
 #ifdef LTC_MECC
                                                 [LTC_PKA_EC] = (import_fn)ecc_import_x509,
 #endif

+ 71 - 30
src/pk/dsa/dsa_import.c

@@ -28,6 +28,69 @@ int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key)
    return err;
 }
 
+static int s_dsa_import_y(const unsigned char *in, unsigned long inlen, dsa_key *key)
+{
+   return der_decode_integer(in, inlen, key->y);
+}
+
+LTC_INLINE static int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params)
+{
+   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, 2, LTC_ASN1_INTEGER, key->g, 1UL);
+   return 3;
+}
+
+static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key)
+{
+   int err;
+   unsigned char* tmpbuf = NULL;
+   ltc_asn1_list params[3];
+   unsigned long tmpbuf_len = inlen, len;
+
+   len = s_dsa_set_params(key, params);
+
+   tmpbuf = XCALLOC(1, tmpbuf_len);
+   if (tmpbuf == NULL) {
+      return CRYPT_MEM;
+   }
+
+   err = x509_decode_subject_public_key_info(in, inlen,
+                                             LTC_OID_DSA,       tmpbuf, &tmpbuf_len,
+                                             LTC_ASN1_SEQUENCE, params, &len);
+   if (err != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   if ((err = s_dsa_import_y(tmpbuf, tmpbuf_len, key)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   key->type = PK_PUBLIC;
+LBL_ERR:
+   XFREE(tmpbuf);
+   return err;
+}
+
+static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_key *key)
+{
+   int err;
+   ltc_asn1_list params[3];
+   unsigned long len;
+
+   len = s_dsa_set_params(key, params);
+
+   if ((err = x509_decode_public_key_from_certificate(in, inlen,
+                                                      LTC_OID_DSA,
+                                                      LTC_ASN1_SEQUENCE, params, &len,
+                                                      (public_key_decode_cb)s_dsa_import_y, key)) == CRYPT_OK) {
+      key->type = PK_PUBLIC;
+      return CRYPT_OK;
+   }
+
+   return err;
+}
+
 /**
    Import a DSA key
    @param in       The binary packet to import from
@@ -38,7 +101,6 @@ int dsa_import_pkcs1(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;
-   unsigned char* tmpbuf = NULL;
    unsigned char flags[1];
 
    LTC_ARGCHK(in  != NULL);
@@ -86,35 +148,14 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
        }
    }
 
-   if (dsa_import_pkcs1(in, inlen, key) != CRYPT_OK) {
-      ltc_asn1_list params[3];
-      unsigned long tmpbuf_len = inlen, len;
-
-      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, 2, LTC_ASN1_INTEGER, key->g, 1UL);
-      len = 3;
-
-      tmpbuf = XCALLOC(1, tmpbuf_len);
-      if (tmpbuf == NULL) {
-         return CRYPT_MEM;
-      }
-
-      err = x509_decode_subject_public_key_info(in, inlen,
-                                                LTC_OID_DSA,       tmpbuf, &tmpbuf_len,
-                                                LTC_ASN1_SEQUENCE, params, &len);
-      if (err != CRYPT_OK) {
-         XFREE(tmpbuf);
-         goto LBL_ERR;
-      }
-
-      if ((err = der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
-         XFREE(tmpbuf);
-         goto LBL_ERR;
-      }
-
-      key->type = PK_PUBLIC;
-      XFREE(tmpbuf);
+   if (dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) {
+      goto LBL_OK;
+   }
+   if (s_dsa_import_spki(in, inlen, key) == CRYPT_OK) {
+      goto LBL_OK;
+   }
+   if ((err = s_dsa_import_x509(in, inlen, key)) != CRYPT_OK) {
+      goto LBL_ERR;
    }
 
 LBL_OK: