On Wed, Oct 01, 2008 at 05:47:18PM +0200, Mark Phalan wrote: > On Mon, 2008-09-29 at 19:20 -0500, Will Fiveash wrote: > > On Thu, Aug 28, 2008 at 08:22:27PM +0200, Mark Phalan wrote: > > > > > > > > > I've just uploaded a webrev of my resync/pkinit workspace. There still > > > needs to be some work on pkinit so don't expect the code in > > > usr/src/lib/krb5/plugins/preauth/pkinit/ to be complete (you can ignore > > > it for now). I'll post another incremental webrev with any changes I > > > make to the pkinit code later on. The rest of the changes are resync > > > changes for MIT 1.6.3. The hg comment needs to be updated, I'll do that > > > once we get the pkinit PSARC case submitted. > > > > > > I've chunked the review up into four pieces as I expect the krb team to > > > do the review. > > > > > > Shawn: Chunk 1 > > > Peter: Chunk 2 > > > Glenn: Chunk 3 > > > Will: Chunk 4 > > > > > > I'd like to have this completed by 17th Sept. Let me know if thats a > > > problem for anyone. > > > > > > webrev here: > > > http://cr.opensolaris.org/~mbp/pkinit/ > > > > Have you run this code through the lint -errsecurity=standard security > > checks? > > <see http://secprog.sfbay.sun.com/lint/levels.html> > > No. I was relying on the standard ON lint checks. I'll re-run with > "-errsecurity=standard" for the new pkinit code. > > > > > Have you compiled with DEBUG defined to make sure the plugin still > > works? > > DEBUG works with the latest version of pkinit code (see below). > > > > > ======================================================================================= > > Chunk 4 code review: > > > > In usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c > > Thanks for reviewing this file - unfortunately there are going to be > more changes to this file which will be need to be reviewed later. I did > mention above: > > "There still needs to be some work on pkinit so don't expect the code in > usr/src/lib/krb5/plugins/preauth/pkinit/ to be complete (you can ignore > it for now). I'll post another incremental webrev with any changes I > make to the pkinit code later on."
Got it. BTW, it would be nice if you would provide a path/URI to your hg repos that I could pull from so I could generate a cscope DB to assist my code review. > > static int pkinit_oids_refs = 0; > > > > and > > > > pkinit_init_pkinit_oids(): > > > > pkinit_oids_refs++; > > > > and > > > > pkinit_fini_pkinit_oids(): > > /* Only call OBJ_cleanup once! */ > > if (--pkinit_oids_refs == 0) > > OBJ_cleanup(); > > > > - Any thread safety issues here? > > Looks like it to me. Probably not an issue as krb5kdc/kinit/pam_krb5 are > not multithreaded applications. May be a problem if krb5kdc becomes > multithreaded. It would be good to add comments at these spots like: /* XXX Not thread safe! */ I also think that we should give back our mods to MIT. > > pkinit_init_req_crypto(): > > > > *cryptoctx = ctx; > > > > - Other funcs would test an output arg like cryptoctx for NULL and > > return EINVAL. This should too I guess. > > Agreed. Fixed. > > > > > out: > > if (retval) > > free(ctx); > > > > - In earlier funcs ctx was tested for NULL as a condition prior to > > calling free(). To be safe, that should happen here as well. > > I agree from a style point of view. However its valid to feed free() a > NULL and nothing bad will happen. > I'm leaving this as is to keep the delta smaller between MIT's and our > code. We can give back our changes yes? > > static krb5_error_code > > pkinit_init_certs(pkinit_identity_crypto_context ctx) > > { > > krb5_error_code retval = ENOMEM; > > int i; > > > > for (i = 0; i < MAX_CREDS_ALLOWED; i++) > > ctx->creds[i] = NULL; > > ctx->my_certs = NULL; > > ctx->cert_index = 0; > > ctx->my_key = NULL; > > ctx->trustedCAs = NULL; > > ctx->intermediateCAs = NULL; > > ctx->revoked = NULL; > > > > retval = 0; > > return retval; > > } > > > > - The retval assignments are unnecessary (just return 0). > > > > Agreed but leaving as they do no harm (and source code differences > matter more...). > > > cms_signeddata_create(): > > > > /* start creating PKCS7 data */ > > if ((p7 = PKCS7_new()) == NULL) > > > > - Are allocation functions like PKCS7_new() allocating zero'ed out > > structs? If not, do you think they should? > > In this case I believe that PKCS7_new will allocate and initialize a > structure with sane values (0s mostly)- i.e. the structure won't have > garbage for values after this call. > > > > > *signed_data_len = i2d_PKCS7(p7, NULL); > > > > - Again, an instance of an output var. assignment without testing for > > NULL. This should be handled consistently one way or another. > > > > Agreed. I've added a check for NULL for both signed_data and > signed_data_len. > > > /* fill-in PKCS7_SIGNER_INFO */ > > if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL) > > goto cleanup; > > if (!ASN1_INTEGER_set(p7si->version, 1)) > > goto cleanup; > > if (!X509_NAME_set(&p7si->issuer_and_serial->issuer, > > X509_get_issuer_name(cert))) > > goto cleanup; > > > > - Opportunity for mem leaks in regards to the error path and p7si? > > > > Fixed. > > > cms_envelopeddata_create(): > > > > switch (pa_type) { > > case KRB5_PADATA_PK_AS_REQ: > > p7->d.enveloped->enc_data->content_type = > > OBJ_nid2obj(NID_pkcs7_signed); > > break; > > case KRB5_PADATA_PK_AS_REP_OLD: > > case KRB5_PADATA_PK_AS_REQ_OLD: > > p7->d.enveloped->enc_data->content_type = > > OBJ_nid2obj(NID_pkcs7_data); > > break; > > break; > > break; > > break; > > } > > > > - too breaky. > > > > Fixed. > > > > pkinit_create_td_dh_parameters(krb5_context context, > > pkinit_plg_crypto_context plg_cryptoctx, > > pkinit_req_crypto_context req_cryptoctx, > > pkinit_identity_crypto_context id_cryptoctx, > > pkinit_plg_opts *opts, > > krb5_data **out_data) > > { > > krb5_error_code retval = ENOMEM; > > unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0; > > unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL; > > krb5_typed_data **typed_data = NULL; > > krb5_data *data = NULL, *encoded_algId = NULL; > > krb5_algorithm_identifier **algId = NULL; > > > > if (opts->dh_min_bits > 4096) > > goto cleanup; > > > > - retval looks wrong in regards to the first goto there. In fact there > > are several functions in this file that have this problem. > > > > Fixed for pkinit_create_dt_dh_parameters(). > Which other functions have this issue? The instances are scattered throughout that file. > > crypto_check_cert_eku(): > > > > *valid_eku = 0; > > if (reqctx->received_cert == NULL) > > goto cleanup; > > > > - I don't think "*valid_eku = 0" should occur before the input is > > checked. The caller must check the return of crypto_check_cert_eku() > > before checking *valid_eku value. > > Agreed. Added a check for valid_eku != NULL. > > > > > pkinit_octetstring2key(): > > > > key_block->magic = 0; > > > > - Why not KV5M_KEYBLOCK? > > > > It should be I guess. > Fixed. If the value is supposed to be 0 then there should be a comment as to why. > > client_create_dh(): > > > > krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED; > > unsigned char *buf = NULL; > > int dh_err = 0; > > ASN1_INTEGER *pub_key = NULL; > > > > if (cryptoctx->dh == NULL) { > > if ((cryptoctx->dh = DH_new()) == NULL) > > goto cleanup; > > - Again retval doesn't seem right for first goto cleanup error path. > > > > Fixed. > > > DH_check(cryptoctx->dh, &dh_err); > > if (dh_err != 0) { > > pkiDebug("Warning: dh_check failed with %d\n", dh_err); > > if (dh_err & DH_CHECK_P_NOT_PRIME) > > pkiDebug("p value is not prime\n"); > > if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME) > > pkiDebug("p value is not a safe prime\n"); > > if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR) > > pkiDebug("unable to check the generator value\n"); > > if (dh_err & DH_NOT_SUITABLE_GENERATOR) > > pkiDebug("the g value is not a generator\n"); > > } > > > > - Why don't the errors above cause the function to goto cleanup? > > Because with the generated dh key here DH_check() always seems to > return DH_NOT_SUITABLE_GENERATOR for the client. I believe this isn't > actually a problem (see this thread: > http://www.mail-archive.com/openssl-users at openssl.org/msg46952.html) > > > If they are meaningless then why call DH_check()? > > I believe they are pretty much meaningless (but harmless) as the > values used to generate the DH key are ok. Then why do the check in the standard path? Why not bracket this with #ifdef DEBUG? > > client_process_dh(): > > > > if (der_decode_data(subjectPublicKey_data, > > (long)subjectPublicKey_length, > > &data, &data_len) != 0) { > > pkiDebug("failed to decode subjectPublicKey\n"); > > retval = -1; > > goto cleanup; > > } > > > > - Will a retval = -1 be interpreted/mapped correctly? > > > > In this case I don't think its a problem. If client_process_dh() > fails it will eventually return to krb5_do_preauth() with "module_ret" > set to -1. krb5_do_preauth just checks this value against 0. > It may however result in confusing debug error messages. > Changed to "KRB5_PREAUTH_FAILED". > > > if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL) > > goto cleanup; > > if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL) > > goto cleanup; > > > > - These don't look like KRB5KDC_ERR_PREAUTH_FAILED errors to me. > > > > Do you mean because they are returned to the client (not the KDC)? > Changed to KRB5_PREAUTH_FAILED. > > > server_process_dh(): > > > > if (!DH_generate_key(dh_server)) > > goto cleanup; > > > > - Seems like the real error may be lost here. > > > > Agreed. The OpenSSL Err_* functions could be used here to set the > error. Currently on the client side no error messages are printed > if things go wrong with preauth as there may be other preauth > plugins/methods that may succeed. There must be a better way of > doing things as it makes debugging pre-auth failures a PITA. Still, > I'm not sure I want to try and change this as part of this > integration. > > > > i2d_ASN1_INTEGER(pub_key, &p); > > > > - should have (void) cast. This occurs in other places as well. > > Fixed (as part of the lint fixes). > > > > > pkinit_open_session(): > > > > /* Init */ > > /* Solaris Kerberos XXX */ > > r = cctx->p11->C_Initialize(NULL); > > > > and > > if ((r = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION, > > NULL, NULL, &cctx->session)) != > > CKR_OK) > > > > - Be aware that pkcs11 session handles are not fork safe. Do you know > > whether the cctx will be used across a fork? See: > > 5102151 krb contexts are not fork safe > > for the krb bug relating to this issue. > > I'll investigate this further. > > Thanks for the review! > > I'll send an updated webrev out tomorrow or friday with the latest pkinit > plugin > code changes (and the above changes), until then please don't review anything > in the "plugins" dir. > > -M -- Will Fiveash Sun Microsystems Inc. http://opensolaris.org/os/project/kerberos/