diff -ruN openssh-4.3p1+x509-5.2/aclocal.m4 openssh-4.3p1+x509-5.3/aclocal.m4 --- openssh-4.3p1+x509-5.2/aclocal.m4 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/aclocal.m4 2006-02-03 09:06:00.000000000 +0200 @@ -88,8 +88,20 @@ # Options to build with LDAP # # Author: Roumen Petrov -# Revision: 29 Oct 2004 +# Revision: 19 Jul 2005 # +dnl The variables provided are : +dnl - build flags: +dnl LDAP_LDFLAGS +dnl LDAP_LIBS +dnl LDAP_CPPFLAGS +dnl - conditional: +dnl LDAP_ON (e.g. '' or '#') +dnl LDAP_OFF (e.g. '#' or '' - oposite of LDAP_ON) +dnl - paths: +dnl LDAP_BINDIR +dnl LDAP_LIBEXECDIR +dnl LDAP_SYSCONFDIR AC_DEFUN(AC_WITH_LDAP, [ @@ -158,7 +170,7 @@ dnl [ dnl $LDAP_SYSCONFDIR/schema/core.schema dnl $LDAP_SYSCONFDIR/schema/cosine.schema -dnl $LDAP_SYSCONFDIR/schema/inetorgperson.schema- +dnl $LDAP_SYSCONFDIR/schema/inetorgperson.schema dnl ] dnl ) dnl fi @@ -205,7 +217,7 @@ ac_ldap_libs="" AC_ARG_WITH(ldap-libs, [ --with-ldap-libs=LIBS Specify LDAP libraries to link with. - (defult is -lldap -llber -lssl -lcrypto)], + (default is -lldap -llber -lssl -lcrypto)], [ac_ldap_libs="$withval"] ) @@ -247,13 +259,9 @@ fi fi AC_MSG_RESULT([done]) - unset ac_LDAP_LINK LIBS="$ac_save_LIBS" LDFLAGS="$ac_save_LDFLAGS" AC_SUBST([LDAP_LIBS]) - - unset ac_ldap_libs - unset ac_ldap_prefix else AC_MSG_NOTICE([LDAP is disabled]) fi @@ -270,6 +278,4 @@ fi AC_SUBST(LDAP_ON) AC_SUBST(LDAP_OFF) - -unset ac_ldap ]) diff -ruN openssh-4.3p1+x509-5.2/compat.c openssh-4.3p1+x509-5.3/compat.c --- openssh-4.3p1+x509-5.2/compat.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/compat.c 2006-02-03 09:06:01.000000000 +0200 @@ -1,7 +1,5 @@ /* * 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 @@ -25,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD$"); +RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $"); #include "buffer.h" #include "packet.h" @@ -38,8 +36,6 @@ int compat20 = 0; int datafellows = 0; -int x509rsasigtype = SSH_X509RSA_MD5; - void enable_compat20(void) { @@ -231,19 +227,3 @@ 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; - logit("invalid x509rsa sigtype=%d, switched to default=%d", _x509rsasigtype, x509rsasigtype); - break; - } - debug3("x509rsa sigtype=%d", x509rsasigtype); - return (x509rsasigtype); -} diff -ruN openssh-4.3p1+x509-5.2/compat.h openssh-4.3p1+x509-5.3/compat.h --- openssh-4.3p1+x509-5.2/compat.h 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/compat.h 2006-02-03 09:06:00.000000000 +0200 @@ -1,9 +1,7 @@ -/* $OpenBSD$ */ +/* $OpenBSD: compat.h,v 1.38 2004/07/11 17:48:47 deraadt Exp $ */ /* * 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 @@ -68,12 +66,4 @@ 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-4.3p1+x509-5.2/configure openssh-4.3p1+x509-5.3/configure --- openssh-4.3p1+x509-5.2/configure 2006-02-03 09:06:02.000000000 +0200 +++ openssh-4.3p1+x509-5.3/configure 2006-02-03 09:06:02.000000000 +0200 @@ -907,7 +907,7 @@ --with-ldap-libdir=PATH Prefix where LDAP libaries are installed (optional) --with-ldap-includedir=PATH Prefix where LDAP header files are installed (optional) --with-ldap-libs=LIBS Specify LDAP libraries to link with. - (defult is -lldap -llber -lssl -lcrypto) + (default is -lldap -llber -lssl -lcrypto) --with-pid-dir=PATH Specify location of ssh.pid file --with-lastlog=FILE|DIR specify lastlog location common locations @@ -26932,13 +26932,9 @@ fi echo "$as_me:$LINENO: result: done" >&5 echo "${ECHO_T}done" >&6 - unset ac_LDAP_LINK LIBS="$ac_save_LIBS" LDFLAGS="$ac_save_LDFLAGS" - - unset ac_ldap_libs - unset ac_ldap_prefix else { echo "$as_me:$LINENO: LDAP is disabled" >&5 echo "$as_me: LDAP is disabled" >&6;} @@ -26959,8 +26955,6 @@ -unset ac_ldap - if test "x$LDAP_ON" = "x"; then LDAP_MSG="yes" fi diff -ruN openssh-4.3p1+x509-5.2/dns.c openssh-4.3p1+x509-5.3/dns.c --- openssh-4.3p1+x509-5.2/dns.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/dns.c 2006-02-03 09:06:01.000000000 +0200 @@ -178,7 +178,7 @@ get_dns_sign_algo(X509 *x509) { int rsa_algo = DNS_KEY_ALGO_UNKNOWN; int algo_nid; - + X509_CINF *ci; X509_ALGOR *sig; ASN1_OBJECT *alg; @@ -612,7 +612,6 @@ } fprintf(f, "\n\t)\n"); success = 1; - } else if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, &rdata_digest, &rdata_digest_len, key)) { diff -ruN openssh-4.3p1+x509-5.2/key.c openssh-4.3p1+x509-5.3/key.c --- openssh-4.3p1+x509-5.2/key.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/key.c 2006-02-03 09:06:01.000000000 +0200 @@ -11,7 +11,7 @@ * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * X.509 certificates support, - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -643,6 +643,11 @@ const char * key_ssh_name(const Key *k) { + const char* p; + + p = ssh_x509key_name(k); + if (p) return(p); + switch (k->type) { case KEY_RSA: return "ssh-rsa"; @@ -650,12 +655,6 @@ case KEY_DSA: return "ssh-dss"; break; - case KEY_X509_RSA: - return "x509v3-sign-rsa"; - break; - case KEY_X509_DSA: - return "x509v3-sign-dss"; - break; } return "ssh-unknown"; } @@ -749,7 +748,11 @@ int key_type_from_name(char *name) { - debug3("call key_type_from_name(%.200s) ...", name); + int k; + + k = ssh_x509key_type(name); + if (k != KEY_UNSPEC) return(k); + if (strcmp(name, "rsa1") == 0) { return KEY_RSA1; } else if (strcmp(name, "rsa") == 0) { @@ -760,10 +763,6 @@ return KEY_RSA; } else if (strcmp(name, "ssh-dss") == 0) { return KEY_DSA; - } else if (strcmp(name, "x509v3-sign-rsa") == 0) { - return KEY_X509_RSA; - } else if (strcmp(name, "x509v3-sign-dss") == 0) { - return KEY_X509_DSA; } debug2("key_type_from_name: unknown key type '%s'", name); return KEY_UNSPEC; diff -ruN openssh-4.3p1+x509-5.2/m4/ldap.m4 openssh-4.3p1+x509-5.3/m4/ldap.m4 --- openssh-4.3p1+x509-5.2/m4/ldap.m4 2004-11-18 23:09:35.000000000 +0200 +++ openssh-4.3p1+x509-5.3/m4/ldap.m4 2005-07-19 23:11:01.000000000 +0300 @@ -1,13 +1,9 @@ # Options to build with LDAP # # Author: Roumen Petrov -# Revision: 7 Nov 2004 +# Revision: 19 Jul 2005 # dnl The variables provided are : -dnl - paths: -dnl LDAP_BINDIR -dnl LDAP_LIBEXECDIR -dnl LDAP_SYSCONFDIR dnl - build flags: dnl LDAP_LDFLAGS dnl LDAP_LIBS @@ -15,6 +11,10 @@ dnl - conditional: dnl LDAP_ON (e.g. '' or '#') dnl LDAP_OFF (e.g. '#' or '' - oposite of LDAP_ON) +dnl - paths: +dnl LDAP_BINDIR +dnl LDAP_LIBEXECDIR +dnl LDAP_SYSCONFDIR AC_DEFUN(AC_WITH_LDAP, [ @@ -83,7 +83,7 @@ dnl [ dnl $LDAP_SYSCONFDIR/schema/core.schema dnl $LDAP_SYSCONFDIR/schema/cosine.schema -dnl $LDAP_SYSCONFDIR/schema/inetorgperson.schema- +dnl $LDAP_SYSCONFDIR/schema/inetorgperson.schema dnl ] dnl ) dnl fi @@ -172,13 +172,9 @@ fi fi AC_MSG_RESULT([done]) - unset ac_LDAP_LINK LIBS="$ac_save_LIBS" LDFLAGS="$ac_save_LDFLAGS" AC_SUBST([LDAP_LIBS]) - - unset ac_ldap_libs - unset ac_ldap_prefix else AC_MSG_NOTICE([LDAP is disabled]) fi @@ -195,6 +191,4 @@ fi AC_SUBST(LDAP_ON) AC_SUBST(LDAP_OFF) - -unset ac_ldap ]) diff -ruN openssh-4.3p1+x509-5.2/Makefile.in openssh-4.3p1+x509-5.3/Makefile.in --- openssh-4.3p1+x509-5.2/Makefile.in 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/Makefile.in 2006-02-03 09:06:01.000000000 +0200 @@ -69,6 +69,7 @@ @OCSP_ON@OCSP_OBJS=ssh-ocsp.o @OCSP_OFF@OCSP_OBJS= +SSHX509_OBJS=ssh-x509.o ssh-xkalg.o x509_nm_cmp.o X509STORE_OBJS=x509store.o $(LDAP_OBJS) $(OCSP_OBJS) TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) @@ -80,7 +81,7 @@ log.o match.o moduli.o nchan.o packet.o \ readpass.o rsa.o ttymodes.o xmalloc.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o ssh-x509.o dh.o kexdh.o \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o $(SSHX509_OBJS) dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ entropy.o scard-opensc.o gss-genr.o diff -ruN openssh-4.3p1+x509-5.2/myproposal.h openssh-4.3p1+x509-5.3/myproposal.h --- openssh-4.3p1+x509-5.2/myproposal.h 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/myproposal.h 2006-02-03 09:06:00.000000000 +0200 @@ -1,9 +1,7 @@ -/* $OpenBSD$ */ +/* $OpenBSD: myproposal.h,v 1.16 2004/06/13 12:53:24 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. - * X.509 certificates support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,7 +26,7 @@ #define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1," \ "diffie-hellman-group14-sha1," \ "diffie-hellman-group1-sha1" -#define KEX_DEFAULT_PK_ALG "x509v3-sign-rsa,x509v3-sign-dss,ssh-rsa,ssh-dss" +#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" #define KEX_DEFAULT_ENCRYPT \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ "arcfour128,arcfour256,arcfour," \ diff -ruN openssh-4.3p1+x509-5.2/readconf.c openssh-4.3p1+x509-5.3/readconf.c --- openssh-4.3p1+x509-5.2/readconf.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/readconf.c 2006-02-03 09:06:01.000000000 +0200 @@ -11,7 +11,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2004 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,6 +47,8 @@ #include "match.h" #include "misc.h" #include "kex.h" +#include "myproposal.h" +#include "ssh-xkalg.h" #include "mac.h" /* Format of the configuration file: @@ -134,7 +136,7 @@ oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, - oX509rsaSigType, + oX509KeyAlgorithm, oAllowedServerCertPurpose, oMandatoryCRL, oCACertificateFile, oCACertificatePath, @@ -237,7 +239,8 @@ { "controlpath", oControlPath }, { "controlmaster", oControlMaster }, { "hashknownhosts", oHashKnownHosts }, - { "x509rsasigtype", oX509rsaSigType }, + { "x509rsasigtype", oDeprecated }, + { "x509keyalgorithm", oX509KeyAlgorithm }, { "allowedcertpurpose", oAllowedServerCertPurpose }, { "mandatorycrl", oMandatoryCRL }, { "cacertificatefile", oCACertificateFile }, @@ -684,9 +687,11 @@ arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); + /* cannot validate here - depend from X509KeyAlgorithm if (!key_names_valid2(arg)) fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", filename, linenum, arg ? arg : ""); + */ if (*activep && options->hostkeyalgorithms == NULL) options->hostkeyalgorithms = xstrdup(arg); break; @@ -928,39 +933,40 @@ intptr = &options->permit_local_command; goto parse_flag; - case oX509rsaSigType: + case oX509KeyAlgorithm: 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; + fatal("%.200s line %d: Missing argument.", filename, linenum); - if (options->x509rsasigtype < 0) { - fatal("%s line %d: Unsupported argument for X509rsaSigType.", - filename, linenum); + if (*activep) { + if (ssh_add_x509key_alg(arg) < 0) { + fatal("%.200s line %d: Bad X.509 key algorithm '%.200s'.", + filename, linenum, arg); + } } break; case oAllowedServerCertPurpose: + intptr = &options->allowedcertpurpose; arg = strdelim(&s); if (arg && *arg) { if (strcasecmp(arg, "skip") == 0) goto skip_purpose; - { /* convert string to OpenSSL index */ - int purpose_index; - 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); + /* convert string to OpenSSL index */ + value = ssh_get_x509purpose_s (0, arg); + if (value < 0) + fatal("%.200s line %d: Bad certificate purpose '%.30s'.", + filename, linenum, arg); - options->allowedcertpurpose = purpose_index; - } + if (*activep && *intptr == -1) + *intptr = value; } 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); + if (*activep && *intptr == -1) { + *intptr = -2; + verbose("%.200s line %d: option is set to don`t check certificate purpose.", + filename, linenum); + } } break; @@ -1034,12 +1040,19 @@ #ifdef SSH_OCSP_ENABLED case oVAType: + intptr = &options->va.type; arg = strdelim(&s); if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - options->va.type = ssh_get_vatype_s(arg); - if (options->va.type < 0) - fatal("config error: OCSP Responder type '%.30s' in file %s line %d.", arg, filename, linenum); + fatal("%.200s line %d: Missing argument.", filename, linenum); + + value = ssh_get_vatype_s(arg); + if (value < 0) { + fatal("%.200s line %d: Bad OCSP responder type '%.30s'.", + filename, linenum, arg); + } + + if (*activep && *intptr == -1) + *intptr = value; break; case oVACertificateFile: @@ -1219,7 +1232,8 @@ options->control_path = NULL; options->control_master = -1; options->hash_known_hosts = -1; - options->x509rsasigtype = -1; + /* Supported X.509 key algorithms and signatures + are defined is external source. */ options->allowedcertpurpose = -1; #ifndef SSH_X509STORE_DISABLED options->mandatory_crl = -1; @@ -1321,7 +1335,7 @@ options->cipher = SSH_CIPHER_NOT_SET; /* options->ciphers, default set in myproposals.h */ /* options->macs, default set in myproposals.h */ - /* options->hostkeyalgorithms, default set in myproposals.h */ + /* HostKeyAlgorithms depend from X509KeyAlgorithm options */ if (options->protocol == SSH_PROTO_UNKNOWN) options->protocol = SSH_PROTO_1|SSH_PROTO_2; if (options->num_identity_files == 0) { @@ -1393,9 +1407,7 @@ /* 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); + fill_default_xkalg(); if (options->allowedcertpurpose == -1) options->allowedcertpurpose = ssh_get_default_x509purpose(0); ssh_set_x509purpose(0, options->allowedcertpurpose); @@ -1417,6 +1429,34 @@ options->va.type = ssh_get_default_vatype(); ssh_set_validator(&options->va); #endif /*def SSH_OCSP_ENABLED*/ + + if (options->hostkeyalgorithms != NULL) { + if (!key_names_valid2(options->hostkeyalgorithms)) + fatal("Bad protocol 2 host key algorithms '%s'.", + options->hostkeyalgorithms); + } else { + Buffer b; + + buffer_init(&b); + ssh_list_xkalg(KEY_X509_RSA, &b); + ssh_list_xkalg(KEY_X509_DSA, &b); + if (buffer_len(&b) > 0) { + /* use defined X.509 "key type name" plus default set in myproposals.h */ + const char *p = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; + + buffer_append(&b, ",", 1); + buffer_append(&b, p, strlen(p)); + buffer_append(&b, "\0", 1); + + options->hostkeyalgorithms = xstrdup(buffer_ptr(&b)); + } else { + /* use default set in myproposals.h */ + } +#ifdef TRACE_XKALG +fprintf(stderr, "TRACE_XKALG hostkeyalgorithms='%s'\n", (options->hostkeyalgorithms ? options->hostkeyalgorithms : "")); +#endif + buffer_free(&b); + } } /* diff -ruN openssh-4.3p1+x509-5.2/readconf.h openssh-4.3p1+x509-5.3/readconf.h --- openssh-4.3p1+x509-5.2/readconf.h 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/readconf.h 2006-02-03 09:06:00.000000000 +0200 @@ -13,7 +13,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -139,8 +139,9 @@ int hash_known_hosts; - /* rumen-XXX: X509 RSA signature type: md5=0, sha1=1 */ - int x509rsasigtype; + /* Supported X.509 key algorithms and signatures + are defined is external source. */ + /* allowed server certificate purpose */ int allowedcertpurpose; #ifndef SSH_X509STORE_DISABLED diff -ruN openssh-4.3p1+x509-5.2/README.x509v3 openssh-4.3p1+x509-5.3/README.x509v3 --- openssh-4.3p1+x509-5.2/README.x509v3 2004-11-18 22:33:59.000000000 +0200 +++ openssh-4.3p1+x509-5.3/README.x509v3 2005-11-22 23:55:40.000000000 +0200 @@ -1,6 +1,6 @@ Roumen Petrov Sofia, Bulgaria - Wed Nov 17 2004 + Tue Nov 22 2005 How to use X.509 certificates with OpenSSH? @@ -66,18 +66,27 @@ Host key for protocol version 2 can contain private key plus X.509 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 me a EMAIL with "X509COMPAT" lines -from log files. +1.1.4.) X509KeyAlgorithm + This is new option that replace old one X509rsaSigType. + The option list multiple "X509 Key Algorithms Formats" + supported by server. + The format is described in sshd_config(5). + The default for certificates with RSA key is: + X509KeyAlgorithm x509v3-sign-rsa,rsa-md5 + X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1 + X509KeyAlgorithm x509v3-sign-rsa-sha1,rsa-sha1,ssh-rsa + The default for certificates with DSA key is: + X509KeyAlgorithm x509v3-sign-dss,dss-asn1 + X509KeyAlgorithm x509v3-sign-dss,dss-raw + X509KeyAlgorithm x509v3-sign-dss-sha1,dss-raw,ssh-dss + The first listed format for each key-type, i.e. RSA or DSA + is used as default in signing. The server will accept + all listed formats. -1.1.5.) VAType none +1.1.5.) X509rsaSigType=md5 + Deprecated option replaced by X509KeyAlgorithm. + +1.1.6.) VAType none Specifies whether `Online Certificate Status Protocol' (OCSP) is used to validate client X.509 certificates. Specified value is used only when OpenSSH is build with OCSP support. See sshd_config(5) man page @@ -160,20 +169,14 @@ "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 +2.2.3.) X509KeyAlgorithm + The meaning of options is same as in server. + See p. 1.1.4.) -Note: ssh-agent use only md5 digest for X.509 certificates. +2.2.4.) X509rsaSigType=md5 + Deprecated option replaced by X509KeyAlgorithm. -2.2.4.) VAType none +2.2.5.) VAType none Specifies whether `Online Certificate Status Protocol' (OCSP) is used to validate server X.509 certificates. Specified value is used only when OpenSSH is build with OCSP support. See ssh_config(5) man page diff -ruN openssh-4.3p1+x509-5.2/servconf.c openssh-4.3p1+x509-5.3/servconf.c --- openssh-4.3p1+x509-5.2/servconf.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/servconf.c 2006-02-03 09:06:01.000000000 +0200 @@ -9,7 +9,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2004 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,6 +38,7 @@ #include "ssh.h" #include "log.h" #include "servconf.h" +#include "ssh-xkalg.h" #include "xmalloc.h" #include "compat.h" #include "pathnames.h" @@ -128,7 +129,8 @@ options->hostbased_algorithms = NULL; options->pubkey_algorithms = NULL; - options->x509rsasigtype = -1; + /* Supported X.509 key algorithms and signatures + are defined is external source. */ options->allowedcertpurpose = -1; #ifndef SSH_X509STORE_DISABLED options->mandatory_crl = -1; @@ -272,9 +274,7 @@ /* options->hostbased_algorithms */ /* options->pubkey_algorithms */ - if (options->x509rsasigtype == -1) - options->x509rsasigtype = SSH_X509RSA_MD5; - options->x509rsasigtype = ssh_x509rsasig(options->x509rsasigtype); + fill_default_xkalg(); if (options->allowedcertpurpose == -1) options->allowedcertpurpose = ssh_get_default_x509purpose(1); ssh_set_x509purpose(1, options->allowedcertpurpose); @@ -303,6 +303,14 @@ options->compression = 0; } #endif + if (options->hostbased_algorithms != NULL) + if (!key_names_valid2(options->hostbased_algorithms)) + fatal("Bad protocol 2 hostbased algorithms '%s'.", + options->hostbased_algorithms); + if (options->pubkey_algorithms != NULL) + if (!key_names_valid2(options->pubkey_algorithms)) + fatal("Bad protocol 2 public key algorithms '%s'.", + options->pubkey_algorithms); } /* Keyword tokens. */ @@ -332,7 +340,7 @@ sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sUsePrivilegeSeparation, - sX509rsaSigType, + sX509KeyAlgorithm, sAllowedClientCertPurpose, sMandatoryCRL, sCACertificateFile, sCACertificatePath, @@ -443,7 +451,8 @@ { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, { "acceptenv", sAcceptEnv }, - { "x509rsasigtype", sX509rsaSigType }, + { "x509rsasigtype", sDeprecated }, + { "x509keyalgorithm", sX509KeyAlgorithm }, { "allowedcertpurpose", sAllowedClientCertPurpose }, { "mandatorycrl", sMandatoryCRL } , { "cacertificatefile", sCACertificateFile }, @@ -1073,9 +1082,11 @@ arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); + /* cannot validate here - depend from X509KeyAlgorithm if (!key_names_valid2(arg)) fatal("%.200s line %d: Bad protocol 2 hostbased algorithms '%s'.", filename, linenum, arg ? arg : ""); + */ if (options->hostbased_algorithms == NULL) options->hostbased_algorithms = xstrdup(arg); break; @@ -1084,45 +1095,46 @@ arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: Missing argument.", filename, linenum); + /* cannot validate here - depend from X509KeyAlgorithm if (!key_names_valid2(arg)) fatal("%.200s line %d: Bad protocol 2 public key algorithms '%s'.", filename, linenum, arg ? arg : ""); + */ if (options->pubkey_algorithms == NULL) options->pubkey_algorithms = xstrdup(arg); break; - case sX509rsaSigType: + case sX509KeyAlgorithm: 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); + if (ssh_add_x509key_alg(arg) < 0) { + fatal("%.200s line %d: Bad X.509 key algorithm '%.200s'.", + filename, linenum, arg); } break; case sAllowedClientCertPurpose: + intptr = &options->allowedcertpurpose; arg = strdelim(&cp); if (arg && *arg) { if (strcasecmp(arg, "skip") == 0) goto skip_purpose; - { /* convert string to OpenSSL index */ - int purpose_index; - 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); + /* convert string to OpenSSL index */ + value = ssh_get_x509purpose_s (1, arg); + if (value < 0) + fatal("%.200s line %d: Bad certificate purpose '%.30s'.", + filename, linenum, arg); - options->allowedcertpurpose = purpose_index; - } + if (*intptr == -1) + *intptr = value; } 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); + if (*intptr == -1) { + *intptr = -2; + verbose("%.200s line %d: option is set to don`t check certificate purpose.", + filename, linenum); + } } break; @@ -1132,67 +1144,70 @@ goto parse_flag; case sCACertificateFile: - case sCACertificatePath: - case sCARevocationFile: - case sCARevocationPath: + /* X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.certificate_file; +parse_string: arg = strdelim(&cp); if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - switch (opcode) { - case sCACertificateFile: - options->ca.certificate_file = xstrdup(arg); break; - case sCACertificatePath: - options->ca.certificate_path = xstrdup(arg); break; - case sCARevocationFile: - options->ca.revocation_file = xstrdup(arg); break; - case sCARevocationPath: - options->ca.revocation_path = xstrdup(arg); break; - default: - break; - } + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (*charptr == NULL) + *charptr = xstrdup(arg); break; + + case sCACertificatePath: + /* X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.certificate_path; + goto parse_string; + + case sCARevocationFile: + /* X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.revocation_file; + goto parse_string; + + case sCARevocationPath: + /* X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.revocation_path; + goto parse_string; #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef LDAP_ENABLED case sCAldapVersion: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - options->ca.ldap_ver = xstrdup(arg); - break; + /* X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.ldap_ver; + goto parse_string; case sCAldapURL: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - options->ca.ldap_url = xstrdup(arg); - break; + /* X509StoreOptions prefered type is 'const char*' */ + charptr = (char**)&options->ca.ldap_url; + goto parse_string; #endif /*def LDAP_ENABLED*/ #ifdef SSH_OCSP_ENABLED case sVAType: + intptr = &options->va.type; arg = strdelim(&cp); if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - options->va.type = ssh_get_vatype_s(arg); - if (options->va.type < 0) - fatal("config error: OCSP Responder type '%.30s' in file %s line %d.", arg, filename, linenum); + fatal("%.200s line %d: Missing argument.", filename, linenum); + + value = ssh_get_vatype_s(arg); + if (value < 0) { + fatal("%.200s line %d: Bad OCSP responder type '%.30s'.", + filename, linenum, arg); + } + + if (*intptr == -1) + *intptr = value; break; case sVACertificateFile: + /* VAOptions prefered type is 'const char*' */ + charptr = (char**)&options->va.certificate_file; + goto parse_string; + case sVAOCSPResponderURL: - arg = strdelim(&cp); - if (!arg || *arg == '\0') - fatal("%s line %d: Missing argument.", filename, linenum); - switch (opcode) { - default: - break; - case sVACertificateFile: - options->va.certificate_file = xstrdup(arg); break; - case sVAOCSPResponderURL: - options->va.responder_url = xstrdup(arg); break; - } - break; + /* VAOptions prefered type is 'const char*' */ + charptr = (char**)&options->va.responder_url; + goto parse_string; #endif /*def SSH_OCSP_ENABLED*/ case sDeprecated: diff -ruN openssh-4.3p1+x509-5.2/servconf.h openssh-4.3p1+x509-5.3/servconf.h --- openssh-4.3p1+x509-5.2/servconf.h 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/servconf.h 2006-02-03 09:06:00.000000000 +0200 @@ -13,7 +13,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -162,8 +162,10 @@ char* hostbased_algorithms; /* Supported hostbased algorithms. */ char* pubkey_algorithms; /* Supported pubkey algorithms. */ - /* rumen-XXX: X509 RSA signature type: md5=0, sha1=1 */ - int x509rsasigtype; + + /* Supported X.509 key algorithms and signatures + are defined is external source. */ + /* allowed client certificate purpose */ int allowedcertpurpose; #ifndef SSH_X509STORE_DISABLED diff -ruN openssh-4.3p1+x509-5.2/ssh.0 openssh-4.3p1+x509-5.3/ssh.0 --- openssh-4.3p1+x509-5.2/ssh.0 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh.0 2006-02-03 09:06:00.000000000 +0200 @@ -726,12 +726,12 @@ /etc/ssh/ca/crt /etc/ssh/ca/crl Part of systemwide ``X.509 store''. ``Hash dirs'' with certifi- - cates, the first file or CLRs, the second of certificate signers. - Each certificate should be stored in separate file with name - [HASH].[NUMBER] or [HASH].r[NUMBER] for the CRL, where [HASH] is - certificate or CRL hash value and [NUMBER] is an integer starting - from zero. Used in verification and validation of server host - certificate. + cates, the first directory or CLRs, the second of certificate + signers. Each certificate should be stored in separate file with + name [HASH].[NUMBER] or [HASH].r[NUMBER] for the CRL, where + [HASH] is certificate or CRL hash value and [NUMBER] is an inte- + ger starting from zero. Used in verification and validation of + server host certificate. /etc/ssh/ssh_config Systemwide configuration file. The file format and configuration diff -ruN openssh-4.3p1+x509-5.2/ssh.1 openssh-4.3p1+x509-5.3/ssh.1 --- openssh-4.3p1+x509-5.2/ssh.1 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh.1 2006-02-03 09:06:00.000000000 +0200 @@ -1271,7 +1271,7 @@ Part of systemwide .Dq "X.509 store" . .Dq "Hash dirs" -with certificates, the first file or CLRs, the second of +with certificates, the first directory or CLRs, the second of certificate signers. Each certificate should be stored in separate file with name [HASH].[NUMBER] or [HASH].r[NUMBER] for the CRL, where [HASH] is diff -ruN openssh-4.3p1+x509-5.2/ssh-add.c openssh-4.3p1+x509-5.3/ssh-add.c --- openssh-4.3p1+x509-5.2/ssh-add.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-add.c 2006-02-03 09:06:01.000000000 +0200 @@ -13,7 +13,7 @@ * SSH2 implementation, * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * X.509 certificates support, - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,6 +51,7 @@ #include "pathnames.h" #include "misc.h" #include "ssh-x509.h" +#include "ssh-xkalg.h" /* argv0 */ extern char *__progname; @@ -334,6 +335,7 @@ seed_rng(); SSLeay_add_all_algorithms(); + fill_default_xkalg(); /* At first, get a connection to the authentication agent. */ ac = ssh_get_authentication_connection(); diff -ruN openssh-4.3p1+x509-5.2/ssh-agent.c openssh-4.3p1+x509-5.3/ssh-agent.c --- openssh-4.3p1+x509-5.2/ssh-agent.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-agent.c 2006-02-03 09:06:01.000000000 +0200 @@ -12,7 +12,7 @@ * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * X.509 certificates support, - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,6 +53,7 @@ #include "compat.h" #include "log.h" #include "ssh-x509.h" +#include "ssh-xkalg.h" #include "misc.h" #ifdef SMARTCARD @@ -1045,6 +1046,7 @@ #endif SSLeay_add_all_algorithms(); + fill_default_xkalg(); __progname = ssh_get_progname(av[0]); init_rng(); diff -ruN openssh-4.3p1+x509-5.2/ssh_config openssh-4.3p1+x509-5.3/ssh_config --- openssh-4.3p1+x509-5.2/ssh_config 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh_config 2006-02-03 09:06:00.000000000 +0200 @@ -37,7 +37,6 @@ # Cipher 3des # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc # EscapeChar ~ -# X509rsaSigType=md5 # AllowedCertPurpose sslserver # MandatoryCRL no # CACertificateFile /etc/ssh/ca/ca-bundle.crt diff -ruN openssh-4.3p1+x509-5.2/ssh_config.0 openssh-4.3p1+x509-5.3/ssh_config.0 --- openssh-4.3p1+x509-5.2/ssh_config.0 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh_config.0 2006-02-03 09:06:00.000000000 +0200 @@ -322,7 +322,9 @@ HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. The default for this - option is: ``x509v3-sign-rsa,x509v3-sign-dss,ssh-rsa,ssh-dss''. + option depend from X509KeyAlgorithm. It contain first specified + X509KeyAlgorithm for RSA key, followed by first specified + X509KeyAlgorithm for DSA key, followed by ``,ssh-rsa,ssh-dss''. HostKeyAlias Specifies an alias that should be used instead of the real host @@ -662,17 +664,30 @@ ``no'' or ``ask''. The default is ``no''. Note that this option applies to protocol version 2 only. + X509KeyAlgorithm + Specifies how X.509 certificates and signatures are used for pro- + tocol version 2. It is possible to have multiple algorithms in + form specified in X509 Key Algorithms Format. sshd use the first + listed for ``rsa'' or ``dsa'' key in signing and accept all + listed. + + The default for certificates with RSA key is: + X509KeyAlgorithm x509v3-sign-rsa,rsa-md5 + X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1 + X509KeyAlgorithm x509v3-sign-rsa-sha1,rsa-sha1,ssh-rsa + + The default for certificates with DSA key is: + X509KeyAlgorithm x509v3-sign-dss,dss-asn1 + X509KeyAlgorithm x509v3-sign-dss,dss-raw + X509KeyAlgorithm x509v3-sign-dss-sha1,dss-raw,ssh-dss + + X509rsaSigType + Deprecated option replaced by X509KeyAlgorithm. + XAuthLocation 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' identities. 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 ~/.ssh/config This is the per-user configuration file. The format of this file diff -ruN openssh-4.3p1+x509-5.2/ssh_config.5 openssh-4.3p1+x509-5.3/ssh_config.5 --- openssh-4.3p1+x509-5.2/ssh_config.5 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh_config.5 2006-02-03 09:06:00.000000000 +0200 @@ -13,7 +13,7 @@ .\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. -.\" Copyright (c) 2002 Roumen Petrov. All rights reserved. +.\" Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -201,10 +201,10 @@ option: Specifies hostport and dn of LDAP URLs (Uniform Resource Locators) as detailed in RFC 2255. The rest of URL is build internally. -Because of OpenSSH options parser limitation use +Because of OpenSSH options parser limitation use .Sq %3D instead of -.Sq = +.Sq = ! .It Cm CARevocationFile .Dq X509 store @@ -583,8 +583,12 @@ .It Cm HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. -The default for this option is: -.Dq x509v3-sign-rsa,x509v3-sign-dss,ssh-rsa,ssh-dss . +The default for this option depend from +.Cm X509KeyAlgorithm . +It contain first specified X509KeyAlgorithm for RSA key, +followed by first specified X509KeyAlgorithm for DSA key, +followed by +.Dq ,ssh-rsa,ssh-dss . .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key @@ -1156,24 +1160,64 @@ The default is .Dq no . Note that this option applies to protocol version 2 only. +.It Cm X509KeyAlgorithm +Specifies how X.509 certificates and signatures are used for protocol version 2. +It is possible to have multiple algorithms +in form specified in +.Sx X509 Key Algorithms Format . +.Nm sshd +use the first listed for +.Dq rsa +or +.Dq dsa +key in signing and +accept all listed. +.Pp +The default for certificates with RSA key is: +.Bl -item -offset indent -compact +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-rsa , Ar rsa-md5 +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-rsa , Ar rsa-sha1 +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-rsa-sha1 , Ar rsa-sha1 , Ar ssh-rsa +.Sm on +.El +.Pp +The default for certificates with DSA key is: +.Bl -item -offset indent -compact +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-dss , Ar dss-asn1 +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-dss , Ar dss-raw +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-dss-sha1 , Ar dss-raw , Ar ssh-dss +.Sm on +.El +.It Cm X509rsaSigType +Deprecated option replaced by X509KeyAlgorithm. .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 program. The default is .Pa /usr/X11R6/bin/xauth . -.It Cm X509rsaSigType -Temporary option. -Specifies signature digest type for -.Sq x509v3-sign-rsa -identities. 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-4.3p1+x509-5.2/sshconnect.c openssh-4.3p1+x509-5.3/sshconnect.c --- openssh-4.3p1+x509-5.2/sshconnect.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/sshconnect.c 2006-02-03 09:06:01.000000000 +0200 @@ -12,7 +12,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X.509 certificates support, - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -60,17 +60,6 @@ char *client_version_string = NULL; char *server_version_string = NULL; -/* rumen-XXX: X.509 RSASIG check */ -extern void (*plogx509rsasig)(const char *msg); -static void logx509rsasig(const char *msg) { - logit("%.400s: server=%.200s (client=%.200s)", - msg, - (server_version_string ? server_version_string : "undefined"), - (client_version_string ? client_version_string : "undefined") - ); -} -/* rumen-XXX^ */ - static int matching_host_key_dns = 0; /* import */ @@ -521,8 +510,6 @@ 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-4.3p1+x509-5.2/sshd.8 openssh-4.3p1+x509-5.3/sshd.8 --- openssh-4.3p1+x509-5.2/sshd.8 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/sshd.8 2006-02-03 09:06:00.000000000 +0200 @@ -425,7 +425,7 @@ .Dq x509v3-sign-rsa or .Dq x509v3-sign-dss . -Instead of +Instead of .Dq "base64 encoded key" line must contain base64 encoded certicate (old style) or a keyword (new style), optional followed by symbol diff -ruN openssh-4.3p1+x509-5.2/sshd.c openssh-4.3p1+x509-5.3/sshd.c --- openssh-4.3p1+x509-5.2/sshd.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/sshd.c 2006-02-03 09:06:01.000000000 +0200 @@ -21,7 +21,7 @@ * Copyright (c) 2002 Niels Provos. All rights reserved. * * X.509 certificates support: - * Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -88,6 +88,7 @@ #include "monitor.h" #include "monitor_wrap.h" #include "monitor_fdpass.h" +#include "ssh-xkalg.h" #ifdef LIBWRAP #include @@ -162,17 +163,6 @@ char *client_version_string = NULL; char *server_version_string = NULL; -/* rumen-XXX: X.509 RSASIG check */ -extern void (*plogx509rsasig)(const char *msg); -static void logx509rsasig(const char *msg) { - logit("%.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; @@ -505,8 +495,6 @@ server_version_string, client_version_string); cleanup_exit(255); } - - plogx509rsasig = logx509rsasig; /* rumen-XXX: X.509 RSASIG check */ } /* Destroy the host and server keys. They will no longer be needed. */ @@ -707,13 +695,15 @@ switch (key->type) { case KEY_RSA: case KEY_DSA: - case KEY_X509_RSA: - case KEY_X509_DSA: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); buffer_append(&b, p, strlen(p)); break; + case KEY_X509_RSA: + case KEY_X509_DSA: + ssh_list_xkalg(key->type, &b); + break; } } buffer_append(&b, "\0", 1); diff -ruN openssh-4.3p1+x509-5.2/sshd_config openssh-4.3p1+x509-5.3/sshd_config --- openssh-4.3p1+x509-5.2/sshd_config 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/sshd_config 2006-02-03 09:06:00.000000000 +0200 @@ -22,8 +22,17 @@ #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key -# Signarure for "x509v3-sign-rsa" keys: md5,sha1 -#X509rsaSigType=md5 +# "key type names" for X.509 certificates with RSA key +# Note first defined is used in signature operations! +#X509KeyAlgorithm x509v3-sign-rsa,rsa-md5 +#X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1 +#X509KeyAlgorithm x509v3-sign-rsa-sha1,rsa-sha1,ssh-rsa + +# "key type names" for X.509 certificates with DSA key +# Note first defined is used in signature operations! +#X509KeyAlgorithm x509v3-sign-dss,dss-asn1 +#X509KeyAlgorithm x509v3-sign-dss,dss-raw +#X509KeyAlgorithm x509v3-sign-dss-sha1,dss-raw,ssh-dss # The intended use for the X509 client certificate. Without this option # no chain verification will be done. Currently accepted uses are case diff -ruN openssh-4.3p1+x509-5.2/sshd_config.0 openssh-4.3p1+x509-5.3/sshd_config.0 --- openssh-4.3p1+x509-5.2/sshd_config.0 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/sshd_config.0 2006-02-03 09:06:00.000000000 +0200 @@ -208,7 +208,10 @@ HostbasedAlgorithms Specifies the protocol version 2 algorithms used in ``hostbased'' authentication that the server accept. The default is all sup- - ported by server. + ported by server. Note algorithms that use X.509 certificates + depend from X509KeyAlgorithm and one of names set in + X509KeyAlgorithm for a certain key-type is enough to enable all + form that key-type. HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication @@ -224,9 +227,9 @@ tocol version 2. Note that sshd will refuse to use a file if it is group/world-accessible. It is possible to have multiple host key files. ``rsa1'' keys are used for version 1 and ``dsa'' or - ``rsa'' are used for version 2 of the SSH protocol. It is possi- - ble host key to contain private key followed by X.509 certificate - that match it for version 2. + ``rsa'' are used for version 2 of the SSH protocol. For version + 2 is possible file to contain private key followed by X.509 cer- + tificate that match the key. IgnoreRhosts Specifies that .rhosts and .shosts files will not be used in @@ -392,7 +395,10 @@ PubkeyAlgorithms Specifies the protocol version 2 algorithms used in ``publickey'' authentication that the server accept. The default is all sup- - ported by server. + ported by server. Note algorithms that use X.509 certificates + depend from X509KeyAlgorithm and one of names set in + X509KeyAlgorithm for a certain key-type is enough to enable all + form that key-type. PubkeyAuthentication Specifies whether public key authentication is allowed. The @@ -546,22 +552,30 @@ card address. The argument must be ``yes'' or ``no''. The default is ``yes''. + X509KeyAlgorithm + Specifies how X.509 certificates and signatures are used for pro- + tocol version 2. It is possible to have multiple algorithms in + form specified in X509 Key Algorithms Format. sshd use the first + listed for ``rsa'' or ``dsa'' key in signing and accept all + listed. + + The default for certificates with RSA key is: + X509KeyAlgorithm x509v3-sign-rsa,rsa-md5 + X509KeyAlgorithm x509v3-sign-rsa,rsa-sha1 + X509KeyAlgorithm x509v3-sign-rsa-sha1,rsa-sha1,ssh-rsa + + The default for certificates with DSA key is: + X509KeyAlgorithm x509v3-sign-dss,dss-asn1 + X509KeyAlgorithm x509v3-sign-dss,dss-raw + X509KeyAlgorithm x509v3-sign-dss-sha1,dss-raw,ssh-dss + + X509rsaSigType + Deprecated option replaced by X509KeyAlgorithm. + XAuthLocation 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 time may be expressed using a sequence of the form: time[qualifier], @@ -584,6 +598,19 @@ 10m 10 minutes 1h30m 1 hour 30 minutes (90 minutes) + X509 Key Algorithms Format + sshd command-line arguments and configuration file options that specify + `X509 Key Algorithms' expressed using a sequence of the form: + key-type-name,digest-name[,signature-identifier], where key-type-name is + key type name, digest-name is + rsa-md5 : RSA key and signature using the MD5 hash; + rsa-sha1 : RSA key and signature using the SHA-1 hash; + dss-asn1 : DSA key and signature as specified in ``RFC3279'' ; + dss-raw : DSA key and signature in ``ssh-dss'' format specified + in ``SecSH transport'' draft . + and optional signature-identifier. When signature-identifier is omited + key-type-name is used as identifier. + FILES /etc/ssh/sshd_config Contains configuration data for sshd. This file should be diff -ruN openssh-4.3p1+x509-5.2/sshd_config.5 openssh-4.3p1+x509-5.3/sshd_config.5 --- openssh-4.3p1+x509-5.2/sshd_config.5 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/sshd_config.5 2006-02-03 09:06:00.000000000 +0200 @@ -13,7 +13,7 @@ .\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved. .\" Copyright (c) 1999 Aaron Campbell. All rights reserved. .\" Copyright (c) 1999 Theo de Raadt. All rights reserved. -.\" Copyright (c) 2002 Roumen Petrov. All rights reserved. +.\" Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -208,10 +208,10 @@ option: Specifies hostport and dn(distinguished name) of LDAP URLs (Uniform Resource Locators) as detailed in RFC 2255. The rest of URL is build internally. -Because of OpenSSH options parser limitation use +Because of OpenSSH options parser limitation use .Sq %3D instead of -.Sq = +.Sq = ! .It Cm CARevocationFile .Dq X509 store @@ -365,10 +365,15 @@ .Dq yes . Note that this option applies to protocol version 2 only. .It Cm HostbasedAlgorithms -Specifies the protocol version 2 algorithms used in +Specifies the protocol version 2 algorithms used in .Dq hostbased authentication that the server accept. The default is all supported by server. +Note algorithms that use X.509 certificates depend from +.Cm X509KeyAlgorithm +and one of names set in +.Cm X509KeyAlgorithm +for a certain key-type is enough to enable all form that key-type. .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed @@ -398,9 +403,8 @@ or .Dq rsa are used for version 2 of the SSH protocol. -It is possible host key to contain private key -followed by X.509 certificate that match it -for version 2. +For version 2 is possible file to contain private key +followed by X.509 certificate that match the key. .It Cm IgnoreRhosts Specifies that .Pa .rhosts @@ -677,10 +681,15 @@ is identical to .Dq 1,2 . .It Cm PubkeyAlgorithms -Specifies the protocol version 2 algorithms used in +Specifies the protocol version 2 algorithms used in .Dq publickey authentication that the server accept. The default is all supported by server. +Note algorithms that use X.509 certificates depend from +.Cm X509KeyAlgorithm +and one of names set in +.Cm X509KeyAlgorithm +for a certain key-type is enough to enable all form that key-type. .It Cm PubkeyAuthentication Specifies whether public key authentication is allowed. The default is @@ -922,32 +931,64 @@ .Dq no . The default is .Dq yes . +.It Cm X509KeyAlgorithm +Specifies how X.509 certificates and signatures are used for protocol version 2. +It is possible to have multiple algorithms +in form specified in +.Sx X509 Key Algorithms Format . +.Nm sshd +use the first listed for +.Dq rsa +or +.Dq dsa +key in signing and +accept all listed. +.Pp +The default for certificates with RSA key is: +.Bl -item -offset indent -compact +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-rsa , Ar rsa-md5 +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-rsa , Ar rsa-sha1 +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-rsa-sha1 , Ar rsa-sha1 , Ar ssh-rsa +.Sm on +.El +.Pp +The default for certificates with DSA key is: +.Bl -item -offset indent -compact +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-dss , Ar dss-asn1 +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-dss , Ar dss-raw +.Sm on +.It +.Cm X509KeyAlgorithm +.Sm off +.Ar x509v3-sign-dss-sha1 , Ar dss-raw , Ar ssh-dss +.Sm on +.El +.It Cm X509rsaSigType +Deprecated option replaced by X509KeyAlgorithm. .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 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 .Nm sshd @@ -990,6 +1031,43 @@ .It 1h30m 1 hour 30 minutes (90 minutes) .El +.Ss X509 Key Algorithms Format +.Nm sshd +command-line arguments and configuration file options that specify +.Sq X509 Key Algorithms +expressed using a sequence of the form: +.Sm off +.Ar key-type-name , Ar digest-name +.Op Ar \&, signature-identifier , +.Sm on +where +.Ar key-type-name +is key type name, +.Ar digest-name +is +.Bl -tag -compact -offset indent +.It Cm rsa-md5 +: RSA key and signature using the MD5 hash; +.It Cm rsa-sha1 +: RSA key and signature using the SHA-1 hash; +.It Cm dss-asn1 +: DSA key and signature as specified in +.Dq RFC3279 +; +.It Cm dss-raw +: DSA key and signature in +.Dq ssh-dss +format specified in +.Dq SecSH transport +draft . +.El +and optional +.Ar signature-identifier . +When +.Ar signature-identifier +is omited +.Ar key-type-name +is used as identifier. .Sh FILES .Bl -tag -width Ds .It Pa /etc/ssh/sshd_config diff -ruN openssh-4.3p1+x509-5.2/ssh-keygen.1 openssh-4.3p1+x509-5.3/ssh-keygen.1 --- openssh-4.3p1+x509-5.2/ssh-keygen.1 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-keygen.1 2006-02-03 09:06:00.000000000 +0200 @@ -434,11 +434,11 @@ with option -y to regenerate its content. Note in case with X.509 certificate you can append content to .Pa ~/.ssh/authorized_keys -or to add certificate +or to add certificate .Dq Distinguished Name / .Dq Subject -in corresponding format to +in corresponding format to .Dq authorized keys file. See .Xr sshd 8 . @@ -471,11 +471,11 @@ with option -y to regenerate its content. Note in case with X.509 certificate you can append content to .Pa ~/.ssh/authorized_keys -or to add certificate +or to add certificate .Dq Distinguished Name / .Dq Subject -in corresponding format to +in corresponding format to .Dq authorized keys file. See .Xr sshd 8 . diff -ruN openssh-4.3p1+x509-5.2/ssh-keygen.c openssh-4.3p1+x509-5.3/ssh-keygen.c --- openssh-4.3p1+x509-5.2/ssh-keygen.c 2005-11-29 04:10:25.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-keygen.c 2006-02-03 09:06:01.000000000 +0200 @@ -9,10 +9,33 @@ * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". + * + * X.509 certificates support, + * Copyright (c) 2005 Roumen Petrov. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: ssh-keygen.c,v 1.135 2005/11/29 02:04:55 dtucker Exp $"); +RCSID("$OpenBSD$"); #include #include @@ -29,6 +52,7 @@ #include "misc.h" #include "match.h" #include "hostfile.h" +#include "ssh-xkalg.h" #ifdef SMARTCARD #include "scard.h" @@ -1026,6 +1050,7 @@ __progname = ssh_get_progname(av[0]); SSLeay_add_all_algorithms(); + fill_default_xkalg(); log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); init_rng(); diff -ruN openssh-4.3p1+x509-5.2/ssh-keyscan.0 openssh-4.3p1+x509-5.3/ssh-keyscan.0 --- openssh-4.3p1+x509-5.2/ssh-keyscan.0 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-keyscan.0 2006-02-03 09:06:00.000000000 +0200 @@ -48,10 +48,11 @@ -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-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''. + ``ssh-rsa'' , ``ssh-dss'' , ``x509v3-sign-rsa'' , + ``x509v3-sign-dss'' , ``x509v3-sign-rsa-sha1'' or + ``x509v3-sign-dss-sha1'' for protocol version 2. Multiple values + may be specified by separating them with commas. The default is + ``rsa1''. -v Verbose mode. Causes ssh-keyscan to print debugging messages about its progress. diff -ruN openssh-4.3p1+x509-5.2/ssh-keyscan.1 openssh-4.3p1+x509-5.3/ssh-keyscan.1 --- openssh-4.3p1+x509-5.2/ssh-keyscan.1 2006-02-03 09:06:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-keyscan.1 2006-02-03 09:06:00.000000000 +0200 @@ -7,7 +7,7 @@ .\" OpenBSD project by leaving this copyright notice intact. .\" .\" X.509 certificates support, -.\" Copyright (c) 2002-2003 Roumen Petrov. All rights reserved. +.\" Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -111,17 +111,17 @@ The possible values are .Dq rsa1 for protocol version 1 and -.Dq rsa -or .Dq ssh-rsa -, -.Dq dsa -or +, .Dq ssh-dss , .Dq x509v3-sign-rsa -or +, .Dq x509v3-sign-dss +, +.Dq x509v3-sign-rsa-sha1 +or +.Dq x509v3-sign-dss-sha1 for protocol version 2. Multiple values may be specified by separating them with commas. The default is diff -ruN openssh-4.3p1+x509-5.2/ssh-keyscan.c openssh-4.3p1+x509-5.3/ssh-keyscan.c --- openssh-4.3p1+x509-5.2/ssh-keyscan.c 2006-02-03 09:06:01.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-keyscan.c 2006-02-03 09:06:01.000000000 +0200 @@ -6,7 +6,7 @@ * OpenBSD project by leaving this copyright notice intact. * * X.509 certificates support, - * Copyright (c) 2002-2004 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,6 +42,7 @@ #include "ssh1.h" #include "key.h" #include "ssh-x509.h" +#include "ssh-xkalg.h" #include "kex.h" #include "compat.h" #include "myproposal.h" @@ -60,13 +61,7 @@ int ssh_port = SSH_DEFAULT_PORT; -#define KT_RSA1 1 -#define KT_DSA 2 -#define KT_RSA 4 -#define KT_X509DSA 8 -#define KT_X509RSA 16 - -int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */ +char* get_keynames = "rsa1"; /* Get only RSA1 keys by default */ int hash_hosts = 0; /* Hash hostname on output */ @@ -100,8 +95,7 @@ int c_plen; /* Packet length field for ssh packet */ int c_len; /* Total bytes which must be read. */ int c_off; /* Length of data read so far. */ - int c_keytype; /* Only one of KT_RSA1, KT_DSA, KT_RSA, - KT_X509DSA or KT_X509RSA */ + const char *c_keyname; char *c_namebase; /* Address to free for c_name and c_namelist */ char *c_name; /* Hostname of connection for errors */ char *c_namelist; /* Pointer to other possible addresses */ @@ -371,19 +365,7 @@ packet_set_connection(c->c_fd, c->c_fd); enable_compat20(); - { - 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_DSA; break; - case KT_X509RSA: k.type = KEY_X509_RSA; break; - default: - fprintf(stderr, "keygrab_ssh2:Invalid keytype!\n"); - exit(1); - } - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = (char*)key_ssh_name(&k); - } + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = (char*)c->c_keyname; c->c_kex = kex_setup(myproposal); c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; @@ -418,7 +400,7 @@ #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); + x509key_write_subject2(key, c->c_keyname, stdout); } else { #endif /*ndef SSH_X509STORE_DISABLED*/ key_write(key, stdout); @@ -462,7 +444,7 @@ } static int -conalloc(char *iname, char *oname, int keytype) +conalloc(char *iname, char *oname, const char *keyname) { char *namebase, *name, *namelist; int s; @@ -491,7 +473,7 @@ fdcon[s].c_data = (char *) &fdcon[s].c_plen; fdcon[s].c_len = 4; fdcon[s].c_off = 0; - fdcon[s].c_keytype = keytype; + fdcon[s].c_keyname = keyname; gettimeofday(&fdcon[s].c_tv, NULL); fdcon[s].c_tv.tv_sec += timeout; TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); @@ -511,7 +493,7 @@ if (fdcon[s].c_status == CS_KEYS) xfree(fdcon[s].c_data); fdcon[s].c_status = CS_UNUSED; - fdcon[s].c_keytype = 0; + fdcon[s].c_keyname = NULL; TAILQ_REMOVE(&tq, &fdcon[s], c_link); FD_CLR(s, read_wait); ncon--; @@ -532,7 +514,7 @@ con *c = &fdcon[s]; int ret; - ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype); + ret = conalloc(c->c_namelist, c->c_output_name, c->c_keyname); confree(s); return (ret); } @@ -545,6 +527,7 @@ char remote_version[sizeof buf]; size_t bufsiz; con *c = &fdcon[s]; + int rsa1key; for (;;) { memset(buf, '\0', sizeof(buf)); @@ -584,7 +567,8 @@ compat_datafellows(remote_version); else datafellows = 0; - if (c->c_keytype != KT_RSA1) { + rsa1key = (strcmp(c->c_keyname, "rsa1") == 0); + if (!rsa1key) { if (!ssh2_capable(remote_major, remote_minor)) { debug("%s doesn't support ssh2", c->c_name); confree(s); @@ -597,8 +581,8 @@ } fprintf(stderr, "# %s %s\n", c->c_name, chop(buf)); n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", - c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, - c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); + rsa1key ? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, + rsa1key ? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); if (n < 0 || (size_t)n >= sizeof(buf)) { error("snprintf: buffer too small"); confree(s); @@ -609,7 +593,7 @@ confree(s); return; } - if (c->c_keytype != KT_RSA1) { + if (!rsa1key) { keyprint(c, keygrab_ssh2(c)); confree(s); return; @@ -714,16 +698,18 @@ do_host(char *host) { char *name = strnnsep(&host, " \t\n"); - int j; + const char *keyname; if (name == NULL) return; - for (j = KT_RSA1; j <= KT_X509RSA; j *= 2) { - if (get_keytypes & j) { - while (ncon >= MAXCON) - conloop(); - conalloc(name, *host ? host : name, j); - } + for ( + keyname = strtok(get_keynames, ","); + keyname != NULL; + keyname = strtok(NULL, ",") + ) { + while (ncon >= MAXCON) + conloop(); + conalloc(name, *host ? host : name, keyname); } } @@ -771,6 +757,7 @@ if (argc <= 1) usage(); + fill_default_xkalg(); while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) { switch (opt) { case 'H': @@ -806,29 +793,12 @@ argv[fopt_count++] = optarg; break; case 't': - get_keytypes = 0; + get_keynames = xstrdup(optarg); tname = strtok(optarg, ","); while (tname) { int type = key_type_from_name(tname); - switch (type) { - case KEY_RSA1: - get_keytypes |= KT_RSA1; - break; - case KEY_DSA: - get_keytypes |= KT_DSA; - break; - case KEY_RSA: - get_keytypes |= KT_RSA; - break; - case KEY_X509_DSA: - get_keytypes |= KT_X509DSA; - break; - case KEY_X509_RSA: - get_keytypes |= KT_X509RSA; - break; - case KEY_UNSPEC: + if (type == KEY_UNSPEC) fatal("unknown key type %s", tname); - } tname = strtok(NULL, ","); } break; diff -ruN openssh-4.3p1+x509-5.2/ssh-x509.c openssh-4.3p1+x509-5.3/ssh-x509.c --- openssh-4.3p1+x509-5.2/ssh-x509.c 2005-06-11 15:03:05.000000000 +0300 +++ openssh-4.3p1+x509-5.3/ssh-x509.c 2005-09-15 21:16:03.000000000 +0300 @@ -23,6 +23,7 @@ */ #include "ssh-x509.h" +#include "ssh-xkalg.h" #include "log.h" #include #include "xmalloc.h" @@ -34,7 +35,6 @@ int (*pssh_x509cert_check)(X509 *_cert) = NULL; -int ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b); static char* @@ -47,9 +47,6 @@ } -/* rumen-XXX: X.509 RSASIG check */ -void (*plogx509rsasig)(const char *msg) = NULL; - #ifndef SSH_X509STORE_DISABLED static const char* x509key_find_subject(const char* s) { @@ -226,10 +223,10 @@ if (_keytype != KEY_X509_RSA && _keytype != KEY_X509_DSA) { - debug3("x509key_from_subject: %d is not x509 key ", _keytype); + debug3("x509key_from_subject: %d is not x509 key", _keytype); return(NULL); } - debug3("x509key_from_subject(%d, [%.*s]) called ", + debug3("x509key_from_subject(%d, [%.*s]) called", _keytype, X509_NAME_MAXLEN, (_cp ? _cp : "")); subject = x509key_find_subject(_cp); if (subject == NULL) @@ -428,10 +425,19 @@ #ifndef SSH_X509STORE_DISABLED int x509key_write_subject(const Key *key, FILE *f) { + return(x509key_write_subject2(key, key_ssh_name(key), f)); +} +#endif /*ndef SSH_X509STORE_DISABLED*/ + + +#ifndef SSH_X509STORE_DISABLED +int +x509key_write_subject2(const Key *key, const char *keyname, FILE *f) { BIO *out; char buf[X509_NAME_MAXLEN]; - if (!x509key_check("x509key_write_subject", key)) return(0); + if (!x509key_check("x509key_write_subject2", key)) return(0); + if (keyname == NULL) return(0); out = BIO_new_fp(f, BIO_NOCLOSE); if (out == NULL) return(0); @@ -442,7 +448,7 @@ } #endif - BIO_puts(out, key_ssh_name(key)); + BIO_puts(out, keyname); BIO_puts(out, " Subject:"); X509_NAME_oneline(X509_get_subject_name(key->x509), buf, sizeof(buf)); BIO_puts(out, buf); @@ -542,274 +548,6 @@ #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); - - int ret = memcmp(a->data, b->data, lmin); - - return((ret == 0) - ? (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) -{ - int la = M_ASN1_STRING_length(a); - int lb = M_ASN1_STRING_length(b); - const char *sa = (const char *)M_ASN1_STRING_data(a); - const char *sb = (const char *)M_ASN1_STRING_data(b); - - return((strncasecmp(sa, sb, MIN(la, lb)) != 0) ? (lb - la) : 0); -} -#endif /*ndef SSH_X509STORE_DISABLED*/ - - -#ifndef SSH_X509STORE_DISABLED -/* from RFC3280 and oldest 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_printable_casecmp(const u_char *pa, int la, const u_char *pb, int lb) -{ -/* - * Be careful: this method work fine only in "C(POSIX)" locale. - * Since OpenSSH now run without to set locale, i.e. - * following comparision is OK. - * This implementation should be changed for other locales !!! - */ - /* skip leading spaces */ - for (; la > 0 && isspace((int)*pa); la--, pa++); - for (; lb > 0 && isspace((int)*pb); lb--, pb++); - - /* skip trailing spaces */ - { - const u_char *p; - for (p = pa + la - 1; la > 0 && isspace((int)*p); la--, p--); - for (p = pb + lb - 1; lb > 0 && isspace((int)*p); lb--, p--); - } - - while (la > 0 && lb > 0) - { - int chA = tolower((int)*pa); - int chB = tolower((int)*pb); - - if (chA != chB) - return(chB - chA); - - pa++; pb++; - la--; lb--; - if (isspace(chA)) { - for (; la > 0 && isspace((int)*pa); la--, pa++); - for (; lb > 0 && isspace((int)*pb); lb--, pb++); - } - } - return(lb - la); -} -#endif /*ndef SSH_X509STORE_DISABLED*/ - - -#ifndef SSH_X509STORE_DISABLED -static int -ssh_ASN1_PRINTABLESTRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) -{ - int n = -1; - int tagA, tagB; - int la, lb; - u_char *pa, *pb; - - tagA = M_ASN1_STRING_type(a); - tagB = M_ASN1_STRING_type(b); - if (tagA != V_ASN1_PRINTABLESTRING) { - debug3("ssh_ASN1_PRINTABLESTRING_cmp: a->type=%d(%.30s) is not PrintableString", tagA, ASN1_tag2str(tagA)); - } - if (tagB != V_ASN1_PRINTABLESTRING) { - debug3("ssh_ASN1_PRINTABLESTRING_cmp: b->type=%d(%.30s) is not PrintableString", tagB, ASN1_tag2str(tagB)); - } - - /* TODO when tagA == tagB */ - /*both are PrintableString*/ - la = M_ASN1_STRING_length(a); - pa = M_ASN1_STRING_data(a); - lb = M_ASN1_STRING_length(b); - pb = M_ASN1_STRING_data(b); - /* TODO else */ - /*convert strings to utf8*/ - - n = ssh_printable_casecmp(pa, la, pb, lb); -#ifdef SSHX509TEST_DBGCMP -fprintf(stderr, "ssh_ASN1_PRINTABLESTRING_cmp: return %d\n", n); -#endif - return(n); -} -#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 - * is more restrictive but more correct (!). - * Problem is that some x509 implementation set X509_NAME entry - * incorrectly to "Printable String" :-[ . - * Work around: when one entry is "Printable String" method compare - * to corresponding entry as "Printable String". - * 2.) - * OpenSSL functions X509_NAME_cmp check nids order in X509_NAME. - * i.e. X509_NAME{"/C=XX/O=YY"} is not equal to X509_NAME{"/O=YY/C=XX"} - */ -int -ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b) { - int k, n; - X509_NAME *b; - -#if 1 - /*XXX: to call fatal when _a or _b is NULL or to use next*/ - if (_a == NULL) { - return((_b == NULL) ? 0 : 1); - } else { - if (_b == NULL) return(-1); - } -#else - if (_a == NULL) { - fatal("ssh_X509_NAME_cmp: first name is NULL"); - } - if (_b == NULL) { - fatal("ssh_X509_NAME_cmp: second name is NULL"); - } -#endif - - k = sk_X509_NAME_ENTRY_num(_a->entries); - n = sk_X509_NAME_ENTRY_num(_b->entries); - - if (k != n) - return(n - k); - - b = X509_NAME_dup(_b); - n = 0; - for (--k; k >= 0; k--) { - X509_NAME_ENTRY *neA; - ASN1_STRING *nvA; - int nid; - X509_NAME_ENTRY *neB; - ASN1_STRING *nvB; - int loc; - - neA = sk_X509_NAME_ENTRY_value(_a->entries, k); - nvA = neA->value; - nid = OBJ_obj2nid(neA->object); - loc = X509_NAME_get_index_by_NID(b, nid, -1); - if (loc < 0) { - char buf1[X509_NAME_MAXLEN]; - char buf2[X509_NAME_MAXLEN]; - - X509_NAME_oneline(_a, buf1, sizeof(buf1)); - X509_NAME_oneline(_b, buf2, sizeof(buf2)); - debug3("ssh_X509_NAME_cmp: insufficient entries with nid=%d(%.40s) in second name." - " na=%.*s, nb=%.*s", - nid, OBJ_nid2ln(nid), - (int) sizeof(buf1), buf1, - (int) sizeof(buf1), buf2); - n = -1; - break; - } -trynextentry: - neB = sk_X509_NAME_ENTRY_value(b->entries, loc); - nvB = neB->value; -#ifdef SSHX509TEST_DBGCMP -{ - int l, tag; - - l = M_ASN1_STRING_length(nvA); - tag = M_ASN1_STRING_type (nvA); - fprintf(stderr, "nvA(%.40s:%d)='", ASN1_tag2str(tag), l); - ASN1_STRING_print_ex_fp(stderr, nvA, /*flags*/0); - fputs("'\n", stderr); - - l = M_ASN1_STRING_length(nvB); - tag = M_ASN1_STRING_type (nvB); - fprintf(stderr, "nvA(%.40s:%d)='", ASN1_tag2str(tag), l); - ASN1_STRING_print_ex_fp(stderr, nvB, /*flags*/0); - fputs("'\n", stderr); -} -#endif - - if (nid == NID_pkcs9_emailAddress) { - int tag; - - tag = M_ASN1_STRING_type(nvA); - if (tag != V_ASN1_IA5STRING) { - /* to be strict and return nonzero or ... ? XXX - n = -1; - break; - */ - error("ssh_X509_NAME_cmp: incorrect type for emailAddress(a) %d(%.30s)", tag, ASN1_tag2str(tag)); - } - - tag = M_ASN1_STRING_type(nvB); - if (tag != V_ASN1_IA5STRING) { - /* to be strict and return nonzero or ... ? XXX - n = 1; - break; - */ - error("ssh_X509_NAME_cmp: incorrect type for emailAddress(b) %d(%.30s)", tag, ASN1_tag2str(tag)); - } - - n = ssh_ASN1_STRING_casecmp(nvA, nvB); - if (n == 0) goto entryisok; - - goto getnextentry; - } - if ((M_ASN1_STRING_type(nvA) == V_ASN1_PRINTABLESTRING) || - (M_ASN1_STRING_type(nvB) == V_ASN1_PRINTABLESTRING) ) { - n = ssh_ASN1_PRINTABLESTRING_cmp(nvA, nvB); - if (n == 0) goto entryisok; - - goto getnextentry; - } - - n = M_ASN1_STRING_length(nvA) - M_ASN1_STRING_length(nvB); - if (n != 0) goto getnextentry; - - n = M_ASN1_STRING_length(nvA); - n = memcmp(nvA->data, nvB->data, n); - if (n != 0) goto getnextentry; - - /* openssl check object too */ - n = ssh_ASN1_OBJECT_cmp(neA->object, neB->object); - if (n != 0) goto getnextentry; - -entryisok: - { - X509_NAME_ENTRY *ne = X509_NAME_delete_entry(b, loc); - X509_NAME_ENTRY_free(ne); - } - continue; -getnextentry: - loc = X509_NAME_get_index_by_NID(b, nid, loc); - if (loc < 0) { - break; - } - goto trynextentry; - } - - X509_NAME_free(b); -#ifdef SSHX509TEST_DBGCMP -fprintf(stderr, "ssh_X509_NAME_cmp: return %d\n", n); -#endif - 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 !!! @@ -839,12 +577,59 @@ int +ssh_x509key_type(const char *name) { + SSHX509KeyAlgs *p; + int k; + + if (name == NULL) { + fatal("ssh_x509key_type: name is NULL"); + return(KEY_UNSPEC); /*unreachable code*/ + } + + k = ssh_xkalg_nameind(name, &p, -1); + return((k >= 0) ? p->type : KEY_UNSPEC); +} + + +static SSHX509KeyAlgs* +ssh_first_xkalg(int type) { + SSHX509KeyAlgs *p; + int k; + + k = ssh_xkalg_typeind(type, &p, -1); + return((k >= 0) ? p : NULL); +} + + +const char* +ssh_x509key_name(const Key *k) { + int type; + SSHX509KeyAlgs *p; + + if (k == NULL) { + fatal("ssh_x509key_name: key is NULL"); + return(NULL); /*unreachable code*/ + } + + type = k->type; + if ((type != KEY_X509_RSA) && (type != KEY_X509_DSA)) return(NULL); + + p = ssh_first_xkalg(type); + if (p != NULL) return(p->name); + + error("ssh_x509key_name: cannot handle type %d", type); + return(NULL); +} + + +int ssh_x509_sign( const Key *key, u_char **psignature, u_int *psignaturelen, const u_char *data, u_int datalen ) { int ret = -1; + SSHX509KeyAlgs *xkalg; u_char sigret[256]; u_int siglen; @@ -875,38 +660,35 @@ } if (ret > 0) { - EVP_MD_CTX ctx; - const EVP_MD *evp_md; - if (key->rsa) { - evp_md = (x509rsasigtype == SSH_X509RSA_SHA1) ? EVP_sha1() : EVP_md5(); - } else { - evp_md = EVP_dss1(); + xkalg = ssh_first_xkalg(key->type); + if (xkalg == NULL) { + error("ssh_x509_sign: cannot handle type %d", key->type); + ret = -1; } + } + if (ret > 0) { + EVP_MD_CTX ctx; - 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); + debug3("ssh_x509_sign: alg=%.50s, md=%.30s", xkalg->name, xkalg->dgst.name); + EVP_SignInit(&ctx, xkalg->dgst.evp); EVP_SignUpdate(&ctx, data, datalen); - - if (ret > 0) { - ret = EVP_SignFinal(&ctx, sigret, &siglen, privkey); - if (ret <= 0) { - char ebuf[256]; - error("ssh_x509_sign: digest failed: %.*s", - sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf))); - } + ret = EVP_SignFinal(&ctx, sigret, &siglen, privkey); + if (ret <= 0) { + char ebuf[256]; + error("ssh_x509_sign: digest failed: %.*s", + sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf))); } } EVP_PKEY_free(privkey); } if (ret > 0) { Buffer b; + const char *signame; buffer_init(&b); - buffer_put_cstring(&b, key_ssh_name(key)); + signame = X509PUBALG_SIGNAME(xkalg); + debug3("ssh_x509_sign: signame=%.50s", signame); + buffer_put_cstring(&b, signame); buffer_put_string(&b, sigret, siglen); { @@ -941,26 +723,27 @@ { /* get signature data only */ Buffer b; + + ret = 1; buffer_init(&b); buffer_append(&b, signature, signaturelen); - { /* check signature key type */ - char *ktype = buffer_get_string(&b, NULL); - debug3("ssh_x509_verify: signature key type = %.40s", ktype); - ret = strcmp("x509v3-sign-rsa", ktype) == 0 || - strcmp("x509v3-sign-dss", ktype) == 0; - if (!ret) { - error("ssh_x509_verify: cannot handle signature key type %.40s", ktype); + { /* check signature format */ + char *sigformat = buffer_get_string(&b, NULL); + + debug3("ssh_x509_verify: signature format = %.40s", sigformat); + if (!ssh_is_x509signame(sigformat)) { + error("ssh_x509_verify: cannot handle signature format %.40s", sigformat); + ret = 0; } - xfree(ktype); + xfree(sigformat); } if (ret > 0) { - sigblob = buffer_get_string(&b, &len); - } + int rlen; - if (ret > 0) { - int rlen = buffer_len(&b); + sigblob = buffer_get_string(&b, &len); + rlen = buffer_len(&b); if (rlen != 0) { error("ssh_x509_verify: remaining bytes in signature %d", rlen); ret = -1; @@ -971,58 +754,36 @@ if (ret > 0 ) { EVP_PKEY* pubkey = X509_get_pubkey(key->x509); + SSHX509KeyAlgs *xkalg; + int loc; + if (pubkey == NULL) { error("ssh_x509_verify: no 'X509 Public Key'"); ret = -1; } - if (ret > 0) { - EVP_MD_CTX ctx; - const EVP_MD *evp_md; - if (key->rsa) { - evp_md = (x509rsasigtype == SSH_X509RSA_SHA1) ? EVP_sha1() : EVP_md5(); - } else { - evp_md = EVP_dss1(); + loc = ssh_xkalg_typeind(key->type, &xkalg, -1); + if (loc < 0) { + error("ssh_x509_verify: cannot handle type %d", key->type); + ret = -1; } - 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); + } + if (ret > 0) { + for (; loc >= 0; loc = ssh_xkalg_typeind(key->type, &xkalg, loc)) { + EVP_MD_CTX ctx; - EVP_VerifyInit(&ctx, evp_md); + debug3("ssh_x509_verify: md=%.30s, loc=%d", xkalg->dgst.name, loc); + EVP_VerifyInit(&ctx, xkalg->dgst.evp); EVP_VerifyUpdate(&ctx, data, datalen); ret = EVP_VerifyFinal(&ctx, sigblob, len, pubkey); - if (ret > 0) { - const 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 - logit(pmsg); - } + if (ret > 0) break; } if (ret <= 0) { - char ebuf[256]; - error("ssh_x509_verify: verify failed: %.*s", - sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf))); + debug3("ssh_x509_verify: failed for all digests"); ret = 0; } } - EVP_PKEY_free(pubkey); /* XXX ?*/ + EVP_PKEY_free(pubkey); } if (sigblob) { memset(sigblob, 's', len); diff -ruN openssh-4.3p1+x509-5.2/ssh-x509.h openssh-4.3p1+x509-5.3/ssh-x509.h --- openssh-4.3p1+x509-5.2/ssh-x509.h 2005-06-10 21:01:46.000000000 +0300 +++ openssh-4.3p1+x509-5.3/ssh-x509.h 2005-08-13 17:58:58.000000000 +0300 @@ -1,7 +1,7 @@ #ifndef SSH_X509_H #define SSH_X509_H /* - * Copyright (c) 2002-2004 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,6 +51,7 @@ * Method write x509 certificate subject. */ int x509key_write_subject(const Key *key, FILE *f); +int x509key_write_subject2(const Key *key, const char *keyname, FILE *f); #endif /*ndef SSH_X509STORE_DISABLED*/ Key* x509key_load_cert(Key *key, FILE *fp); @@ -60,6 +61,10 @@ #ifndef SSH_X509STORE_DISABLED int ssh_x509_equal(const Key *a, const Key *b); #endif /*ndef SSH_X509STORE_DISABLED*/ + +int ssh_x509key_type(const char *name); +const char* ssh_x509key_name(const Key *k); + int ssh_x509_sign(const Key *key, u_char **psignature, u_int *psignaturelen, const u_char *data, u_int datalen); int ssh_x509_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen); u_int ssh_x509_key_size(const Key *key); diff -ruN openssh-4.3p1+x509-5.2/ssh-xkalg.c openssh-4.3p1+x509-5.3/ssh-xkalg.c --- openssh-4.3p1+x509-5.2/ssh-xkalg.c 1970-01-01 02:00:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-xkalg.c 2005-08-14 00:43:51.000000000 +0300 @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2005 Roumen Petrov. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ssh-xkalg.h" +#include "log.h" +#include "key.h" +#include "xmalloc.h" + + +#define SHARAW_DIGEST_LENGTH (2*SHA_DIGEST_LENGTH) + + +#ifdef OPENSSL_NO_DSA +# error "OPENSSL_NO_DSA" +#endif +#ifdef OPENSSL_NO_SHA +# error "OPENSSL_NO_SHA" +#endif + + +#define EVP_PKEY_DSARAW_method \ + DSARAW_sign,DSARAW_verify, \ + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3,EVP_PKEY_DSA4,0} + + +static int/*bool*/ +DSARAW_sign( + int type, + const unsigned char *dgst, + int dlen, + unsigned char *sigret, unsigned int *siglen, + DSA *dsa +) { + int ret = 0; + DSA_SIG *sig = NULL; + +#ifdef TRACE_XKALG +fprintf(stderr, "TRACE_XKALG DSARAW_sign:\n"); +#endif + sig = DSA_do_sign(dgst, dlen, dsa); + if (sig == NULL) { + *siglen=0; + return(ret); + } + + *siglen = SHARAW_DIGEST_LENGTH; + if (sigret != NULL) { + u_int rlen, slen; + rlen = BN_num_bytes(sig->r); + slen = BN_num_bytes(sig->s); + if (rlen > SHA_DIGEST_LENGTH || slen > SHA_DIGEST_LENGTH) { + error("DSARAW_sign: bad sig size %u %u", rlen, slen); + goto done; + } + memset(sigret, 0, SHARAW_DIGEST_LENGTH); + BN_bn2bin(sig->r, sigret + SHARAW_DIGEST_LENGTH - SHA_DIGEST_LENGTH - rlen); + BN_bn2bin(sig->s, sigret + SHARAW_DIGEST_LENGTH - slen); + } + ret = 1; + +done: + DSA_SIG_free(sig); + return(ret); +} + + +static int +DSARAW_verify( + int type, + const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, + DSA *dsa +) { + int ret = -1; + DSA_SIG *sig = NULL; + +#ifdef TRACE_XKALG +fprintf(stderr, "TRACE_XKALG DSARAW_verify: siglen=%d\n", siglen); +#endif + if (siglen != SHARAW_DIGEST_LENGTH) return(ret); + + sig = DSA_SIG_new(); + if (sig == NULL) return(ret); + + sig->r = BN_new(); + if (sig->r == NULL) + fatal("DSARAW_verify: BN_new failed"); + sig->s = BN_new(); + if (sig->s == NULL) + fatal("DSARAW_verify: BN_new failed"); + + BN_bin2bn(sigbuf , SHA_DIGEST_LENGTH, sig->r); + BN_bin2bn(sigbuf+SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH, sig->s); + + ret = DSA_do_verify(dgst, dgst_len, sig, dsa); + + DSA_SIG_free(sig); + return(ret); +} + + +static int +init(EVP_MD_CTX *ctx) { + return(SHA1_Init(ctx->md_data)); +} + + +static int +update(EVP_MD_CTX *ctx, const void *data, unsigned long count) { + return(SHA1_Update(ctx->md_data, data, count)); +} + + +static int +final(EVP_MD_CTX *ctx, unsigned char *md) { + return(SHA1_Final(md, ctx->md_data)); +} + + +static const +EVP_MD dss1_md = { + NID_dsa, + NID_dsaWithSHA1, + SHA_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_DSARAW_method, + SHA_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA_CTX), +}; + + +extern const EVP_MD* +EVP_dss1raw(void); + + +const EVP_MD* +EVP_dss1raw(void) { + return(&dss1_md); +} + + +/* SSH X509 public key algorithms*/ +static int x509keyalgs_initialized = 0; +static SSHX509KeyAlgs x509keyalgs[10]; + + +static void +initialize_xkalg(void) { + SSHX509KeyAlgs *p = x509keyalgs; + int k; + + if (x509keyalgs_initialized) return; + +#ifdef TRACE_XKALG +fprintf(stderr, "TRACE_XKALG initialize_xkalg:\n"); +#endif + k = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]); + for (; k > 0; k--, p++) { + p->type = KEY_UNSPEC; + p->name = NULL; + p->dgst.name = NULL; + p->dgst.evp = NULL; + p->signame = NULL; + } + x509keyalgs_initialized = 1; +} + + +static void +add_default_xkalg(void) { +#ifdef TRACE_XKALG +fprintf(stderr, "TRACE_XKALG add_default_xkalg:\n"); +#endif + + /*RSA public key algorithm*/ +#if 1 + /* OpenSSH defaults note that + * draft-ietf-secsh-transport-NN.txt where NN <= 12 + * don't define signature format + */ + if (ssh_add_x509key_alg("x509v3-sign-rsa,rsa-md5") < 0) + fatal("ssh_init_xkalg: oops"); +#endif + if (ssh_add_x509key_alg("x509v3-sign-rsa,rsa-sha1") < 0) + fatal("ssh_init_xkalg: oops"); + + /* "draft-ietf-secsh-x509-01.txt" */ + if (ssh_add_x509key_alg("x509v3-sign-rsa-sha1,rsa-sha1,ssh-rsa") < 0) + fatal("ssh_init_xkalg: oops"); + + /*DSA public key algorithm*/ +#if 1 + /* OpenSSH default compatible with + * draft-ietf-secsh-transport-NN.txt where NN <= 12 + */ + if (ssh_add_x509key_alg("x509v3-sign-dss,dss-asn1") < 0) + fatal("ssh_init_xkalg: oops"); +#endif + /* some non OpenSSH implementations incompatible with + * draft-ietf-secsh-transport-NN.txt where NN <= 12 + */ + if (ssh_add_x509key_alg("x509v3-sign-dss,dss-raw") < 0) + fatal("ssh_init_xkalg: oops"); + + /* draft-ietf-secsh-x509-01.txt */ + if (ssh_add_x509key_alg("x509v3-sign-dss-sha1,dss-raw,ssh-dss") < 0) + fatal("ssh_init_xkalg: oops"); +} + + +void +fill_default_xkalg(void) { + SSHX509KeyAlgs *p = x509keyalgs; + +#ifdef TRACE_XKALG +fprintf(stderr, "TRACE_XKALG fill_default_xkalg:\n"); +#endif + initialize_xkalg(); + if (p[0].name == NULL) add_default_xkalg(); +} + + +static const EVP_MD* +ssh_evp_md(const char *dgstname) { + if (dgstname == NULL) { + fatal("ssh_get_md: dgstname is NULL"); + return(NULL); /*unreachable code*/ + } + + if (strcasecmp("rsa-sha1", dgstname) == 0) return(EVP_sha1()); + if (strcasecmp("rsa-md5" , dgstname) == 0) return(EVP_md5()); +/*?: if (strcasecmp("ssh-rsa" , dgstname) == 0) return(EVP_sha1());*/ + + if (strcasecmp("dss-asn1", dgstname) == 0) return(EVP_dss1()); + if (strcasecmp("dss-raw" , dgstname) == 0) return(EVP_dss1raw()); +/*?: if (strcasecmp("ssh-dss" , dgstname) == 0) return(EVP_dss1raw());*/ + +#if 0 + fatal("ssh_get_md: invalid sigformat '%.10s'", dgstname); +#endif + return(NULL); /*unreachable code*/ +} + + +int +ssh_add_x509key_alg(const char *data) { + char *name, *mdname, *signame; + SSHX509KeyAlgs* p; + const EVP_MD* md; + + if (data == NULL) { + error("ssh_add_x509pubkey_alg: data is NULL"); + return(-1); + } + + name = xstrdup(data); /*fatal on error*/ + + mdname = strchr(name, ','); + if (mdname == NULL) { + error("ssh_add_x509pubkey_alg: cannot get digest"); + goto err; + } + *mdname++ = '\0'; + + signame = strchr(mdname, ','); + if (signame != NULL) *signame++ = '\0'; + + md = ssh_evp_md(mdname); + if (md == NULL) { + error("ssh_add_x509pubkey_alg: unsupported digest"); + goto err; + } + + initialize_xkalg(); + p = x509keyalgs; + { + int k = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]); + + for (; k > 0; k--, p++) { + if (p->name == NULL) break; + } + if (k <= 0) { + error("ssh_add_x509pubkey_alg: insufficient slots"); + goto err; + } + } + + if ((md == EVP_dss1()) || (md == EVP_dss1raw())) { + p->type = KEY_X509_DSA; + } else { + p->type = KEY_X509_RSA; + } + p->name = name; + p->dgst.name = mdname; + p->dgst.evp = md; + p->signame = signame; + + return (1); + +err: + xfree((void*)name); + return (-1); +} + + +int/*bool*/ +ssh_is_x509signame(const char *signame) { + SSHX509KeyAlgs *xkalg; + int k; + + if (signame == NULL) { + fatal("ssh_is_x509signame: signame is NULL"); + return(0); /*unreachable code*/ + } + + initialize_xkalg(); + xkalg = x509keyalgs; + k = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]); + + for (; k > 0; k--, xkalg++) { + if (xkalg->name == NULL) return(0); + if (strcmp(signame, X509PUBALG_SIGNAME(xkalg)) == 0) return(1); + } + return(0); +} + + +int +ssh_xkalg_nameind(const char *name, SSHX509KeyAlgs **q, int loc) { + int k, n; + SSHX509KeyAlgs *p; + + if (name == NULL) return (-1); + + initialize_xkalg(); + k = (loc < 0) ? 0 : (loc + 1); + n = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]); + if (k < n) p = &x509keyalgs[k]; + + for (; k < n; k++, p++) { + if (p->name == NULL) return(-1); + if (strcmp(p->name, name) == 0) { + if (q) *q = p; + return(k); + } + } + return(-1); +} + + +int +ssh_xkalg_typeind(int type, SSHX509KeyAlgs **q, int loc) { + int k, n; + SSHX509KeyAlgs *p; + + initialize_xkalg(); + k = (loc < 0) ? 0 : (loc + 1); + n = sizeof(x509keyalgs) / sizeof(x509keyalgs[0]); + if (k < n) p = &x509keyalgs[k]; + + for (; k < n; k++, p++) { + if (p->name == NULL) return(-1); + if (p->type == type) { + if (q) *q = p; + return(k); + } + } + return(-1); +} + + +void +ssh_list_xkalg(int type, Buffer *b) { + SSHX509KeyAlgs *xkalg; + int loc; + + if ((type != KEY_X509_RSA) && (type != KEY_X509_DSA)) { + error("ssh_list_xkalg: %d is not x509 key", type); + return; + } + if (b == NULL) { + error("ssh_list_xkalg: buffer is NULL"); + return; + } + +#if 1 + /* add only(!) first found */ + loc = ssh_xkalg_typeind(type, &xkalg, -1); + if (loc < 0) return; + + if (buffer_len(b) > 0) buffer_append(b, ",", 1); + buffer_append(b, xkalg->name, strlen(xkalg->name)); +#else +IMPORTANT NOTE: + For every unique "key name" we MUST define unique "key type" +otherwise cannot distinguish them ! +As example structure Kex contain integer attribute "kex_type" +and kex use method "load_host_key" to find hostkey. When client +request hostkey algorithms (comma separated list with names) +server should be able to find first hostkey that match one of them. +Note to "load_host_key" is assigned method "get_hostkey_by_type" +defined in "sshd.c". + + for ( + loc = ssh_xkalg_typeind(type, &xkalg, -1); + loc >= 0; + loc = ssh_xkalg_typeind(type, &xkalg, loc) + ) { + const char *p; + int dupl, k; + + p = xkalg->name; + + dupl = 0; + + for ( + k = ssh_xkalg_typeind(type, &xkalg, -1); + (k >= 0) && (k < loc); + k = ssh_xkalg_typeind(type, &xkalg, k) + ) { + if (strcmp(p, xkalg->name) == 0) { + dupl = 1; + break; + } + } + if (dupl) continue; + + if (buffer_len(b) > 0) buffer_append(b, ",", 1); + buffer_append(b, p, strlen(p)); + } +#endif +} diff -ruN openssh-4.3p1+x509-5.2/ssh-xkalg.h openssh-4.3p1+x509-5.3/ssh-xkalg.h --- openssh-4.3p1+x509-5.2/ssh-xkalg.h 1970-01-01 02:00:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/ssh-xkalg.h 2005-08-13 14:01:31.000000000 +0300 @@ -0,0 +1,58 @@ +#ifndef SSH_XKALG_H +#define SSH_XKALG_H +/* + * Copyright (c) 2005 Roumen Petrov. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "includes.h" +#include +#include "buffer.h" + + +typedef struct { + int type; + const char *name; + struct { + const char *name; + const EVP_MD *evp; + } dgst; + const char *signame; +} SSHX509KeyAlgs; +#define X509PUBALG_SIGNAME(p) (p->signame ? p->signame : p->name) + + +void fill_default_xkalg(void); + /* format "name,dgst_name[,sig_name]" */ +int ssh_add_x509key_alg(const char *data); + + +int/*bool*/ ssh_is_x509signame(const char *signame); + +int ssh_xkalg_nameind(const char *name, SSHX509KeyAlgs **q, int loc); +int ssh_xkalg_typeind(int type, SSHX509KeyAlgs **q, int loc); + +void ssh_list_xkalg(int type, Buffer *b); + + +#endif /* SSH_XKALG_H */ diff -ruN openssh-4.3p1+x509-5.2/tests/CA/1-cre_cadb.sh openssh-4.3p1+x509-5.3/tests/CA/1-cre_cadb.sh --- openssh-4.3p1+x509-5.2/tests/CA/1-cre_cadb.sh 2004-10-30 00:17:59.000000000 +0300 +++ openssh-4.3p1+x509-5.3/tests/CA/1-cre_cadb.sh 2005-11-22 20:33:34.000000000 +0200 @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2002-2004 Roumen Petrov, Sofia, Bulgaria +# Copyright (c) 2002-2005 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -177,8 +177,8 @@ [ usr_cert ] # These extensions are added when 'ca' signs a request. -basicConstraints=CA:FALSE -nsCertType = client, email +basicConstraints = CA:FALSE +nsCertType = client, email # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment @@ -219,6 +219,10 @@ # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always + +# Some SSH clients require server certificate to contain +# correct alternate name of type DNS (FQDN) +subjectAltName = DNS:localhost EOF echo_CA_ocsp_options >> "$1" diff -ruN openssh-4.3p1+x509-5.2/tests/CA/5-cre_ldap.sh openssh-4.3p1+x509-5.3/tests/CA/5-cre_ldap.sh --- openssh-4.3p1+x509-5.2/tests/CA/5-cre_ldap.sh 2004-11-08 20:36:45.000000000 +0200 +++ openssh-4.3p1+x509-5.3/tests/CA/5-cre_ldap.sh 2005-08-30 00:57:02.000000000 +0300 @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2004 Roumen Petrov, Sofia, Bulgaria +# Copyright (c) 2004-2005 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -88,50 +88,6 @@ # === -cre_ca_ldif() { -( - for type in ${SSH_SIGN_TYPES}; do - N="${CAKEY_PREFIX}-${type}.crt" - if test ! -f "ldap/${N}.der"; then - ${OPENSSL} x509 \ - -in "${SSH_CACERTDIR}/${N}".pem \ - -out "ldap/${N}.der" -outform DER \ - || exit $? - fi - - N="${CAKEY_PREFIX}-${type}.crl" - if test ! -f "ldap/${N}.der"; then - ${OPENSSL} crl \ - -in "${SSH_CACRLDIR}/${N}".pem \ - -out "ldap/${N}.der" -outform DER \ - || exit $? - fi - done -) || return $? - -( - for type in ${SSH_SIGN_TYPES}; do - cat < ldap/ca.ldif -} - - -# === cre_slapdconf () { ( cat < ldap/slapd.conf.tmpl @@ -162,7 +116,6 @@ # === cre_base_ldif && -cre_ca_ldif && cre_slapdconf && : ; retval=$? diff -ruN openssh-4.3p1+x509-5.2/tests/CA/Makefile.in openssh-4.3p1+x509-5.3/tests/CA/Makefile.in --- openssh-4.3p1+x509-5.2/tests/CA/Makefile.in 2005-06-02 22:20:11.000000000 +0300 +++ openssh-4.3p1+x509-5.3/tests/CA/Makefile.in 2005-08-10 21:02:59.000000000 +0300 @@ -124,7 +124,7 @@ @LDAP_OFF@ldap_files: @LDAP_ON@ldap_files: ldap/slapd.conf.tmpl -@LDAP_ON@ldap/slapd.conf.tmpl: +@LDAP_ON@ldap/slapd.conf.tmpl: env @LDAP_ON@ @echo @LDAP_ON@ $(SHELL) $(srcdir)/5-cre_ldap.sh diff -ruN openssh-4.3p1+x509-5.2/tests/CA/test-alg.sh.inc openssh-4.3p1+x509-5.3/tests/CA/test-alg.sh.inc --- openssh-4.3p1+x509-5.2/tests/CA/test-alg.sh.inc 2004-10-17 16:17:12.000000000 +0300 +++ openssh-4.3p1+x509-5.3/tests/CA/test-alg.sh.inc 2005-08-20 00:45:24.000000000 +0300 @@ -1,5 +1,5 @@ # -# Copyright (c) 2004 Roumen Petrov, Sofia, Bulgaria +# Copyright (c) 2004-2005 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -86,11 +86,12 @@ for type in ${SSH_SIGN_TYPES}; do if test -n "$withcert"; then must_fail="" - if test "X$alg" = "Xx509v3-sign-rsa"; then - test "$keytype" = "rsa" || must_fail="yes" - else - test "$keytype" = "dsa" || must_fail="yes" - fi + case $alg in + x509v3-sign-rsa*) test "$keytype" = "rsa" || must_fail="yes";; + x509v3-sign-dss*) test "$keytype" = "dsa" || must_fail="yes";; + *) echo "${warn}unknown X.509 alg${norm}" + exit 1;; + esac else must_fail="yes" fi @@ -129,6 +130,8 @@ "ssh-dss" \ "x509v3-sign-rsa" \ "x509v3-sign-dss" \ + "x509v3-sign-rsa-sha1" \ + "x509v3-sign-dss-sha1" \ ; do testAlg; retval=$? if test $retval -ne 0; then diff -ruN openssh-4.3p1+x509-5.2/tests/CA/test-by_ldap.sh.inc openssh-4.3p1+x509-5.3/tests/CA/test-by_ldap.sh.inc --- openssh-4.3p1+x509-5.2/tests/CA/test-by_ldap.sh.inc 2004-11-07 22:52:06.000000000 +0200 +++ openssh-4.3p1+x509-5.3/tests/CA/test-by_ldap.sh.inc 2005-08-30 01:43:39.000000000 +0300 @@ -1,5 +1,5 @@ # -# Copyright (c) 2004 Roumen Petrov, Sofia, Bulgaria +# Copyright (c) 2004-2005 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -69,11 +69,56 @@ cat < ${LDAPD_CFG} +} + + +# === +creTestLDAPDCAldifFile() { +( + for type in ${SSH_SIGN_TYPES}; do + N="${CAKEY_PREFIX}-${type}.crt" + if test ! -f "ldap/${N}.der"; then + ${OPENSSL} x509 \ + -in "${SSH_CACERTDIR}/${N}".pem \ + -out "ldap/${N}.der" -outform DER \ + || exit $? + fi + N="${CAKEY_PREFIX}-${type}.crl" + if test ! -f "ldap/${N}.der"; then + ${OPENSSL} crl \ + -in "${SSH_CACRLDIR}/${N}".pem \ + -out "ldap/${N}.der" -outform DER \ + || exit $? + fi + done +) || return $? + +( + for type in ${SSH_SIGN_TYPES}; do + cat < ldap/ca.ldif } @@ -159,6 +204,7 @@ echo "Begin test with LDAP ${extd}version${norm} ${attn}$1${norm}" creTestLDAPDcfgFile + creTestLDAPDCAldifFile creTestSSHDcfgFile #openssh config parser limitation diff -ruN openssh-4.3p1+x509-5.2/x509_nm_cmp.c openssh-4.3p1+x509-5.3/x509_nm_cmp.c --- openssh-4.3p1+x509-5.2/x509_nm_cmp.c 1970-01-01 02:00:00.000000000 +0200 +++ openssh-4.3p1+x509-5.3/x509_nm_cmp.c 2005-08-05 23:30:30.000000000 +0300 @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2005 Roumen Petrov. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* initial code is moved from ssh-x509.c */ +#include "includes.h" + +#ifndef SSH_X509STORE_DISABLED + +#include "x509store.h" +#include "log.h" + + +static int +ssh_ASN1_OBJECT_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + int lmin = MIN(a->length, b->length); + + int ret = memcmp(a->data, b->data, lmin); + + return((ret == 0) + ? (b->length - a->length) + : ret); +} + + +static int +ssh_ASN1_STRING_casecmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int la = M_ASN1_STRING_length(a); + int lb = M_ASN1_STRING_length(b); + const char *sa = (const char *)M_ASN1_STRING_data(a); + const char *sb = (const char *)M_ASN1_STRING_data(b); + + return((strncasecmp(sa, sb, MIN(la, lb)) != 0) ? (lb - la) : 0); +} + + +/* from RFC3280 and oldest 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_printable_casecmp(const u_char *pa, int la, const u_char *pb, int lb) +{ +/* + * Be careful: this method work fine only in "C(POSIX)" locale. + * Since OpenSSH now run without to set locale, i.e. + * following comparision is OK. + * This implementation should be changed for other locales !!! + */ + /* skip leading spaces */ + for (; la > 0 && isspace((int)*pa); la--, pa++); + for (; lb > 0 && isspace((int)*pb); lb--, pb++); + + /* skip trailing spaces */ + { + const u_char *p; + for (p = pa + la - 1; la > 0 && isspace((int)*p); la--, p--); + for (p = pb + lb - 1; lb > 0 && isspace((int)*p); lb--, p--); + } + + while (la > 0 && lb > 0) + { + int chA = tolower((int)*pa); + int chB = tolower((int)*pb); + + if (chA != chB) + return(chB - chA); + + pa++; pb++; + la--; lb--; + if (isspace(chA)) { + for (; la > 0 && isspace((int)*pa); la--, pa++); + for (; lb > 0 && isspace((int)*pb); lb--, pb++); + } + } + return(lb - la); +} + + +static int +ssh_ASN1_PRINTABLESTRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int n = -1; + int tagA, tagB; + int la, lb; + u_char *pa, *pb; + + tagA = M_ASN1_STRING_type(a); + tagB = M_ASN1_STRING_type(b); + if (tagA != V_ASN1_PRINTABLESTRING) { + debug3("ssh_ASN1_PRINTABLESTRING_cmp: a->type=%d(%.30s) is not PrintableString", tagA, ASN1_tag2str(tagA)); + } + if (tagB != V_ASN1_PRINTABLESTRING) { + debug3("ssh_ASN1_PRINTABLESTRING_cmp: b->type=%d(%.30s) is not PrintableString", tagB, ASN1_tag2str(tagB)); + } + + /* TODO when tagA == tagB */ + /*both are PrintableString*/ + la = M_ASN1_STRING_length(a); + pa = M_ASN1_STRING_data(a); + lb = M_ASN1_STRING_length(b); + pb = M_ASN1_STRING_data(b); + /* TODO else */ + /*convert strings to utf8*/ + + n = ssh_printable_casecmp(pa, la, pb, lb); +#ifdef SSHX509TEST_DBGCMP +fprintf(stderr, "ssh_ASN1_PRINTABLESTRING_cmp: return %d\n", n); +#endif + return(n); +} + + +/* + * 1.) + * Since version 0.9.7.beta4 and 0.9.6h OpenSSL function X509_NAME_cmp + * is more restrictive but more correct (!). + * Problem is that some x509 implementation set X509_NAME entry + * incorrectly to "Printable String" :-[ . + * Work around: when one entry is "Printable String" method compare + * to corresponding entry as "Printable String". + * 2.) + * OpenSSL functions X509_NAME_cmp check nids order in X509_NAME. + * i.e. X509_NAME{"/C=XX/O=YY"} is not equal to X509_NAME{"/O=YY/C=XX"} + */ +int +ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b) { + int k, n; + X509_NAME *b; + +#if 1 + /*XXX: to call fatal when _a or _b is NULL or to use next*/ + if (_a == NULL) { + return((_b == NULL) ? 0 : 1); + } else { + if (_b == NULL) return(-1); + } +#else + if (_a == NULL) { + fatal("ssh_X509_NAME_cmp: first name is NULL"); + } + if (_b == NULL) { + fatal("ssh_X509_NAME_cmp: second name is NULL"); + } +#endif + + k = sk_X509_NAME_ENTRY_num(_a->entries); + n = sk_X509_NAME_ENTRY_num(_b->entries); + + if (k != n) + return(n - k); + + b = X509_NAME_dup(_b); + n = 0; + for (--k; k >= 0; k--) { + X509_NAME_ENTRY *neA; + ASN1_STRING *nvA; + int nid; + X509_NAME_ENTRY *neB; + ASN1_STRING *nvB; + int loc; + + neA = sk_X509_NAME_ENTRY_value(_a->entries, k); + nvA = neA->value; + nid = OBJ_obj2nid(neA->object); + loc = X509_NAME_get_index_by_NID(b, nid, -1); + if (loc < 0) { + char buf1[X509_NAME_MAXLEN]; + char buf2[X509_NAME_MAXLEN]; + + X509_NAME_oneline(_a, buf1, sizeof(buf1)); + X509_NAME_oneline(_b, buf2, sizeof(buf2)); + debug3("ssh_X509_NAME_cmp: insufficient entries with nid=%d(%.40s) in second name." + " na=%.*s, nb=%.*s", + nid, OBJ_nid2ln(nid), + (int) sizeof(buf1), buf1, + (int) sizeof(buf1), buf2); + n = -1; + break; + } +trynextentry: + neB = sk_X509_NAME_ENTRY_value(b->entries, loc); + nvB = neB->value; +#ifdef SSHX509TEST_DBGCMP +{ + int l, tag; + + l = M_ASN1_STRING_length(nvA); + tag = M_ASN1_STRING_type (nvA); + fprintf(stderr, "nvA(%.40s:%d)='", ASN1_tag2str(tag), l); + ASN1_STRING_print_ex_fp(stderr, nvA, /*flags*/0); + fputs("'\n", stderr); + + l = M_ASN1_STRING_length(nvB); + tag = M_ASN1_STRING_type (nvB); + fprintf(stderr, "nvA(%.40s:%d)='", ASN1_tag2str(tag), l); + ASN1_STRING_print_ex_fp(stderr, nvB, /*flags*/0); + fputs("'\n", stderr); +} +#endif + + if (nid == NID_pkcs9_emailAddress) { + int tag; + + tag = M_ASN1_STRING_type(nvA); + if (tag != V_ASN1_IA5STRING) { + /* to be strict and return nonzero or ... ? XXX + n = -1; + break; + */ + error("ssh_X509_NAME_cmp: incorrect type for emailAddress(a) %d(%.30s)", tag, ASN1_tag2str(tag)); + } + + tag = M_ASN1_STRING_type(nvB); + if (tag != V_ASN1_IA5STRING) { + /* to be strict and return nonzero or ... ? XXX + n = 1; + break; + */ + error("ssh_X509_NAME_cmp: incorrect type for emailAddress(b) %d(%.30s)", tag, ASN1_tag2str(tag)); + } + + n = ssh_ASN1_STRING_casecmp(nvA, nvB); + if (n == 0) goto entryisok; + + goto getnextentry; + } + if ((M_ASN1_STRING_type(nvA) == V_ASN1_PRINTABLESTRING) || + (M_ASN1_STRING_type(nvB) == V_ASN1_PRINTABLESTRING) ) { + n = ssh_ASN1_PRINTABLESTRING_cmp(nvA, nvB); + if (n == 0) goto entryisok; + + goto getnextentry; + } + + n = M_ASN1_STRING_length(nvA) - M_ASN1_STRING_length(nvB); + if (n != 0) goto getnextentry; + + n = M_ASN1_STRING_length(nvA); + n = memcmp(nvA->data, nvB->data, n); + if (n != 0) goto getnextentry; + + /* openssl check object too */ + n = ssh_ASN1_OBJECT_cmp(neA->object, neB->object); + if (n != 0) goto getnextentry; + +entryisok: + { + X509_NAME_ENTRY *ne = X509_NAME_delete_entry(b, loc); + X509_NAME_ENTRY_free(ne); + } + continue; +getnextentry: + loc = X509_NAME_get_index_by_NID(b, nid, loc); + if (loc < 0) { + break; + } + goto trynextentry; + } + + X509_NAME_free(b); +#ifdef SSHX509TEST_DBGCMP +fprintf(stderr, "ssh_X509_NAME_cmp: return %d\n", n); +#endif + return(n); +} +#endif /*ndef SSH_X509STORE_DISABLED*/ diff -ruN openssh-4.3p1+x509-5.2/x509store.h openssh-4.3p1+x509-5.3/x509store.h --- openssh-4.3p1+x509-5.2/x509store.h 2004-11-07 22:44:28.000000000 +0200 +++ openssh-4.3p1+x509-5.3/x509store.h 2005-07-19 22:27:16.000000000 +0300 @@ -1,7 +1,7 @@ #ifndef X509STORE_H #define X509STORE_H /* - * Copyright (c) 2002-2004 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,6 +40,7 @@ #ifndef SSH_X509STORE_DISABLED +int ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b); int ssh_x509store_lookup(X509_STORE *store, int type, X509_NAME *name, X509_OBJECT *xobj);