bool Pluto_IsFIPS(void) { char fips_flag[1]; int n; FILE *fd=fopen("/proc/sys/crypto/fips_enabled","r"); if(fd!=NULL) { n = fread ((void *)fips_flag, 1, 1, fd); if(n==1) { if(fips_flag[0]=='1') { fclose(fd); return TRUE; } else { openswan_log("Non-fips mode set in /proc/sys/crypto/fips_enabled"); } } else { openswan_log("error in reading /proc/sys/crypto/fips_enabled, returning non-fips mode"); } fclose(fd); } else { openswan_log("Not able to open /proc/sys/crypto/fips_enabled, returning non-fips mode"); } return FALSE; }
void init_nat_traversal (bool activate, unsigned int keep_alive_period, bool fka, bool spf) { nat_traversal_enabled = activate; nat_traversal_support_non_ike = activate; #ifdef NAT_T_SUPPORT_LAST_DRAFTS nat_traversal_support_port_floating = activate ? spf : FALSE; openswan_log("Setting NAT-Traversal port-4500 floating to %s" , nat_traversal_support_port_floating ? "on" : "off"); openswan_log(" port floating activation criteria nat_t=%d/port_float=%d" , activate, spf); #endif { FILE *f = fopen("/proc/net/ipsec/natt", "r"); char n; if(f != NULL) { n=getc(f); if(n=='0') { nat_traversal_enabled = FALSE; nat_traversal_support_non_ike=FALSE; nat_traversal_support_port_floating=FALSE; openswan_log(" KLIPS does not have NAT-Traversal built in (see /proc/net/ipsec/natt)\n"); } fclose(f); } } _force_ka = fka; _kap = keep_alive_period ? keep_alive_period : DEFAULT_KEEP_ALIVE_PERIOD; plog(" NAT-Traversal support %s%s%s", activate ? " [enabled]" : " [disabled]", activate & fka ? " [Force KeepAlive]" : "", activate & !spf ? " [Port Floating disabled]" : ""); }
/* * Loads authority certificates */ void load_authcerts(const char *type, const char *path, u_char auth_flags) { struct dirent **filelist; char buf[ASN1_BUF_LEN]; char *save_dir; int n; /* change directory to specified path */ save_dir = getcwd(buf, ASN1_BUF_LEN); if (chdir(path)) { openswan_log("Could not change to directory '%s': %s", path, strerror(errno)); } else { DBG(DBG_CONTROL, DBG_log("Changed path to directory '%s'", path)); n = scandir(".", &filelist, (void *) file_select, alphasort); if (n < 0){ char buff[256]; strerror_r(errno, buff, 256 ); openswan_log(" scandir() ./ error: %s", buff); } else { while (n--) { cert_t cert; if (load_cert(CERT_NONE, filelist[n]->d_name, #ifdef SINGLE_CONF_DIR FALSE, /* too verbose in single conf dir */ #else TRUE, #endif type, &cert)) add_authcert(cert.u.x509, auth_flags); free(filelist[n]); } free(filelist); } /* restore directory path */ if(chdir(save_dir) != 0) { char buff[256]; strerror_r(errno, buff, 256 ); openswan_log(" chdir() ./ error: %s", buff); } } }
/* * initialize the helpers. * * Later we will have to make provisions for helpers that have hardware * underneath them, in which case, they may be able to accept many * more requests than average. * */ void init_crypto_helpers(int nhelpers) { int i; pc_workers = NULL; pc_workers_cnt = 0; pcw_id = 1; TAILQ_INIT(&backlog); /* find out how many CPUs there are, if nhelpers is -1 */ /* if nhelpers == 0, then we do all the work ourselves */ if(nhelpers == -1) { int ncpu_online; #if !(defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))) ncpu_online = sysconf(_SC_NPROCESSORS_ONLN); #else int mib[2], numcpu; size_t len; mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof(numcpu); ncpu_online = sysctl(mib, 2, &numcpu, &len, NULL, 0); #endif if(ncpu_online > 2) { nhelpers = ncpu_online - 1; } else { /* * if we have 2 CPUs or less, then create 1 helper, since * we still want to deal with head-of-queue problem. */ nhelpers = 1; } } if(nhelpers > 0) { openswan_log("starting up %d cryptographic helpers", nhelpers); pc_workers = alloc_bytes(sizeof(*pc_workers)*nhelpers , "pluto helpers"); pc_workers_cnt = nhelpers; for(i=0; i<nhelpers; i++) { init_crypto_helper(&pc_workers[i], i); } } else { openswan_log("no helpers will be started, all cryptographic operations will be done inline"); } pc_worker_num = 0; }
stf_status dpd_init(struct state *st) { /** * Used to store the 1st state */ struct state *p1st; /* find the related Phase 1 state */ p1st = find_state_ikev1(st->st_icookie, st->st_rcookie, &st->st_connection->spd.that.host_addr, 0); if (p1st == NULL) { loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD"); /* * if the phase 1 state has gone away, it really should have * deleted all of its children. * Why would this happen? because a quick mode SA can take * some time to create (DNS lookups for instance), and the phase 1 * might have been taken down for some reason in the meantime. * We really can not do anything here --- attempting to invoke * the DPD action would be a good idea, but we really should * do that outside this function. */ return STF_FAIL; } /* if it was enabled, and we haven't turned it on already */ if (p1st->hidden_variables.st_dpd) { time_t n = now(); openswan_log("Dead Peer Detection (RFC 3706): enabled"); if(st->st_dpd_event == NULL || (st->st_connection->dpd_delay + n) < st->st_dpd_event->ev_time) { delete_dpd_event(st); event_schedule(EVENT_DPD, st->st_connection->dpd_delay, st); } } else { openswan_log("Dead Peer Detection (RFC 3706): not enabled because peer did not advertise it"); } if(p1st != st) { /* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */ if(p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD) { delete_dpd_event(p1st); } } return STF_OK; }
void extra_debugging(const struct connection *c) { if(c == NULL) { reset_debugging(); return; } if (c!= NULL && c->extra_debugging != 0) { openswan_log("extra debugging enabled for connection: %s" , bitnamesof(debug_bit_names, c->extra_debugging & ~cur_debugging)); set_debugging(cur_debugging | c->extra_debugging); } /* * if any debugging is no, make sure that we log the connection * we are processing, because it may not be clear in later debugging. */ if(cur_debugging) { char b1[CONN_INST_BUF]; fmt_conn_instance(c, b1); DBG_log("processing connection %s%s" , c->name, b1); } }
void rekeyit() { struct state *st = NULL; struct pcr_kenonce *kn = &crypto_req->pcr_d.kn; fprintf(stderr, "now pretend that the keylife timer is up, and rekey the connection\n"); show_states_status(); timer_list(); st = state_with_serialno(2); /* capture the rekey message */ send_packet_setup_pcap("OUTPUT/rekeyikev2-I1.pcap"); if(st) { DBG(DBG_LIFECYCLE , openswan_log("replacing stale %s SA" , (IS_PHASE1(st->st_state)|| IS_PHASE15(st->st_state ))? "ISAKMP" : "IPsec")); ipsecdoi_replace(st, LEMPTY, LEMPTY, 1); } else { fprintf(stderr, "no state #2 found\n"); } passert(kn->oakley_group == tc14_oakleygroup); /* now fill in the KE values from a constant.. not calculated */ clonetowirechunk(&kn->thespace, kn->space, &kn->secret, tc14_secret,tc14_secret_len); clonetowirechunk(&kn->thespace, kn->space, &kn->n, tc14_ni, tc14_ni_len); /* maybe change nonce for rekey? */ clonetowirechunk(&kn->thespace, kn->space, &kn->gi, tc14_gi, tc14_gi_len); run_continuation(crypto_req); send_packet_close(); }
/* send the request, make sure it all goes down. */ static bool crypto_write_request(struct pluto_crypto_worker *w ,struct pluto_crypto_req *r) { unsigned char *wdat = (unsigned char *)r; int wlen = r->pcr_len; int cnt; DBG(DBG_CONTROL , DBG_log("asking helper %d to do %s op on seq: %u (len=%u, pcw_work=%d)" , w->pcw_helpernum , enum_show(&pluto_cryptoop_names, r->pcr_type) , r->pcr_id, (unsigned int)r->pcr_len, w->pcw_work+1)); do { errno=0; cnt = write(w->pcw_pipe, wdat, wlen); if(cnt <= 0) { openswan_log("write to helper failed: cnt=%d err=%s\n", cnt, strerror(errno)); return FALSE; } if(DBGP(DBG_CONTROL) || cnt != wlen) { DBG_log("crypto helper write of request: cnt=%d<wlen=%d. \n", cnt, wlen); } wlen -= cnt; wdat += cnt; } while(wlen > 0); return TRUE; }
/* Checks if the current certificate is revoked. It goes through the * list of revoked certificates of the corresponding crl. If the * certificate is found in the list, TRUE is returned */ bool x509_check_revocation(const x509crl_t *crl, chunk_t serial) { revokedCert_t *revokedCert = crl->revokedCertificates; char tbuf[TIMETOA_BUF]; DBG(DBG_X509, DBG_dump_chunk("serial number:", serial) ) while(revokedCert != NULL) { /* compare serial numbers */ if (revokedCert->userCertificate.len == serial.len && memcmp(revokedCert->userCertificate.ptr, serial.ptr, serial.len) == 0) { openswan_log("certificate was revoked on %s", timetoa(&revokedCert->revocationDate, TRUE, tbuf, sizeof(tbuf))); return TRUE; } revokedCert = revokedCert->next; } DBG(DBG_X509, DBG_log("certificate not revoked") ) return FALSE; }
static void netlink_shunt_expire(struct xfrm_userpolicy_info *pol) { const xfrm_address_t *srcx, *dstx; ip_address src, dst; unsigned family; unsigned transport_proto; err_t ugh = NULL; srcx = &pol->sel.saddr; dstx = &pol->sel.daddr; family = pol->sel.family; transport_proto = pol->sel.proto; if ((ugh = xfrm_to_ip_address(family, srcx, &src)) || (ugh = xfrm_to_ip_address(family, dstx, &dst))) { openswan_log("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh); return; } replace_bare_shunt(&src, &dst , BOTTOM_PRIO , SPI_PASS , FALSE , transport_proto , "delete expired bare shunt"); }
/* * we write out an empty record with the right WHACK magic. * this should permit a later mechanism to figure out the * endianess of the file, since we will get records from * other systems for analysis eventually. */ static bool openwhackrecordfile(char *file) { char when[256]; char FQDN[HOST_NAME_MAX + 1]; u_int32_t magic; struct tm tm1, *tm; time_t n; strcpy(FQDN, "unknown host"); gethostname(FQDN, sizeof(FQDN)); strncpy(whackrecordname, file, sizeof(whackrecordname)); whackrecordfile = fopen(whackrecordname, "w"); if(whackrecordfile==NULL) { openswan_log("Failed to open whack record file: '%s'\n" , whackrecordname); return FALSE; } time(&n); tm = localtime_r(&n, &tm1); strftime(when, sizeof(when), "%F %T", tm); fprintf(whackrecordfile, "#!-pluto-whack-file- recorded on %s on %s\n", FQDN, when); magic = WHACK_BASIC_MAGIC; writewhackrecord((char *)&magic, 4); DBG(DBG_CONTROL , DBG_log("started recording whack messages to %s\n" , whackrecordname)); return TRUE; }
/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ bool load_coded_file(const char *filename, prompt_pass_t *pass, int verbose, const char *type, chunk_t *blob, bool *pgp) { err_t ugh = NULL; FILE *fd; fd = fopen(filename, "r"); if (fd) { int bytes; fseek(fd, 0, SEEK_END ); blob->len = ftell(fd); rewind(fd); blob->ptr = alloc_bytes(blob->len, type); bytes = fread(blob->ptr, 1, blob->len, fd); fclose(fd); if(verbose) { openswan_log(" loaded %s file '%s' (%d bytes)", type, filename, bytes); } *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" file coded in DER format"); ) return TRUE; }
/* * Remove all shell metacharacters ', \, ", `, and $ in a character string */ void remove_metachar(const unsigned char *src, char *dst, size_t dstlen) { bool changed = FALSE; passert(dstlen >= 1); while (*src != '\0' && dstlen > 1) { if((*src >= '0' && *src <= '9') || (*src >= 'a' && *src <= 'z') || (*src >= 'A' && *src <= 'Z') || *src == '_') { *dst++ = *src; dstlen--; } else { changed = TRUE; } src++; } *dst = '\0'; if (changed) openswan_log("Warning: XAUTH username changed from '%s' to '%s'",src,dst); }
/* * Parse PKCS#7 wrapped X.509 certificates */ bool parse_pkcs7_cert(chunk_t blob, x509cert_t **cert) { asn1_ctx_t ctx; chunk_t object; u_int level; int objectID = 0; asn1_init(&ctx, blob, 0, FALSE, DBG_RAW); while (objectID < PKCS7_INFO_ROOF) { if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx)) return FALSE; if (objectID == PKCS7_INFO_TYPE) { if (known_oid(object) != OID_PKCS7_SIGNED_DATA) { openswan_log("PKCS#7 content type is not signedData"); return FALSE; } } else if (objectID == PKCS7_INFO_CONTENT) { parse_pkcs7_signedData(object, level+1, cert); } objectID++; } return TRUE; }
static void disable_nat_traversal(int type) { if (type == ESPINUDP_WITH_NON_IKE) nat_traversal_support_non_ike = FALSE; else { openswan_log("NAT-Traversal port floating turned off"); nat_traversal_support_port_floating = FALSE; } if (!nat_traversal_support_non_ike && !nat_traversal_support_port_floating) { openswan_log("NAT-Traversal is turned OFF due to lack of KERNEL support: %d/%d" , nat_traversal_support_non_ike , nat_traversal_support_port_floating); nat_traversal_enabled = FALSE; } }
static void netlink_acquire(struct nlmsghdr *n) { struct xfrm_user_acquire *acquire; const xfrm_address_t *srcx, *dstx; int src_proto, dst_proto; ip_address src, dst; ip_subnet ours, his; unsigned family; unsigned transport_proto; err_t ugh = NULL; if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire))) { openswan_log("netlink_acquire got message with length %lu < %lu bytes; ignore message" , (unsigned long) n->nlmsg_len , (unsigned long) sizeof(*acquire)); return; } acquire = NLMSG_DATA(n); srcx = &acquire->sel.saddr; dstx = &acquire->sel.daddr; family = acquire->policy.sel.family; transport_proto = acquire->sel.proto; src_proto = 0; /* XXX-MCR where to get protocol from? */ dst_proto = 0; /* ditto */ /* XXX also the type of src/dst should be checked to make sure * that they aren't v4 to v6 or something goofy */ if (!(ugh = xfrm_to_ip_address(family, srcx, &src)) && !(ugh = xfrm_to_ip_address(family, dstx, &dst)) && !(ugh = src_proto == dst_proto? NULL : "src and dst protocols differ") && !(ugh = addrtosubnet(&src, &ours)) && !(ugh = addrtosubnet(&dst, &his))) record_and_initiate_opportunistic(&ours, &his, transport_proto , "%acquire-netlink"); if (ugh != NULL) openswan_log("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh); }
/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ bool load_coded_file(const char *filename, prompt_pass_t *pass, int verbose, const char *type, chunk_t *blob, bool *pgp) { err_t ugh = NULL; FILE *fd; fd = fopen(filename, "r"); if (fd) { size_t bytes; fseek(fd, 0, SEEK_END ); blob->len = ftell(fd); if (blob->len <= 0) { if (verbose) openswan_log(" discarded %s file '%s', bad size %zu bytes", type, filename, blob->len); fclose(fd); return FALSE; } rewind(fd); blob->ptr = alloc_bytes(blob->len, type); bytes = fread(blob->ptr, 1, blob->len, fd); if(bytes != blob->len) { openswan_log(" WARNING: could not fully read certificate-blob filename '%s'\n", filename); } fclose(fd); if(verbose) { openswan_log(" loaded %s file '%s' (%zu bytes)", type, filename, bytes); } *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" file coded in DER format"); ) return TRUE; }
/* * verify the ocsp status of a certificate */ bool verify_by_ocsp(/*const*/ x509cert_t *cert, bool strict, time_t *until) { u_char status; ocsp_location_t location; time_t nextUpdate = 0; /* is an ocsp location defined? */ if (!build_ocsp_location(cert, &location)) return FALSE; lock_ocsp_cache("verify_by_ocsp"); status = get_ocsp_status(&location, cert->serialNumber, &nextUpdate); unlock_ocsp_cache("verify_by_ocsp"); #ifdef HAVE_THREADS if (status == CERT_UNDEFINED || nextUpdate < time(NULL)) { openswan_log("ocsp status is stale or not in cache"); add_ocsp_fetch_request(&location, cert->serialNumber); /* inititate fetching of ocsp status */ wake_fetch_thread("verify_by_ocsp"); return !strict; } #endif switch (status) { case CERT_GOOD: DBG(DBG_CONTROL, DBG_log("certificate is good") ) /* with strict crl policy the public key must have the * same lifetime as the validity of the ocsp status */ if (strict && nextUpdate < *until) *until = nextUpdate; break; case CERT_REVOKED: plog("certificate is revoked"); remove_x509_public_key(cert); return FALSE; case CERT_UNKNOWN: plog("certificate status unkown"); if (strict) { remove_x509_public_key(cert); return FALSE; } break; } return TRUE; }
const struct osw_conf_options *osw_init_ipsecdir(const char *ipsec_dir) { if(!setup) osw_conf_setdefault(); global_oco.confddir = clone_str(ipsec_dir, "override ipsec.d"); osw_conf_calculate(&global_oco); setup = TRUE; openswan_log("adjusting ipsec.d to %s", global_oco.confddir); return &global_oco; }
/* * Initialize the random pool. */ void init_rnd_pool(void) { unsigned int i; unsigned int max_rnd_devices = elemsof(random_devices)+1; const char *rnd_dev; if(random_fd != -1) close(random_fd); random_fd = -1; for(i=0; random_fd == -1 && i<max_rnd_devices; i++) { DBG(DBG_CONTROL, DBG_log("opening %s", random_devices[i])); random_fd = open(random_devices[i], O_RDONLY); rnd_dev = random_devices[i]; if (random_fd == -1) { openswan_log("WARNING: open of %s failed: %s", random_devices[i] , strerror(errno)); } } if(random_fd == -1 || i == max_rnd_devices) { openswan_log("Failed to open any source of random. Unable to start any connections."); return; } openswan_log("using %s as source of random entropy", rnd_dev); fcntl(random_fd, F_SETFD, FD_CLOEXEC); get_rnd_bytes(random_pool, RANDOM_POOL_SIZE); mix_pool(); /* start of rand(3) on the right foot */ { unsigned int seed; get_rnd_bytes((void *)&seed, sizeof(seed)); srand(seed); } }
/* * Do the modular exponentiation without Chinese Remainder Theorem in hardware */ static void cryptodev_rsa_mod_exp_crt( mpz_t dst, const mpz_t src, const mpz_t p, const mpz_t dP, const mpz_t q, const mpz_t dQ, const mpz_t qInv) { struct crypt_kop kop; BIGNUM D, S, P, DP, Q, DQ, QI; BN_CTX *ctx; memset(&kop, 0, sizeof kop); kop.crk_op = CRK_MOD_EXP; ctx = BN_CTX_new(); mp2bn(dst, &D); mp2bn(src, &S); mp2bn(p, &P); mp2bn(dP, &DP); mp2bn(q, &Q); mp2bn(dQ, &DQ); mp2bn(qInv, &QI); /* inputs: a^p % m */ if (bn2crparam(&P, &kop.crk_param[0])) goto err; if (bn2crparam(&Q, &kop.crk_param[1])) goto err; if (bn2crparam(&S, &kop.crk_param[2])) goto err; if (bn2crparam(&DP, &kop.crk_param[3])) goto err; if (bn2crparam(&DQ, &kop.crk_param[4])) goto err; if (bn2crparam(&QI, &kop.crk_param[5])) goto err; kop.crk_iparams = 6; if (cryptodev_asym(&kop, BN_num_bytes(&D), &D, 0, NULL) == -1) { openswan_log("OCF CRK_MOD_EXP_CRT failed %d, using SW\n", errno); goto err; } bn2mp(&D, dst); zapparams(&kop); BN_CTX_free(ctx); return; err: zapparams(&kop); BN_CTX_free(ctx); soft_meth.rsa_mod_exp_crt(dst, src, p, dP, q, dQ, qInv); }
char *getNSSPassword(PK11SlotInfo *slot, PRBool retry, void *arg) { secuPWData *pwdInfo = (secuPWData *)arg; PRFileDesc *fd; PRInt32 nb; /*number of bytes*/ char* password; const long maxPwdFileSize = 4096; if(retry) return 0; if(pwdInfo->source == PW_FROMFILE) { if(pwdInfo->data !=NULL) { fd = PR_Open(pwdInfo->data, PR_RDONLY, 0); if (!fd) { openswan_log("No password file \"%s\" exists.", pwdInfo->data); return 0; } password=PORT_ZAlloc(maxPwdFileSize); nb = PR_Read(fd, password, maxPwdFileSize); PR_Close(fd); if (nb == 0) { openswan_log("password file contains no data"); PORT_Free(password); return 0; } password[nb-1]='\0'; openswan_log("Password passed to NSS is %s", password); return password; } else { openswan_log("File with Password to NSS DB is not provided"); return 0; } } openswan_log("nss password source is not specified as file"); return 0; }
void pbs_poke(pb_stream *pbs, int offset, int value) { if(offset < pbs_room(pbs)) { pbs->start[offset] = value; if(pbs->cur < pbs->start + offset) { pbs->cur = pbs->start + offset; } } else { openswan_log("pbs_peek offset:%d < pbs_room(pbs):%d", offset, pbs_room(pbs)); pexpect(offset < pbs_room(pbs)); } }
/* monotonic version of time(3) */ time_t now(void) { static time_t delta = 0 , last_time = 0; time_t n = time(NULL); passert(n != (time_t)-1); if (last_time > n) { openswan_log("time moved backwards %ld seconds", (long)(last_time - n)); delta += last_time - n; } last_time = n; return n + delta; }
void tpm_initCallbacks(Tcl_Interp *PlutoInterp) { int val; val = Tcl_Eval(PlutoInterp, tpm_template); switch(val) { case TCL_OK: return; case TCL_ERROR: case TCL_RETURN: case TCL_BREAK: case TCL_CONTINUE: openswan_log("tpm init callback error: %s\n", Tcl_GetObjResult(PlutoInterp)); break; } }
void receive_ike_echo_reply(struct msg_digest *md) { char b1[ADDRTOT_BUF]; addrtot(&md->sender, 0, b1, sizeof(b1)); openswan_log("received ike-echo-reply-%d packet from %s/%d\n", md->hdr.isa_xchg, b1, md->sender_port); #if 0 op->isa_np = NOTHING_WRONG; op->isa_version = (1 << ISA_MAJ_SHIFT) | 0; op->isa_xchg = ISAKMP_XCHG_ECHOREPLY; op->isa_flags =0; op->isa_msgid =rand(); op->isa_length=0; #endif }
/* * this routine accepts the I3 packet, and the causes a rekey to be queued */ void recv_pcap_I3_rekey(u_char *user , const struct pcap_pkthdr *h , const u_char *bytes) { struct state *st = NULL; struct pcr_kenonce *kn = &crypto_req->pcr_d.kn; /* create a socket for a possible whack process that is doing --up */ int fake_whack_fd = open("/dev/null", O_RDWR); passert(fake_whack_fd != -1); recv_pcap_packet(user, h, bytes); fprintf(stderr, "now pretend that the keylife timer is up, and rekey the connection\n"); show_states_status(); timer_list(); st = state_with_serialno(2); st->st_whack_sock = fake_whack_fd; if(st) { DBG(DBG_LIFECYCLE , openswan_log("replacing stale %s SA" , (IS_PHASE1(st->st_state)|| IS_PHASE15(st->st_state ))? "ISAKMP" : "IPsec")); ipsecdoi_replace(st, LEMPTY, LEMPTY, 1); } else { fprintf(stderr, "no state #2 found\n"); } /* find new state! */ st = state_with_serialno(3); passert(st->st_whack_sock != -1); passert(kn->oakley_group == SS(oakleygroup)); /* now fill in the KE values from a constant.. not calculated */ clonetowirechunk(&kn->thespace, kn->space, &kn->secret, SS(secret.ptr),SS(secret.len)); clonetowirechunk(&kn->thespace, kn->space, &kn->n, SS(ni.ptr), SS(ni.len)); /* maybe change nonce for rekey? */ clonetowirechunk(&kn->thespace, kn->space, &kn->gi, SS(gi.ptr), SS(gi.len)); run_continuation(crypto_req); }
/* * Compute mod exp in hardware */ static void cryptodev_mod_exp(mpz_t dst, const mpz_t mp_g, const mpz_t secret, const mpz_t modulus) { struct crypt_kop kop; BIGNUM r0, a, p, m; BN_CTX *ctx; memset(&kop, 0, sizeof kop); kop.crk_op = CRK_MOD_EXP; ctx = BN_CTX_new(); mp2bn(mp_g, &a); mp2bn(secret, &p); mp2bn(modulus, &m); mp2bn(dst, &r0); /* inputs: a^p % m */ if (bn2crparam(&a, &kop.crk_param[0])) goto err; if (bn2crparam(&p, &kop.crk_param[1])) goto err; if (bn2crparam(&m, &kop.crk_param[2])) goto err; kop.crk_iparams = 3; if (cryptodev_asym(&kop, BN_num_bytes(&m), &r0, 0, NULL) == -1) { openswan_log("OCF CRK_MOD_EXP failed %d, using SW\n", errno); goto err; } bn2mp(&r0, dst); zapparams(&kop); BN_CTX_free(ctx); return; err: zapparams(&kop); BN_CTX_free(ctx); soft_meth.mod_exp(dst, mp_g, secret, modulus); }
msgid_t generate_msgid(struct state *isakmp_sa) { int timeout = 100; /* only try so hard for unique msgid */ msgid_t msgid; passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state)); for (;;) { get_rnd_bytes((void *) &msgid, sizeof(msgid)); if (msgid != 0 && unique_msgid(isakmp_sa, msgid)) break; if (--timeout == 0) { openswan_log("gave up looking for unique msgid; using 0x%08lx" , (unsigned long) msgid); break; } } return msgid; }
/* * Parses a PKCS#1 private key */ bool parse_pkcs1_private_key(chunk_t blob, rsa_privkey_t *key) { asn1_ctx_t ctx; chunk_t object; u_int level; int objectID = 0; asn1_init(&ctx, blob, 0, FALSE, DBG_PRIVATE); while (objectID < PKCS1_PRIV_KEY_ROOF) { if (!extract_object(privkeyObjects, &objectID, &object, &level, &ctx)) return FALSE; if (objectID == PKCS1_PRIV_KEY_OBJECT) { key->keyobject = object; } else if (objectID == PKCS1_PRIV_KEY_VERSION) { if (*object.ptr != 0) { openswan_log(" wrong PKCS#1 private key version"); return FALSE; } } else if (objectID >= PKCS1_PRIV_KEY_MODULUS && objectID <= PKCS1_PRIV_KEY_COEFF) { key->field[objectID - PKCS1_PRIV_KEY_MODULUS] = object; } objectID++; } return TRUE; }