summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-03-04 21:51:11 +1100
committerDamien Miller <djm@mindrot.org>2010-03-04 21:51:11 +1100
commit41396573afc94d64973d9eb824ca510d39260b3e (patch)
tree4aa4eeda0157ac9d415c1221fa3e79bb971c358a
parente1abf4d6bc4bea0bb76e6ff89ca6048122e90d81 (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--ChangeLog5
-rw-r--r--auth-options.c28
-rw-r--r--key.c36
3 files changed, 48 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 248fdfa91..36ef5c911 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
1020100303 1520100303
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
391auth_cert_constraints(Buffer *c_orig, struct passwd *pw) 391auth_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");
diff --git a/key.c b/key.c
index 387190b53..e6266fa58 100644
--- a/key.c
+++ b/key.c
@@ -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
1000cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) 1000cert_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)