]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
certtool: support generating RSA-OAEP private key
authorDaiki Ueno <ueno@gnu.org>
Thu, 8 Feb 2024 09:40:00 +0000 (18:40 +0900)
committerDaiki Ueno <ueno@gnu.org>
Sun, 3 Mar 2024 02:07:31 +0000 (11:07 +0900)
Signed-off-by: Daiki Ueno <ueno@gnu.org>
src/certtool-common.c
src/certtool-common.h
src/certtool-options.json
src/certtool.c

index 9c83cb89b4e92128651e3abf1eee9070b7850f54..45f2ad8e30000fde34bd725708dc391dc5c002ea 100644 (file)
@@ -1185,7 +1185,8 @@ static void privkey_info_int(FILE *outfile, common_info_st *cinfo,
        cprint = gnutls_pk_algorithm_get_name(key_type);
        fprintf(outfile, "%s\n", cprint ? cprint : "Unknown");
 
-       if (key_type == GNUTLS_PK_RSA_PSS) {
+       switch (key_type) {
+       case GNUTLS_PK_RSA_PSS: {
                unsigned int salt_size;
 
                ret = gnutls_x509_privkey_get_spki(key, spki, 0);
@@ -1207,6 +1208,44 @@ static void privkey_info_int(FILE *outfile, common_info_st *cinfo,
                                gnutls_digest_get_name(dig));
                        fprintf(outfile, "\t\tSalt Length: %d\n", salt_size);
                }
+               break;
+       }
+       case GNUTLS_PK_RSA_OAEP: {
+               gnutls_datum_t label = { NULL, 0 };
+
+               ret = gnutls_x509_privkey_get_spki(key, spki, 0);
+               if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+                       goto spki_skip;
+
+               if (ret < 0) {
+                       fprintf(stderr, "spki_get: %s\n", gnutls_strerror(ret));
+                       goto spki_skip;
+               }
+
+               ret = gnutls_x509_spki_get_rsa_oaep_params(spki, &dig, &label);
+               if (ret < 0) {
+                       fprintf(stderr, "spki_get_rsa_oaep_params: %s\n",
+                               gnutls_strerror(ret));
+               } else {
+                       fprintf(outfile, "\t\tHash Algorithm: %s\n",
+                               gnutls_digest_get_name(dig));
+                       if (label.data) {
+                               gnutls_datum_t hex;
+
+                               ret = gnutls_hex_encode2(&label, &hex);
+                               if (ret < 0) {
+                                       fprintf(stderr, "hex_encode2: %s\n",
+                                               gnutls_strerror(ret));
+                                       goto spki_skip;
+                               }
+                               fprintf(outfile, "\t\tLabel: %s\n", hex.data);
+                               gnutls_free(hex.data);
+                       }
+               }
+               break;
+       }
+       default:
+               break;
        }
 
 spki_skip:
@@ -1602,6 +1641,8 @@ gnutls_pk_algorithm_t figure_key_type(const char *key_type)
                return GNUTLS_PK_RSA;
        else if (strcasecmp(key_type, "rsa-pss") == 0)
                return GNUTLS_PK_RSA_PSS;
+       else if (strcasecmp(key_type, "rsa-oaep") == 0)
+               return GNUTLS_PK_RSA_OAEP;
        else if (strcasecmp(key_type, "ed25519") == 0 ||
                 strcasecmp(key_type, "eddsa") == 0)
                return GNUTLS_PK_EDDSA_ED25519;
index 5607f4c4d27e444e44c830dbbbeb10b9a06fcb72..07b7ae09ccf972d6065cc514acfa99938a865371 100644 (file)
@@ -67,6 +67,8 @@ typedef struct common_info {
        unsigned char *seed;
        unsigned seed_size;
 
+       gnutls_datum_t label;
+
        const char *pin;
        const char *so_pin;
 
index 3b712cbc45598e1914639b8fcca3f32887832bb4..8c5ead34b3541d5b46f30cf73b4ed51f6261dfb8 100644 (file)
           "long-option": "generate-privkey",
           "short-option": "p",
           "description": "Generate a private key",
-          "detail": "When generating RSA-PSS private keys, the --hash option will\nrestrict the allowed hash for the key; in the same keys the --salt-size\noption is also acceptable."
+          "detail": "When generating RSA-PSS or RSA-OAEP private keys, the --hash option will\nrestrict the allowed hash for the key; For RSA-PSS keys the --salt-size\noption is also acceptable."
         },
         {
           "long-option": "key-type",
           "description": "Specify the key type to use on key generation",
-          "detail": "This option can be combined with --generate-privkey, to specify\nthe key type to be generated. Valid options are, 'rsa', 'rsa-pss', 'dsa', 'ecdsa', 'ed25519, 'ed448', 'x25519', and 'x448'.'.\nWhen combined with certificate generation it can be used to specify an\nRSA-PSS certificate when an RSA key is given.",
+          "detail": "This option can be combined with --generate-privkey, to specify\nthe key type to be generated. Valid options are, 'rsa', 'rsa-pss', 'rsa-oaep', 'dsa', 'ecdsa', 'ed25519, 'ed448', 'x25519', and 'x448'.'.\nWhen combined with certificate generation it can be used to specify an\nRSA-PSS certificate when an RSA key is given.",
           "argument-type": "string"
         },
         {
           "detail": "Typical keys shouldn't set or restrict this option.",
           "argument-type": "number"
         },
+        {
+          "long-option": "label",
+          "description": "Specify the RSA-OAEP label, encoded in hexadecimal",
+          "detail": "Typical keys shouldn't set or restrict this option.",
+          "argument-type": "string"
+        },
         {
           "long-option": "inder",
           "description": "Use DER format for input certificates, private keys, and DH parameters ",
       ]
     }
   ]
