]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth pkcs11: add ECDSA support, use softhsm2-util, other fixes
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Fri, 5 Jun 2020 23:05:22 +0000 (01:05 +0200)
committerPeter van Dijk <peter.van.dijk@powerdns.com>
Mon, 8 Jun 2020 19:28:58 +0000 (21:28 +0200)
pdns/pdnsutil.cc
pdns/pkcs11signers.cc
regression-tests/start-test-stop

index fd5bcccfe91e13065d3e3e6284bf17e3b7bd0be4..04fa2378ed1bdf64bff66e5a7a823abca516d7b9 100644 (file)
@@ -1682,7 +1682,7 @@ static bool showZone(DNSSECKeeper& dk, const DNSName& zone, bool exportDS = fals
         cout<<"ID = "<<value.second.id<<" ("<<DNSSECKeeper::keyTypeToString(value.second.keyType)<<")";
       }
       if (value.first.getKey()->getBits() < 1) {
-        cerr<<" <key missing or defunct>" <<endl;
+        cout<<" <key missing or defunct>" <<endl;
         continue;
       }
       if (!exportDS) {
@@ -3264,7 +3264,7 @@ try
          return 1;
       }
 
-      cerr << "Key of size " << bits << " created" << std::endl;
+      cerr << "Key of size " << dke->getBits() << " created" << std::endl;
       return 0;
     }
 #else
index ddb1506492f606845111878a724df3929885b070..a7c188634474088087a5f9bf5049e6cf552006be 100644 (file)
@@ -63,6 +63,14 @@ static std::map<unsigned int,CK_MECHANISM_TYPE> dnssec2hmech = boost::assign::ma
 (13, CKM_SHA256)
 (14, CKM_SHA384);
 
+static std::map<unsigned int,CK_MECHANISM_TYPE> dnssec2cmech = boost::assign::map_list_of
+(5, CKM_RSA_PKCS_KEY_PAIR_GEN)
+(7, CKM_RSA_PKCS_KEY_PAIR_GEN)
+(8, CKM_RSA_PKCS_KEY_PAIR_GEN)
+(10, CKM_RSA_PKCS_KEY_PAIR_GEN)
+(13, CKM_ECDSA_KEY_PAIR_GEN)
+(14, CKM_ECDSA_KEY_PAIR_GEN);
+
 typedef enum { Attribute_Byte, Attribute_Long, Attribute_String } CkaValueType;
 
 // Attribute handling
