diff options
author | Rob Austein <sra@hactrn.net> | 2013-10-08 03:30:21 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2013-10-08 03:30:21 +0000 |
commit | 9a6b8284b0912344993f6af9929915c6363396e3 (patch) | |
tree | b63e086ce0f97c1be877ade86b4509639573e82a | |
parent | 5f47f2efe1f069b959d3e837234614ed0f64d25c (diff) |
Switch RSA key generation to use a new .generateRSA() class method
rather than abusing the Asymmetric __init__() method, in preparation
for adding support for other public key algorithms like ECDSA.
svn path=/trunk/; revision=5553
-rw-r--r-- | rpkid/ext/POW.c | 96 | ||||
-rw-r--r-- | rpkid/rpki/x509.py | 4 |
2 files changed, 64 insertions, 36 deletions
diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index de675718..bab7b94c 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -4931,50 +4931,22 @@ asymmetric_object_new(PyTypeObject *type, GCC_UNUSED PyObject *args, GCC_UNUSED static int asymmetric_object_init(asymmetric_object *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"cipher", "key_size", NULL}; - int cipher_type = RSA_CIPHER, key_size = 2048; - EVP_PKEY_CTX *ctx = NULL; - int ok = 0; + static char *kwlist[] = {NULL}; ENTERING(asymmetric_object_init); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &cipher_type, &key_size)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) goto error; /* - * This silliness is necessary until we move this to an RSA-specific class method. + * We used to take arguments to generate an RSA key, but that's + * now in the .generateRSA() class method. */ - if (cipher_type != RSA_CIPHER) - lose("unsupported cipher"); - - if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL || - EVP_PKEY_keygen_init(ctx) <= 0 || - EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_size) <= 0) - lose_openssl_error("Couldn't initialize EVP_PKEY_CTX"); - /* - * Should set RSA_F4 for drill, although I think it's the default now. - * Looks like the call is - * int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); - * while RSA_F4 is a plain C long integer, so would need to make a bignum (sigh), - * which is probably BN_new()/BN_set_word()/BN_free(). - */ - - EVP_PKEY_free(self->pkey); - self->pkey = NULL; - - if (EVP_PKEY_keygen(ctx, &self->pkey) <= 0) - lose_openssl_error("Couldn't generate new RSA key"); - - ok = 1; + return 0; error: - EVP_PKEY_CTX_free(ctx); - - if (ok) - return 0; - else - return -1; + return -1; } static void @@ -5323,6 +5295,61 @@ asymmetric_object_der_write_public(asymmetric_object *self) return result; } +static char asymmetric_object_generate_rsa__doc__[] = + "Generate a new RSA keypair.\n" + "\n" + "Optional argument key_size is the desired key size, in bits;\n" + "if not specified, the default is 2048." + ; + +static PyObject * +asymmetric_object_generate_rsa(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key_size", NULL}; + asymmetric_object *self = NULL; + EVP_PKEY_CTX *ctx = NULL; + int key_size = 2048; + int ok = 0; + + ENTERING(asymmetric_object_generate_rsa); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &key_size)) + goto error; + + if ((self = (asymmetric_object *) asymmetric_object_new(type, NULL, NULL)) == NULL) + goto error; + + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL || + EVP_PKEY_keygen_init(ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_size) <= 0) + lose_openssl_error("Couldn't initialize EVP_PKEY_CTX"); + + /* + * We should set RSA_F4 for drill, but it's the default so not urgent. + * Looks like the call is + * int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); + * while RSA_F4 is a plain C long integer, so would need to make a bignum (sigh), + * which is probably BN_new()/BN_set_word()/BN_free(). + */ + + EVP_PKEY_free(self->pkey); + self->pkey = NULL; + + if (EVP_PKEY_keygen(ctx, &self->pkey) <= 0) + lose_openssl_error("Couldn't generate new RSA key"); + + ok = 1; + + error: + EVP_PKEY_CTX_free(ctx); + + if (ok) + return (PyObject *) self; + + Py_XDECREF(self); + return NULL; +} + static char asymmetric_object_calculate_ski__doc__[] = "Calculate SKI value for this key.\n" "\n" @@ -5367,6 +5394,7 @@ static struct PyMethodDef asymmetric_object_methods[] = { Define_Class_Method(pemReadPrivateFile, asymmetric_object_pem_read_private_file, METH_VARARGS), Define_Class_Method(derReadPrivate, asymmetric_object_der_read_private, METH_VARARGS), Define_Class_Method(derReadPrivateFile, asymmetric_object_der_read_private_file, METH_VARARGS), + Define_Class_Method(generateRSA, asymmetric_object_generate_rsa, METH_KEYWORDS), {NULL} }; diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py index 3bd0a3cd..fcdd988b 100644 --- a/rpkid/rpki/x509.py +++ b/rpkid/rpki/x509.py @@ -1011,7 +1011,7 @@ class insecure_debug_only_rsa_key_generator(object): try: v = rpki.POW.Asymmetric.derReadPrivate(self.db[k]) except KeyError: - v = rpki.POW.Asymmetric(rpki.POW.RSA_CIPHER, 2048) + v = rpki.POW.Asymmetric.generateRSA(2048) self.db[k] = v.derWritePrivate() self.keyno += 1 return v @@ -1067,7 +1067,7 @@ class RSA(DER_object): if generate_insecure_debug_only_rsa_key is not None: return cls(POW = generate_insecure_debug_only_rsa_key()) else: - return cls(POW = rpki.POW.Asymmetric(rpki.POW.RSA_CIPHER, keylength)) + return cls(POW = rpki.POW.Asymmetric.generateRSA(keylength)) def get_public_DER(self): """ |