📄 keys.c
字号:
memcpy(fn, flp->filename, pl); p += pl; } if (flp->cur - tok >= &fn[sizeof(fn)] - p) { loglog(RC_LOG_SERIOUS, "\"%s\" line %d: include pathname too long" , flp->filename, flp->lino); continue; /* abandon this record */ } strcpy(p, tok); (void) shift(); /* move to Record Boundary, we hope */ if (flushline("ignoring malformed INCLUDE -- expected Record Boundary after filename")) { process_secrets_file(fn, whackfd); tok = NULL; /* correct, but probably redundant */ } } else { /* expecting a list of indices and then the key info */ struct secret *s = alloc_thing(struct secret, "secret"); s->ids = NULL; s->kind = PPK_PSK; /* default */ setchunk(s->u.preshared_secret, NULL, 0); s->secretlineno=flp->lino; s->next = NULL; for (;;) { if (tokeq(":")) { /* found key part */ shift(); /* discard explicit separator */ process_secret(s, whackfd); break; } else { /* an id * See RFC2407 IPsec Domain of Interpretation 4.6.2 */ struct id id; err_t ugh; if (tokeq("%any")) { id = empty_id; id.kind = ID_IPV4_ADDR; ugh = anyaddr(AF_INET, &id.ip_addr); } else if (tokeq("%any6")) { id = empty_id; id.kind = ID_IPV6_ADDR; ugh = anyaddr(AF_INET6, &id.ip_addr); } else { ugh = atoid(tok, &id, FALSE); } if (ugh != NULL) { loglog(RC_LOG_SERIOUS , "ERROR \"%s\" line %d: index \"%s\" %s" , flp->filename, flp->lino, tok, ugh); } else { struct id_list *i = alloc_thing(struct id_list , "id_list"); i->id = id; unshare_id_content(&i->id); i->next = s->ids; s->ids = i; /* DBG_log("id type %d: %s %.*s", i->kind, ip_str(&i->ip_addr), (int)i->name.len, i->name.ptr); */ } if (!shift()) { /* unexpected Record Boundary or EOF */ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of id list" , flp->filename, flp->lino); break; } } } } }}static intglobugh(const char *epath, int eerrno){ log_errno_routine(eerrno, "problem with secrets file \"%s\"", epath); return 1; /* stop glob */}static voidprocess_secrets_file(const char *file_pat, int whackfd){ struct file_lex_position pos; char **fnp; glob_t globbuf; pos.depth = flp == NULL? 0 : flp->depth + 1; if (pos.depth > 10) { loglog(RC_LOG_SERIOUS, "preshared secrets file \"%s\" nested too deeply", file_pat); return; } /* do globbing */ { int r = glob(file_pat, GLOB_ERR, globugh, &globbuf); if (r != 0) { switch (r) { case GLOB_NOSPACE: loglog(RC_LOG_SERIOUS, "out of space processing secrets filename \"%s\"", file_pat); break; case GLOB_ABORTED: break; /* already logged */ case GLOB_NOMATCH: loglog(RC_LOG_SERIOUS, "no secrets filename matched \"%s\"", file_pat); break; default: loglog(RC_LOG_SERIOUS, "unknown glob error %d", r); break; } globfree(&globbuf); return; } } /* for each file... */ for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++) { if (lexopen(&pos, *fnp, FALSE)) { openswan_log("loading secrets from \"%s\"", *fnp); (void) flushline("file starts with indentation (continuation notation)"); process_secret_records(whackfd); lexclose(); } } globfree(&globbuf);}voidfree_preshared_secrets(void){ lock_certs_and_keys("free_preshared_secrets"); if (secrets != NULL) { struct secret *s, *ns; openswan_log("forgetting secrets"); for (s = secrets; s != NULL; s = ns) { struct id_list *i, *ni; ns = s->next; /* grab before freeing s */ for (i = s->ids; i != NULL; i = ni) { ni = i->next; /* grab before freeing i */ free_id_content(&i->id); pfree(i); } switch (s->kind) { case PPK_PSK: pfree(s->u.preshared_secret.ptr); break; case PPK_RSA: free_RSA_public_content(&s->u.RSA_private_key.pub); mpz_clear(&s->u.RSA_private_key.d); mpz_clear(&s->u.RSA_private_key.p); mpz_clear(&s->u.RSA_private_key.q); mpz_clear(&s->u.RSA_private_key.dP); mpz_clear(&s->u.RSA_private_key.dQ); mpz_clear(&s->u.RSA_private_key.qInv); break;#ifdef SMARTCARD case PPK_PIN: scx_release(s->u.smartcard); break;#endif default: bad_case(s->kind); } pfree(s); } secrets = NULL; } unlock_certs_and_keys("free_preshard_secrets");}voidload_preshared_secrets(int whackfd){ free_preshared_secrets(); (void) process_secrets_file(shared_secrets_file, whackfd);}/* public key machinery * Note: caller must set dns_auth_level. */struct pubkey *public_key_from_rsa(const struct RSA_public_key *k){ struct pubkey *p = alloc_thing(struct pubkey, "pubkey"); p->id = empty_id; /* don't know, doesn't matter */ p->issuer = empty_chunk; p->alg = PUBKEY_ALG_RSA; memcpy(p->u.rsa.keyid, k->keyid, sizeof(p->u.rsa.keyid)); p->u.rsa.k = k->k; mpz_init_set(&p->u.rsa.e, &k->e); mpz_init_set(&p->u.rsa.n, &k->n); /* note that we return a 1 reference count upon creation: * invariant: recount > 0. */ p->refcnt = 1; p->installed_time = now(); return p;}void free_RSA_public_content(struct RSA_public_key *rsa){ mpz_clear(&rsa->n); mpz_clear(&rsa->e);}/* Free a public key record. * As a convenience, this returns a pointer to next. */struct pubkey_list *free_public_keyentry(struct pubkey_list *p){ struct pubkey_list *nxt = p->next; if (p->key != NULL) unreference_key(&p->key); pfree(p); return nxt;}voidfree_public_keys(struct pubkey_list **keys){ while (*keys != NULL) *keys = free_public_keyentry(*keys);}/* root of chained public key list */struct pubkey_list *pubkeys = NULL; /* keys from ipsec.conf */voidfree_remembered_public_keys(void){ free_public_keys(&pubkeys);}/* transfer public keys from *keys list to front of pubkeys list */voidtransfer_to_public_keys(struct gw_info *gateways_from_dns#ifdef USE_KEYRR, struct pubkey_list **keys#endif /* USE_KEYRR */){ { struct gw_info *gwp; for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next) { struct pubkey_list *pl = alloc_thing(struct pubkey_list, "from TXT"); pl->key = gwp->key; /* note: this is a transfer */ gwp->key = NULL; /* really, it is! */ pl->next = pubkeys; pubkeys = pl; } }#ifdef USE_KEYRR { struct pubkey_list **pp = keys; while (*pp != NULL) pp = &(*pp)->next; *pp = pubkeys; pubkeys = *keys; *keys = NULL; }#endif /* USE_KEYRR */}/* decode of RSA pubkey chunk * - format specified in RFC 2537 RSA/MD5 Keys and SIGs in the DNS * - exponent length in bytes (1 or 3 octets) * + 1 byte if in [1, 255] * + otherwise 0x00 followed by 2 bytes of length * - exponent * - modulus */err_tunpack_RSA_public_key(struct RSA_public_key *rsa, const chunk_t *pubkey){ chunk_t exp; chunk_t mod; rsa->keyid[0] = '\0'; /* in case of keybolbtoid failure */ if (pubkey->len < 3) return "RSA public key blob way to short"; /* not even room for length! */ if (pubkey->ptr[0] != 0x00) { setchunk(exp, pubkey->ptr + 1, pubkey->ptr[0]); } else { setchunk(exp, pubkey->ptr + 3 , (pubkey->ptr[1] << BITS_PER_BYTE) + pubkey->ptr[2]); } if (pubkey->len - (exp.ptr - pubkey->ptr) < exp.len + RSA_MIN_OCTETS_RFC) return "RSA public key blob too short"; mod.ptr = exp.ptr + exp.len; mod.len = &pubkey->ptr[pubkey->len] - mod.ptr; if (mod.len < RSA_MIN_OCTETS) return RSA_MIN_OCTETS_UGH; if (mod.len > RSA_MAX_OCTETS) return RSA_MAX_OCTETS_UGH; n_to_mpz(&rsa->e, exp.ptr, exp.len); n_to_mpz(&rsa->n, mod.ptr, mod.len); keyblobtoid(pubkey->ptr, pubkey->len, rsa->keyid, sizeof(rsa->keyid));#ifdef DEBUG DBG(DBG_PRIVATE, RSA_show_public_key(rsa));#endif rsa->k = mpz_sizeinbase(&rsa->n, 2); /* size in bits, for a start */ rsa->k = (rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE; /* now octets */ if (rsa->k != mod.len) { mpz_clear(&rsa->e); mpz_clear(&rsa->n); return "RSA modulus shorter than specified"; } return NULL;}boolsame_RSA_public_key(const struct RSA_public_key *a , const struct RSA_public_key *b){ return a == b || (a->k == b->k && mpz_cmp(&a->n, &b->n) == 0 && mpz_cmp(&a->e, &b->e) == 0);}voidinstall_public_key(struct pubkey *pk, struct pubkey_list **head){ struct pubkey_list *p = alloc_thing(struct pubkey_list, "pubkey entry"); unshare_id_content(&pk->id); /* copy issuer dn */ if (pk->issuer.ptr != NULL) pk->issuer.ptr = clone_bytes(pk->issuer.ptr, pk->issuer.len, "issuer dn"); /* store the time the public key was installed */ time(&pk->installed_time); /* install new key at front */ p->key = reference_key(pk); p->next = *head; *head = p;}voiddelete_public_keys(const struct id *id, enum pubkey_alg alg){ struct pubkey_list **pp, *p; struct pubkey *pk; for (pp = &pubkeys; (p = *pp) != NULL; ) { pk = p->key; if (same_id(id, &pk->id) && pk->alg == alg) *pp = free_public_keyentry(p); else pp = &p->next; }}struct pubkey *reference_key(struct pubkey *pk){ pk->refcnt++; return pk;}voidunreference_key(struct pubkey **pkp){ struct pubkey *pk = *pkp; char b[IDTOA_BUF]; if (pk == NULL) return; /* print stuff */ DBG(DBG_CONTROLMORE, idtoa(&pk->id, b, sizeof(b)); DBG_log("unreference key: %p %s cnt %d--", pk, b, pk->refcnt) ); /* cancel out the pointer */ *pkp = NULL; passert(pk->refcnt != 0); pk->refcnt--; /* we are going to free the key as the refcount will hit zero */ if (pk->refcnt == 0) free_public_key(pk);}err_tadd_public_key(const struct id *id, enum dns_auth_level dns_auth_level, enum pubkey_alg alg, const chunk_t *key, struct pubkey_list **head){ struct pubkey *pk = alloc_thing(struct pubkey, "pubkey"); /* first: algorithm-specific decoding of key chunk */ switch (alg) { case PUBKEY_ALG_RSA: { err_t ugh = unpack_RSA_public_key(&pk->u.rsa, key); if (ugh != NULL) { pfree(pk); return ugh; } } break; default: bad_case(alg); } pk->id = *id; pk->dns_auth_level = dns_auth_level; pk->alg = alg; pk->until_time = UNDEFINED_TIME; pk->issuer = empty_chunk; install_public_key(pk, head); return NULL;}/* * list all public keys in the chained list */void list_public_keys(bool utc){ struct pubkey_list *p = pubkeys; whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, "List of Public Keys:"); whack_log(RC_COMMENT, " "); while (p != NULL) { struct pubkey *key = p->key; if (key->alg == PUBKEY_ALG_RSA) { char id_buf[IDTOA_BUF]; char expires_buf[TIMETOA_BUF]; char installed_buf[TIMETOA_BUF]; idtoa(&key->id, id_buf, IDTOA_BUF); whack_log(RC_COMMENT, "%s, %4d RSA Key %s, until %s %s" , timetoa(&key->installed_time, utc, installed_buf, sizeof(installed_buf)) , 8*key->u.rsa.k , key->u.rsa.keyid , timetoa(&key->until_time, utc, expires_buf, sizeof(expires_buf)) , check_expiry(key->until_time , PUBKEY_WARNING_INTERVAL , TRUE)); whack_log(RC_COMMENT," %s '%s'", enum_show(&ident_names, key->id.kind), id_buf); if (key->issuer.len > 0) { dntoa(id_buf, IDTOA_BUF, key->issuer); whack_log(RC_COMMENT," Issuer '%s'", id_buf); } } p = p->next; }}/* * Local Variables: * c-basic-offset:4 * c-style: pluto * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -