svn rev #24355: branches/nss/src/lib/crypto/nss/enc_provider/
ghudson@MIT.EDU
ghudson at MIT.EDU
Sun Sep 26 19:35:05 EDT 2010
http://src.mit.edu/fisheye/changelog/krb5/?cs=24355
Commit By: ghudson
Log Message:
When using stream ciphers with NSS, use a loopback pointer instead of
a bogus length to detect copying, and remember the pid to detect use
across fork.
Changed Files:
U branches/nss/src/lib/crypto/nss/enc_provider/enc_gen.c
Modified: branches/nss/src/lib/crypto/nss/enc_provider/enc_gen.c
===================================================================
--- branches/nss/src/lib/crypto/nss/enc_provider/enc_gen.c 2010-09-25 21:48:56 UTC (rev 24354)
+++ branches/nss/src/lib/crypto/nss/enc_provider/enc_gen.c 2010-09-26 23:35:05 UTC (rev 24355)
@@ -53,6 +53,12 @@
static pid_t k5_nss_pid = 0;
static k5_mutex_t k5_nss_lock = K5_MUTEX_PARTIAL_INITIALIZER;
+struct stream_state {
+ struct stream_state *loopback; /* To detect copying */
+ pid_t pid; /* To detect use across fork */
+ PK11Context *ctx;
+};
+
krb5_error_code
k5_nss_map_error(int nss_error)
{
@@ -265,16 +271,27 @@
krb5_error_code
k5_nss_stream_init_state(krb5_data *new_state)
{
- new_state->data = NULL;
- new_state->length = 0;
+ struct stream_state *sstate;
+
+ /* Create a state structure with an uninitialized context. */
+ sstate = calloc(1, sizeof(*sstate));
+ if (sstate == NULL)
+ return ENOMEM;
+ sstate->loopback = NULL;
+ new_state->data = (char *) sstate;
+ new_state->length = sizeof(*sstate);
return 0;
}
krb5_error_code
k5_nss_stream_free_state(krb5_data *state)
{
- if (state->length == (unsigned)-1 && state->data)
- PK11_Finalize((PK11Context *)state->data);
+ struct stream_state *sstate = (struct stream_state *) state->data;
+
+ /* Clean up the OpenSSL context if it was initialized. */
+ if (sstate && sstate->loopback == sstate)
+ PK11_Finalize(sstate->ctx);
+ free(sstate);
return 0;
}
@@ -288,25 +305,30 @@
SECStatus rv;
SECItem param;
krb5_crypto_iov *iov;
+ struct stream_state *sstate = NULL;
int i;
param.data = NULL;
param.len = 0;
- if (state && state->data) {
- ctx = (PK11Context *)state->data;
- } else {
+ sstate = (state == NULL) ? NULL : (struct stream_state *) state->data;
+ if (sstate == NULL || sstate->loopback == NULL) {
ctx = k5_nss_create_context(krb_key, mech, operation, ¶m);
- if (state && ctx) {
- state->data = (char *)ctx;
- state->length = -1; /* you don't get to copy this, */
- /* blow up if you try */
+ if (ctx == NULL) {
+ ret = k5_nss_map_last_error();
+ goto done;
}
+ if (sstate) {
+ sstate->loopback = sstate;
+ sstate->pid = getpid();
+ sstate->ctx = ctx;
+ }
+ } else {
+ /* Cipher state can't be copied or used across a fork. */
+ if (sstate->loopback != sstate || sstate->pid != getpid())
+ return EINVAL;
+ ctx = sstate->ctx;
}
- if (ctx == NULL) {
- ret = k5_nss_map_last_error();
- goto done;
- }
for (i=0; i < (int)num_data; i++) {
int return_length;
More information about the cvs-krb5
mailing list