EC public key to make X509 cert

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

EC public key to make X509 cert

Larry Bugbee
Using 0.9.9-dev (SNAP-20080417) I am able to create an EC CSR, and in turn, use it to create a X509 cert signed with an EC CA key.  No problem.  As long as the individual/device is capable of creating a CSR, it all works very nicely.  Thank you.

My problem is that there are times when the individual or device is incapable of creating a CSR.  The EC key pair has been generated and the private key is safely tucked away, but I still want a cert.  Even though the public key is sent to the CA through a trusted process, I cannot use it to create a X509 cert.  The routines that purport to accept a public key for inclusion into the cert will not accept an EC public key.  RSA keys work fine; EC keys do not.  (I've tried both openssl (the executable) and the library APIs from a C program.)

If it helps, here is a minimalist test program.  BTW, making a CSR by loading the EC public key fails as well.

I know 0.9.9 is still in development so perhaps I'm being premature.  Then again, perhaps I'm doing something stupid.  If someone has a suggestion......  

My thanks,

Larry

======================================================================

// compile with:
//   gcc testECcert.c -L/usr/local/lib -lcrypto -o testECcert

#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/x509.h>

// not in any header file I can find
// EC_KEY* PEM_read_bio_EC_PUBKEY(BIO* buf, ...);

char *pubkeypem = "\
-----BEGIN PUBLIC KEY-----\n\
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAsEnmej3TZulFozEchUtEVradA2X\n\
vlO3bYFlSQKk9CzK2+MBerbAU0NVSOcUycad4R8M2rAi1PCFzUStt0QSmw==\n\
-----END PUBLIC KEY-----\n";
    

int main(int argc, char* argv[]) {
    int         err;
    BIO        *buf  = NULL;
    EC_KEY     *ecpubkey = NULL;
    X509       *cert = NULL;
X509_NAME  *name = NULL;
    int         days = 365;

    OpenSSL_add_all_algorithms();
    
    //----------------------------------------------------------
    // load public key
    buf = BIO_new_mem_buf(pubkeypem, strlen(pubkeypem));
    ecpubkey = (EC_KEY*)PEM_read_bio_EC_PUBKEY(buf, NULL, NULL, NULL);
EC_KEY_print_fp(stdout, ecpubkey, 2);    // ignore "Private-Key"

    //----------------------------------------------------------
    // load cert
    cert = X509_new();
X509_set_version(cert,2);
// set issuer and subject here
X509_gmtime_adj(X509_get_notBefore(cert),0);
X509_gmtime_adj(X509_get_notAfter(cert),(long)60*60*24*days);
//                            v---------v cast to satisify warning
// err = X509_set_pubkey(cert, (EVP_PKEY*)ecpubkey);
err = X509_set_pubkey(cert, ecpubkey);
if (err) printf("set public key error: ", err);
    //----------------------------------------------------------
    // let's see it
    X509_print_fp(stdout, cert);
}

======================================================================
======================================================================

Reply | Threaded
Open this post in threaded view
|

Re: EC public key to make X509 cert

Dr. Stephen Henson
On Mon, Apr 28, 2008, Larry Bugbee wrote:

> I know 0.9.9 is still in development so perhaps I'm being premature.  Then
> again, perhaps I'm doing something stupid.  If someone has a
> suggestion......
>
> My thanks,
>
> Larry
>
> ======================================================================
>
> // compile with:
> //   gcc testECcert.c -L/usr/local/lib -lcrypto -o testECcert
>
> #include <stdio.h>
> #include <string.h>
> #include <openssl/crypto.h>
> #include <openssl/ec.h>
> #include <openssl/x509.h>
>
> // not in any header file I can find
> // EC_KEY* PEM_read_bio_EC_PUBKEY(BIO* buf, ...);
>
> char *pubkeypem = "\
> -----BEGIN PUBLIC KEY-----\n\
> MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAsEnmej3TZulFozEchUtEVradA2X\n\
> vlO3bYFlSQKk9CzK2+MBerbAU0NVSOcUycad4R8M2rAi1PCFzUStt0QSmw==\n\
> -----END PUBLIC KEY-----\n";
>
>
> int main(int argc, char* argv[]) {
>     int         err;
>     BIO        *buf  = NULL;
>     EC_KEY     *ecpubkey = NULL;
>     X509       *cert = NULL;
> X509_NAME  *name = NULL;
>     int         days = 365;
>
>     OpenSSL_add_all_algorithms();
>
>     //----------------------------------------------------------
>     // load public key
>     buf = BIO_new_mem_buf(pubkeypem, strlen(pubkeypem));
>     ecpubkey = (EC_KEY*)PEM_read_bio_EC_PUBKEY(buf, NULL, NULL, NULL);
> EC_KEY_print_fp(stdout, ecpubkey, 2);    // ignore "Private-Key"
>
>     //----------------------------------------------------------
>     // load cert
>     cert = X509_new();
> X509_set_version(cert,2);
> // set issuer and subject here
> X509_gmtime_adj(X509_get_notBefore(cert),0);
> X509_gmtime_adj(X509_get_notAfter(cert),(long)60*60*24*days);
> //                            v---------v cast to satisify warning
> // err = X509_set_pubkey(cert, (EVP_PKEY*)ecpubkey);
> err = X509_set_pubkey(cert, ecpubkey);
> if (err) printf("set public key error: ", err);
>
>     //----------------------------------------------------------
>     // let's see it
>     X509_print_fp(stdout, cert);
> }
>

You can't just cast and EC_KEY structure to EVP_PKEY: they are different
structures which need to be converted.

If you call PEM_read_bio_PUBKEY() instead you get an EVP_PKEY directly.

Alternatively calling:

EVP_PKEY *pk = EVP_PKEY_new();
...
EVP_PKEY_assign_EC_KEY(pk, ecpubkey;

Will work.

Steve.
--
Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage
OpenSSL project core developer and freelance consultant.
Homepage: http://www.drh-consultancy.demon.co.uk
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: EC public key to make X509 cert

Larry Bugbee-2
On Apr 29, 2008, at 3:29 AM, Dr. Stephen Henson wrote:
> Alternatively calling:
>
> EVP_PKEY *pk = EVP_PKEY_new();
> ...
> EVP_PKEY_assign_EC_KEY(pk, ecpubkey;
>
> Will work.

Indeed it does!  A thousand thanks!!!

Larry

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]