]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix hex conversion of PKINIT certid strings
authorSumit Bose <sbose@redhat.com>
Fri, 26 Jan 2018 16:47:50 +0000 (11:47 -0500)
committerGreg Hudson <ghudson@mit.edu>
Wed, 7 Mar 2018 15:57:01 +0000 (10:57 -0500)
When parsing a PKCS11 token specification, correctly convert from hex
to binary instead of using OpenSSL bignum functions (which would strip
leading zeros).

[ghudson@mit.edu: made hex_string_to_bin() a bit less verbose; wrote
commit message]

ticket: 8636

src/plugins/preauth/pkinit/pkinit_crypto_openssl.c

index 9d18ed2a430d0f02d577a3f79134d1bb072c74a7..3a1180d9cac07ad1741fa0f2c6bb5a39fa50e40f 100644 (file)
@@ -4636,6 +4636,43 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts)
     return ret;
 }
 
+static int
+hex_string_to_bin(const char *str, int *bin_len_out, CK_BYTE **bin_out)
+{
+    size_t str_len, i;
+    CK_BYTE *bin;
+    char *endptr, tmp[3] = { '\0', '\0', '\0' };
+    long val;
+
+    *bin_len_out = 0;
+    *bin_out = NULL;
+
+    str_len = strlen(str);
+    if (str_len % 2 != 0)
+        return EINVAL;
+    bin = malloc(str_len / 2);
+    if (bin == NULL)
+        return ENOMEM;
+
+    errno = 0;
+    for (i = 0; i < str_len / 2; i++) {
+        tmp[0] = str[i * 2];
+        tmp[1] = str[i * 2 + 1];
+
+        val = strtol(tmp, &endptr, 16);
+        if (val < 0 || val > 255 || errno != 0 || endptr != &tmp[2]) {
+            free(bin);
+            return EINVAL;
+        }
+
+        bin[i] = (CK_BYTE)val;
+    }
+
+    *bin_len_out = str_len / 2;
+    *bin_out = bin;
+    return 0;
+}
+
 static krb5_error_code
 pkinit_get_certs_pkcs11(krb5_context context,
                         pkinit_plg_crypto_context plg_cryptoctx,
@@ -4678,18 +4715,14 @@ pkinit_get_certs_pkcs11(krb5_context context,
     }
     /* Convert the ascii cert_id string into a binary blob */
     if (idopts->cert_id_string != NULL) {
-        BIGNUM *bn = NULL;
-        BN_hex2bn(&bn, idopts->cert_id_string);
-        if (bn == NULL)
-            return ENOMEM;
-        id_cryptoctx->cert_id_len = BN_num_bytes(bn);
-        id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len);
-        if (id_cryptoctx->cert_id == NULL) {
-            BN_free(bn);
-            return ENOMEM;
+        r = hex_string_to_bin(idopts->cert_id_string,
+                              &id_cryptoctx->cert_id_len,
+                              &id_cryptoctx->cert_id);
+        if (r != 0) {
+            pkiDebug("Failed to convert certid string [%s]\n",
+                     idopts->cert_id_string);
+            return r;
         }
-        BN_bn2bin(bn, id_cryptoctx->cert_id);
-        BN_free(bn);
     }
     id_cryptoctx->slotid = idopts->slotid;
     id_cryptoctx->pkcs11_method = 1;