Hi,
here a patch that allows to update a cert (while leaving the private key intact, very usefull for expired certs). If the new cert is not bigger that the old one, the same file is used; otherwise the file is deleted and a new one with the same file ID is made. Comments/questions? Cheers, Stef _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
Stef Hoeben wrote:
> Hi, > > here a patch that allows to update a cert (while leaving the private key > intact, > very usefull for expired certs). > > If the new cert is not bigger that the old one, the same file is used; > otherwise > the file is deleted and a new one with the same file ID is made. > > Comments/questions? as you wish ;-) > +int > +sc_pkcs15init_update_certificate(sc_pkcs15_card_t *p15card, ... > + /* Fill the remaining space in the EF (if any) with zeros */ > + if (certlen < file->size) { > + unsigned char *tmp = (unsigned char *) calloc(file->size - certlen, 1); > + if (tmp == NULL) { > + r = SC_ERROR_OUT_OF_MEMORY; > + goto done; > + } > + r = sc_update_binary(p15card->card, certlen, tmp, file->size - certlen, 0); > + free(tmp); > + } why ? > Index: tools/pkcs15-init.c > =================================================================== ... > +static int > +do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, > + const char *filename, const char *format, sc_pkcs15_der_t *newcert_raw) > +{ > + X509 *oldcert, *newcert; > + EVP_PKEY *oldpk, *newpk; > + BIO *bio = NULL; > + int r; > + > + /* Get the public key from the old cert */ > + bio = BIO_new_mem_buf(sc_oldcert->data, sc_oldcert->data_len); > + if (bio == NULL) > + return SC_ERROR_INTERNAL; > + oldcert = d2i_X509_bio(bio, NULL); > + BIO_free(bio); isn't this the same as u8 *ptr = sc_oldcert->data; oldcert = d2i_X509(NULL, &ptr, sc_oldcert->data_len); just without using a BIO ? > + if (oldcert == NULL) > + return SC_ERROR_INTERNAL; > + oldpk = X509_get_pubkey(oldcert); > + > + /* Read the new cert from file and get it's public key */ > + r = do_read_certificate(filename, format, &newcert); > + if (r < 0) { > + X509_free(oldcert); > + return r; > + } > + newpk = X509_get_pubkey(newcert); > + > + /* Compare the public keys, there's no high level openssl function for this(?) */ what about "int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *)" ? > + r = SC_ERROR_INVALID_ARGUMENTS; > + if (oldpk->type == newpk->type) > + { > + if ((oldpk->type == EVP_PKEY_DSA) && > + !BN_cmp(oldpk->pkey.dsa->p, newpk->pkey.dsa->p) && > + !BN_cmp(oldpk->pkey.dsa->q, newpk->pkey.dsa->q) && > + !BN_cmp(oldpk->pkey.dsa->g, newpk->pkey.dsa->g)) > + r = 0; > + else if ((oldpk->type == EVP_PKEY_RSA) && > + !BN_cmp(oldpk->pkey.rsa->n, newpk->pkey.rsa->n) && > + !BN_cmp(oldpk->pkey.rsa->e, newpk->pkey.rsa->e)) > + r = 0; > + } > + > + X509_free(oldcert); > + > + if (r == 0) > + r = do_convert_cert(newcert_raw, newcert); > + else > + error("the public keys in the old and new certificate differ"); > + > + X509_free(newcert); as X509_get_pubkey should increase the reference counter of the EVP_PKEY object newpk you must free it with EVP_PKEY_free (mutatis mutandis for oldpk). Cheers, Nils _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Stef Hoeben-2
Hi Nils,
thx for the openssl improvements (if you know some docs describing these functions, I'd be happy to read them..) As for writing zeros at the end of the cert file if the new cert is smaller: it's not realy nesessary because in that case the index and offset are added to the EF's path in the CDF; but it's just nicer not to have part of the old cert left in the file, IMHO. Cheers, Stef -----Original Message----- From: Nils Larsch [mailto:[hidden email]] Sent: donderdag 15 september 2005 13:18 To: Stef Hoeben Cc: [hidden email] Subject: Re: [opensc-devel] pkcs15init: add update_cert functionality Stef Hoeben wrote: > Hi, > > here a patch that allows to update a cert (while leaving the private > key intact, very usefull for expired certs). > > If the new cert is not bigger that the old one, the same file is used; > otherwise the file is deleted and a new one with the same file ID is > made. > > Comments/questions? as you wish ;-) > +int > +sc_pkcs15init_update_certificate(sc_pkcs15_card_t *p15card, ... > + /* Fill the remaining space in the EF (if any) with zeros */ > + if (certlen < file->size) { > + unsigned char *tmp = (unsigned char *) calloc(file->size - certlen, 1); > + if (tmp == NULL) { > + r = SC_ERROR_OUT_OF_MEMORY; > + goto done; > + } > + r = sc_update_binary(p15card->card, certlen, tmp, file->size - certlen, 0); > + free(tmp); > + } why ? > Index: tools/pkcs15-init.c > =================================================================== ... > +static int > +do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, > + const char *filename, const char *format, sc_pkcs15_der_t > +*newcert_raw) { > + X509 *oldcert, *newcert; > + EVP_PKEY *oldpk, *newpk; > + BIO *bio = NULL; > + int r; > + > + /* Get the public key from the old cert */ > + bio = BIO_new_mem_buf(sc_oldcert->data, sc_oldcert->data_len); > + if (bio == NULL) > + return SC_ERROR_INTERNAL; > + oldcert = d2i_X509_bio(bio, NULL); > + BIO_free(bio); isn't this the same as u8 *ptr = sc_oldcert->data; oldcert = d2i_X509(NULL, &ptr, sc_oldcert->data_len); just without using a BIO ? > + if (oldcert == NULL) > + return SC_ERROR_INTERNAL; > + oldpk = X509_get_pubkey(oldcert); > + > + /* Read the new cert from file and get it's public key */ > + r = do_read_certificate(filename, format, &newcert); > + if (r < 0) { > + X509_free(oldcert); > + return r; > + } > + newpk = X509_get_pubkey(newcert); > + > + /* Compare the public keys, there's no high level openssl function > +for this(?) */ what about "int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *)" ? > + r = SC_ERROR_INVALID_ARGUMENTS; > + if (oldpk->type == newpk->type) > + { > + if ((oldpk->type == EVP_PKEY_DSA) && > + !BN_cmp(oldpk->pkey.dsa->p, newpk->pkey.dsa->p) && > + !BN_cmp(oldpk->pkey.dsa->q, newpk->pkey.dsa->q) && > + !BN_cmp(oldpk->pkey.dsa->g, newpk->pkey.dsa->g)) > + r = 0; > + else if ((oldpk->type == EVP_PKEY_RSA) && > + !BN_cmp(oldpk->pkey.rsa->n, newpk->pkey.rsa->n) && > + !BN_cmp(oldpk->pkey.rsa->e, newpk->pkey.rsa->e)) > + r = 0; > + } > + > + X509_free(oldcert); > + > + if (r == 0) > + r = do_convert_cert(newcert_raw, newcert); > + else > + error("the public keys in the old and new certificate > + > + X509_free(newcert); as X509_get_pubkey should increase the reference counter of the EVP_PKEY object newpk you must free it with EVP_PKEY_free (mutatis mutandis for oldpk). Cheers, Nils _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Stef Hoeben-2
On Sep 15, 2005, at 5:10 AM, Stef Hoeben wrote: > Hi, > > here a patch that allows to update a cert (while leaving the private > key > intact, > very usefull for expired certs). Be careful! In the S/MIME protocols, certificates are identified by issuer and serial number. What this means is that if a message was encrypted in the past using the old, expired certificate, then deleting that certificate and replacing it with a new one will prevent mail agents from being able to locate the key and decrypt the message. Even if the new certificate has the same public key. This is really a documentation/usage problem, but methinks it says something about what default behavior should be. Eric Norman University of WIsconsin _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Stef Hoeben-2
Hm, nasty issue indeed...
What could be done is to re-update again with the old cert if mails need to be recovered (people should have a backup of their encryption keys anyway), but I'll add a warning in the usage info... Thx, Stef -----Original Message----- From: Eric Norman [mailto:[hidden email]] Sent: donderdag 15 september 2005 16:53 To: OpenSC List Subject: Re: [opensc-devel] pkcs15init: add update_cert functionality On Sep 15, 2005, at 5:10 AM, Stef Hoeben wrote: > Hi, > > here a patch that allows to update a cert (while leaving the private > key > intact, > very usefull for expired certs). Be careful! In the S/MIME protocols, certificates are identified by issuer and serial number. What this means is that if a message was encrypted in the past using the old, expired certificate, then deleting that certificate and replacing it with a new one will prevent mail agents from being able to locate the key and decrypt the message. Even if the new certificate has the same public key. This is really a documentation/usage problem, but methinks it says something about what default behavior should be. Eric Norman University of WIsconsin _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Stef Hoeben-2
Hi Nils,
can't find an EVP_PKEY_cmp() in my openssl-0.9.7d, only an EVP_PKEY_cmp_parameters() which only works for DSA? Looks like it's been added only in 0.9.8, which raises the question if it's not too recent? Cheers, Stef -----Original Message----- From: Nils Larsch [mailto:[hidden email]] Sent: donderdag 15 september 2005 13:18 To: Stef Hoeben Cc: [hidden email] Subject: Re: [opensc-devel] pkcs15init: add update_cert functionality > + if (oldcert == NULL) > + return SC_ERROR_INTERNAL; > + oldpk = X509_get_pubkey(oldcert); > + > + /* Read the new cert from file and get it's public key */ > + r = do_read_certificate(filename, format, &newcert); > + if (r < 0) { > + X509_free(oldcert); > + return r; > + } > + newpk = X509_get_pubkey(newcert); > + > + /* Compare the public keys, there's no high level openssl function > +for this(?) */ what about "int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *)" ? _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
Stef Hoeben wrote:
> Hi Nils, > > can't find an EVP_PKEY_cmp() in my openssl-0.9.7d, only an > EVP_PKEY_cmp_parameters() which only works for DSA? > > Looks like it's been added only in 0.9.8, which raises the > question if it's not too recent? ops, sorry. You are right is has been recently added in 0.9.8 and above => it's definitly too recent. What about letting configure finding out whether this function exists or not and if not use a local function ? Cheers, Nils _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Eric Norman
Eric Norman wrote:
> > On Sep 15, 2005, at 5:10 AM, Stef Hoeben wrote: > >> Hi, >> >> here a patch that allows to update a cert (while leaving the private key >> intact, >> very usefull for expired certs). > > > Be careful! In the S/MIME protocols, certificates are identified by issuer > and serial number. What this means is that if a message was encrypted > in the past using the old, expired certificate, then deleting that > certificate > and replacing it with a new one will prevent mail agents from being able > to locate the key and decrypt the message. Even if the new certificate > has the same public key. true, however due to the limited space on a smartcard you can't really store much expired certs on the token. As Stef already wrote the user should have a backup of the encryption key (+ certificate) anyway (for example to prevent data loss if the card suddenly dies) > > This is really a documentation/usage problem, but methinks it says > something about what default behavior should be. it's more a certificate management problem, but that's definitely something that should be put a card personalization guide ... Cheers, Nils _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Nils Larsch
Nils Larsch wrote:
> Stef Hoeben wrote: > >> Hi Nils, >> >> can't find an EVP_PKEY_cmp() in my openssl-0.9.7d, only an >> EVP_PKEY_cmp_parameters() which only works for DSA? >> >> Looks like it's been added only in 0.9.8, which raises the >> question if it's not too recent? > > > ops, sorry. You are right is has been recently added in 0.9.8 > and above => it's definitly too recent. What about letting configure > finding out whether this function exists or not and if not > use a local function ? Okay, I already checked all in using the local function; will try tomorrow to add the pkginfo things. Cheers, Stef _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
In reply to this post by Nils Larsch
Hi Nils,
attached is a patch to do it; but not tested with openssl 0.8.0, it's a bit overkill IMHO... Cheers, Stef Nils Larsch wrote: > Stef Hoeben wrote: > >> Hi Nils, >> >> can't find an EVP_PKEY_cmp() in my openssl-0.9.7d, only an >> EVP_PKEY_cmp_parameters() which only works for DSA? >> >> Looks like it's been added only in 0.9.8, which raises the >> question if it's not too recent? > > > ops, sorry. You are right is has been recently added in 0.9.8 > and above => it's definitly too recent. What about letting configure > finding out whether this function exists or not and if not > use a local function ? > > Cheers, > Nils > Index: configure.in =================================================================== --- configure.in (revision 2595) +++ configure.in (working copy) @@ -216,6 +216,22 @@ AM_CONDITIONAL(HAVE_OPENSSL, test "x$OPENSSL_MSG" = "xyes") +saved_LIBS="$LIBS" +saved_CFLAGS="$CFLAGS" +if test "OPENSSL_MSG" = "xyes"; then + CFLAGS="${OPENSSL_CFLAGS} $saved_CFLAGS" + LIBS="OPENSSL_LIBS $saved_LIBS" + AC_TRY_LINK([ +#include <openssl/evp.h> + ], [ +EVP_PKEY_cmp(NULL, NULL); + ], [ + AC_DEFINE(HAVE_OPENSSL_NEW, 1, [openssl version with EVP_PKEY_cmp()]) + ]) +fi +LIBS="$saved_LIBS" +CFLAGS="$saved_CFLAGS" + case "$host" in *-*-darwin*) if test -z "$PCSC_LIBS" -a -z "$PCSC_LIBS" Index: src/tools/pkcs15-init.c =================================================================== --- src/tools/pkcs15-init.c (revision 2595) +++ src/tools/pkcs15-init.c (working copy) @@ -941,6 +941,9 @@ newpk = X509_get_pubkey(newcert); /* Compare the public keys, there's no high level openssl function for this(?) */ +#ifdef HAVE_OPENSSL_NEW + r = EVP_PKEY_cmp(oldpk, newpk) == 0 ? 0 : SC_ERROR_INVALID_ARGUMENTS; +#else r = SC_ERROR_INVALID_ARGUMENTS; if (oldpk->type == newpk->type) { @@ -954,7 +957,7 @@ !BN_cmp(oldpk->pkey.rsa->e, newpk->pkey.rsa->e)) r = 0; } - +#endif EVP_PKEY_free(newpk); EVP_PKEY_free(oldpk); X509_free(oldcert); _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
Stef Hoeben wrote:
> Hi Nils, > > attached is a patch to do it; but not tested with openssl 0.8.0, > it's a bit overkill IMHO... agree, currently that shouldn't be necessary. Attached is a somewhat experimental patch that doesn't use EVP_PKEY at all, but that's not really important. Cheers, Nils Index: src/tools/pkcs15-init.c =================================================================== --- src/tools/pkcs15-init.c (Revision 2596) +++ src/tools/pkcs15-init.c (Arbeitskopie) @@ -919,7 +919,7 @@ const char *filename, const char *format, sc_pkcs15_der_t *newcert_raw) { X509 *oldcert, *newcert; - EVP_PKEY *oldpk, *newpk; + X509_PUBKEY *k1, *k2; u8 *ptr; int r; @@ -937,26 +937,15 @@ return r; } - oldpk = X509_get_pubkey(oldcert); - newpk = X509_get_pubkey(newcert); - /* Compare the public keys, there's no high level openssl function for this(?) */ r = SC_ERROR_INVALID_ARGUMENTS; - if (oldpk->type == newpk->type) - { - if ((oldpk->type == EVP_PKEY_DSA) && - !BN_cmp(oldpk->pkey.dsa->p, newpk->pkey.dsa->p) && - !BN_cmp(oldpk->pkey.dsa->q, newpk->pkey.dsa->q) && - !BN_cmp(oldpk->pkey.dsa->g, newpk->pkey.dsa->g)) - r = 0; - else if ((oldpk->type == EVP_PKEY_RSA) && - !BN_cmp(oldpk->pkey.rsa->n, newpk->pkey.rsa->n) && - !BN_cmp(oldpk->pkey.rsa->e, newpk->pkey.rsa->e)) - r = 0; - } - EVP_PKEY_free(newpk); - EVP_PKEY_free(oldpk); + k1 = X509_get_X509_PUBKEY(oldcert); + k2 = X509_get_X509_PUBKEY(newcert); + if (OBJ_obj2nid(k1->algor->algorithm) == OBJ_obj2nid(k2->algor->algorithm) && + !M_ASN1_BIT_STRING_cmp(k1->public_key, k2->public_key)) + r = 0; + X509_free(oldcert); if (r == 0) @@ -980,7 +969,6 @@ sc_pkcs15_object_t *obj; sc_pkcs15_cert_info_t *certinfo; sc_pkcs15_cert_t *oldcert = NULL; - X509 *newcert = NULL; sc_pkcs15_der_t newcert_raw; int r; _______________________________________________ opensc-devel mailing list [hidden email] http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel |
Free forum by Nabble | Edit this page |