On Sun, Nov 30, 2014 at 5:35 AM, Carsten Haitzler <[email protected]> wrote: > On Sun, 30 Nov 2014 13:03:19 +0900 Carsten Haitzler (The Rasterman) > <[email protected]> said: >> On Sun, 30 Nov 2014 04:07:10 +0100 Cedric BAIL <[email protected]> said: >> > I think this is a bad addition to eet as it is a useless API in any >> > kind of scenario where you want to use public crypto key. The good way >> > is to either check it against a root certificate with gnutls/openssl >> > or against a gnupg ring. Checking if it is the copy of an available >> > key is just going to push people to use a master private key to sign >> > data and go with that. Basically, it is pushing for bad practice and I >> > fail to see in which scenario it could be rightfully used. >> >> document eet_identity etc. then. :) it's pretty much not documented and i've >> figured out how to use it despite that. >> >> eet_identity_open() accepts 2 patchs to pem files (base64 encoded blobs of >> rsa/x509 etc. crypto stuff). it literally asks for a private key file. it >> literally asks for the certificate (public key). you set the identity of an >> eet file using the eet_key you get from this: eet_identity_set(). saving >> signs the file using your private key. the question is... you have these apis >> that accept these input files, but there is no way to VERIFY that something >> was signed with a given private key - eg this file says it came from cedric.. >> did it actually come from cedric?
You never check it was from cedric. You check that you know the root certificate part of the chain of trust used to sign a file. The root certificate can be provided by the system, or be specific to your application, or be part of a gpg key ring. Of course all of those method have some very different way to implement this security mechanism and mostly depend on the crypto library that you use. That's why you have eet_identity_x509 to get the associated x509 public key. You can't provide it at open time as it doesn't make sense. If the file is correctly signed it will open, then you can check it accordingly to the proper policy you choose. And no, ensuring that every public key of every developers is distributed is insane. It is impossible to have any kind of trust on the user side as he is not the one doing the compilation and signing. That why you do have a chain of trust which usually involve multiple level. Logically you have at least, the top root key, that is used to sign the currently used service key, that sign the developer master key who can finally sign is current key. This way you don't require developer to have their master key on their machine. Same for the server doing the signing that can know put the master root key on an offline media. Overall that pretty much basic security for any certificate use case. >> how do i ensure that - i need a copy of >> your public (certificate) file that i keep stored. i can get this via some >> separate mechanism that i might trust (or trust the whole thing if they come >> via different mechanisms). the only way to really check is to compare >> byte-for-byte if the certificates match. since the certificate files are >> base64 encoded lumps of ascii, it is left up to me to write my own decoder >> and then get the x509 data and compare them then. why should i be forced to >> write a decoder when another api seemingly does the decoding for me >> (eet_identity_open()). it leads to me writing excess code in my app that >> shouldn't be there as eet provides me no mechanism to check that a signature >> is actually the one i expect. At least, it's a good things you did it in eet, I can tell you it is wrong :-) >> anyone can generate an rsa keys they like via openssl - they can contain any >> metadata i like like name, address, organization, email etc - these are not >> valid ways to check a key is right. then how do you propose someone checks >> that a file that claims to come from cedric .. actually DID come from cedric? >> eet_identity_verify() does that .. assuming a copy of the certificate (public >> part of the key) was shared/saves/stored earlier. this allows it all to work >> without a 3rd party to rely on. That's why you need to approve every developers and sign their master key with a service key. > oh yeah... and isn't this what ssh does... with public key auth? i have never > heard of that being considered.... insecure. : ssh security has absolutely nothing in common with what you try to implement here. ssh is based on the fact that you know each end of the service and therefor you can check that their is no man in the middle attack. It doesn't protect you from you trying to connect on a rogue server that would try to arm your local computer ... and that you wouldn't even know why you connect to it. It is actually not exchanging a file... >> > On Fri, Nov 28, 2014 at 10:59 AM, Tom Hacohen <[email protected]> >> > wrote: >> > > Yay! \o/ >> > > >> > > On 28/11/14 08:54, Carsten Haitzler wrote: >> > >> raster pushed a commit to branch master. >> > >> >> > >> http://git.enlightenment.org/core/efl.git/commit/?id=8669ab8a98ac36db6c228bcc1bb4688c25d1dccc >> > >> >> > >> commit 8669ab8a98ac36db6c228bcc1bb4688c25d1dccc >> > >> Author: Carsten Haitzler (Rasterman) <[email protected]> >> > >> Date: Fri Nov 28 17:54:39 2014 +0900 >> > >> >> > >> eet - add new api to verify eet file against stored cert >> > >> >> > >> this api makes it far more obvious as to how to verify an eet file >> > >> via the eet identify mechanisms that use x509 certificates to sign >> > >> files. >> > >> this is consistent with the api used to generate the key for >> > >> sigining thus you can use the same certificate file to compare against >> > >> for identify. >> > >> >> > >> @feature >> > >> --- >> > >> src/lib/eet/Eet.h | 20 +++++++ >> > >> src/lib/eet/eet_lib.c | 148 >> > >> +++++++++++++++++++++++++++++++++++++++ >> > >> ++ +++++ src/tests/eet/eet_suite.c | 3 + >> > >> 3 files changed, 171 insertions(+) >> > >> >> > >> diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h >> > >> index b3451fa..de56b18 100644 >> > >> --- a/src/lib/eet/Eet.h >> > >> +++ b/src/lib/eet/Eet.h >> > >> @@ -2063,6 +2063,26 @@ eet_identity_print(Eet_Key *key, >> > >> FILE *out); >> > >> >> > >> /** >> > >> + * Compare the identify certificate of an eet file against a stored one >> > >> + * >> > >> + * @param ef The file handle to check the identify of >> > >> + * @param certificate_file The path to the certificate file >> > >> + * @return EINA_TRUE if the certificates match, otherwise EINA_FALSE; >> > >> + * >> > >> + * The @p ef file handle mus be valid, and a signed file, otherwise >> > >> + * checking will fail. The path to the certificate file must be a valid >> > >> + * file path to a 'pem' format file (the same used for siging with >> > >> + * eet_identity_open() as a certificate file). >> > >> + * >> > >> + * @warning You need to compile signature support in EET. >> > >> + * @since 1.13 >> > >> + * @ingroup Eet_Cipher_Group >> > >> + */ >> > >> +EAPI Eina_Bool >> > >> +eet_identity_verify(Eet_File *ef, >> > >> + const char *certificate_file); >> > >> + >> > >> +/** >> > >> * Get the x509 der certificate associated with an Eet_File. Will >> > >> return NULL >> > >> * if the file is not signed. >> > >> * >> > >> diff --git a/src/lib/eet/eet_lib.c b/src/lib/eet/eet_lib.c >> > >> index daa6d3b..ed610f6 100644 >> > >> --- a/src/lib/eet/eet_lib.c >> > >> +++ b/src/lib/eet/eet_lib.c >> > >> @@ -1676,6 +1676,154 @@ eet_mode_get(Eet_File *ef) >> > >> return ef->mode; >> > >> } >> > >> >> > >> +static const char *_b64_table = >> > >> + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; >> > >> + >> > >> +static Eina_Bool >> > >> +_b64_is(char c) >> > >> +{ >> > >> + const char *p; >> > >> + >> > >> + if (!c) return EINA_FALSE; >> > >> + p = strchr(_b64_table, c); >> > >> + if (p >= _b64_table) return EINA_TRUE; >> > >> + return EINA_FALSE; >> > >> +} >> > >> + >> > >> +static unsigned char >> > >> +_b64_val(char c) >> > >> +{ >> > >> + const char *p = strchr(_b64_table, c); >> > >> + if (p) return p - _b64_table; >> > >> + return 0; >> > >> +} >> > >> + >> > >> +static int >> > >> +_b64_dec(unsigned char *dst, const char *src, int len) >> > >> +{ >> > >> + unsigned char *p = dst; >> > >> + *dst = 0; >> > >> + >> > >> + if (!*src) return 0; >> > >> + do >> > >> + { >> > >> + unsigned char a = _b64_val(src[0]); >> > >> + unsigned char b = _b64_val(src[1]); >> > >> + unsigned char c = _b64_val(src[2]); >> > >> + unsigned char d = _b64_val(src[3]); >> > >> + >> > >> + *p++ = (a << 2) | (b >> 4); >> > >> + *p++ = (b << 4) | (c >> 2); >> > >> + *p++ = (c << 6) | d; >> > >> + >> > >> + if (!_b64_is(src[1])) >> > >> + { >> > >> + p -= 2; >> > >> + break; >> > >> + } >> > >> + else if (!_b64_is(src[2])) >> > >> + { >> > >> + p -= 2; >> > >> + break; >> > >> + } >> > >> + else if (!_b64_is(src[3])) >> > >> + { >> > >> + p--; >> > >> + break; >> > >> + } >> > >> + src += 4; >> > >> + while (*src && ((*src == 13) || (*src == 10))) src++; >> > >> + } >> > >> + while ((len -= 4)); >> > >> + *p = 0; >> > >> + return (int)(p - dst); >> > >> +} >> > >> + >> > >> +static unsigned char * >> > >> +_base64_dec(const char *file, int *size_ret) >> > >> +{ >> > >> + char buf[4096], *p, *end; >> > >> + unsigned char *data = NULL; >> > >> + Eina_Binbuf *binbuf; >> > >> + FILE *f; >> > >> + >> > >> + f = fopen(file, "rb"); >> > >> + if (!f) return NULL; >> > >> + binbuf = eina_binbuf_new(); >> > >> + if (!binbuf) >> > >> + { >> > >> + fclose(f); >> > >> + return NULL; >> > >> + } >> > >> + while (fgets(buf, sizeof(buf) - 1, f)) >> > >> + { >> > >> + buf[sizeof(buf) - 1] = 0; >> > >> + // check where first invalid char in a line is >> > >> + for (p = buf; *p; p++) >> > >> + { >> > >> + // this is the first invalid char >> > >> + if ((*p != '=') && (!_b64_is(*p))) break; >> > >> + } >> > >> + end = p; >> > >> + // go from line start to (but not including) first invalid char >> > >> + if (((end - buf) > 0) && (((end - buf) % 4) == 0)) >> > >> + { >> > >> + unsigned char *tmp = malloc((end - buf + 4) * 2); >> > >> + >> > >> + if (tmp) >> > >> + { >> > >> + int len = _b64_dec(tmp, buf, end - buf); >> > >> + char *str = malloc(end - buf + 1); >> > >> + strncpy(str, buf, end - buf); >> > >> + str[end - buf] = 0; >> > >> + free(str); >> > >> + eina_binbuf_append_length(binbuf, tmp, len); >> > >> + free(tmp); >> > >> + } >> > >> + } >> > >> + } >> > >> + fclose(f); >> > >> + // as long as data is less than a mb - we have a cert that is >> > >> possibly ok >> > >> + if (eina_binbuf_length_get(binbuf) < (1 * 1024 * 1024)) >> > >> + { >> > >> + *size_ret = eina_binbuf_length_get(binbuf); >> > >> + data = eina_binbuf_string_steal(binbuf); >> > >> + } >> > >> + eina_binbuf_free(binbuf); >> > >> + return data; >> > >> +} >> > >> + >> > >> +EAPI Eina_Bool >> > >> +eet_identity_verify(Eet_File *ef, >> > >> + const char *certificate_file) >> > >> +{ >> > >> + unsigned char *cert; >> > >> + int cert_len; >> > >> + >> > >> + if (eet_check_pointer(ef)) >> > >> + return EINA_FALSE; >> > >> + >> > >> + if (!ef->x509_der) >> > >> + return EINA_FALSE; >> > >> + >> > >> + cert = _base64_dec(certificate_file, &cert_len); >> > >> + if (!cert) >> > >> + return EINA_FALSE; >> > >> + >> > >> + if (cert_len != ef->x509_length) >> > >> + { >> > >> + free(cert); >> > >> + return EINA_FALSE; >> > >> + } >> > >> + if (memcmp(ef->x509_der, cert, cert_len)) >> > >> + { >> > >> + free(cert); >> > >> + return EINA_FALSE; >> > >> + } >> > >> + free(cert); >> > >> + return EINA_TRUE; >> > >> +} >> > >> + >> > >> EAPI const void * >> > >> eet_identity_x509(Eet_File *ef, >> > >> int *der_length) >> > >> diff --git a/src/tests/eet/eet_suite.c b/src/tests/eet/eet_suite.c >> > >> index 7baabe6..a028d64 100644 >> > >> --- a/src/tests/eet/eet_suite.c >> > >> +++ b/src/tests/eet/eet_suite.c >> > >> @@ -1752,6 +1752,9 @@ START_TEST(eet_identity_simple) >> > >> ef = eet_open(file, EET_FILE_MODE_READ); >> > >> fail_if(!ef); >> > >> >> > >> + /* check that the certificates match */ >> > >> + fail_if(!eet_identity_verify(ef, _cert_pem)); >> > >> + >> > >> test = eet_read(ef, "keys/tests", &size); >> > >> fail_if(!test); >> > >> fail_if(size != (int)strlen(buffer) + 1); >> > >> >> > > >> > > >> > > >> > > >> > > ------------------------------------------------------------------------------ >> > > Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server >> > > from Actuate! Instantly Supercharge Your Business Reports and Dashboards >> > > with Interactivity, Sharing, Native Excel Exports, App Integration & more >> > > Get technology previously reserved for billion-dollar corporations, FREE >> > > http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk >> > > _______________________________________________ >> > > enlightenment-devel mailing list >> > > [email protected] >> > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel >> > > >> > >> > >> > >> > -- >> > Cedric BAIL >> > >> > ------------------------------------------------------------------------------ >> > Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server >> > from Actuate! Instantly Supercharge Your Business Reports and Dashboards >> > with Interactivity, Sharing, Native Excel Exports, App Integration & more >> > Get technology previously reserved for billion-dollar corporations, FREE >> > http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk >> > _______________________________________________ >> > enlightenment-devel mailing list >> > [email protected] >> > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel >> > >> >> >> -- >> ------------- Codito, ergo sum - "I code, therefore I am" -------------- >> The Rasterman (Carsten Haitzler) [email protected] >> >> >> ------------------------------------------------------------------------------ >> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server >> from Actuate! Instantly Supercharge Your Business Reports and Dashboards >> with Interactivity, Sharing, Native Excel Exports, App Integration & more >> Get technology previously reserved for billion-dollar corporations, FREE >> http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk >> _______________________________________________ >> enlightenment-devel mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel >> > > > -- > ------------- Codito, ergo sum - "I code, therefore I am" -------------- > The Rasterman (Carsten Haitzler) [email protected] > > -- Cedric BAIL ------------------------------------------------------------------------------ Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server from Actuate! Instantly Supercharge Your Business Reports and Dashboards with Interactivity, Sharing, Native Excel Exports, App Integration & more Get technology previously reserved for billion-dollar corporations, FREE http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
