diff options
author | Damien Miller <djm@mindrot.org> | 2010-03-04 21:51:11 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-03-04 21:51:11 +1100 |
commit | 41396573afc94d64973d9eb824ca510d39260b3e (patch) | |
tree | 4aa4eeda0157ac9d415c1221fa3e79bb971c358a | |
parent | e1abf4d6bc4bea0bb76e6ff89ca6048122e90d81 (diff) |
- OpenBSD CVS Sync
- djm@cvs.openbsd.org 2010/03/03 01:44:36
[auth-options.c key.c]
reject strings with embedded ASCII nul chars in certificate key IDs,
principal names and constraints
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | auth-options.c | 28 | ||||
-rw-r--r-- | key.c | 36 |
3 files changed, 48 insertions, 21 deletions
@@ -6,6 +6,11 @@ | |||
6 | imorgan AT nas.nasa.gov in bz#1731 | 6 | imorgan AT nas.nasa.gov in bz#1731 |
7 | - (djm) [.cvsignore] Ignore ssh-pkcs11-helper | 7 | - (djm) [.cvsignore] Ignore ssh-pkcs11-helper |
8 | - (djm) [regress/Makefile] Cleanup sshd_proxy_orig | 8 | - (djm) [regress/Makefile] Cleanup sshd_proxy_orig |
9 | - OpenBSD CVS Sync | ||
10 | - djm@cvs.openbsd.org 2010/03/03 01:44:36 | ||
11 | [auth-options.c key.c] | ||
12 | reject strings with embedded ASCII nul chars in certificate key IDs, | ||
13 | principal names and constraints | ||
9 | 14 | ||
10 | 20100303 | 15 | 20100303 |
11 | - (djm) [PROTOCOL.certkeys] Add RCS Ident | 16 | - (djm) [PROTOCOL.certkeys] Add RCS Ident |
diff --git a/auth-options.c b/auth-options.c index 396bda62f..d14624bf4 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.c,v 1.45 2010/02/26 20:29:54 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.c,v 1.46 2010/03/03 01:44:36 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -391,7 +391,7 @@ int | |||
391 | auth_cert_constraints(Buffer *c_orig, struct passwd *pw) | 391 | auth_cert_constraints(Buffer *c_orig, struct passwd *pw) |
392 | { | 392 | { |
393 | u_char *name = NULL, *data_blob = NULL; | 393 | u_char *name = NULL, *data_blob = NULL; |
394 | u_int len; | 394 | u_int nlen, dlen, clen; |
395 | Buffer c, data; | 395 | Buffer c, data; |
396 | int ret = -1; | 396 | int ret = -1; |
397 | 397 | ||
@@ -410,14 +410,18 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) | |||
410 | buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig)); | 410 | buffer_append(&c, buffer_ptr(c_orig), buffer_len(c_orig)); |
411 | 411 | ||
412 | while (buffer_len(&c) > 0) { | 412 | while (buffer_len(&c) > 0) { |
413 | if ((name = buffer_get_string_ret(&c, NULL)) == NULL || | 413 | if ((name = buffer_get_string_ret(&c, &nlen)) == NULL || |
414 | (data_blob = buffer_get_string_ret(&c, &len)) == NULL) { | 414 | (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { |
415 | error("Certificate constraints corrupt"); | 415 | error("Certificate constraints corrupt"); |
416 | goto out; | 416 | goto out; |
417 | } | 417 | } |
418 | buffer_append(&data, data_blob, len); | 418 | buffer_append(&data, data_blob, dlen); |
419 | debug3("found certificate constraint \"%.100s\" len %u", | 419 | debug3("found certificate constraint \"%.100s\" len %u", |
420 | name, len); | 420 | name, dlen); |
421 | if (strlen(name) != nlen) { | ||
422 | error("Certificate constraint name contains \\0"); | ||
423 | goto out; | ||
424 | } | ||
421 | if (strcmp(name, "permit-X11-forwarding") == 0) | 425 | if (strcmp(name, "permit-X11-forwarding") == 0) |
422 | cert_no_x11_forwarding_flag = 0; | 426 | cert_no_x11_forwarding_flag = 0; |
423 | else if (strcmp(name, "permit-agent-forwarding") == 0) | 427 | else if (strcmp(name, "permit-agent-forwarding") == 0) |
@@ -429,13 +433,17 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) | |||
429 | else if (strcmp(name, "permit-user-rc") == 0) | 433 | else if (strcmp(name, "permit-user-rc") == 0) |
430 | cert_no_user_rc = 0; | 434 | cert_no_user_rc = 0; |
431 | else if (strcmp(name, "force-command") == 0) { | 435 | else if (strcmp(name, "force-command") == 0) { |
432 | char *command = buffer_get_string_ret(&data, NULL); | 436 | char *command = buffer_get_string_ret(&data, &clen); |
433 | 437 | ||
434 | if (command == NULL) { | 438 | if (command == NULL) { |
435 | error("Certificate constraint \"%s\" corrupt", | 439 | error("Certificate constraint \"%s\" corrupt", |
436 | name); | 440 | name); |
437 | goto out; | 441 | goto out; |
438 | } | 442 | } |
443 | if (strlen(command) != clen) { | ||
444 | error("force-command constrain contains \\0"); | ||
445 | goto out; | ||
446 | } | ||
439 | if (cert_forced_command != NULL) { | 447 | if (cert_forced_command != NULL) { |
440 | error("Certificate has multiple " | 448 | error("Certificate has multiple " |
441 | "forced-command constraints"); | 449 | "forced-command constraints"); |
@@ -444,7 +452,7 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) | |||
444 | } | 452 | } |
445 | cert_forced_command = command; | 453 | cert_forced_command = command; |
446 | } else if (strcmp(name, "source-address") == 0) { | 454 | } else if (strcmp(name, "source-address") == 0) { |
447 | char *allowed = buffer_get_string_ret(&data, NULL); | 455 | char *allowed = buffer_get_string_ret(&data, &clen); |
448 | const char *remote_ip = get_remote_ipaddr(); | 456 | const char *remote_ip = get_remote_ipaddr(); |
449 | 457 | ||
450 | if (allowed == NULL) { | 458 | if (allowed == NULL) { |
@@ -452,6 +460,10 @@ auth_cert_constraints(Buffer *c_orig, struct passwd *pw) | |||
452 | name); | 460 | name); |
453 | goto out; | 461 | goto out; |
454 | } | 462 | } |
463 | if (strlen(allowed) != clen) { | ||
464 | error("source-address constrain contains \\0"); | ||
465 | goto out; | ||
466 | } | ||
455 | if (cert_source_address_done++) { | 467 | if (cert_source_address_done++) { |
456 | error("Certificate has multiple " | 468 | error("Certificate has multiple " |
457 | "source-address constraints"); | 469 | "source-address constraints"); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.83 2010/02/26 20:29:54 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.84 2010/03/03 01:44:36 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * read_bignum(): |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1000,7 +1000,7 @@ static int | |||
1000 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | 1000 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) |
1001 | { | 1001 | { |
1002 | u_char *principals, *constraints, *sig_key, *sig; | 1002 | u_char *principals, *constraints, *sig_key, *sig; |
1003 | u_int signed_len, plen, clen, sklen, slen; | 1003 | u_int signed_len, plen, clen, sklen, slen, kidlen; |
1004 | Buffer tmp; | 1004 | Buffer tmp; |
1005 | char *principal; | 1005 | char *principal; |
1006 | int ret = -1; | 1006 | int ret = -1; |
@@ -1012,7 +1012,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1012 | 1012 | ||
1013 | principals = constraints = sig_key = sig = NULL; | 1013 | principals = constraints = sig_key = sig = NULL; |
1014 | if (buffer_get_int_ret(&key->cert->type, b) != 0 || | 1014 | if (buffer_get_int_ret(&key->cert->type, b) != 0 || |
1015 | (key->cert->key_id = buffer_get_string_ret(b, NULL)) == NULL || | 1015 | (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || |
1016 | (principals = buffer_get_string_ret(b, &plen)) == NULL || | 1016 | (principals = buffer_get_string_ret(b, &plen)) == NULL || |
1017 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || | 1017 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || |
1018 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || | 1018 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || |
@@ -1024,6 +1024,11 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1024 | goto out; | 1024 | goto out; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | if (kidlen != strlen(key->cert->key_id)) { | ||
1028 | error("%s: key ID contains \\0 character", __func__); | ||
1029 | goto out; | ||
1030 | } | ||
1031 | |||
1027 | /* Signature is left in the buffer so we can calculate this length */ | 1032 | /* Signature is left in the buffer so we can calculate this length */ |
1028 | signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); | 1033 | signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); |
1029 | 1034 | ||
@@ -1041,11 +1046,16 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1041 | buffer_append(&tmp, principals, plen); | 1046 | buffer_append(&tmp, principals, plen); |
1042 | while (buffer_len(&tmp) > 0) { | 1047 | while (buffer_len(&tmp) > 0) { |
1043 | if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { | 1048 | if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { |
1044 | error("Too many principals"); | 1049 | error("%s: Too many principals", __func__); |
1045 | goto out; | 1050 | goto out; |
1046 | } | 1051 | } |
1047 | if ((principal = buffer_get_string_ret(&tmp, NULL)) == NULL) { | 1052 | if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) { |
1048 | error("Principals data invalid"); | 1053 | error("%s: Principals data invalid", __func__); |
1054 | goto out; | ||
1055 | } | ||
1056 | if (strlen(principal) != plen) { | ||
1057 | error("%s: Principal contains \\0 character", | ||
1058 | __func__); | ||
1049 | goto out; | 1059 | goto out; |
1050 | } | 1060 | } |
1051 | key->cert->principals = xrealloc(key->cert->principals, | 1061 | key->cert->principals = xrealloc(key->cert->principals, |
@@ -1061,7 +1071,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1061 | while (buffer_len(&tmp) != 0) { | 1071 | while (buffer_len(&tmp) != 0) { |
1062 | if (buffer_get_string_ptr(&tmp, NULL) == NULL || | 1072 | if (buffer_get_string_ptr(&tmp, NULL) == NULL || |
1063 | buffer_get_string_ptr(&tmp, NULL) == NULL) { | 1073 | buffer_get_string_ptr(&tmp, NULL) == NULL) { |
1064 | error("Constraints data invalid"); | 1074 | error("%s: Constraints data invalid", __func__); |
1065 | goto out; | 1075 | goto out; |
1066 | } | 1076 | } |
1067 | } | 1077 | } |
@@ -1069,12 +1079,12 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1069 | 1079 | ||
1070 | if ((key->cert->signature_key = key_from_blob(sig_key, | 1080 | if ((key->cert->signature_key = key_from_blob(sig_key, |
1071 | sklen)) == NULL) { | 1081 | sklen)) == NULL) { |
1072 | error("Signature key invalid"); | 1082 | error("%s: Signature key invalid", __func__); |
1073 | goto out; | 1083 | goto out; |
1074 | } | 1084 | } |
1075 | if (key->cert->signature_key->type != KEY_RSA && | 1085 | if (key->cert->signature_key->type != KEY_RSA && |
1076 | key->cert->signature_key->type != KEY_DSA) { | 1086 | key->cert->signature_key->type != KEY_DSA) { |
1077 | error("Invalid signature key type %s (%d)", | 1087 | error("%s: Invalid signature key type %s (%d)", __func__, |
1078 | key_type(key->cert->signature_key), | 1088 | key_type(key->cert->signature_key), |
1079 | key->cert->signature_key->type); | 1089 | key->cert->signature_key->type); |
1080 | goto out; | 1090 | goto out; |
@@ -1083,17 +1093,17 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1083 | switch (key_verify(key->cert->signature_key, sig, slen, | 1093 | switch (key_verify(key->cert->signature_key, sig, slen, |
1084 | buffer_ptr(&key->cert->certblob), signed_len)) { | 1094 | buffer_ptr(&key->cert->certblob), signed_len)) { |
1085 | case 1: | 1095 | case 1: |
1096 | ret = 0; | ||
1086 | break; /* Good signature */ | 1097 | break; /* Good signature */ |
1087 | case 0: | 1098 | case 0: |
1088 | error("Invalid signature on certificate"); | 1099 | error("%s: Invalid signature on certificate", __func__); |
1089 | goto out; | 1100 | goto out; |
1090 | case -1: | 1101 | case -1: |
1091 | error("Certificate signature verification failed"); | 1102 | error("%s: Certificate signature verification failed", |
1103 | __func__); | ||
1092 | goto out; | 1104 | goto out; |
1093 | } | 1105 | } |
1094 | 1106 | ||
1095 | ret = 0; | ||
1096 | |||
1097 | out: | 1107 | out: |
1098 | buffer_free(&tmp); | 1108 | buffer_free(&tmp); |
1099 | if (principals != NULL) | 1109 | if (principals != NULL) |