/* * replaces try_RSA_signature_v2() */ err_t try_RSA_signature_v2(const u_char hash_val[MAX_DIGEST_LEN] , size_t hash_len , const pb_stream *sig_pbs, struct pubkey *kr , struct state *st) { const u_char *sig_val = sig_pbs->cur; size_t sig_len = pbs_left(sig_pbs); const struct RSA_public_key *k = &kr->u.rsa; if (k == NULL) return "1""no key available"; /* failure: no key to use */ /* decrypt the signature -- reversing RSA_sign_hash */ if (sig_len != k->k) { return "1""SIG length does not match public key length"; } err_t ugh = RSA_signature_verify_nss (k,hash_val,hash_len,sig_val,sig_len); if(ugh!=NULL) { return ugh; } unreference_key(&st->st_peer_pubkey); st->st_peer_pubkey = reference_key(kr); return NULL; }
static err_t try_RSA_signature_v2(const u_char hash_val[MAX_DIGEST_LEN] , size_t hash_len , const pb_stream *sig_pbs, struct pubkey *kr , struct state *st) { const u_char *sig_val = sig_pbs->cur; size_t sig_len = pbs_left(sig_pbs); u_char s[RSA_MAX_OCTETS]; /* for decrypted sig_val */ u_char *sig; const struct RSA_public_key *k = &kr->u.rsa; unsigned int padlen; if (k == NULL) return "1""no key available"; /* failure: no key to use */ /* decrypt the signature -- reversing RSA_sign_hash */ if (sig_len != k->k) { return "1""SIG length does not match public key length"; } /* actual exponentiation; see PKCS#1 v2.0 5.1 */ { chunk_t temp_s; MP_INT c; n_to_mpz(&c, sig_val, sig_len); oswcrypto.mod_exp(&c, &c, &k->e, &k->n); temp_s = mpz_to_n(&c, sig_len); /* back to octets */ memcpy(s, temp_s.ptr, sig_len); pfree(temp_s.ptr); mpz_clear(&c); } /* check signature contents */ /* verify padding */ padlen = sig_len - 3 - (hash_len+der_digestinfo_len); /* now check padding */ sig = s; if(sig[0] != 0x00 || sig[1] != 0x01 || sig[padlen+2] != 0x00) { return "2""SIG padding does not check out"; } /* skip padding */ sig += padlen+3; /* 2 verify that the has was done with SHA1 */ if(memcmp(der_digestinfo, sig, der_digestinfo_len)!=0) { return "SIG not performed with SHA1"; } sig += der_digestinfo_len; if(DBGP(DBG_CRYPT)) { DBG_dump("v2rsa decrypted SIG:", hash_val, hash_len); DBG_dump("v2rsa computed hash:", sig, hash_len); } if(memcmp(sig, hash_val, hash_len) != 0) { return "9""authentication failure: received SIG does not match computed HASH, but message is well-formed"; } unreference_key(&st->st_peer_pubkey); st->st_peer_pubkey = reference_key(kr); return NULL; }
/* here we are just freeing RAM */ void free_state(struct state *st) { delete_event(st); /* delete any pending timer event */ { struct msgid_list *p = st->st_used_msgids; while (p != NULL) { struct msgid_list *q = p; p = p->next; pfree(q); } } unreference_key(&st->st_peer_pubkey); free_sa(st->st_sadb); st->st_sadb=NULL; if (st->st_sec_in_use) { #ifdef HAVE_LIBNSS SECKEYPrivateKey *privk; SECKEYPublicKey *pubk; memcpy(&pubk,st->pubk.ptr,st->pubk.len); SECKEY_DestroyPublicKey(pubk); freeanychunk(st->pubk); memcpy(&privk,st->st_sec_chunk.ptr,st->st_sec_chunk.len); SECKEY_DestroyPrivateKey(privk); #else mpz_clear(&(st->st_sec)); #endif pfreeany(st->st_sec_chunk.ptr); } freeanychunk(st->st_firstpacket_me); freeanychunk(st->st_firstpacket_him); freeanychunk(st->st_tpacket); freeanychunk(st->st_rpacket); freeanychunk(st->st_p1isa); freeanychunk(st->st_gi); freeanychunk(st->st_gr); freeanychunk(st->st_shared); freeanychunk(st->st_ni); freeanychunk(st->st_nr); #ifdef HAVE_LIBNSS free_osw_nss_symkey(st->st_skeyid); free_osw_nss_symkey(st->st_skey_d); free_osw_nss_symkey(st->st_skey_ai); free_osw_nss_symkey(st->st_skey_ar); free_osw_nss_symkey(st->st_skey_ei); free_osw_nss_symkey(st->st_skey_er); free_osw_nss_symkey(st->st_skey_pi); free_osw_nss_symkey(st->st_skey_pr); free_osw_nss_symkey(st->st_enc_key); if(st->st_ah.our_keymat!=NULL) memset(st->st_ah.our_keymat, 0, st->st_ah.keymat_len); if(st->st_ah.peer_keymat!=NULL) memset(st->st_ah.peer_keymat, 0, st->st_ah.keymat_len); if(st->st_esp.our_keymat!=NULL) memset(st->st_esp.our_keymat, 0, st->st_esp.keymat_len); if(st->st_esp.peer_keymat!=NULL) memset(st->st_esp.peer_keymat, 0, st->st_esp.keymat_len); #endif freeanychunk(st->st_skeyid); freeanychunk(st->st_skey_d); freeanychunk(st->st_skey_ai); freeanychunk(st->st_skey_ar); freeanychunk(st->st_skey_ei); freeanychunk(st->st_skey_er); freeanychunk(st->st_skey_pi); freeanychunk(st->st_skey_pr); freeanychunk(st->st_enc_key); pfreeany(st->st_ah.our_keymat); pfreeany(st->st_ah.peer_keymat); pfreeany(st->st_esp.our_keymat); pfreeany(st->st_esp.peer_keymat); freeanychunk(st->st_xauth_password); #ifdef HAVE_LABELED_IPSEC pfreeany(st->sec_ctx); #endif pfree(st); }