@@ -212,7 +220,7 @@ class Pkcs11Slot {
 
     void logError(const std::string& operation) const {
       if (d_err) {
-        std::string msg = boost::str( boost::format("PKCS#11 operation %s failed: %s (0x%X)") % operation % p11_kit_strerror(d_err) % d_err );
+        std::string msg = boost::str( boost::format("PKCS#11 operation %s failed: %s (0x%X) (%s)") % operation % p11_kit_strerror(d_err) % d_err % p11_kit_message() );
         g_log<<Logger::Error<< msg << endl;
       }
     }
@@ -290,7 +298,7 @@ class Pkcs11Token {
 
     void logError(const std::string& operation) const {
       if (d_err) {
-        std::string msg = boost::str( boost::format("PKCS#11 operation %s failed: %s (0x%X)") % operation % p11_kit_strerror(d_err) % d_err );
+        std::string msg = boost::str( boost::format("PKCS#11 operation %s failed: %s (0x%X) (%s)") % operation % p11_kit_strerror(d_err) % d_err % p11_kit_message());
         g_log<<Logger::Error<< msg << endl;
       }
     }
@@ -793,32 +801,59 @@ void PKCS11DNSCryptoKeyEngine::create(unsigned int bits) {
 
   std::string pubExp("\000\001\000\001", 4); // 65537
 
-  pubAttr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PUBLIC_KEY));
-  pubAttr.push_back(P11KitAttribute(CKA_KEY_TYPE, (unsigned long)CKK_RSA));
-  pubAttr.push_back(P11KitAttribute(CKA_TOKEN, (char)CK_TRUE));
-  pubAttr.push_back(P11KitAttribute(CKA_ENCRYPT, (char)CK_TRUE));
-  pubAttr.push_back(P11KitAttribute(CKA_VERIFY, (char)CK_TRUE));
-  pubAttr.push_back(P11KitAttribute(CKA_WRAP, (char)CK_TRUE));
-  pubAttr.push_back(P11KitAttribute(CKA_MODULUS_BITS, (unsigned long)bits));
-  pubAttr.push_back(P11KitAttribute(CKA_PUBLIC_EXPONENT, pubExp));
-  pubAttr.push_back(P11KitAttribute(CKA_LABEL, d_pub_label));
-
-  privAttr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PRIVATE_KEY));
-  privAttr.push_back(P11KitAttribute(CKA_KEY_TYPE, (unsigned long)CKK_RSA));
-  privAttr.push_back(P11KitAttribute(CKA_TOKEN, (char)CK_TRUE));
-  privAttr.push_back(P11KitAttribute(CKA_PRIVATE, (char)CK_TRUE));
-//  privAttr.push_back(P11KitAttribute(CKA_SUBJECT, "CN=keygen"));
-  privAttr.push_back(P11KitAttribute(CKA_ID, "\x01\x02\x03\x04")); // this is mandatory if you want to export anything
-  privAttr.push_back(P11KitAttribute(CKA_SENSITIVE, (char)CK_TRUE));
-  privAttr.push_back(P11KitAttribute(CKA_DECRYPT, (char)CK_TRUE));
-  privAttr.push_back(P11KitAttribute(CKA_SIGN, (char)CK_TRUE));
-  privAttr.push_back(P11KitAttribute(CKA_UNWRAP, (char)CK_TRUE));
-  privAttr.push_back(P11KitAttribute(CKA_LABEL, d_label));
-
-  mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
+  mech.mechanism = dnssec2cmech[d_algorithm];
   mech.pParameter = NULL;
   mech.ulParameterLen = 0;
 
+  if (mech.mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN) {
+    pubAttr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PUBLIC_KEY));
+    pubAttr.push_back(P11KitAttribute(CKA_KEY_TYPE, (unsigned long)CKK_RSA));
+    pubAttr.push_back(P11KitAttribute(CKA_TOKEN, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_ENCRYPT, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_VERIFY, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_WRAP, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_MODULUS_BITS, (unsigned long)bits));
+    pubAttr.push_back(P11KitAttribute(CKA_PUBLIC_EXPONENT, pubExp));
+    pubAttr.push_back(P11KitAttribute(CKA_LABEL, d_pub_label));
+
+    privAttr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PRIVATE_KEY));
+    privAttr.push_back(P11KitAttribute(CKA_KEY_TYPE, (unsigned long)CKK_RSA));
+    privAttr.push_back(P11KitAttribute(CKA_TOKEN, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_PRIVATE, (char)CK_TRUE));
+  //  privAttr.push_back(P11KitAttribute(CKA_SUBJECT, "CN=keygen"));
+    privAttr.push_back(P11KitAttribute(CKA_ID, "\x01\x02\x03\x04")); // this is mandatory if you want to export anything
+    privAttr.push_back(P11KitAttribute(CKA_SENSITIVE, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_DECRYPT, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_SIGN, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_UNWRAP, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_LABEL, d_label));
+  } else if (mech.mechanism == CKM_ECDSA_KEY_PAIR_GEN) {
+    pubAttr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PUBLIC_KEY));
+    pubAttr.push_back(P11KitAttribute(CKA_KEY_TYPE, (unsigned long)CKK_ECDSA));
+    pubAttr.push_back(P11KitAttribute(CKA_TOKEN, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_ENCRYPT, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_VERIFY, (char)CK_TRUE));
+    pubAttr.push_back(P11KitAttribute(CKA_LABEL, d_pub_label));
+    if (d_algorithm == 13) pubAttr.push_back(P11KitAttribute(CKA_ECDSA_PARAMS, "\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07"));
+    else if (d_algorithm == 14) pubAttr.push_back(P11KitAttribute(CKA_ECDSA_PARAMS, "\x06\x05\x2b\x81\x04\x00\x22"));
+    else throw PDNSException("pkcs11: unknown algorithm "+std::to_string(d_algorithm)+" for ECDSA key pair gen");
+
+    privAttr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PRIVATE_KEY));
+    privAttr.push_back(P11KitAttribute(CKA_KEY_TYPE, (unsigned long)CKK_ECDSA));
+    privAttr.push_back(P11KitAttribute(CKA_TOKEN, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_PRIVATE, (char)CK_TRUE));
+  //  privAttr.push_back(P11KitAttribute(CKA_SUBJECT, "CN=keygen"));
+    privAttr.push_back(P11KitAttribute(CKA_ID, "\x01\x02\x03\x04")); // this is mandatory if you want to export anything
+    privAttr.push_back(P11KitAttribute(CKA_SENSITIVE, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_DECRYPT, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_SIGN, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_UNWRAP, (char)CK_TRUE));
+    privAttr.push_back(P11KitAttribute(CKA_LABEL, d_label));
+  } else {
+    throw PDNSException("pkcs11: don't know how make key for algorithm "+std::to_string(d_algorithm));
+  }
+
+
   if (d_slot->GenerateKeyPair(&mech, pubAttr, privAttr, &pubKey, &privKey)) {
     throw PDNSException("Keypair generation failed");
   }