-}
\ No newline at end of file
+}
index 078af7dcf19facfc054a7f342197f0a87a9c75a2..b19e4970f3b722d2acc9ce22589843c4f9b10504 100644 (file)
@@ -134,7 +134,7 @@ int main(int argc, char **argv)
        return 0;
 }
 
-#define SET_SPKI_PARAMS(spki, cinfo)                                                                               \
+#define SET_RSA_PSS_PARAMS(spki, cinfo)                                                                            \
        do {                                                                                                       \
                unsigned _salt_size;                                                                               \
                if (!cinfo->hash) {                                                                                \
@@ -151,6 +151,18 @@ int main(int argc, char **argv)
                                                    _salt_size);                                                   \
        } while (0)
 
+#define SET_RSA_OAEP_PARAMS(spki, cinfo)                                                                        \
+       do {                                                                                                    \
+               if (!cinfo->hash) {                                                                             \
+                       fprintf(stderr,                                                                         \
+                               "You must provide the hash algorithm and optionally the label for RSA-OAEP\n"); \
+                       app_exit(1);                                                                            \
+               }                                                                                               \
+               gnutls_x509_spki_set_rsa_oaep_params(                                                           \
+                       spki, cinfo->hash,                                                                      \
+                       cinfo->label.data ? &cinfo->label : NULL);                                              \
+       } while (0)
+
 static gnutls_x509_privkey_t generate_private_key_int(common_info_st *cinfo)
 {
        gnutls_x509_privkey_t key;
@@ -264,7 +276,16 @@ static gnutls_x509_privkey_t generate_private_key_int(common_info_st *cinfo)
 
        if (key_type == GNUTLS_PK_RSA_PSS &&
            (cinfo->hash || HAVE_OPT(SALT_SIZE))) {
-               SET_SPKI_PARAMS(spki, cinfo);
+               SET_RSA_PSS_PARAMS(spki, cinfo);
+
+               kdata[kdata_size].type = GNUTLS_KEYGEN_SPKI;
+               kdata[kdata_size].data = (void *)spki;
+               kdata[kdata_size++].size = sizeof(spki);
+       }
+
+       if (key_type == GNUTLS_PK_RSA_OAEP &&
+           (cinfo->hash || HAVE_OPT(LABEL))) {
+               SET_RSA_OAEP_PARAMS(spki, cinfo);
 
                kdata[kdata_size].type = GNUTLS_KEYGEN_SPKI;
                kdata[kdata_size].data = (void *)spki;
@@ -780,7 +801,7 @@ static gnutls_x509_crt_t generate_certificate(gnutls_privkey_t *ret_key,
                        app_exit(1);
                }
 
-               SET_SPKI_PARAMS(spki, cinfo);
+               SET_RSA_PSS_PARAMS(spki, cinfo);
 
                result = gnutls_x509_crt_set_spki(crt, spki, 0);
                if (result < 0) {
@@ -1359,6 +1380,20 @@ static void cmd_parser(int argc, char **argv)
                cinfo.seed_size = seed.size;
        }
 
+       if (HAVE_OPT(LABEL)) {
+               gnutls_datum_t hex;
+
+               hex.data = (uint8_t *)OPT_ARG(LABEL);
+               hex.size = strlen(OPT_ARG(LABEL));
+
+               ret = gnutls_hex_decode2(&hex, &cinfo.label);
+               if (ret < 0) {
+                       fprintf(stderr, "unable to decode label: %s\n",
+                               gnutls_strerror(ret));
+                       app_exit(1);
+               }
+       }
+
        cinfo.batch = batch;
        cinfo.cprint = HAVE_OPT(CPRINT);