diff -ruN openssh-3.6.1p2+x509g1/acconfig.h openssh-3.6.1p2+x509g2/acconfig.h --- openssh-3.6.1p2+x509g1/acconfig.h 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/acconfig.h 2003-06-12 09:06:00.000000000 +0300 @@ -1,4 +1,4 @@ -/* $Id$*/ +/* $Id: acconfig.h,v 1.149 2003/03/10 00:38:10 djm Exp $ */ #ifndef _CONFIG_H #define _CONFIG_H @@ -292,9 +292,6 @@ /* Specify default $PATH */ #undef USER_PATH -/* Specify location of ssh CA root */ -#undef SSHCADIR - /* Specify location of ssh.pid */ #undef _PATH_SSH_PIDDIR diff -ruN openssh-3.6.1p2+x509g1/auth2-pubkey.c openssh-3.6.1p2+x509g2/auth2-pubkey.c --- openssh-3.6.1p2+x509g1/auth2-pubkey.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/auth2-pubkey.c 2003-06-12 09:06:01.000000000 +0300 @@ -249,9 +249,9 @@ key_type(found), fp); if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { - if (ssh_x509store_check(key->x509) != 1) { + if (ssh_x509cert_check(key->x509) != 1) { found_key = 0; - verbose("x509store reject matching key"); + verbose("x509 certificate check reject matching key"); } } xfree(fp); diff -ruN openssh-3.6.1p2+x509g1/compat.c openssh-3.6.1p2+x509g2/compat.c --- openssh-3.6.1p2+x509g1/compat.c 2003-04-01 14:44:37.000000000 +0300 +++ openssh-3.6.1p2+x509g2/compat.c 2003-06-12 09:06:01.000000000 +0300 @@ -1,5 +1,7 @@ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. + * X509 certificate support, + * Copyright (c) 2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.66 2003/04/01 10:31:26 markus Exp $"); +RCSID("$OpenBSD$"); #include "buffer.h" #include "packet.h" @@ -36,6 +38,8 @@ int compat20 = 0; int datafellows = 0; +int x509rsasigtype = SSH_X509RSA_MD5; + void enable_compat20(void) { @@ -226,3 +230,19 @@ return(fix_ciphers); } + +int +ssh_x509rsasig(int _x509rsasigtype) { + switch(_x509rsasigtype) { + case SSH_X509RSA_MD5 : + case SSH_X509RSA_SHA1: + x509rsasigtype = _x509rsasigtype; + break; + default : + x509rsasigtype = SSH_X509RSA_MD5; + log("invalid x509rsa sigtype=%d, switched to default=%d", _x509rsasigtype, x509rsasigtype); + break; + } + debug3("x509rsa sigtype=%d", x509rsasigtype); + return (x509rsasigtype); +} diff -ruN openssh-3.6.1p2+x509g1/compat.h openssh-3.6.1p2+x509g2/compat.h --- openssh-3.6.1p2+x509g1/compat.h 2003-04-01 14:44:37.000000000 +0300 +++ openssh-3.6.1p2+x509g2/compat.h 2003-06-12 09:06:00.000000000 +0300 @@ -1,7 +1,9 @@ -/* $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $ */ +/* $OpenBSD$ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. + * X509 certificate support, + * Copyright (c) 2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,4 +68,12 @@ extern int compat13; extern int compat20; extern int datafellows; + + +#define SSH_X509RSA_MD5 0 +#define SSH_X509RSA_SHA1 1 +int ssh_x509rsasig(int _x509rsasigtype); + +extern int x509rsasigtype; + #endif diff -ruN openssh-3.6.1p2+x509g1/config.h.in openssh-3.6.1p2+x509g2/config.h.in --- openssh-3.6.1p2+x509g1/config.h.in 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/config.h.in 2003-06-12 09:06:01.000000000 +0300 @@ -1,5 +1,5 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -/* $Id$*/ +/* $Id: acconfig.h,v 1.149 2003/03/10 00:38:10 djm Exp $ */ #ifndef _CONFIG_H #define _CONFIG_H @@ -292,9 +292,6 @@ /* Specify default $PATH */ #undef USER_PATH -/* Specify location of ssh CA root */ -#undef SSHCADIR - /* Specify location of ssh.pid */ #undef _PATH_SSH_PIDDIR @@ -921,6 +918,16 @@ /* The size of a `short int', as computed by sizeof. */ #undef SIZEOF_SHORT_INT +/* Specify location of ssh CA root */ +#undef SSHCADIR + +/* Define if your openssl library don't support Email in X.509 'Distinguished + Name' */ +#undef SSH_OPENSSL_DN_WITHOUT_EMAIL + +/* Define if you don't want to verify certificates */ +#undef SSH_X509STORE_DISABLED + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff -ruN openssh-3.6.1p2+x509g1/configure openssh-3.6.1p2+x509g2/configure --- openssh-3.6.1p2+x509g1/configure 2003-04-30 09:06:02.000000000 +0300 +++ openssh-3.6.1p2+x509g2/configure 2003-06-12 09:06:02.000000000 +0300 @@ -845,6 +845,7 @@ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files --disable-strip Disable calling strip(1) on install + --disable-x509store Disable X.509 store --disable-lastlog disable use of lastlog even if detected no --disable-utmp disable use of utmp even if detected no --disable-utmpx disable use of utmpx even if detected no @@ -17519,6 +17520,7 @@ fi; + cat >>confdefs.h <<_ACEOF #define SSHCADIR "$sshcadir" _ACEOF @@ -17526,6 +17528,94 @@ +ssh_x509store="yes" +ssh_x509dn_email="yes" +# Check whether --enable-x509store or --disable-x509store was given. +if test "${enable_x509store+set}" = set; then + enableval="$enable_x509store" + + if test "x$enableval" = "xno" ; then + ssh_x509store="no" + fi + + +fi; +if test "x$ssh_x509store" = "xno"; then + +cat >>confdefs.h <<_ACEOF +#define SSH_X509STORE_DISABLED 1 +_ACEOF + +else + # Check for Email in X.509 'Distinguished Name' + echo "$as_me:$LINENO: checking for Email in X.509 'Distinguished Name'" >&5 +echo $ECHO_N "checking for Email in X.509 'Distinguished Name'... $ECHO_C" >&6 + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + +int main(void) { + int nid; + nid = OBJ_txt2nid("Email"); + if (nid == NID_undef) + exit (1); + exit (0); + return (0); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ssh_x509dn_email="no" + + +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +if test "x$ssh_x509dn_email" = "xno"; then + +cat >>confdefs.h <<_ACEOF +#define SSH_OPENSSL_DN_WITHOUT_EMAIL 1 +_ACEOF + +fi + # Where to place sshd.pid piddir=/var/run # make sure the directory exists @@ -19242,6 +19332,7 @@ echo " S/KEY support: $SKEY_MSG" echo " TCP Wrappers support: $TCPW_MSG" echo " MD5 password support: $MD5_MSG" +echo " X.509 store support: $ssh_x509store" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Use IPv4 by default hack: $IPV4_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" diff -ruN openssh-3.6.1p2+x509g1/configure.ac openssh-3.6.1p2+x509g2/configure.ac --- openssh-3.6.1p2+x509g1/configure.ac 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/configure.ac 2003-06-12 09:06:00.000000000 +0300 @@ -2277,10 +2277,55 @@ ] ) -AC_DEFINE_UNQUOTED(SSHCADIR, "$sshcadir") +AC_DEFINE_UNQUOTED(SSHCADIR, "$sshcadir", [Specify location of ssh CA root]) AC_SUBST(sshcadir) +ssh_x509store="yes" +ssh_x509dn_email="yes" +AC_ARG_ENABLE(x509store, + [ --disable-x509store Disable X.509 store], + [ + if test "x$enableval" = "xno" ; then + ssh_x509store="no" + fi + ] +) +if test "x$ssh_x509store" = "xno"; then + AC_DEFINE_UNQUOTED( + SSH_X509STORE_DISABLED, 1, + [Define if you don't want to verify certificates]) +else + # Check for Email in X.509 'Distinguished Name' + AC_MSG_CHECKING([for Email in X.509 'Distinguished Name']) + AC_TRY_RUN( + [ +#include + +int main(void) { + int nid; + nid = OBJ_txt2nid("Email"); + if (nid == NID_undef) + exit (1); + exit (0); + return (0); +} + ], + [ + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + ssh_x509dn_email="no" + ] +) +fi +if test "x$ssh_x509dn_email" = "xno"; then + AC_DEFINE_UNQUOTED( + SSH_OPENSSL_DN_WITHOUT_EMAIL, 1, + [Define if your openssl library don't support Email in X.509 'Distinguished Name']) +fi + # Where to place sshd.pid piddir=/var/run # make sure the directory exists @@ -2585,6 +2630,7 @@ echo " S/KEY support: $SKEY_MSG" echo " TCP Wrappers support: $TCPW_MSG" echo " MD5 password support: $MD5_MSG" +echo " X.509 store support: $ssh_x509store" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Use IPv4 by default hack: $IPV4_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" diff -ruN openssh-3.6.1p2+x509g1/hostfile.c openssh-3.6.1p2+x509g2/hostfile.c --- openssh-3.6.1p2+x509g1/hostfile.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/hostfile.c 2003-06-12 09:06:01.000000000 +0300 @@ -14,7 +14,7 @@ * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. * Copyright (c) 1999 Niels Provos. All rights reserved. * X509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -224,12 +224,16 @@ if (!f) return 0; fprintf(f, "%s ", host); +#ifndef SSH_X509STORE_DISABLED if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { /* key_write will print x509 certificate in blob format :-( */ success = x509key_write_subject(key, f); } else { +#endif /*ndef SSH_X509STORE_DISABLED*/ success = key_write(key, f); +#ifndef SSH_X509STORE_DISABLED } +#endif /*ndef SSH_X509STORE_DISABLED*/ if (success) { success = 1; } else { diff -ruN openssh-3.6.1p2+x509g1/INSTALL openssh-3.6.1p2+x509g2/INSTALL --- openssh-3.6.1p2+x509g1/INSTALL 2002-07-25 07:36:25.000000000 +0300 +++ openssh-3.6.1p2+x509g2/INSTALL 2003-06-12 09:06:00.000000000 +0300 @@ -56,6 +56,9 @@ installed. No other current S/Key library is currently known to be supported. +X.509 certificate support: +http://roumenpetrov.info/openssh + 2. Building / Installation -------------------------- @@ -177,6 +180,15 @@ --with-sectok=DIR allows for OpenSC or sectok smartcard libraries to be used with OpenSSH. See 'README.smartcard' for more details. +--with-sshca-dir=PATH allows you to specify location of ssh CA root +used by ssh "x509 store" to verify certificates. + +--disable-x509store allows you to disable ssh "x509 store". In that +case ssh don't verify certificates. Format "Distinguished Name" for a +certificate in ssh files is disabled too. In that case ssh accept only +blob format of certificate in files (aka format of pub files). +See 'README.x509v3' for more details. + If you need to pass special options to the compiler or linker, you can specify these as environment variables before running ./configure. For example: @@ -217,4 +229,4 @@ http://www.openssh.com/ -$Id: INSTALL,v 1.55 2002/07/25 04:36:25 djm Exp $ +$Id$ diff -ruN openssh-3.6.1p2+x509g1/key.c openssh-3.6.1p2+x509g2/key.c --- openssh-3.6.1p2+x509g1/key.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/key.c 2003-06-12 09:06:01.000000000 +0300 @@ -11,7 +11,7 @@ * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * X509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -197,21 +197,29 @@ switch (a->type) { case KEY_RSA1: case KEY_RSA: +#ifdef SSH_X509STORE_DISABLED + case KEY_X509_RSA: +#endif return a->rsa != NULL && b->rsa != NULL && BN_cmp(a->rsa->e, b->rsa->e) == 0 && BN_cmp(a->rsa->n, b->rsa->n) == 0; break; case KEY_DSA: +#ifdef SSH_X509STORE_DISABLED + case KEY_X509_DSA: +#endif return a->dsa != NULL && b->dsa != NULL && BN_cmp(a->dsa->p, b->dsa->p) == 0 && BN_cmp(a->dsa->q, b->dsa->q) == 0 && BN_cmp(a->dsa->g, b->dsa->g) == 0 && BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; break; +#ifndef SSH_X509STORE_DISABLED case KEY_X509_RSA: case KEY_X509_DSA: return ssh_x509_equal(a, b) == 0; break; +#endif /*ndef SSH_X509STORE_DISABLED*/ default: fatal("key_equal: bad key type %d", a->type); break; @@ -484,9 +492,11 @@ debug3("key_read: type mismatch"); return -1; } +#ifndef SSH_X509STORE_DISABLED k = x509key_from_subject(type, cp); if(k != NULL) goto noblob; +#endif /*ndef SSH_X509STORE_DISABLED*/ len = 2*strlen(cp); blob = xmalloc(len); n = uudecode(cp, blob, len); diff -ruN openssh-3.6.1p2+x509g1/LICENCE openssh-3.6.1p2+x509g2/LICENCE --- openssh-3.6.1p2+x509g1/LICENCE 2002-06-21 04:19:12.000000000 +0300 +++ openssh-3.6.1p2+x509g2/LICENCE 2003-06-12 09:06:00.000000000 +0300 @@ -192,6 +192,7 @@ Kevin Steves Daniel Kouril Per Allansson + Roumen Petrov * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -ruN openssh-3.6.1p2+x509g1/readconf.c openssh-3.6.1p2+x509g2/readconf.c --- openssh-3.6.1p2+x509g1/readconf.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/readconf.c 2003-06-12 09:06:01.000000000 +0300 @@ -10,8 +10,8 @@ * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". * - * X509 certificate store support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * X509 certificate support, + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -138,6 +138,7 @@ oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, oClearAllForwardings, oNoHostAuthenticationForLocalhost, + sX509rsaSigType, sAllowedServerCertPurpose, sCACertificateFile, sCACertificatePath, sCARevocationFile, sCARevocationPath, @@ -217,6 +218,7 @@ { "clearallforwardings", oClearAllForwardings }, { "enablesshkeysign", oEnableSSHKeysign }, { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, + { "x509rsasigtype", sX509rsaSigType }, { "allowedcertpurpose", sAllowedServerCertPurpose }, { "cacertificatefile", sCACertificateFile }, { "cacertificatepath", sCACertificatePath }, @@ -708,6 +710,22 @@ intptr = &options->enable_ssh_keysign; goto parse_flag; + case sX509rsaSigType: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + + if (strcasecmp(arg, "md5") == 0) + options->x509rsasigtype = SSH_X509RSA_MD5; + else if (strcasecmp(arg, "sha1") == 0) + options->x509rsasigtype = SSH_X509RSA_SHA1; + + if (options->x509rsasigtype < 0) { + fatal("%s line %d: Unsupported argument for X509rsaSigType.", + filename, linenum); + } + break; + case sAllowedServerCertPurpose: arg = strdelim(&s); if (arg && *arg) { @@ -715,7 +733,7 @@ { /* convert string to OpenSSL index */ int purpose_index; - purpose_index = sshserver_cert_purpose (arg); + purpose_index = ssh_get_x509purpose_s (0, arg); if (purpose_index < 0) fatal("config error: unsupported purpose '%.30s' in file %s line %d.", arg, filename, linenum); @@ -737,6 +755,7 @@ case sUserCARevocationFile: case sUserCARevocationPath: arg = strdelim(&s); +#ifndef SSH_X509STORE_DISABLED if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); switch (opcode) { @@ -758,6 +777,11 @@ options->userca.revocation_path = xstrdup(arg); break; default: } +#else /*def SSH_X509STORE_DISABLED*/ + debug("%s line %d: Unsupported option \"%s\"", + filename, linenum, keyword); + for(; arg; arg = strdelim(&s)); +#endif /*def SSH_X509STORE_DISABLED*/ break; case oDeprecated: @@ -885,7 +909,9 @@ options->smartcard_device = NULL; options->enable_ssh_keysign = - 1; options->no_host_authentication_for_localhost = - 1; + options->x509rsasigtype = -1; options->allowedcertpurpose = -1; +#ifndef SSH_X509STORE_DISABLED options->ca.certificate_file = NULL; options->ca.certificate_path = NULL; options->ca.revocation_file = NULL; @@ -894,14 +920,14 @@ options->userca.certificate_path = NULL; options->userca.revocation_file = NULL; options->userca.revocation_path = NULL; +#endif /*ndef SSH_X509STORE_DISABLED*/ } +#ifndef SSH_X509STORE_DISABLED static int ssh_x509store_init (Options *options) { int x509_store_loaded = 0; - ssh_x509store_setpurpose(options->allowedcertpurpose); - if(ssh_x509store_addlocations(&options->userca)) { x509_store_loaded = 1; } @@ -911,7 +937,9 @@ return x509_store_loaded; } +#endif /*ndef SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED static void tilde_expand_filename2(char **_fn, char* _default) { extern uid_t original_real_uid; @@ -920,10 +948,11 @@ *_fn = tilde_expand_filename(_default, original_real_uid); } else { char *p = *_fn; - *_fn = tilde_expand_filename(*_fn, original_real_uid); + *_fn = tilde_expand_filename(p, original_real_uid); xfree(p); } } +#endif /*ndef SSH_X509STORE_DISABLED*/ /* * Called after processing other sources of option data, this fills those @@ -1045,8 +1074,13 @@ /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ + if (options->x509rsasigtype == -1) + options->x509rsasigtype = SSH_X509RSA_MD5; + options->x509rsasigtype = ssh_x509rsasig(options->x509rsasigtype); if (options->allowedcertpurpose == -1) - options->allowedcertpurpose = sshserver_cert_purpose("sslserver"); + options->allowedcertpurpose = ssh_get_default_x509purpose(0); + ssh_set_x509purpose(0, options->allowedcertpurpose); +#ifndef SSH_X509STORE_DISABLED if (options->ca.certificate_file == NULL) options->ca.certificate_file = _PATH_CA_CERTIFICATE_FILE; if (options->ca.certificate_path == NULL) @@ -1062,4 +1096,5 @@ tilde_expand_filename2(&options->userca.revocation_path , _PATH_USERCA_REVOCATION_PATH ); ssh_x509store_init(options); +#endif /*ndef SSH_X509STORE_DISABLED*/ } diff -ruN openssh-3.6.1p2+x509g1/readconf.h openssh-3.6.1p2+x509g2/readconf.h --- openssh-3.6.1p2+x509g1/readconf.h 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/readconf.h 2003-06-12 09:06:00.000000000 +0300 @@ -12,8 +12,8 @@ * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". * - * X509 certificate store support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * X509 certificate support, + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -126,13 +126,17 @@ int enable_ssh_keysign; int no_host_authentication_for_localhost; - + + /* rumen-XXX: X509 RSA signature type: md5=0, sha1=1 */ + int x509rsasigtype; /* allowed server certificate purpose */ int allowedcertpurpose; +#ifndef SSH_X509STORE_DISABLED /* sshd PKI(X509) global store */ X509StoreOptions ca; /* sshd PKI(X509) user store */ X509StoreOptions userca; +#endif /*ndef SSH_X509STORE_DISABLED*/ } Options; diff -ruN openssh-3.6.1p2+x509g1/README.x509v3 openssh-3.6.1p2+x509g2/README.x509v3 --- openssh-3.6.1p2+x509g1/README.x509v3 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/README.x509v3 2003-06-11 11:51:51.000000000 +0300 @@ -1,6 +1,6 @@ Roumen Petrov Sofia, Bulgaria - Wed Apr 30 2003 + Tue Jun 11 2003 How to use X.509 certificates with OpenSSH? @@ -23,10 +23,11 @@ 1.) server configuration: 1.1.) .../sshd_config -1.1.1.) "X509 store". "X509 store" is used to verify client keys. +1.1.1.) AllowedCertPurpose sslclient - The intended use off the X509 client certificate. + The intended use off the X.509 client certificate. +1.1.2.) "X509 store". Server use "X509 store" to verify client keys. CACertificateFile /etc/ssh/ca/ca-bundle.crt This file contain multiple certificates of certificate signers in PEM format concatenated together. You can get a copy from openssl, apache, @@ -52,14 +53,26 @@ integer starting from zero. Hash is result from command like this: $ openssl crl -in crl_file_name -noout -hash -1.1.2.) HostKey files... +1.1.3.) HostKey files... Host key for protocol version 2 can contain private key plus x509 certificate in PEM format. +1.1.4.) +X509rsaSigType=md5 + Specifies prefered signature digest type for "x509v3-sign-rsa" keys. +The possible values are "md5" and "sha1". When X.509 certificate +signature blob fail with specified value, server try other and print +log message like this: +... X509COMPAT: RSA succeed for sha1 digest ... +This options is intended to collect information about default +signature digest type in other SecSH implementations. +When you see this PLEASE send a EMAIL with "X509COMPAT" lines +from log files. + 1.2.) append in USER_HOME/.ssh/authorized_keys a record with following format: - +{|CertBlob} where: KEY_TYPE:=x509v3-sign-rsa|x509v3-sign-dss (case sensitive !) WORDDN:={Distinguished Name| @@ -80,42 +93,70 @@ - Order of items in is not important and separator can be symbol "/", "," or mixed. All following subjects are equal: -a)CN=OpenSSH RSA test certificate(dsa),OU=OpenSSH Testers,O=OpenSSH Test Team,ST=World,C=XX -b)/C=XX/ST=World/O=OpenSSH Test Team/OU=OpenSSH Testers/CN=OpenSSH RSA test certificate(dsa) -c)/O=OpenSSH Test Team/OU=OpenSSH Testers/C=XX/ST=World/CN=OpenSSH RSA test certificate(dsa) -d)O=OpenSSH Test Team,OU=OpenSSH Testers/C=XX,ST=World/CN=OpenSSH RSA test certificate(dsa) +a)CN=dsa test certificate,OU=OpenSSH Testers,O=Test Team,ST=World,C=XX +b)/C=XX/ST=World/O=Test Team/OU=OpenSSH Testers/CN=dsa test certificate +c)/O=Test Team/OU=OpenSSH Testers/C=XX/ST=World/CN=dsa test certificate +d)O=Test Team,OU=OpenSSH Testers/C=XX,ST=World/CN=dsa test certificate +- CertBlob is uuencoded sequence of bytes in only one line. Shell sample: -$ printf 'x509v3-sign-rsa '; +- "Distinguished Name" format: +$ ( printf 'x509v3-sign-rsa '; openssl x509 -noout -subject \ - -in A_OPENSSH_CERT_FILE \ + -in A_OPENSSH_IDENTITY_FILE \ + ) >> $HOME/.ssh/authorized_keys + +- "blob" format: +$ cat A_OPENSSH_IDENTITY_FILE.pub \ >> $HOME/.ssh/authorized_keys NOTES: - adjust user authorized_keys file ownership - user must have at least read access. - SecSH x509v3 key type is "x509v3-sign-rsa" or "x509v3-sign-dss". - +- When OpenSSH is build with "--disable-x509store" YOU CANNOT USE +"Distinguished Name" format. You shold use ONLY "blob" format. 2.) client settings: 2.1.) IdentityFile Depends from client. To use X.509 certificate "OpenSSH id-file" must contain both sections - private key and certificate in PEM format: Note: Don't forget to update public key file with command: -$ ssh-keygen -y -f KEY_FILE_NAME > KEY_FILE_NAME.pub +$ ssh-keygen -y -f IDENTITY_FILE > IDENTITY_FILE.pub Command ssh-add use public key file! -2.2.) global ssh_config or $HOME/.ssh/config - Check options AllowedCertPurpose, [User]CACertificatePath, -[User]CACertificateFile, [User]CARevocationFile and -[User]CARevocationPath. See p. 1.1.1. All nine options are for "x509 -store". "x509 store" is used to verify server hostkey. +2.2.) global ssh_config, $HOME/.ssh/config or command line + +2.2.1.) +AllowedCertPurpose sslserver + The intended use off the X.509 server certificate. + +2.2.2.) "X509 store". Client use "x509 store" to verify server hostkey. + Check options: +- [User]CACertificatePath; +- [User]CACertificateFile; +- [User]CARevocationFile; +- [User]CARevocationPath. + See p. 1.1.2.). Note: When we use own CA we must import CA certificate[s] to "x509 store". More info on: http://roumenpetrov.info/domino_CA/#dca2bundle +2.2.3.) +X509rsaSigType=md5 + Temporary option. Specifies signature digest type for +'x509v3-sign-rsa' keys. The possible values are "md5" and "sha1". Use +this option only in session with other SecSH servers with X.509 +certificates as identity or host key. When ssh print message like this +... X509COMPAT: RSA succeed for sha1 digest ... +PLEASE send a EMAIL with this message. +When you cannot use X.509 certificate as identity in session with other +SecSH implementations try this option. Example: +$ ssh -o X509rsaSigType=sha1 .... non_openssh_host + +Note: ssh-agent use only md5 digest for X.509 certificates. 3.) test x509 certificates. @@ -138,7 +179,7 @@ Some command in a test script must fail. Part of "simple information" about command expected to fail is in RED(!). When command fail script print "done" (THIS IS CORRECT - COMMAND MUST FAIL) and on next lines -print in GREEN(!) response. Usualy this occur when server reject logon. +print in GREEN(!) response. Usually this occur when server reject logon. WHEN ALL TESTS SUCCEED output is: .... Testing OpenSSH client with certificates finished. @@ -150,8 +191,9 @@ 3.1.1.) Description of variables in Makefile file: - SHELL - Used shell to run tests. For example: - make check SHELL=/bin/zsh + Used shell to run tests. Supported shell are bash, ksh, zsh and ash. + Example: + $ make check SHELL=/bin/zsh 3.1.2.) Description of variables in config file: @@ -210,6 +252,7 @@ $ SSHD_PORT=1122 SSH_X509TESTS="agent blob_auth" make check $ RSA_DIGEST_LIST="md5 sha1" make check $ make check SHELL=/bin/ksh + When check fail see "Troubleshooting" later in document. @@ -253,8 +296,8 @@ file. Files without extention are openssh identity or hostkey files. File with .pub extention contain openssh public key (BLOB format). File with .crt extention contain openssl "text output" for identity - files. File with .p12 extention are for "Microsoft Windows keystore". - + files. Files with .p12 extention are for "Microsoft Windows keystore". +Note: .p12 = .pfx for Windows. verify.sh: to check certificates against "Test CA". Note: check only @@ -275,17 +318,17 @@ Note that hostbased authentication we cannot test without to install. Generated testhostkey_* certificates are with sslserver and sslclient -purposes and you can use them to test manualy hostbased authentication. +purposes and you can use them to test manually hostbased authentication. 4.) Troubleshooting make check fails on: 4.1.) "... 1-cre_cadb.sh: local: not found" -run: [ENVSETTINGS] make check SHELL=/bin/ksh +try other shell: [ENVSETTINGS] make check SHELL=/bin/ksh 4.2.) "generating a new ... private key for the TEST CA ..." -Usially this happen on system without /dev/{u}random. +Usually this happen on system without /dev/{u}random. In file [BUILDDIR]/tests/CA/openssh_ca-2.log we can see a message: "... PRNG not seeded ...". Read again WARNING.RNG from OpenSSH sourcedir and/or @@ -309,7 +352,10 @@ /usr/local/ssl/bin/openssl genrsa -des3 -passout pass:change_it Tip: before to create every key with OpenSSL run ssh-rand-helper ! -4.2.2.4.) run againg "... make check ..." +4.2.2.4.) run again "... make check ..." + +4.3.) fail on first check: "* rsa_md5 valid blob failed" +Usually SUDO command is not set. See p. 3.1.2.1. Enjoy ;-) diff -ruN openssh-3.6.1p2+x509g1/servconf.c openssh-3.6.1p2+x509g2/servconf.c --- openssh-3.6.1p2+x509g1/servconf.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/servconf.c 2003-06-12 09:06:01.000000000 +0300 @@ -8,8 +8,8 @@ * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". * - * X509 certificate store support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * X509 certificate support, + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -146,29 +146,19 @@ options->client_alive_count_max = -1; options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; + options->x509rsasigtype = -1; options->allowedcertpurpose = -1; +#ifndef SSH_X509STORE_DISABLED options->ca.certificate_file = NULL; options->ca.certificate_path = NULL; options->ca.revocation_file = NULL; options->ca.revocation_path = NULL; +#endif /*ndef SSH_X509STORE_DISABLED*/ /* Needs to be accessable in many places */ use_privsep = -1; } -static int -sshd_x509store_init (ServerOptions *options) { - int x509_store_loaded = 0; - - ssh_x509store_setpurpose(options->allowedcertpurpose); - - if(ssh_x509store_addlocations(&options->ca)) { - x509_store_loaded = 1; - } - - return x509_store_loaded; -} - void fill_default_server_options(ServerOptions *options) { @@ -297,8 +287,13 @@ if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + if (options->x509rsasigtype == -1) + options->x509rsasigtype = SSH_X509RSA_MD5; + options->x509rsasigtype = ssh_x509rsasig(options->x509rsasigtype); if (options->allowedcertpurpose == -1) - options->allowedcertpurpose = sshclient_cert_purpose("sslclient"); + options->allowedcertpurpose = ssh_get_default_x509purpose(1); + ssh_set_x509purpose(1, options->allowedcertpurpose); +#ifndef SSH_X509STORE_DISABLED if (options->ca.certificate_file == NULL) options->ca.certificate_file = _PATH_CA_CERTIFICATE_FILE; if (options->ca.certificate_path == NULL) @@ -307,6 +302,8 @@ options->ca.revocation_file = _PATH_CA_REVOCATION_FILE; if (options->ca.revocation_path == NULL) options->ca.revocation_path = _PATH_CA_REVOCATION_PATH; + ssh_x509store_addlocations(&options->ca); +#endif /*ndef SSH_X509STORE_DISABLED*/ /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -320,8 +317,6 @@ options->compression = 0; } #endif - - sshd_x509store_init(options); } /* Keyword tokens. */ @@ -355,6 +350,7 @@ sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sUsePrivilegeSeparation, + sX509rsaSigType, sAllowedClientCertPurpose, sCACertificateFile, sCACertificatePath, sCARevocationFile, sCARevocationPath, @@ -436,6 +432,7 @@ { "authorizedkeysfile", sAuthorizedKeysFile }, { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, + { "x509rsasigtype", sX509rsaSigType }, { "allowedcertpurpose", sAllowedClientCertPurpose }, { "cacertificatefile", sCACertificateFile }, { "cacertificatepath", sCACertificatePath }, @@ -970,6 +967,21 @@ intptr = &options->client_alive_count_max; goto parse_int; + case sX509rsaSigType: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", filename, linenum); + + if (strcasecmp(arg, "md5") == 0) + options->x509rsasigtype = SSH_X509RSA_MD5; + else if (strcasecmp(arg, "sha1") == 0) + options->x509rsasigtype = SSH_X509RSA_SHA1; + + if (options->x509rsasigtype < 0) { + fatal("config error: unsupported X509rsaSigType '%.30s' in file %s line %d.", arg, filename, linenum); + } + break; + case sAllowedClientCertPurpose: arg = strdelim(&cp); if (arg && *arg) { @@ -977,7 +989,7 @@ { /* convert string to OpenSSL index */ int purpose_index; - purpose_index = sshclient_cert_purpose (arg); + purpose_index = ssh_get_x509purpose_s (1, arg); if (purpose_index < 0) fatal("config error: unsupported purpose '%.30s' in file %s line %d.", arg, filename, linenum); @@ -986,15 +998,15 @@ } else { skip_purpose: options->allowedcertpurpose = -2; - verbose("config warning: option is set to don`t check certificate purpose in file %s line %d.", filename, linenum); + verbose("config warning: option is set to don't check certificate purpose in file %s line %d.", filename, linenum); } break; - case sCACertificateFile: case sCACertificatePath: case sCARevocationFile: case sCARevocationPath: +#ifndef SSH_X509STORE_DISABLED arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); @@ -1009,6 +1021,11 @@ options->ca.revocation_path = xstrdup(arg); break; default: } +#else /*def SSH_X509STORE_DISABLED*/ + log("%s line %d: Unsupported option %s", + filename, linenum, arg); + for (; arg; arg = strdelim(&cp)); +#endif /*def SSH_X509STORE_DISABLED*/ break; case sDeprecated: diff -ruN openssh-3.6.1p2+x509g1/servconf.h openssh-3.6.1p2+x509g2/servconf.h --- openssh-3.6.1p2+x509g1/servconf.h 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/servconf.h 2003-06-12 09:06:00.000000000 +0300 @@ -12,8 +12,8 @@ * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". * - * X509 certificate store support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * X509 certificate support, + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -158,10 +158,14 @@ char *authorized_keys_file2; int pam_authentication_via_kbd_int; + /* rumen-XXX: X509 RSA signature type: md5=0, sha1=1 */ + int x509rsasigtype; /* allowed client certificate purpose */ int allowedcertpurpose; +#ifndef SSH_X509STORE_DISABLED /* sshd PKI(X509) global store */ X509StoreOptions ca; +#endif /*ndef SSH_X509STORE_DISABLED*/ } ServerOptions; void initialize_server_options(ServerOptions *); diff -ruN openssh-3.6.1p2+x509g1/ssh-add.c openssh-3.6.1p2+x509g2/ssh-add.c --- openssh-3.6.1p2+x509g1/ssh-add.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh-add.c 2003-06-12 09:06:01.000000000 +0300 @@ -13,7 +13,7 @@ * SSH2 implementation, * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * X509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -237,16 +237,20 @@ key_size(key), fp, comment, key_type(key)); xfree(fp); } else { +#ifndef SSH_X509STORE_DISABLED if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { /* key_write will print x509 certificate in blob format :-( */ if(!x509key_write_subject(key, stdout)) fprintf(stderr, "x509key_write_subject failed"); fprintf(stdout, "\n"); } else { - if (!key_write(key, stdout)) - fprintf(stderr, "key_write failed"); - fprintf(stdout, " %s\n", comment); +#endif /*ndef SSH_X509STORE_DISABLED*/ + if (!key_write(key, stdout)) + fprintf(stderr, "key_write failed"); + fprintf(stdout, " %s\n", comment); +#ifndef SSH_X509STORE_DISABLED } +#endif /*ndef SSH_X509STORE_DISABLED*/ } key_free(key); xfree(comment); diff -ruN openssh-3.6.1p2+x509g1/ssh-agent.c openssh-3.6.1p2+x509g2/ssh-agent.c --- openssh-3.6.1p2+x509g1/ssh-agent.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh-agent.c 2003-06-12 09:06:01.000000000 +0300 @@ -12,7 +12,7 @@ * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * X509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -508,6 +508,7 @@ } /* enable blinding */ switch (k->type) { + case KEY_X509_RSA: case KEY_RSA: case KEY_RSA1: if (RSA_blinding_on(k->rsa, NULL) != 1) { diff -ruN openssh-3.6.1p2+x509g1/ssh_config openssh-3.6.1p2+x509g2/ssh_config --- openssh-3.6.1p2+x509g1/ssh_config 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh_config 2003-06-12 09:06:00.000000000 +0300 @@ -34,6 +34,7 @@ # Cipher 3des # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc # EscapeChar ~ +# X509rsaSigType=md5 # AllowedCertPurpose sslserver # CACertificateFile /etc/ssh/ca/ca-bundle.crt # CACertificatePath /etc/ssh/ca/crt diff -ruN openssh-3.6.1p2+x509g1/ssh_config.0 openssh-3.6.1p2+x509g2/ssh_config.0 --- openssh-3.6.1p2+x509g1/ssh_config.0 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh_config.0 2003-06-12 09:06:00.000000000 +0300 @@ -423,6 +423,13 @@ Specifies the full pathname of the xauth(1) program. The default is /usr/X11R6/bin/xauth. + X509rsaSigType + Temporary option. Specifies signature digest type for + `x509v3-sign-rsa keys'. The possible values are ``md5'' and + ``sha1''. Use this option only in session with other SecSH + servers with X.509 certificates as identity or host key. The + default is ``md5''. + FILES $HOME/.ssh/config This is the per-user configuration file. The format of this file diff -ruN openssh-3.6.1p2+x509g1/ssh_config.5 openssh-3.6.1p2+x509g2/ssh_config.5 --- openssh-3.6.1p2+x509g1/ssh_config.5 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh_config.5 2003-06-12 09:06:00.000000000 +0300 @@ -708,6 +708,18 @@ program. The default is .Pa /usr/X11R6/bin/xauth . +.It Cm X509rsaSigType +Temporary option. +Specifies signature digest type for +.Sq x509v3-sign-rsa keys . +The possible values are +.Dq md5 +and +.Dq sha1 . +Use this option only in session with other SecSH servers +with X.509 certificates as identity or host key. +The default is +.Dq md5 . .El .Sh FILES .Bl -tag -width Ds diff -ruN openssh-3.6.1p2+x509g1/sshconnect.c openssh-3.6.1p2+x509g2/sshconnect.c --- openssh-3.6.1p2+x509g1/sshconnect.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/sshconnect.c 2003-06-12 09:06:01.000000000 +0300 @@ -12,7 +12,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. */ #include "includes.h" @@ -40,6 +40,18 @@ char *client_version_string = NULL; char *server_version_string = NULL; +/* rumen-XXX: X.509 RSASIG check */ +extern void (*plogx509rsasig)(char *msg); +static void logx509rsasig(char *msg) { + log("%.400s: server=%.200s (client=%.200s)", + msg, + (server_version_string ? server_version_string : "undefined"), + (client_version_string ? client_version_string : "undefined") + ); +} +/* rumen-XXX^ */ + + /* import */ extern Options options; extern char *__progname; @@ -455,6 +467,8 @@ chop(client_version_string); chop(server_version_string); debug("Local version string %.100s", client_version_string); + + plogx509rsasig = logx509rsasig; /* rumen-XXX: X.509 RSASIG check */ } /* defaults to 'no' */ diff -ruN openssh-3.6.1p2+x509g1/sshd.c openssh-3.6.1p2+x509g2/sshd.c --- openssh-3.6.1p2+x509g1/sshd.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/sshd.c 2003-06-12 09:06:01.000000000 +0300 @@ -21,7 +21,7 @@ * Copyright (c) 2002 Niels Provos. All rights reserved. * * X509 certificates support: - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -160,6 +160,17 @@ char *client_version_string = NULL; char *server_version_string = NULL; +/* rumen-XXX: X.509 RSASIG check */ +extern void (*plogx509rsasig)(char *msg); +static void logx509rsasig(char *msg) { + log("%.400s: client=%.200s (server=%.200s)", + msg, + (client_version_string ? client_version_string : "undefined"), + (server_version_string ? server_version_string : "undefined") + ); +} +/* rumen-XXX^ */ + /* for rekeying XXX fixme */ Kex *xxx_kex; @@ -484,6 +495,8 @@ server_version_string, client_version_string); fatal_cleanup(); } + + plogx509rsasig = logx509rsasig; /* rumen-XXX: X.509 RSASIG check */ } /* Destroy the host and server keys. They will no longer be needed. */ diff -ruN openssh-3.6.1p2+x509g1/sshd_config openssh-3.6.1p2+x509g2/sshd_config --- openssh-3.6.1p2+x509g1/sshd_config 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/sshd_config 2003-06-12 09:06:00.000000000 +0300 @@ -21,6 +21,9 @@ #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key +# Signarure for "x509v3-sign-rsa" keys: md5,sha1 +#X509rsaSigType=md5 + # The intended use for the X509 client certificate. Without this option # no chain verification will be done. Currently accepted uses are case # insensitive: @@ -28,7 +31,7 @@ # - "any", "Any Purpose", "Any_Purpose" or "AnyPurpose" # - "skip" or ""(empty): don`t check purpose. #AllowedCertPurpose sslclient - + # A file with multiple certificates of certificate signers # in PEM format concatenated together. #CACertificateFile /etc/ssh/ca/ca-bundle.crt diff -ruN openssh-3.6.1p2+x509g1/sshd_config.0 openssh-3.6.1p2+x509g2/sshd_config.0 --- openssh-3.6.1p2+x509g1/sshd_config.0 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/sshd_config.0 2003-06-12 09:06:00.000000000 +0300 @@ -461,6 +461,18 @@ Specifies the full pathname of the xauth(1) program. The default is /usr/X11R6/bin/xauth. + X509rsaSigType + Temporary option. Specifies prefered signature digest type for + `x509v3-sign-rsa' keys. The possible values are ``md5'' and + ``sha1''. Server use this value to compute signature for host + X.509 RSA certificates. In new client connection with X.509 RSA + certificate as identity when signature blob fail with specified + value, server try to check signature with other possible value + and print log message containing text like this: `X509COMPAT: RSA + succeed for sha1 digest'. This options is intended to collect + information about default signature digest type in other SecSH + implementations. The default is ``md5''. + Time Formats sshd command-line arguments and configuration file options that specify diff -ruN openssh-3.6.1p2+x509g1/sshd_config.5 openssh-3.6.1p2+x509g2/sshd_config.5 --- openssh-3.6.1p2+x509g1/sshd_config.5 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/sshd_config.5 2003-06-12 09:06:00.000000000 +0300 @@ -759,6 +759,26 @@ program. The default is .Pa /usr/X11R6/bin/xauth . +.It Cm X509rsaSigType +Temporary option. +Specifies prefered signature digest type for +.Sq x509v3-sign-rsa +keys. The possible values are +.Dq md5 +and +.Dq sha1 . +Server use this value to compute signature for +host X.509 RSA certificates. +In new client connection with X.509 RSA certificate as identity +when signature blob fail with specified value, +server try to check signature with other possible value and +print log message containing text like this: +.Sq X509COMPAT: RSA succeed for sha1 digest . +This options is intended to collect information +about default signature digest type +in other SecSH implementations. +The default is +.Dq md5 . .El .Ss Time Formats .Pp diff -ruN openssh-3.6.1p2+x509g1/ssh-keyscan.0 openssh-3.6.1p2+x509g2/ssh-keyscan.0 --- openssh-3.6.1p2+x509g1/ssh-keyscan.0 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh-keyscan.0 2003-06-12 09:06:00.000000000 +0300 @@ -35,7 +35,7 @@ -t type Specifies the type of the key to fetch from the scanned hosts. The possible values are ``rsa1'' for protocol version 1 and - ``rsa'' or ``ssh-rsa'' , ``dsa'' or ``ssh-rsa'' , + ``rsa'' or ``ssh-rsa'' , ``dsa'' or ``ssh-dss'' , ``x509v3-sign-rsa'' or ``x509v3-sign-dss'' for protocol version 2. Multiple values may be specified by separating them with com- mas. The default is ``rsa1''. @@ -83,7 +83,7 @@ host-or-namelist keytype base64-encoded-key - Where keytype is either ``ssh-rsa'' or ``ssh-dsa''. + Where keytype is either ``ssh-rsa'' or ``ssh-dss''. Output format for rsa and dsa keys with x509 certificates: diff -ruN openssh-3.6.1p2+x509g1/ssh-keyscan.1 openssh-3.6.1p2+x509g2/ssh-keyscan.1 --- openssh-3.6.1p2+x509g1/ssh-keyscan.1 2003-04-30 09:06:00.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh-keyscan.1 2003-06-12 09:06:00.000000000 +0300 @@ -7,7 +7,7 @@ .\" OpenBSD project by leaving this copyright notice intact. .\" .\" X509 certificates support, -.\" Copyright (c) 2002 Roumen Petrov. All rights reserved. +.\" Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -90,7 +90,7 @@ , .Dq dsa or -.Dq ssh-rsa +.Dq ssh-dss , .Dq x509v3-sign-rsa or @@ -173,7 +173,7 @@ is either .Dq ssh-rsa or -.Dq ssh-dsa . +.Dq ssh-dss . .Pp .Pa Output format for rsa and dsa keys with x509 certificates: .Bd -literal diff -ruN openssh-3.6.1p2+x509g1/ssh-keyscan.c openssh-3.6.1p2+x509g2/ssh-keyscan.c --- openssh-3.6.1p2+x509g1/ssh-keyscan.c 2003-04-30 09:06:01.000000000 +0300 +++ openssh-3.6.1p2+x509g2/ssh-keyscan.c 2003-06-12 09:06:01.000000000 +0300 @@ -6,7 +6,7 @@ * OpenBSD project by leaving this copyright notice intact. * * X509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -377,17 +377,13 @@ packet_set_connection(c->c_fd, c->c_fd); enable_compat20(); -/* - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? - "ssh-dss": "ssh-rsa"; -*/ { Key k; switch (c->c_keytype) { case KT_DSA: k.type = KEY_DSA; break; case KT_RSA: k.type = KEY_RSA; break; - case KT_X509DSA: k.type = KEY_X509_RSA; break; - case KT_X509RSA: k.type = KEY_X509_DSA; break; + case KT_X509DSA: k.type = KEY_X509_DSA; break; + case KT_X509RSA: k.type = KEY_X509_RSA; break; default: fprintf(stderr, "keygrab_ssh2:Invalid keytype!\n"); exit(1); @@ -420,12 +416,16 @@ return; fprintf(stdout, "%s ", c->c_output_name ? c->c_output_name : c->c_name); +#ifndef SSH_X509STORE_DISABLED if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { /* key_write will print x509 certificate in blob format :-( */ x509key_write_subject(key, stdout); } else { - key_write(key, stdout); +#endif /*ndef SSH_X509STORE_DISABLED*/ + key_write(key, stdout); +#ifndef SSH_X509STORE_DISABLED } +#endif /*ndef SSH_X509STORE_DISABLED*/ fputs("\n", stdout); } @@ -731,7 +731,7 @@ static void usage(void) { - fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-f file]\n" + fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n" "\t\t [host | addrlist namelist] [...]\n", __progname); exit(1); diff -ruN openssh-3.6.1p2+x509g1/ssh-x509.c openssh-3.6.1p2+x509g2/ssh-x509.c --- openssh-3.6.1p2+x509g1/ssh-x509.c 2003-03-19 18:00:58.000000000 +0200 +++ openssh-3.6.1p2+x509g2/ssh-x509.c 2003-06-09 18:31:34.000000000 +0300 @@ -29,8 +29,22 @@ #include #include "bufaux.h" #include "x509store.h" +#include "compat.h" +static char* +openssl_errormsg(char *buf, size_t len) { + ERR_error_string_n(ERR_get_error(), buf, len); + + /* clear rest of errors in OpenSSL "error buffer" */ + ERR_clear_error(); + return buf; +} + +/* rumen-XXX: X.509 RSASIG check */ +void (*plogx509rsasig)(char *msg) = NULL; + +#ifndef SSH_X509STORE_DISABLED static char* x509key_find_subject(int _keytype, char* _cp) { static char *keywords[] = { @@ -74,8 +88,10 @@ } return NULL; } +#endif /*ndef SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED static int x509key_str2X509NAME(char* _str, X509_NAME *_name) { int ret = 1; @@ -117,6 +133,14 @@ } *q = 0; nid = OBJ_txt2nid(p); +#ifdef SSH_OPENSSL_DN_WITHOUT_EMAIL + if (nid == NID_undef) { + /* work around for OpenSSL 0.9.7+ */ + if (strcasecmp(p, "Email") == 0) { + nid = OBJ_txt2nid("emailAddress"); + } + } +#endif /* def SSH_OPENSSL_DN_WITHOUT_EMAIL */ *q = '='; if (nid == NID_undef) { error("x509key_str2X509NAME: cannot get nid from string '%.200s'", p); @@ -135,17 +159,14 @@ *q = 0; ret = X509_NAME_add_entry_by_NID(_name, nid, MBSTRING_ASC, p, q - p, -1, 0); if(ret <= 0) { - int ecode = ERR_get_error(); + char ebuf[256]; error("x509key_str2X509NAME: X509_NAME_add_entry_by_NID" - " fail with errormsg='%.200s'" + " fail with errormsg='%.256s'" " for nid=%d/%.32s" " and data='%.128s'" - , ERR_error_string(ecode, NULL) + , openssl_errormsg(ebuf, sizeof(ebuf)) , nid, OBJ_nid2ln(nid) , p); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); } *q = save; } @@ -160,8 +181,10 @@ debug3("x509key_str2X509NAME: return %d", ret); return ret; } +#endif /*ndef SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED Key* x509key_from_subject(int _keytype, char* _cp) { int ret = 1; @@ -202,6 +225,7 @@ debug3("x509key_from_subject: return %p", key); return key; } +#endif /*ndef SSH_X509STORE_DISABLED*/ static Key* @@ -212,11 +236,9 @@ env_pkey = X509_get_pubkey(x509); if (env_pkey == NULL) { - int ecode = ERR_get_error(); - error("x509_to_key: X509_get_pubkey fail %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + error("x509_to_key: X509_get_pubkey fail %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); return key; } else { @@ -272,15 +294,13 @@ X509* x509 = NULL; x509 = d2i_X509_bio(mbio,NULL); if (x509 == NULL) { - int ecode = ERR_get_error(); /* We will print only debug info !!! * This method is used in place where we can only check incomming data. * If data contain x506 certificate blob we will return a key otherwise NULL. */ - debug3("x509key_from_blob: read X509 from BIO fail %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + debug3("x509key_from_blob: read X509 from BIO fail %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); } else { key = x509_to_key(x509); @@ -382,6 +402,7 @@ } +#ifndef SSH_X509STORE_DISABLED int x509key_write_subject( Key *key, @@ -409,6 +430,7 @@ BIO_free_all(out); return 1; } +#endif /*ndef SSH_X509STORE_DISABLED*/ Key* @@ -422,11 +444,9 @@ (key->type == KEY_DSA) ) { key->x509 = PEM_read_X509(fp, NULL, NULL, NULL); if (key->x509 == NULL) { - int ecode = ERR_get_error(); - debug3("x509key_load_cert: PEM_read_X509 fail %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + debug3("x509key_load_cert: PEM_read_X509 fail %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); } else { key->type = (key->type == KEY_RSA) ? KEY_X509_RSA : KEY_X509_DSA; @@ -473,11 +493,9 @@ } ret = PEM_write_bio_X509(out, x509); if (!ret) { - int ecode = ERR_get_error(); - error("x509key_save_cert: PEM_write_bio_X509 fail %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + error("x509key_save_cert: PEM_write_bio_X509 fail %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); } BIO_free_all(out); @@ -510,6 +528,7 @@ } +#ifndef SSH_X509STORE_DISABLED static int ssh_ASN1_OBJECT_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { int lmin = MIN(a->length, b->length); @@ -520,8 +539,10 @@ ? (b->length - a->length) : ret; } +#endif /*ndef SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED static int ssh_ASN1_STRING_casecmp(const ASN1_STRING *a, const ASN1_STRING *b) { @@ -533,15 +554,16 @@ ? (M_ASN1_STRING_length(b) - M_ASN1_STRING_length(a)) : ret; } +#endif /*ndef SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED /* from RFC2459 (d) attribute values in PrintableString are compared after removing leading and trailing white space and converting internal substrings of one or more consecutive white space characters to a single space. */ - static int ssh_ASN1_PRINTABLESTRING_casecmp(const ASN1_STRING *a, const ASN1_STRING *b) { @@ -578,8 +600,10 @@ } return (lb - la); } +#endif /*ndef SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED /* 1.) Since version 0.9.7.beta4 and 0.9.6h OpenSSL function X509_NAME_cmp @@ -718,7 +742,10 @@ X509_NAME_free(b); return n; } +#endif /*ndef SSH_X509STORE_DISABLED*/ + +#ifndef SSH_X509STORE_DISABLED /* we can check only by Subject (Distinguished Name): - sshd receive from client only x509 certificate !!! - sshadd -d ... send only x509 certificate !!! @@ -745,6 +772,7 @@ return X509_subject_name_cmp(a->x509, b->x509); #endif } +#endif /*ndef SSH_X509STORE_DISABLED*/ int @@ -780,18 +808,25 @@ : EVP_PKEY_set1_DSA(privkey, key->dsa); if (ret <= 0) { - int ecode = ERR_get_error(); - error("ssh_x509_sign: EVP_PKEY_set1_XXX: failed %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + error("ssh_x509_sign: EVP_PKEY_set1_XXX: failed %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); } } if (ret > 0) { EVP_MD_CTX ctx; - const EVP_MD *evp_md = (key->rsa) ? EVP_md5() : EVP_dss1(); - debug3("ssh_x509_sign: evp_md { %d, %d, %d, ... }", evp_md->type, evp_md->pkey_type, evp_md->md_size); + const EVP_MD *evp_md; + if (key->rsa) { + evp_md = (x509rsasigtype == SSH_X509RSA_SHA1) ? EVP_sha1() : EVP_md5(); + } else { + evp_md = EVP_dss1(); + } + + debug3("ssh_x509_sign: evp_md { %d(%.30s), %d(%.30s), %d, ... }", + evp_md->type, OBJ_nid2ln(evp_md->type), + evp_md->pkey_type, OBJ_nid2ln(evp_md->pkey_type), + evp_md->md_size); EVP_SignInit(&ctx,evp_md); EVP_SignUpdate(&ctx,data,datalen); @@ -799,11 +834,9 @@ if (ret > 0) { ret = EVP_SignFinal(&ctx,sigret,&siglen,privkey); if (ret <= 0) { - int ecode = ERR_get_error(); - error("ssh_x509_sign: digest failed: %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + error("ssh_x509_sign: digest failed: %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); } } } @@ -887,24 +920,54 @@ if (ret > 0) { EVP_MD_CTX ctx; - const EVP_MD *evp_md = (key->rsa) ? EVP_md5() : EVP_dss1(); - debug3("ssh_x509_verify: evp_md { %d, %d, %d, ... }", evp_md->type, evp_md->pkey_type, evp_md->md_size); + const EVP_MD *evp_md; + if (key->rsa) { + evp_md = (x509rsasigtype == SSH_X509RSA_SHA1) ? EVP_sha1() : EVP_md5(); + } else { + evp_md = EVP_dss1(); + } + debug3("ssh_x509_verify: evp_md { %d(%.30s), %d(%.30s), %d, ... }", + evp_md->type, OBJ_nid2ln(evp_md->type), + evp_md->pkey_type, OBJ_nid2ln(evp_md->pkey_type), + evp_md->md_size); EVP_VerifyInit(&ctx,evp_md); EVP_VerifyUpdate(&ctx,data,datalen); ret = EVP_VerifyFinal(&ctx,sigblob,len,pubkey); + if ((ret <= 0) && key->rsa) { + /* rumen-XXX: X.509 RSASIG check */ + evp_md = (x509rsasigtype == SSH_X509RSA_SHA1) ? EVP_md5() : EVP_sha1(); + debug3("ssh_x509_verify: evp_md { %d(%.30s), %d(%.30s), %d, ... }", + evp_md->type, OBJ_nid2ln(evp_md->type), + evp_md->pkey_type, OBJ_nid2ln(evp_md->pkey_type), + evp_md->md_size); + + EVP_VerifyInit(&ctx,evp_md); + EVP_VerifyUpdate(&ctx,data,datalen); + ret = EVP_VerifyFinal(&ctx,sigblob,len,pubkey); + if (ret > 0) { + char *pmsg; + if (x509rsasigtype == SSH_X509RSA_SHA1) + pmsg = "X509COMPAT: RSA succeed for md5 digest"; + else + pmsg = "X509COMPAT: RSA succeed for sha1 digest"; + if (plogx509rsasig) + plogx509rsasig(pmsg); + else + log(pmsg); + } + } if (ret <= 0) { - int ecode = ERR_get_error(); - error("ssh_x509_verify: verify failed: %.200s", ERR_error_string(ecode, NULL)); - - /* clear rest of errors in OpenSSL "error buffer" */ - ERR_clear_error(); + char ebuf[256]; + error("ssh_x509_verify: verify failed: %.256s", + openssl_errormsg(ebuf, sizeof(ebuf))); ret = 0; } } + EVP_PKEY_free(pubkey); /* XXX ?*/ } if (ret > 0) { - ret = ssh_x509store_check(key->x509); + ret = ssh_x509cert_check(key->x509); } if (sigblob) { memset(sigblob, 's', len); diff -ruN openssh-3.6.1p2+x509g1/ssh-x509.h openssh-3.6.1p2+x509g2/ssh-x509.h --- openssh-3.6.1p2+x509g1/ssh-x509.h 2003-03-19 18:00:53.000000000 +0200 +++ openssh-3.6.1p2+x509g2/ssh-x509.h 2003-06-09 09:44:13.000000000 +0300 @@ -29,10 +29,12 @@ #include "key.h" #include "buffer.h" +#ifndef SSH_X509STORE_DISABLED /* * This method return a key(x509) only with "Subject"("Distinguished Name") ! */ Key* x509key_from_subject(int _keytype, char* _cp); +#endif /*ndef SSH_X509STORE_DISABLED*/ Key* x509key_from_blob(u_char *blob, int blen); @@ -43,15 +45,19 @@ /* write x509 certificate as blob */ int x509key_write(Key *key, FILE *f); +#ifndef SSH_X509STORE_DISABLED /* write x509 certificate subject */ int x509key_write_subject(Key *key, FILE *f); +#endif /*ndef SSH_X509STORE_DISABLED*/ Key* x509key_load_cert(Key *key, FILE *fp); int x509key_save_pem(FILE *fp, Key *key, const EVP_CIPHER *cipher, u_char *passphrase, int len); +#ifndef SSH_X509STORE_DISABLED int ssh_x509_equal(Key *a, Key *b); +#endif /*ndef SSH_X509STORE_DISABLED*/ int ssh_x509_sign(Key *, u_char **, u_int *, u_char *, u_int); int ssh_x509_verify(Key *key, u_char *signature, u_int signaturelen, u_char *data, u_int datalen); u_int ssh_x509_key_size(Key *key); diff -ruN openssh-3.6.1p2+x509g1/tests/CA/1-cre_cadb.sh openssh-3.6.1p2+x509g2/tests/CA/1-cre_cadb.sh --- openssh-3.6.1p2+x509g1/tests/CA/1-cre_cadb.sh 2003-03-19 18:12:17.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/1-cre_cadb.sh 2003-05-26 11:30:04.000000000 +0300 @@ -88,17 +88,18 @@ stateOrProvinceName_default = $SSH_DN_ST localityName = Locality Name (eg, city) +localityName_default = $SSH_DN_L 0.organizationName = Organization Name (eg, company) 0.organizationName_default = $SSH_DN_O -0.organizationalUnitName = Organizational Unit1 Name (eg, section1) +0.organizationalUnitName = Organizational Unit1 Name (eg, section1 - optional) 0.organizationalUnitName_default = ${SSH_DN_OU}-1 -1.organizationalUnitName = Organizational Unit2 Name (eg, section2) +1.organizationalUnitName = Organizational Unit2 Name (eg, section2 - optional) 1.organizationalUnitName_default = ${SSH_DN_OU}-2 -2.organizationalUnitName = Organizational Unit3 Name (eg, section3) +2.organizationalUnitName = Organizational Unit3 Name (eg, section3 - optional) 2.organizationalUnitName_default = ${SSH_DN_OU}-3 commonName = Common Name (eg, YOUR name) @@ -107,6 +108,7 @@ emailAddress = Email Address (optional) emailAddress_max = 40 +emailAddress_default = $SSH_DN_EM [ req_attributes ] challengePassword = A challenge password diff -ruN openssh-3.6.1p2+x509g1/tests/CA/2-cre_cakeys.sh openssh-3.6.1p2+x509g2/tests/CA/2-cre_cakeys.sh --- openssh-3.6.1p2+x509g1/tests/CA/2-cre_cakeys.sh 2003-03-19 18:54:04.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/2-cre_cakeys.sh 2003-06-11 12:09:08.000000000 +0300 @@ -43,9 +43,11 @@ cat </dev/null echo_SSH_CA_DN "rsa_${DIGEST}" | -$OPENSSL req -new -x509 \ +$OPENSSL req \ + -new -x509 \ + -config "${SSH_CACFGFILE}" \ -days $SSH_CACERTDAYS \ -passin pass:${KEY_PASS} \ -key "${TMPDIR}/${RSA_BASENAME}.key" \ @@ -118,7 +122,9 @@ rm -f "${TMPDIR}/${DSA_BASENAME}.crt" 2>/dev/null echo_SSH_CA_DN "dsa" | -$OPENSSL req -new -x509 \ +$OPENSSL req \ + -new -x509 \ + -config "${SSH_CACFGFILE}" \ -days $SSH_CACERTDAYS \ -passin pass:${KEY_PASS} \ -key "${TMPDIR}/${DSA_BASENAME}.key" \ diff -ruN openssh-3.6.1p2+x509g1/tests/CA/3-cre_certs.sh openssh-3.6.1p2+x509g2/tests/CA/3-cre_certs.sh --- openssh-3.6.1p2+x509g1/tests/CA/3-cre_certs.sh 2003-03-19 18:05:34.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/3-cre_certs.sh 2003-06-11 12:11:38.000000000 +0300 @@ -117,20 +117,27 @@ local subtype="$2" echo "=== create a new CSR ===" >> "$OPENSSH_LOG" - ( cat <> "$OPENSSH_LOG" - $OPENSSL ca -config "${SSH_CACFGFILE}" \ + $OPENSSL ca \ + -config "${SSH_CACFGFILE}" \ -batch \ -in "${TMPDIR}/${SSH_X509V3_EXTENSIONS}-${type}${subtype}.csr" \ -name "CA_OpenSSH_${type}" \ @@ -220,7 +228,8 @@ echo "=== revoke a CRT ===" >> "$OPENSSH_LOG" printf '%s' "revoke ${extd}certificate${norm} with signature ${attn}${type}${norm}${subtype} ..." - $OPENSSL ca -config "${SSH_CACFGFILE}" \ + $OPENSSL ca \ + -config "${SSH_CACFGFILE}" \ -name "CA_OpenSSH_${type}" \ -passin pass:$KEY_PASS \ -revoke "${SSH_BASE_KEY}-${type}${subtype}" \ @@ -232,6 +241,8 @@ # === cre_all2 () { local type="$1" + + echo cre_csr "${type}" && cre_crt "${type}" && cre_OpenSSH_Crt "${type}" && @@ -244,6 +255,7 @@ cre_all3 () { local type="$1" + echo cre_csr "${type}" "-revoked" && cre_crt "${type}" "-revoked" && cre_OpenSSH_Crt "${type}" "-revoked" && @@ -274,4 +286,5 @@ cre_all; retval=$? -show_status $retval "${extd}Creating ${warn}TEST certificates${norm} ${extd}wich common name:${norm}${attn}${SSH_BASE_DN_CN}${norm} ..." +echo +show_status $retval "${extd}Creating ${warn}TEST certificates${norm} ${extd}with common name:${norm}${attn}${SSH_BASE_DN_CN}${norm} ..." diff -ruN openssh-3.6.1p2+x509g1/tests/CA/4-cre_crls.sh openssh-3.6.1p2+x509g2/tests/CA/4-cre_crls.sh --- openssh-3.6.1p2+x509g1/tests/CA/4-cre_crls.sh 2003-03-19 18:05:18.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/4-cre_crls.sh 2003-05-26 10:10:45.000000000 +0300 @@ -44,7 +44,8 @@ FILE="${CAKEY_PREFIX}-${type}.crl.pem" printf '%s' "creating ${extd}CA CRL file${norm} for ${attn}${type}${norm} certificates..." - ${OPENSSL} ca -config "${SSH_CACFGFILE}" \ + ${OPENSSL} ca \ + -config "${SSH_CACFGFILE}" \ -name "CA_OpenSSH_${type}" \ -passin pass:$KEY_PASS \ -gencrl \ diff -ruN openssh-3.6.1p2+x509g1/tests/CA/config openssh-3.6.1p2+x509g2/tests/CA/config --- openssh-3.6.1p2+x509g1/tests/CA/config 2003-03-07 01:59:20.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/config 2003-06-09 19:12:17.000000000 +0300 @@ -85,6 +85,8 @@ # These are the known patent issues with OpenSSL: # name # expires # mdc2: 4,908,861 13/03/2007 +# idea: 5,214,703 25/05/2010 +# rc5: 5,724,428 03/03/2015 if test -z "${RSA_DIGEST_LIST}"; then for DIGEST in md5 sha1 md2 md4 rmd160; do @@ -141,5 +143,7 @@ SSH_DN_C="XX" SSH_DN_ST="World" +SSH_DN_L="Somewhere" SSH_DN_O="OpenSSH Test Team" SSH_DN_OU="OpenSSH Testers" +SSH_DN_EM="email@not.set" diff -ruN openssh-3.6.1p2+x509g1/tests/CA/Makefile.in openssh-3.6.1p2+x509g2/tests/CA/Makefile.in --- openssh-3.6.1p2+x509g1/tests/CA/Makefile.in 2003-03-19 18:17:31.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/Makefile.in 2003-05-26 11:35:07.000000000 +0300 @@ -15,15 +15,18 @@ # === check-certs: ca_files host_keys rsa_keys dsa_keys crl_files + @echo $(SHELL) $(srcdir)/openssh_tests.sh # === ca_files: ca-test/catest.config ca-test/catest-bundle.crt ca-test/catest.config: + @echo $(SHELL) $(srcdir)/1-cre_cadb.sh ca-test/catest-bundle.crt: + @echo $(SHELL) $(srcdir)/2-cre_cakeys.sh @@ -31,15 +34,23 @@ host_keys: testhostkey_rsa testhostkey_rsa-rsa_md5 testhostkey_dsa testhostkey_dsa-rsa_md5 testhostkey_rsa: + @echo + @echo "generating RSA 'hostkey'" $(TEST_SSH_SSHKEYGEN) -t rsa -b 1024 -f $@ -N "" testhostkey_rsa-rsa_md5: testhostkey_rsa + @echo + @echo "generating RSA server certificates, keys, etc." $(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_rsa -t server -n "localhost RSA" testhostkey_dsa: + @echo + @echo "generating DSA 'hostkey'" $(TEST_SSH_SSHKEYGEN) -t dsa -b 1024 -f $@ -N "" testhostkey_dsa-rsa_md5: testhostkey_dsa + @echo + @echo "generating DSA server certificates, keys, etc." $(SHELL) $(srcdir)/3-cre_certs.sh -f testhostkey_dsa -t server -n "localhost DSA" @@ -47,9 +58,13 @@ rsa_keys: testid_rsa testid_rsa-rsa_md5 testid_rsa: + @echo + @echo "generating RSA 'Identity'" $(TEST_SSH_SSHKEYGEN) -t rsa -b 1024 -f $@ -N "" testid_rsa-rsa_md5: testid_rsa + @echo + @echo "generating RSA client certificates, keys, etc." $(SHELL) $(srcdir)/3-cre_certs.sh -f testid_rsa -t client -n "OpenSSH RSA test certificate" @@ -57,9 +72,13 @@ dsa_keys: testid_dsa testid_dsa-rsa_md5 testid_dsa: + @echo + @echo "generating DSA 'Identity'" $(TEST_SSH_SSHKEYGEN) -t dsa -b 1024 -f $@ -N "" testid_dsa-rsa_md5: testid_dsa + @echo + @echo "generating DSA client certificates, keys, etc." $(SHELL) $(srcdir)/3-cre_certs.sh -f testid_dsa -t client -n "OpenSSH DSA test certificate" @@ -67,4 +86,5 @@ crl_files: ca-test/catest-bundle.crl ca-test/catest-bundle.crl: + @echo $(SHELL) $(srcdir)/4-cre_crls.sh diff -ruN openssh-3.6.1p2+x509g1/tests/CA/openssh_tests.sh openssh-3.6.1p2+x509g2/tests/CA/openssh_tests.sh --- openssh-3.6.1p2+x509g1/tests/CA/openssh_tests.sh 2003-03-19 19:12:37.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/openssh_tests.sh 2003-06-10 15:39:04.000000000 +0300 @@ -60,14 +60,39 @@ USERDIR="${HOME}/.ssh" if test ! -d "${USERDIR}"; then mkdir "${USERDIR}" || exit 1 + chmod 700 "${USERDIR}" || exit 1 fi -chmod 700 "${USERDIR}" || exit 1 AUTHORIZEDKEYSFILE="${USERDIR}/authorized_keys-certTests" USERKNOWNHOSTSFILE="${USERDIR}/known_hosts-certTests" # === +# remove unsupported tests + +cat > "$SSHD_CFG" < "${SSHD_LOG}" 2>&1 +if grep 'Unsupported.*CACertificateFile' "${SSHD_LOG}" > /dev/null; then + SSH_X509STORE_DISABLED="yes" +else + SSH_X509STORE_DISABLED="no" +fi + +echo SSH_X509STORE_DISABLED=${SSH_X509STORE_DISABLED} +if test "x${SSH_X509STORE_DISABLED}" = "xyes"; then + SSH_X509TESTS=`echo "${SSH_X509TESTS}" | \ + sed \ + -e 's|dn_auth_file||g' \ + -e 's|dn_auth_path||g' \ + -e 's|crl||g'` +fi +echo SSH_X509TESTS=$SSH_X509TESTS + + +# === runSSHdaemon() { echo "=======================================================================" >> "${SSHD_LOG}" @@ -152,6 +177,7 @@ #!NO(linux):KerberosAuthentication no #!NO(linux):KerberosOrLocalPasswd no #!NO(OpenBSD):PAMAuthenticationViaKbdInt no +StrictModes no PasswordAuthentication no PubkeyAuthentication yes RhostsAuthentication no @@ -162,6 +188,7 @@ HostKey ${TEST_SSHD_HOSTKEY} +#X509rsaSigType=md5 #AllowedCertPurpose sslclient EOF } @@ -174,6 +201,7 @@ StrictHostKeyChecking yes UserKnownHostsFile ${USERKNOWNHOSTSFILE} +#X509rsaSigType=md5 #AllowedCertPurpose sslserver CACertificatePath /path/not/found/global CACertificateFile ${SSH_CAROOT}/${CACERTFILE} @@ -293,6 +321,8 @@ # call the test scripts for LTEST in ${SSH_X509TESTS}; do ( + echo + echo "using: ${attn}${SCRIPTDIR}test-${LTEST}.sh.inc${norm}" . ${SCRIPTDIR}test-${LTEST}.sh.inc && do_test ) || return $? @@ -305,14 +335,17 @@ # === echo -echo "${extd}Testing OpenSSH client with certificates:${norm}" +printSeparator +echo "${extd}Testing OpenSSH client and server with certificates:${norm}" printSeparator do_all; retval=$? echo -echo "${extd}Testing OpenSSH client with certificates finished.${norm}" -show_status $retval " ${extd}retval${norm}:" +printSeparator +echo "${extd}Testing OpenSSH client and server with certificates finished.${norm}" +show_status $retval " ${extd}status${norm}:" +printSeparator echo exit $retval diff -ruN openssh-3.6.1p2+x509g1/tests/CA/test-agent.sh.inc openssh-3.6.1p2+x509g2/tests/CA/test-agent.sh.inc --- openssh-3.6.1p2+x509g1/tests/CA/test-agent.sh.inc 2003-03-07 14:37:52.000000000 +0200 +++ openssh-3.6.1p2+x509g2/tests/CA/test-agent.sh.inc 2003-05-29 12:38:07.000000000 +0300 @@ -35,13 +35,16 @@ error_file_not_readable "${identity_file}"; return $? fi - local sshkeytype - local subject + ( + if test "x${SSH_X509STORE_DISABLED}" = "xyes"; then + cat "${identity_file}.pub" + else + sshkeytype=`getSSHkeyType "${identity_file}"` || exit $? + subject=`getSubject "${identity_file}"` || exit $? - sshkeytype=`getSSHkeyType "${identity_file}"` || return $? - subject=`getSubject "${identity_file}"` || return $? - - echo "${sshkeytype} Subject: ${subject}" > "${AUTHORIZEDKEYSFILE}" + echo "${sshkeytype} Subject: ${subject}" + fi + ) > "${AUTHORIZEDKEYSFILE}" || return $? ( killAgent () { @@ -92,7 +95,11 @@ showAgentMsg ${retval} else printf " ${done}-${norm} " - cat "${SSH_REPLY}" + if test "x${SSH_X509STORE_DISABLED}" = "xyes"; then + printf '%s.......\n' "`cut -c -60 \"${SSH_REPLY}\"`" + else + cat "${SSH_REPLY}" + fi fi runTest "${type}" \ @@ -115,8 +122,11 @@ do_test () { local retval=0 - echo - echo "* ${extd}against ${attn}CACertificateFile${norm} and x509 key from ${attn}agent${norm}:" + if test "x${SSH_X509STORE_DISABLED}" = "xyes"; then + echo "* ${extd}with x509 identity from ${attn}agent${norm}:" + else + echo "* ${extd}against ${attn}CACertificateFile${norm} and x509 identity from ${attn}agent${norm}:" + fi creTestSSHDcfgFile cat >> "$SSHD_CFG" <> "$SSHD_CFG" <= 0) { - X509_PURPOSE *xptmp = X509_PURPOSE_get0(sshpurpose_index); - if (X509_STORE_CTX_set_purpose(_csc, X509_PURPOSE_get_id(xptmp)) == 0) { - int ecode = X509_STORE_CTX_get_error(_csc); - error("ssh_x509store_check: purpose error, code=%d, msg='%.200s'" + if (sshpurpose.index >= 0) { + int def_purpose = ( sshpurpose.is_server + ? X509_PURPOSE_SSL_CLIENT + : X509_PURPOSE_SSL_SERVER + ); + X509_PURPOSE *xptmp = X509_PURPOSE_get0(sshpurpose.index); + int purpose, flag; + if (xptmp == NULL) { + fatal("ssh_verify_cert: cannot get purpose from index"); + return -1; /* ;-) */ + } + purpose = X509_PURPOSE_get_id(xptmp); + flag = X509_STORE_CTX_purpose_inherit(_csc, def_purpose, purpose, 0); + if (flag <= 0) { + /* + * By default openssl applications don't check return code from + * X509_STORE_CTX_set_purpose or X509_STORE_CTX_purpose_inherit. + * + * Both methods return 0 (zero) and don't change purpose in context when: + * -X509_STORE_CTX_set_purpose (...) + * purpose is X509_PURPOSE_ANY + * -X509_STORE_CTX_purpose_inherit (...) + * purpose is X509_PURPOSE_ANY and default purpose is zero (!) + * + * Take note when purpose is "any" check method in current + * OpenSSL code just return 1. This openssl behavior is same + * as ssh option "AllowedCertPurpose=skip". + */ + int ecode; + char ebuf[256]; + + ecode = X509_STORE_CTX_get_error(_csc); + error("ssh_verify_cert: context purpose error, code=%d, msg='%.200s'" , ecode , X509_verify_cert_error_string(ecode)); + + ecode = ERR_get_error(); + ERR_error_string_n(ecode, ebuf, sizeof(ebuf)); + error("ssh_verify_cert: X509_STORE_CTX_purpose_inherit failed with '%.256s'" + , ebuf); + + /* clear rest of errors in OpenSSL "error buffer" */ + ERR_clear_error(); return -1; } } @@ -324,9 +388,9 @@ X509_STORE_CTX_set_flags(_csc, X509_V_FLAG_CB_ISSUER_CHECK); */ - if(X509_verify_cert(_csc) == 0) { + if (X509_verify_cert(_csc) == 0) { int ecode = X509_STORE_CTX_get_error(_csc); - error("ssh_x509store_check: verify error, code=%d, msg='%.200s'" + error("ssh_verify_cert: verify error, code=%d, msg='%.200s'" , ecode , X509_verify_cert_error_string(ecode)); return -1; @@ -334,28 +398,36 @@ return 1; } +#endif /*ndef SSH_X509STORE_DISABLED*/ int -ssh_x509store_check(X509 *_cert) { - X509_STORE_CTX *csc; +ssh_x509cert_check(X509 *_cert) { int ret = 1; +#ifndef SSH_X509STORE_DISABLED + X509_STORE_CTX *csc; +#else /*def SSH_X509STORE_DISABLED*/ + X509_PURPOSE *xptmp; +#endif /*def SSH_X509STORE_DISABLED*/ +#ifndef SSH_X509STORE_DISABLED if (x509store == NULL) { - error("ssh_x509store_check: context is NULL\n"); + error("ssh_x509cert_check: context is NULL\n"); return -1; } if (get_log_level() >= SYSLOG_LEVEL_DEBUG3) { char buf[512]; X509_NAME_oneline( X509_get_subject_name(_cert), buf, sizeof(buf)); - debug3("ssh_x509store_check: for '%.512s'", buf); + debug3("ssh_x509cert_check: for '%.512s'", buf); } csc = X509_STORE_CTX_new(); if (csc == NULL) { int ecode = ERR_get_error(); - error("ssh_x509store_check:X509_STORE_CTX_new failed with '%.200s'", ERR_error_string(ecode, NULL)); + char ebuf[256]; + ERR_error_string_n(ecode, ebuf, sizeof(ebuf)); + error("ssh_x509cert_check:X509_STORE_CTX_new failed with '%.256s'", ebuf); /* clear rest of errors in OpenSSL "error buffer" */ ERR_clear_error(); @@ -365,11 +437,26 @@ ret = ssh_verify_cert(csc, _cert); X509_STORE_CTX_free(csc); - debug3("ssh_x509store_check: return %d", ret); +#else /*def SSH_X509STORE_DISABLED*/ + if (sshpurpose.index >=0) { + xptmp = X509_PURPOSE_get0(sshpurpose.index); + if (xptmp == NULL) { + fatal("ssh_x509cert_check: cannot get purpose from index"); + return -1; /* ;-) */ + } + ret = X509_check_purpose(_cert, X509_PURPOSE_get_id(xptmp), 0); + if (ret < 0) { + log("ssh_x509cert_check: X509_check_purpose return %d", ret); + ret = 0; + } + } +#endif /*def SSH_X509STORE_DISABLED*/ + debug3("ssh_x509cert_check: return %d", ret); return (ret); } +#ifndef SSH_X509STORE_DISABLED #ifdef SSH_CHECK_REVOKED static int ssh_check_crl(X509_STORE_CTX *_ctx, X509_CRL *_crl) { @@ -565,3 +652,5 @@ return ok; } #endif + +#endif /*ndef SSH_X509STORE_DISABLED*/ diff -ruN openssh-3.6.1p2+x509g1/x509store.h openssh-3.6.1p2+x509g2/x509store.h --- openssh-3.6.1p2+x509g1/x509store.h 2003-03-19 18:01:09.000000000 +0200 +++ openssh-3.6.1p2+x509g2/x509store.h 2003-06-11 11:25:59.000000000 +0300 @@ -38,12 +38,16 @@ #endif -int ssh_x509store_check(X509 *_cert); +int ssh_x509cert_check(X509 *_cert); /* return purpose index, not purpose id (!) */ -int sshclient_cert_purpose (const char* _purpose_synonym); -int sshserver_cert_purpose (const char* _purpose_synonym); +int ssh_get_x509purpose_s (int _is_server, const char* _purpose_synonym); +int ssh_get_default_x509purpose(int _is_server); +void ssh_set_x509purpose(int _is_server, int _sshpurpose_index); + + +#ifndef SSH_X509STORE_DISABLED typedef struct { /* ssh PKI(X509) store */ @@ -53,7 +57,9 @@ char *revocation_path; } X509StoreOptions; -void ssh_x509store_setpurpose(int _sshpurpose_index); int ssh_x509store_addlocations (const X509StoreOptions *_locations); +#endif /*ndef SSH_X509STORE_DISABLED*/ + + #endif /* X509STORE_H */