void pluto_do_crypto_op(struct pluto_crypto_req *r) { switch(r->pcr_type) { case pcr_build_kenonce: calc_ke(r); calc_nonce(r); break; case pcr_build_nonce: calc_nonce(r); break; case pcr_compute_dh_iv: calc_dh_iv(r); break; case pcr_compute_dh: calc_dh(r); break; case pcr_compute_dh_v2: calc_dh_v2(r); break; case pcr_rsa_sign: case pcr_rsa_check: case pcr_x509cert_fetch: case pcr_x509crl_fetch: break; } }
void pluto_do_crypto_op(struct pluto_crypto_req *r, int helpernum) { DBG(DBG_CONTROL , DBG_log("helper %d doing %s op id: %u" , helpernum , enum_show(&pluto_cryptoop_names, r->pcr_type) , r->pcr_id)); #else void pluto_do_crypto_op(struct pluto_crypto_req *r) { DBG(DBG_CONTROL , DBG_log("helper %d doing %s op id: %u" , pc_helper_num , enum_show(&pluto_cryptoop_names, r->pcr_type) , r->pcr_id)); #endif #ifdef DEBUG { char *d = getenv("PLUTO_CRYPTO_HELPER_DELAY"); if(d != NULL) { int delay=atoi(d); DBG_log("helper is pausing for %d seconds", delay); sleep(delay); } } #endif /* now we have the entire request in the buffer, process it */ switch(r->pcr_type) { case pcr_build_kenonce: calc_ke(r); calc_nonce(r); break; case pcr_build_nonce: calc_nonce(r); break; case pcr_compute_dh_iv: calc_dh_iv(r); break; case pcr_compute_dh: calc_dh(r); break; case pcr_compute_dh_v2: calc_dh_v2(r); break; case pcr_rsa_sign: case pcr_rsa_check: case pcr_x509cert_fetch: case pcr_x509crl_fetch: break; } }
/* * Create {WWW,Proxy}-Authenticate header field */ static inline char *build_auth_hf(int _retries, int _stale, str* _realm, int* _len, int _qop, char* _hf_name) { int hf_name_len; char *hf, *p; /* length calculation */ *_len=hf_name_len=strlen(_hf_name); *_len+=DIGEST_REALM_LEN +_realm->len +DIGEST_NONCE_LEN +NONCE_LEN +1 /* '"' */ +((_qop)? QOP_PARAM_LEN:0) +((_stale)? STALE_PARAM_LEN : 0) #ifdef _PRINT_MD5 +DIGEST_MD5_LEN #endif +CRLF_LEN ; p=hf=pkg_malloc(*_len+1); if (!hf) { LOG(L_ERR, "ERROR: build_auth_hf: no memory\n"); *_len=0; return 0; } memcpy(p, _hf_name, hf_name_len); p+=hf_name_len; memcpy(p, DIGEST_REALM, DIGEST_REALM_LEN);p+=DIGEST_REALM_LEN; memcpy(p, _realm->s, _realm->len);p+=_realm->len; memcpy(p, DIGEST_NONCE, DIGEST_NONCE_LEN);p+=DIGEST_NONCE_LEN; calc_nonce(p, time(0) + nonce_expire, &secret); p+=NONCE_LEN; *p='"';p++; if (_qop) { memcpy(p, QOP_PARAM, QOP_PARAM_LEN); p+=QOP_PARAM_LEN; } if (_stale) { memcpy(p, STALE_PARAM, STALE_PARAM_LEN); p+=STALE_PARAM_LEN; } #ifdef _PRINT_MD5 memcpy(p, DIGEST_MD5, DIGEST_MD5_LEN ); p+=DIGEST_MD5_LEN; #endif memcpy(p, CRLF, CRLF_LEN ); p+=CRLF_LEN; *p=0; /* zero terminator, just in case */ DBG("build_auth_hf(): '%s'\n", hf); return hf; }
static void pluto_do_crypto_op(struct pluto_crypto_req *r, int helpernum) { struct timeval tv0; gettimeofday(&tv0, NULL); const char *story = NULL; DBG(DBG_CONTROL, DBG_log("crypto helper %d doing %s; request ID %u", helpernum, enum_show(&pluto_cryptoop_names, r->pcr_type), r->pcr_id)); if (crypto_helper_delay > 0) { DBG_log("crypto helper is pausing for %u seconds", crypto_helper_delay); sleep(crypto_helper_delay); } /* now we have the entire request in the buffer, process it */ switch (r->pcr_type) { case pcr_build_ke_and_nonce: calc_ke(r); /* FALL THROUGH */ case pcr_build_nonce: calc_nonce(r); break; case pcr_compute_dh_iv: calc_dh_iv(r); break; case pcr_compute_dh: calc_dh(r); break; case pcr_compute_dh_v2: calc_dh_v2(r, &story); break; } DBG(DBG_CONTROL, { struct timeval tv1; unsigned long tv_diff; gettimeofday(&tv1, NULL); tv_diff = (tv1.tv_sec - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec); DBG_log("crypto helper %d finished %s%s; request ID %u time elapsed %ld usec", helpernum, enum_show(&pluto_cryptoop_names, r->pcr_type), (story != NULL) ? story : "", r->pcr_id, tv_diff)); } }
/* * Create {WWW,Proxy}-Authenticate header field */ static inline char *build_auth_hf(int _retries, int _stale, str* _realm, int* _len, int _qop, char* _hf_name) { int hf_name_len; char *hf, *p; int index = 0; if(!disable_nonce_check) { /* get the nonce index and mark it as used */ index= reserve_nonce_index(); if(index == -1) { LM_ERR("no more nonces can be generated\n"); return 0; } LM_DBG("nonce index= %d\n", index); } /* length calculation */ *_len=hf_name_len=strlen(_hf_name); *_len+=DIGEST_REALM_LEN +_realm->len +DIGEST_NONCE_LEN +((!disable_nonce_check)?NONCE_LEN:NONCE_LEN-8) +1 /* '"' */ +((_qop)? QOP_PARAM_LEN:0) +((_stale)? STALE_PARAM_LEN : 0) #ifdef _PRINT_MD5 +DIGEST_MD5_LEN #endif +CRLF_LEN ; p=hf=pkg_malloc(*_len+1); if (!hf) { LM_ERR("no pkg memory left\n"); *_len=0; return 0; } memcpy(p, _hf_name, hf_name_len); p+=hf_name_len; memcpy(p, DIGEST_REALM, DIGEST_REALM_LEN);p+=DIGEST_REALM_LEN; memcpy(p, _realm->s, _realm->len);p+=_realm->len; memcpy(p, DIGEST_NONCE, DIGEST_NONCE_LEN);p+=DIGEST_NONCE_LEN; calc_nonce(p, time(0) + nonce_expire, index, &secret); p+=((!disable_nonce_check)?NONCE_LEN:NONCE_LEN-8); *p='"';p++; if (_qop) { memcpy(p, QOP_PARAM, QOP_PARAM_LEN); p+=QOP_PARAM_LEN; } if (_stale) { memcpy(p, STALE_PARAM, STALE_PARAM_LEN); p+=STALE_PARAM_LEN; } #ifdef _PRINT_MD5 memcpy(p, DIGEST_MD5, DIGEST_MD5_LEN ); p+=DIGEST_MD5_LEN; #endif memcpy(p, CRLF, CRLF_LEN ); p+=CRLF_LEN; *p=0; /* zero terminator, just in case */ LM_DBG("'%s'\n", hf); return hf; }
/** * Create and return {WWW,Proxy}-Authenticate header field * @param nonce nonce value * @param algorithm algorithm value * @param qop qop value * @return -1 on error, 0 on success * * The result is stored in param ahf. * If nonce is not null that it is used, instead of call calc_nonce. * If algorithm is not null that it is used irrespective of _PRINT_MD5 * * Major usage of nonce and algorithm params is AKA authentication. */ int get_challenge_hf(struct sip_msg* msg, int stale, str* realm, str* nonce, str* algorithm, struct qp* qop, int hftype, str *ahf) { char *p; str* hfn, hf; int nonce_len, l, cfg; int t; #if defined USE_NC || defined USE_OT_NONCE unsigned int n_id; unsigned char pool; unsigned char pool_flags; #endif if(!ahf) { LM_ERR("invalid output parameter\n"); return -1; } if (realm) { DEBUG("build_challenge_hf: realm='%.*s'\n", realm->len, realm->s); } if (nonce) { DEBUG("build_challenge_hf: nonce='%.*s'\n", nonce->len, nonce->s); } if (algorithm) { DEBUG("build_challenge_hf: algorithm='%.*s'\n", algorithm->len, algorithm->s); } if (qop && qop->qop_parsed != QOP_UNSPEC) { DEBUG("build_challenge_hf: qop='%.*s'\n", qop->qop_str.len, qop->qop_str.s); } if (hftype == HDR_PROXYAUTH_T) { hfn = &proxy_challenge_header; } else { hfn = &www_challenge_header; } cfg = get_auth_checks(msg); nonce_len = get_nonce_len(cfg, nc_enabled || otn_enabled); hf.len = hfn->len; hf.len += DIGEST_REALM_LEN + realm->len + DIGEST_NONCE_LEN; if (nonce) { hf.len += nonce->len + 1; /* '"' */ } else { hf.len += nonce_len + 1; /* '"' */ } hf.len += ((stale) ? STALE_PARAM_LEN : 0); if (algorithm) { hf.len += DIGEST_ALGORITHM_LEN + algorithm->len; } else { hf.len += 0 #ifdef _PRINT_MD5 +DIGEST_MD5_LEN #endif ; } if (qop && qop->qop_parsed != QOP_UNSPEC) { hf.len += QOP_PARAM_START_LEN + qop->qop_str.len + QOP_PARAM_END_LEN; } hf.len += CRLF_LEN; p = hf.s = pkg_malloc(hf.len); if (!hf.s) { ERR("auth: No memory left (%d bytes)\n", hf.len); return -1; } memcpy(p, hfn->s, hfn->len); p += hfn->len; memcpy(p, DIGEST_REALM, DIGEST_REALM_LEN); p += DIGEST_REALM_LEN; memcpy(p, realm->s, realm->len); p += realm->len; memcpy(p, DIGEST_NONCE, DIGEST_NONCE_LEN); p += DIGEST_NONCE_LEN; if (nonce) { memcpy(p, nonce->s, nonce->len); p += nonce->len; } else { l=nonce_len; t=ser_time(0); #if defined USE_NC || defined USE_OT_NONCE if (nc_enabled || otn_enabled){ pool=nid_get_pool(); n_id=nid_inc(pool); pool_flags=0; #ifdef USE_NC if (nc_enabled){ nc_new(n_id, pool); pool_flags|= NF_VALID_NC_ID; } #endif #ifdef USE_OT_NONCE if (otn_enabled){ otn_new(n_id, pool); pool_flags|= NF_VALID_OT_ID; } #endif }else{ pool=0; pool_flags=0; n_id=0; } if (calc_nonce(p, &l, cfg, t, t + nonce_expire, n_id, pool | pool_flags, &secret1, &secret2, msg) != 0) #else /* USE_NC || USE_OT_NONCE*/ if (calc_nonce(p, &l, cfg, t, t + nonce_expire, &secret1, &secret2, msg) != 0) #endif /* USE_NC || USE_OT_NONCE */ { ERR("auth: calc_nonce failed (len %d, needed %d)\n", nonce_len, l); pkg_free(hf.s); return -1; } p += l; } *p = '"'; p++; if (qop && qop->qop_parsed != QOP_UNSPEC) { memcpy(p, QOP_PARAM_START, QOP_PARAM_START_LEN); p += QOP_PARAM_START_LEN; memcpy(p, qop->qop_str.s, qop->qop_str.len); p += qop->qop_str.len; memcpy(p, QOP_PARAM_END, QOP_PARAM_END_LEN); p += QOP_PARAM_END_LEN; } if (stale) { memcpy(p, STALE_PARAM, STALE_PARAM_LEN); p += STALE_PARAM_LEN; } if (algorithm) { memcpy(p, DIGEST_ALGORITHM, DIGEST_ALGORITHM_LEN); p += DIGEST_ALGORITHM_LEN; memcpy(p, algorithm->s, algorithm->len); p += algorithm->len; } else { #ifdef _PRINT_MD5 memcpy(p, DIGEST_MD5, DIGEST_MD5_LEN ); p += DIGEST_MD5_LEN; #endif } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; hf.len=(int)(p-hf.s); /* fix len, it might be smaller due to a smaller nonce */ DBG("auth: '%.*s'\n", hf.len, ZSW(hf.s)); *ahf = hf; return 0; }