index 96044e25f09a1f749f4ace22d54a6d98916d21d7..48e513e16c685796e06205f85b7f195859d289e7 100755 (executable)
@@ -129,22 +129,23 @@ securezone ()
        else
                # check if PKCS#11 should be used
                if [ "$pkcs11" -eq 1 ]; then
-                  if [ "$slot" == "" ]; then
-                    slot=0
-                  else
-                    slot=$((slot+1))
-                  fi
-                  sudo softhsm --init-token --slot $slot --label label$slot --pin 123$slot --so-pin 123$slot
-                  kid=`$PDNSUTIL --config-dir=. $configname hsm assign $zone ecdsa256 zsk softhsm label$slot 123$slot label$slot 2>&1 | grep softhsm | awk '{ print $NF }'`
-                  kid=`$PDNSUTIL --config-dir=. $configname show-zone $zone | grep 'ID =.*ZSK' | awk '{ print $3 }'`
-                  $PDNSUTIL --config-dir=. $configname hsm create-key $zone $kid
-                else
-                  $PDNSUTIL --config-dir=. $configname secure-zone $zone 2>&1
-                  if [ "${zone: 0:20}" = "cdnskey-cds-test.com" ]; then
-                    $PDNSUTIL --config-dir=. $configname set-publish-cds $zone 2>&1
-                    $PDNSUTIL --config-dir=. $configname set-publish-cdnskey $zone 2>&1
-                  fi
-                fi
+                       if [ "$slot" == "" ]; then
+                               slot=0
+                       else
+                               slot=$((slot+1))
+                       fi
+                       label=pdnstest-${EPOCHSECONDS}-${slot}
+                       softhsm2-util --delete-token --label $label 2> /dev/null || true
+                       softhsm2-util --init-token --label $label --free --pin 1234 --so-pin 1234
+                       kid=`$PDNSUTIL --config-dir=. $configname hsm assign $zone ecdsa256 ksk softhsm $label 1234 $label 2>&1 | grep softhsm | awk '{ print $NF }'`
+                       $PDNSUTIL --config-dir=. $configname hsm create-key $zone $kid
+               else
+                       $PDNSUTIL --config-dir=. $configname secure-zone $zone 2>&1
+               fi
+               if [ "${zone: 0:20}" = "cdnskey-cds-test.com" ]; then
+                       $PDNSUTIL --config-dir=. $configname set-publish-cds $zone 2>&1
+                       $PDNSUTIL --config-dir=. $configname set-publish-cdnskey $zone 2>&1
+               fi
        fi
 }