📄 pkinit.c
字号:
goto out; } hx509_verify_attach_anchors(id->verify_ctx, id->anchors); hx509_verify_attach_revoke(id->verify_ctx, id->revokectx);out: if (ret) { hx509_verify_destroy_ctx(id->verify_ctx); hx509_certs_free(&id->certs); hx509_certs_free(&id->anchors); hx509_certs_free(&id->certpool); hx509_revoke_free(&id->revokectx); hx509_context_free(&id->hx509ctx); free(id); } else *ret_id = id; hx509_lock_free(lock); return ret;}static krb5_error_codeselect_dh_group(krb5_context context, DH *dh, unsigned long bits, struct krb5_dh_moduli **moduli){ const struct krb5_dh_moduli *m; if (bits == 0) { m = moduli[1]; /* XXX */ if (m == NULL) m = moduli[0]; /* XXX */ } else { int i; for (i = 0; moduli[i] != NULL; i++) { if (bits < moduli[i]->bits) break; } if (moduli[i] == NULL) { krb5_set_error_string(context, "Did not find a DH group parameter " "matching requirement of %lu bits", bits); return EINVAL; } m = moduli[i]; } dh->p = integer_to_BN(context, "p", &m->p); if (dh->p == NULL) return ENOMEM; dh->g = integer_to_BN(context, "g", &m->g); if (dh->g == NULL) return ENOMEM; dh->q = integer_to_BN(context, "q", &m->q); if (dh->q == NULL) return ENOMEM; return 0;}#endif /* PKINIT */static intparse_integer(krb5_context context, char **p, const char *file, int lineno, const char *name, heim_integer *integer){ int ret; char *p1; p1 = strsep(p, " \t"); if (p1 == NULL) { krb5_set_error_string(context, "moduli file %s missing %s on line %d", file, name, lineno); return EINVAL; } ret = der_parse_hex_heim_integer(p1, integer); if (ret) { krb5_set_error_string(context, "moduli file %s failed parsing %s " "on line %d", file, name, lineno); return ret; } return 0;}krb5_error_code_krb5_parse_moduli_line(krb5_context context, const char *file, int lineno, char *p, struct krb5_dh_moduli **m){ struct krb5_dh_moduli *m1; char *p1; int ret; *m = NULL; m1 = calloc(1, sizeof(*m1)); if (m1 == NULL) { krb5_set_error_string(context, "malloc - out of memory"); return ENOMEM; } while (isspace((unsigned char)*p)) p++; if (*p == '#') return 0; ret = EINVAL; p1 = strsep(&p, " \t"); if (p1 == NULL) { krb5_set_error_string(context, "moduli file %s missing name " "on line %d", file, lineno); goto out; } m1->name = strdup(p1); if (p1 == NULL) { krb5_set_error_string(context, "malloc - out of memeory"); ret = ENOMEM; goto out; } p1 = strsep(&p, " \t"); if (p1 == NULL) { krb5_set_error_string(context, "moduli file %s missing bits on line %d", file, lineno); goto out; } m1->bits = atoi(p1); if (m1->bits == 0) { krb5_set_error_string(context, "moduli file %s have un-parsable " "bits on line %d", file, lineno); goto out; } ret = parse_integer(context, &p, file, lineno, "p", &m1->p); if (ret) goto out; ret = parse_integer(context, &p, file, lineno, "g", &m1->g); if (ret) goto out; ret = parse_integer(context, &p, file, lineno, "q", &m1->q); if (ret) goto out; *m = m1; return 0;out: free(m1->name); der_free_heim_integer(&m1->p); der_free_heim_integer(&m1->g); der_free_heim_integer(&m1->q); free(m1); return ret;}void_krb5_free_moduli(struct krb5_dh_moduli **moduli){ int i; for (i = 0; moduli[i] != NULL; i++) { free(moduli[i]->name); der_free_heim_integer(&moduli[i]->p); der_free_heim_integer(&moduli[i]->g); der_free_heim_integer(&moduli[i]->q); free(moduli[i]); } free(moduli);}static const char *default_moduli_RFC2412_MODP_group2 = /* name */ "RFC2412-MODP-group2 " /* bits */ "1024 " /* p */ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF " /* g */ "02 " /* q */ "7FFFFFFF" "FFFFFFFF" "E487ED51" "10B4611A" "62633145" "C06E0E68" "94812704" "4533E63A" "0105DF53" "1D89CD91" "28A5043C" "C71A026E" "F7CA8CD9" "E69D218D" "98158536" "F92F8A1B" "A7F09AB6" "B6A8E122" "F242DABB" "312F3F63" "7A262174" "D31BF6B5" "85FFAE5B" "7A035BF6" "F71C35FD" "AD44CFD2" "D74F9208" "BE258FF3" "24943328" "F67329C0" "FFFFFFFF" "FFFFFFFF";static const char *default_moduli_rfc3526_MODP_group14 = /* name */ "rfc3526-MODP-group14 " /* bits */ "1760 " /* p */ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF " /* g */ "02 " /* q */ "7FFFFFFF" "FFFFFFFF" "E487ED51" "10B4611A" "62633145" "C06E0E68" "94812704" "4533E63A" "0105DF53" "1D89CD91" "28A5043C" "C71A026E" "F7CA8CD9" "E69D218D" "98158536" "F92F8A1B" "A7F09AB6" "B6A8E122" "F242DABB" "312F3F63" "7A262174" "D31BF6B5" "85FFAE5B" "7A035BF6" "F71C35FD" "AD44CFD2" "D74F9208" "BE258FF3" "24943328" "F6722D9E" "E1003E5C" "50B1DF82" "CC6D241B" "0E2AE9CD" "348B1FD4" "7E9267AF" "C1B2AE91" "EE51D6CB" "0E3179AB" "1042A95D" "CF6A9483" "B84B4B36" "B3861AA7" "255E4C02" "78BA3604" "650C10BE" "19482F23" "171B671D" "F1CF3B96" "0C074301" "CD93C1D1" "7603D147" "DAE2AEF8" "37A62964" "EF15E5FB" "4AAC0B8C" "1CCAA4BE" "754AB572" "8AE9130C" "4C7D0288" "0AB9472D" "45565534" "7FFFFFFF" "FFFFFFFF";krb5_error_code_krb5_parse_moduli(krb5_context context, const char *file, struct krb5_dh_moduli ***moduli){ /* name bits P G Q */ krb5_error_code ret; struct krb5_dh_moduli **m = NULL, **m2; char buf[4096]; FILE *f; int lineno = 0, n = 0; *moduli = NULL; m = calloc(1, sizeof(m[0]) * 3); if (m == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } strlcpy(buf, default_moduli_rfc3526_MODP_group14, sizeof(buf)); ret = _krb5_parse_moduli_line(context, "builtin", 1, buf, &m[0]); if (ret) { _krb5_free_moduli(m); return ret; } n++; strlcpy(buf, default_moduli_RFC2412_MODP_group2, sizeof(buf)); ret = _krb5_parse_moduli_line(context, "builtin", 1, buf, &m[1]); if (ret) { _krb5_free_moduli(m); return ret; } n++; if (file == NULL) file = MODULI_FILE; f = fopen(file, "r"); if (f == NULL) { *moduli = m; return 0; } while(fgets(buf, sizeof(buf), f) != NULL) { struct krb5_dh_moduli *element; buf[strcspn(buf, "\n")] = '\0'; lineno++; m2 = realloc(m, (n + 2) * sizeof(m[0])); if (m2 == NULL) { krb5_set_error_string(context, "malloc: out of memory"); _krb5_free_moduli(m); return ENOMEM; } m = m2; m[n] = NULL; ret = _krb5_parse_moduli_line(context, file, lineno, buf, &element); if (ret) { _krb5_free_moduli(m); return ret; } if (element == NULL) continue; m[n] = element; m[n + 1] = NULL; n++; } *moduli = m; return 0;}krb5_error_code_krb5_dh_group_ok(krb5_context context, unsigned long bits, heim_integer *p, heim_integer *g, heim_integer *q, struct krb5_dh_moduli **moduli, char **name){ int i; if (name) *name = NULL; for (i = 0; moduli[i] != NULL; i++) { if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 && der_heim_integer_cmp(&moduli[i]->p, p) == 0 && (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0)) { if (bits && bits > moduli[i]->bits) { krb5_set_error_string(context, "PKINIT: DH group parameter %s " "no accepted, not enough bits generated", moduli[i]->name); return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; } if (name) *name = strdup(moduli[i]->name); return 0; } } krb5_set_error_string(context, "PKINIT: DH group parameter no ok"); return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;}void KRB5_LIB_FUNCTION_krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt){#ifdef PKINIT krb5_pk_init_ctx ctx; if (opt->opt_private == NULL || opt->opt_private->pk_init_ctx == NULL) return; ctx = opt->opt_private->pk_init_ctx; if (ctx->dh) DH_free(ctx->dh); ctx->dh = NULL; if (ctx->id) { hx509_verify_destroy_ctx(ctx->id->verify_ctx); hx509_certs_free(&ctx->id->certs); hx509_certs_free(&ctx->id->anchors); hx509_certs_free(&ctx->id->certpool); hx509_context_free(&ctx->id->hx509ctx); if (ctx->clientDHNonce) { krb5_free_data(NULL, ctx->clientDHNonce); ctx->clientDHNonce = NULL; } if (ctx->m) _krb5_free_moduli(ctx->m); free(ctx->id); ctx->id = NULL; } free(opt->opt_private->pk_init_ctx); opt->opt_private->pk_init_ctx = NULL;#endif} krb5_error_code KRB5_LIB_FUNCTIONkrb5_get_init_creds_opt_set_pkinit(krb5_context context, krb5_get_init_creds_opt *opt, krb5_principal principal, const char *user_id, const char *x509_anchors, char * const * pool, char * const * pki_revoke, int flags, krb5_prompter_fct prompter, void *prompter_data, char *password){#ifdef PKINIT krb5_error_code ret; char *anchors = NULL; if (opt->opt_private == NULL) { krb5_set_error_string(context, "PKINIT: on non extendable opt"); return EINVAL; } opt->opt_private->pk_init_ctx = calloc(1, sizeof(*opt->opt_private->pk_init_ctx)); if (opt->opt_private->pk_init_ctx == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } opt->opt_private->pk_init_ctx->dh = NULL; opt->opt_private->pk_init_ctx->id = NULL; opt->opt_private->pk_init_ctx->clientDHNonce = NULL; opt->opt_private->pk_init_ctx->require_binding = 0; opt->opt_private->pk_init_ctx->require_eku = 1; opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1; opt->opt_private->pk_init_ctx->peer = NULL; /* XXX implement krb5_appdefault_strings */ if (pool == NULL) pool = krb5_config_get_strings(context, NULL, "appdefaults", "pkinit_pool", NULL); if (pki_revoke == NULL) pki_revoke = krb5_config_get_strings(context, NULL, "appdefaults", "pkinit_revoke", NULL); if (x509_anchors == NULL) { krb5_appdefault_string(context, "kinit", krb5_principal_get_realm(context, principal), "pkinit_anchors", NULL, &anchors); x509_anchors = anchors; } ret = _krb5_pk_load_id(context, &opt->opt_private->pk_init_ctx->id, user_id, x509_anchors, pool, pki_revoke, prompter, prompter_data, password); if (ret) { free(opt->opt_private->pk_init_ctx); opt->opt_private->pk_init_ctx = NULL; return ret; } if ((flags & 2) == 0) { const char *moduli_file; unsigned long dh_min_bits; moduli_file = krb5_config_get_string(context, NULL, "libdefaults", "moduli", NULL); dh_min_bits = krb5_config_get_int_default(context, NULL, 0, "libdefaults", "pkinit_dh_min_bits", NULL); ret = _krb5_parse_moduli(context, moduli_file, &opt->opt_private->pk_init_ctx->m); if (ret) { _krb5_get_init_creds_opt_free_pkinit(opt); return ret; } opt->opt_private->pk_init_ctx->dh = DH_new(); if (opt->opt_private->pk_init_ctx->dh == NULL) { krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } ret = select_dh_group(context, opt->opt_private->pk_init_ctx->dh, dh_min_bits, opt->opt_private->pk_init_ctx->m); if (ret) { _krb5_get_init_creds_opt_free_pkinit(opt); return ret; } if (DH_generate_key(opt->opt_private->pk_init_ctx->dh) != 1) { krb5_set_error_string(context, "pkinit: failed to generate DH key"); _krb5_get_init_creds_opt_free_pkinit(opt); return ENOMEM; } } return 0;#else krb5_set_error_string(context, "no support for PKINIT compiled in"); return EINVAL;#endif}/* * */static void_krb5_pk_copy_error(krb5_context context, hx509_context hx509ctx, int hxret, const char *fmt, ...){ va_list va; char *s, *f; va_start(va, fmt); vasprintf(&f, fmt, va); va_end(va); if (f == NULL) { krb5_clear_error_string(context); return; } s = hx509_get_error_string(hx509ctx, hxret); if (s == NULL) { krb5_clear_error_string(context); free(f); return; } krb5_set_error_string(context, "%s: %s", f, s); free(s); free(f);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -