diff -ruN openssh-4.3p2+x509-5.3/auth2-pubkey.c openssh-4.3p2+x509-5.4/auth2-pubkey.c --- openssh-4.3p2+x509-5.3/auth2-pubkey.c 2006-01-16 22:42:50.000000000 +0200 +++ openssh-4.3p2+x509-5.4/auth2-pubkey.c 2006-04-26 09:06:01.000000000 +0300 @@ -1,7 +1,7 @@ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * X.509 certificates support, - * Copyright (c) 2003 Roumen Petrov. All rights reserved. + * Copyright (c) 2003-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -197,6 +197,99 @@ return(0); } +static int +key_readx(Key *ret, char **cpp) { + int flag; + + flag = key_read(ret, cpp); + if (flag == 1) return(1); + + switch (ret->type) { + case KEY_X509_RSA: + debug3("pubkey key_readx(RSA)"); + ret->type = KEY_RSA; + flag = key_read(ret, cpp); + break; + case KEY_X509_DSA: + debug3("pubkey key_readx(DSA)"); + ret->type = KEY_DSA; + flag = key_read(ret, cpp); + break; + } + return(flag); +} + +static int +key_match(const Key *key, const Key *found) { + if (key == NULL || found == NULL) + return(0); + + if (key->type == found->type) { +#ifdef SSH_X509STORE_DISABLED + return(key_equal(key, found)); +#else /*ndef SSH_X509STORE_DISABLED*/ + if (!key_equal(key, found)) + return(0); + + /* + * Key are equal but in case of certificates + * when x509store is enabled found key may + * contain only distinguished name. + */ + if ((found->type != KEY_X509_RSA) && + (found->type != KEY_X509_DSA)) + return(1); + + debug3("key_match:found matching certificate"); + if (!options.x509flags->key_allow_selfissued) { + /* + * Only the verification process can + * allow the received certificate. + */ + return(1); + } + + /* + * The public key or certificate found in + * autorized keys file can allow self-issued. + */ + if (!ssh_is_selfsigned(key->x509)) + return(1); + + debug3("key_match:self-signed certificate"); + options.x509flags->key_allow_selfissued = 0; + if (ssh_x509cert_check(key->x509) == 1) { + /* the certificated is trusted by x509store */ + options.x509flags->key_allow_selfissued = 1; + return(1); + } + options.x509flags->key_allow_selfissued = 1; + + /* the certificate can be allowed by public key */ +#endif /*ndef SSH_X509STORE_DISABLED*/ + } + + if ((key->type == KEY_X509_RSA) && + ((found->type == KEY_RSA) || (found->type == KEY_X509_RSA)) + ) { + debug3("key_match:RSA"); + return(key->rsa != NULL && found->rsa != NULL && + BN_cmp(key->rsa->e, found->rsa->e) == 0 && + BN_cmp(key->rsa->n, found->rsa->n) == 0); + } + if ((key->type == KEY_X509_DSA) && + ((found->type == KEY_DSA) || (found->type == KEY_X509_DSA)) + ) { + debug3("key_match:DSA"); + return(key->dsa != NULL && found->dsa != NULL && + BN_cmp(key->dsa->p, found->dsa->p) == 0 && + BN_cmp(key->dsa->q, found->dsa->q) == 0 && + BN_cmp(key->dsa->g, found->dsa->g) == 0 && + BN_cmp(key->dsa->pub_key, found->dsa->pub_key) == 0); + } + return(0); +} + /* return 1 if user allows given key */ static int user_key_allowed2(struct passwd *pw, Key *key, char *file) @@ -247,7 +340,8 @@ if (!*cp || *cp == '\n' || *cp == '#') continue; - if (key_read(found, &cp) != 1) { + found->type = key->type; + if (key_readx(found, &cp) != 1) { /* no key? check if there are options for this key */ int quoted = 0; debug2("user_key_allowed: check options: '%s'", cp); @@ -261,13 +355,14 @@ /* Skip remaining whitespace. */ for (; *cp == ' ' || *cp == '\t'; cp++) ; - if (key_read(found, &cp) != 1) { + found->type = key->type; + if (key_readx(found, &cp) != 1) { debug2("user_key_allowed: advance: '%s'", cp); /* still no key? advance to next line*/ continue; } } - if (key_equal(found, key) && + if (key_match(key, found) && auth_parse_options(pw, key_options, file, linenum) == 1) { found_key = 1; debug("matching key found: file %s, line %lu", diff -ruN openssh-4.3p2+x509-5.3/authfile.c openssh-4.3p2+x509-5.4/authfile.c --- openssh-4.3p2+x509-5.3/authfile.c 2006-01-16 22:42:50.000000000 +0200 +++ openssh-4.3p2+x509-5.4/authfile.c 2006-04-26 09:06:01.000000000 +0300 @@ -14,7 +14,7 @@ * * Copyright (c) 2000 Markus Friedl. All rights reserved. * X509 certificate support, - * Copyright (c) 2002 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -507,8 +507,14 @@ error("PEM_read_PrivateKey: mismatch or " "unknown EVP_PKEY save_type %d", pk->save_type); } - if (prv) + if (prv) { x509key_load_cert(prv, fp); + if (prv->x509 != NULL) { + if (!X509_check_private_key(prv->x509, pk)) { + fatal("X509 certificate don't match private key"); + } + } + } fclose(fp); if (pk != NULL) EVP_PKEY_free(pk); diff -ruN openssh-4.3p2+x509-5.3/configure openssh-4.3p2+x509-5.4/configure --- openssh-4.3p2+x509-5.3/configure 2006-02-12 09:06:02.000000000 +0200 +++ openssh-4.3p2+x509-5.4/configure 2006-04-26 09:06:02.000000000 +0300 @@ -26242,6 +26242,13 @@ fi; +# X.509 support +ssh_x509="yes" +# Reserved for future use +#AC_DEFINE_UNQUOTED( +# X509_DISABLED, 1, +# [Define if you want to disable X.509 certificates]) + # Where to place ssh CA root sshcadir='${sysconfdir}/ca' sshcadir=`eval echo ${sshcadir}` diff -ruN openssh-4.3p2+x509-5.3/configure.ac openssh-4.3p2+x509-5.4/configure.ac --- openssh-4.3p2+x509-5.3/configure.ac 2006-02-11 21:11:09.000000000 +0200 +++ openssh-4.3p2+x509-5.4/configure.ac 2006-04-26 09:06:00.000000000 +0300 @@ -3419,6 +3419,13 @@ ] ) +# X.509 support +ssh_x509="yes" +# Reserved for future use +#AC_DEFINE_UNQUOTED( +# X509_DISABLED, 1, +# [Define if you want to disable X.509 certificates]) + # Where to place ssh CA root sshcadir='${sysconfdir}/ca' sshcadir=`eval echo ${sshcadir}` diff -ruN openssh-4.3p2+x509-5.3/Makefile.in openssh-4.3p2+x509-5.4/Makefile.in --- openssh-4.3p2+x509-5.3/Makefile.in 2006-02-12 09:06:01.000000000 +0200 +++ openssh-4.3p2+x509-5.4/Makefile.in 2006-04-26 09:06:01.000000000 +0300 @@ -222,6 +222,7 @@ rm -rf autom4te.cache (cd openbsd-compat && $(MAKE) distclean) (cd scard && $(MAKE) distclean) + (cd tests/CA && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ fi @@ -437,9 +438,6 @@ check-certs: $(TARGETS) - @if test ! -d "tests/CA"; then \ - mkdir -p "tests/CA" || exit 1; \ - fi @BUILDDIR="`pwd`"; \ ( cd "tests/CA" && \ $(MAKE) \ diff -ruN openssh-4.3p2+x509-5.3/readconf.c openssh-4.3p2+x509-5.4/readconf.c --- openssh-4.3p2+x509-5.3/readconf.c 2006-02-12 09:06:01.000000000 +0200 +++ openssh-4.3p2+x509-5.4/readconf.c 2006-04-26 09:06:01.000000000 +0300 @@ -11,7 +11,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -136,6 +136,7 @@ oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, + oPubkeyAlgorithms, oX509KeyAlgorithm, oAllowedServerCertPurpose, oMandatoryCRL, @@ -239,6 +240,7 @@ { "controlpath", oControlPath }, { "controlmaster", oControlMaster }, { "hashknownhosts", oHashKnownHosts }, + { "pubkeyalgorithms", oPubkeyAlgorithms }, { "x509rsasigtype", oDeprecated }, { "x509keyalgorithm", oX509KeyAlgorithm }, { "allowedcertpurpose", oAllowedServerCertPurpose }, @@ -933,6 +935,20 @@ intptr = &options->permit_local_command; goto parse_flag; + case oPubkeyAlgorithms: + charptr = (char**)&options->pubkey_algorithms; + 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 public key algorithms '%s'.", + filename, linenum, arg ? arg : ""); + */ + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + case oX509KeyAlgorithm: arg = strdelim(&s); if (!arg || *arg == '\0') @@ -947,7 +963,7 @@ break; case oAllowedServerCertPurpose: - intptr = &options->allowedcertpurpose; + intptr = &options->x509flags->allowedcertpurpose; arg = strdelim(&s); if (arg && *arg) { if (strcasecmp(arg, "skip") == 0) goto skip_purpose; @@ -972,7 +988,7 @@ #ifndef SSH_X509STORE_DISABLED case oMandatoryCRL: - intptr = &options->mandatory_crl; + intptr = &options->x509flags->mandatory_crl; goto parse_flag; case oCACertificateFile: @@ -1232,11 +1248,12 @@ options->control_path = NULL; options->control_master = -1; options->hash_known_hosts = -1; + options->pubkey_algorithms = NULL; /* Supported X.509 key algorithms and signatures are defined is external source. */ - options->allowedcertpurpose = -1; + options->x509flags = &ssh_x509flags; + ssh_x509flags_initialize(options->x509flags, 0); #ifndef SSH_X509STORE_DISABLED - options->mandatory_crl = -1; ssh_x509store_initialize(&options->ca); ssh_x509store_initialize(&options->userca); #endif /*ndef SSH_X509STORE_DISABLED*/ @@ -1257,8 +1274,6 @@ ssh_x509store_init (Options *options) { int x509_store_loaded = 0; - ssh_x509store_mandatory_crl(options->mandatory_crl); - if(ssh_x509store_addlocations(&options->userca)) { x509_store_loaded = 1; } @@ -1407,14 +1422,10 @@ /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ + /* options->pubkey_algorithms */ fill_default_xkalg(); - if (options->allowedcertpurpose == -1) - options->allowedcertpurpose = ssh_get_default_x509purpose(0); - ssh_set_x509purpose(0, options->allowedcertpurpose); + ssh_x509flags_defaults(options->x509flags); #ifndef SSH_X509STORE_DISABLED - if (options->mandatory_crl == -1) - options->mandatory_crl = 0; - ssh_x509store_system_defaults(&options->ca); { @@ -1457,6 +1468,11 @@ #endif buffer_free(&b); } + + if (options->pubkey_algorithms != NULL) + if (!key_names_valid2(options->pubkey_algorithms)) + fatal("Bad protocol 2 public key algorithms '%s'.", + options->pubkey_algorithms); } /* diff -ruN openssh-4.3p2+x509-5.3/readconf.h openssh-4.3p2+x509-5.4/readconf.h --- openssh-4.3p2+x509-5.3/readconf.h 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/readconf.h 2006-04-26 09:06:00.000000000 +0300 @@ -13,7 +13,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2006 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,13 +139,14 @@ int hash_known_hosts; + char* pubkey_algorithms; /* Allowed pubkey algorithms. */ + /* Supported X.509 key algorithms and signatures are defined is external source. */ - /* allowed server certificate purpose */ - int allowedcertpurpose; + /* ssh PKI(X509) flags */ + SSH_X509Flags *x509flags; #ifndef SSH_X509STORE_DISABLED - int mandatory_crl; /* sshd PKI(X509) system store */ X509StoreOptions ca; /* sshd PKI(X509) user store */ diff -ruN openssh-4.3p2+x509-5.3/README.x509v3 openssh-4.3p2+x509-5.4/README.x509v3 --- openssh-4.3p2+x509-5.3/README.x509v3 2005-11-22 23:55:40.000000000 +0200 +++ openssh-4.3p2+x509-5.4/README.x509v3 2006-04-26 00:16:13.000000000 +0300 @@ -1,6 +1,6 @@ Roumen Petrov Sofia, Bulgaria - Tue Nov 22 2005 + Wed Apr 12 2006 How to use X.509 certificates with OpenSSH? @@ -74,11 +74,9 @@ 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. @@ -92,6 +90,11 @@ when OpenSSH is build with OCSP support. See sshd_config(5) man page for allowed values and other VA* options. +1.1.7.) KeyAllowSelfIssued no + Specifies whether self-issued(self-signed) X.509 certificate can be + allowed only by entry in AutorizedKeysFile that contain matching + public key or certificate blob. + 1.2.) user files on the server Append in USER_HOME/.ssh/authorized_keys a record with following format: @@ -387,6 +390,7 @@ test-dn_auth_path.sh.inc, test-agent.sh.inc, test-crl.sh.inc, +test-self.sh.inc, test-alg.sh.inc, test-ocsp.sh.inc, test-by_ldap.sh.inc: diff -ruN openssh-4.3p2+x509-5.3/servconf.c openssh-4.3p2+x509-5.4/servconf.c --- openssh-4.3p2+x509-5.3/servconf.c 2006-02-12 09:06:01.000000000 +0200 +++ openssh-4.3p2+x509-5.4/servconf.c 2006-04-26 09:06:01.000000000 +0300 @@ -9,7 +9,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -131,9 +131,9 @@ options->pubkey_algorithms = NULL; /* Supported X.509 key algorithms and signatures are defined is external source. */ - options->allowedcertpurpose = -1; + options->x509flags = &ssh_x509flags; + ssh_x509flags_initialize(options->x509flags, 1); #ifndef SSH_X509STORE_DISABLED - options->mandatory_crl = -1; ssh_x509store_initialize(&options->ca); #endif /*ndef SSH_X509STORE_DISABLED*/ #ifdef SSH_OCSP_ENABLED @@ -275,13 +275,8 @@ /* options->hostbased_algorithms */ /* options->pubkey_algorithms */ fill_default_xkalg(); - if (options->allowedcertpurpose == -1) - options->allowedcertpurpose = ssh_get_default_x509purpose(1); - ssh_set_x509purpose(1, options->allowedcertpurpose); + ssh_x509flags_defaults(options->x509flags); #ifndef SSH_X509STORE_DISABLED - if (options->mandatory_crl == -1) - options->mandatory_crl = 0; - ssh_x509store_mandatory_crl(options->mandatory_crl); ssh_x509store_system_defaults(&options->ca); ssh_x509store_addlocations(&options->ca); #endif /*ndef SSH_X509STORE_DISABLED*/ @@ -340,14 +335,14 @@ sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sUsePrivilegeSeparation, + sHostbasedAlgorithms, + sPubkeyAlgorithms, sX509KeyAlgorithm, sAllowedClientCertPurpose, - sMandatoryCRL, + sKeyAllowSelfIssued, sMandatoryCRL, sCACertificateFile, sCACertificatePath, sCARevocationFile, sCARevocationPath, sCAldapVersion, sCAldapURL, - sHostbasedAlgorithms, - sPubkeyAlgorithms, sVAType, sVACertificateFile, sVAOCSPResponderURL, sDeprecated, sUnsupported @@ -451,9 +446,12 @@ { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, { "acceptenv", sAcceptEnv }, + { "hostbasedalgorithms", sHostbasedAlgorithms }, + { "pubkeyalgorithms", sPubkeyAlgorithms }, { "x509rsasigtype", sDeprecated }, { "x509keyalgorithm", sX509KeyAlgorithm }, { "allowedcertpurpose", sAllowedClientCertPurpose }, + { "keyallowselfissued", sKeyAllowSelfIssued } , { "mandatorycrl", sMandatoryCRL } , { "cacertificatefile", sCACertificateFile }, { "cacertificatepath", sCACertificatePath }, @@ -461,8 +459,6 @@ { "carevocationpath", sCARevocationPath }, { "caldapversion", sCAldapVersion }, { "caldapurl", sCAldapURL }, - { "hostbasedalgorithms", sHostbasedAlgorithms }, - { "pubkeyalgorithms", sPubkeyAlgorithms }, { "vatype", sVAType }, { "vacertificatefile", sVACertificateFile }, { "vaocspresponderurl", sVAOCSPResponderURL }, @@ -1115,7 +1111,7 @@ break; case sAllowedClientCertPurpose: - intptr = &options->allowedcertpurpose; + intptr = &options->x509flags->allowedcertpurpose; arg = strdelim(&cp); if (arg && *arg) { if (strcasecmp(arg, "skip") == 0) goto skip_purpose; @@ -1139,8 +1135,12 @@ break; #ifndef SSH_X509STORE_DISABLED + case sKeyAllowSelfIssued: + intptr = &options->x509flags->key_allow_selfissued; + goto parse_flag; + case sMandatoryCRL: - intptr = &options->mandatory_crl; + intptr = &options->x509flags->mandatory_crl; goto parse_flag; case sCACertificateFile: @@ -1218,6 +1218,7 @@ break; #ifdef SSH_X509STORE_DISABLED + case sKeyAllowSelfIssued: case sMandatoryCRL: case sCACertificateFile: case sCACertificatePath: diff -ruN openssh-4.3p2+x509-5.3/servconf.h openssh-4.3p2+x509-5.4/servconf.h --- openssh-4.3p2+x509-5.3/servconf.h 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/servconf.h 2006-04-26 09:06:00.000000000 +0300 @@ -13,7 +13,7 @@ * called by a name other than "ssh" or "Secure Shell". * * X509 certificate support, - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -160,16 +160,15 @@ int use_pam; /* Enable auth via PAM */ - char* hostbased_algorithms; /* Supported hostbased algorithms. */ - char* pubkey_algorithms; /* Supported pubkey algorithms. */ + char* hostbased_algorithms; /* Allowed hostbased algorithms. */ + char* pubkey_algorithms; /* Allowed pubkey algorithms. */ /* Supported X.509 key algorithms and signatures are defined is external source. */ - /* allowed client certificate purpose */ - int allowedcertpurpose; + /* sshd PKI(X509) flags */ + SSH_X509Flags *x509flags; #ifndef SSH_X509STORE_DISABLED - int mandatory_crl; /* sshd PKI(X509) system store */ X509StoreOptions ca; #endif /*ndef SSH_X509STORE_DISABLED*/ diff -ruN openssh-4.3p2+x509-5.3/ssh_config.0 openssh-4.3p2+x509-5.4/ssh_config.0 --- openssh-4.3p2+x509-5.3/ssh_config.0 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/ssh_config.0 2006-04-26 09:06:00.000000000 +0300 @@ -465,6 +465,13 @@ ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p + PubkeyAlgorithms + Specifies the protocol version 2 algorithms used in ``publickey'' + authentication allowed to sent to the host. The default is all + supported by client and depend from X509KeyAlgorithm, i.e. the + option allow all specified by X509KeyAlgorithm plus ``ssh-rsa'' + and ``ssh-dss''. + PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be ``yes'' or ``no''. The default is @@ -674,12 +681,10 @@ 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. diff -ruN openssh-4.3p2+x509-5.3/ssh_config.5 openssh-4.3p2+x509-5.4/ssh_config.5 --- openssh-4.3p2+x509-5.3/ssh_config.5 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/ssh_config.5 2006-04-26 09:06:00.000000000 +0300 @@ -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-2005 Roumen Petrov. All rights reserved. +.\" Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -805,6 +805,18 @@ .Bd -literal -offset 3n ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p .Ed +.It Cm PubkeyAlgorithms +Specifies the protocol version 2 algorithms used in +.Dq publickey +authentication allowed to sent to the host. +The default is all supported by client and depend from +.Cm X509KeyAlgorithm , +i.e. the option allow all specified by +.Cm X509KeyAlgorithm +plus +.Dq ssh-rsa +and +.Dq ssh-dss . .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be @@ -1185,11 +1197,6 @@ .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: @@ -1204,11 +1211,6 @@ .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. diff -ruN openssh-4.3p2+x509-5.3/sshconnect2.c openssh-4.3p2+x509-5.4/sshconnect2.c --- openssh-4.3p2+x509-5.3/sshconnect2.c 2005-11-05 06:07:33.000000000 +0200 +++ openssh-4.3p2+x509-5.4/sshconnect2.c 2006-04-26 09:06:01.000000000 +0300 @@ -1,5 +1,6 @@ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $"); +RCSID("$OpenBSD$"); #include "openbsd-compat/sys-queue.h" @@ -155,6 +156,7 @@ TAILQ_ENTRY(identity) next; AuthenticationConnection *ac; /* set if agent supports key */ Key *key; /* public/private key */ + int pktype; /* reserved: public key-type to use */ char *filename; /* comment for agent-only keys */ int tried; int isprivate; /* key points to the private key */ @@ -996,6 +998,70 @@ return private; } +static void +prepare_allowed(Idlist *preferred) +{ + int allowed[KEY_UNSPEC], pktype; + Identity *id; + + if (options.pubkey_algorithms == NULL) return; + + TAILQ_FOREACH(id, preferred, next) { + } + + memset(allowed, 0, sizeof(allowed)); + { /* prepare allowed key-types flags */ + char *s, *cp, *p; + s = cp = xstrdup(options.pubkey_algorithms); + for (p = strsep(&cp, ","); + p && *p != '\0'; + p = strsep(&cp, ",") + ) { + pktype = key_type_from_name(p); + allowed[pktype] = 1; + } + xfree(s); + } + +/* RUMEN TODO + - first remove (filter) keys + - second set a flag with key-type{-name(?)} to send +*/ + id = TAILQ_FIRST(preferred); + while (id != TAILQ_END(preferred)) { + pktype = id->key->type; + if (allowed[pktype]) goto nextid; + +#if 0 + /* TODO: check for ???stripe-down??? case */ + switch(pktype) { + case KEY_X509_RSA: pktype = KEY_RSA; break; + case KEY_X509_DSA: pktype = KEY_DSA; break; + } + if (allowed[pktype]) goto nextid; +#endif + + { /* remove current */ + Identity *idnext = TAILQ_NEXT(id, next); + + TAILQ_REMOVE(preferred, id, next); + debug2("key not allowed: %s (%p)", id->filename, (void*)id->key); + if (id->key) + key_free(id->key); + if (id->filename) + xfree(id->filename); + xfree(id); + id = idnext; + continue; + } + +nextid: + id->pktype = pktype; + id = TAILQ_NEXT(id, next); + } + +} + /* * try keys in the following order: * 1. agent keys that are found in the config file @@ -1012,6 +1078,7 @@ char *comment; int i, found; + debug2("preparing keys"); TAILQ_INIT(&agent); /* keys from the agent */ TAILQ_INIT(&files); /* keys from the config file */ preferred = &authctxt->keys; @@ -1026,6 +1093,7 @@ id = xmalloc(sizeof(*id)); memset(id, 0, sizeof(*id)); id->key = key; + id->pktype = id->key ? id->key->type : KEY_UNSPEC; id->filename = xstrdup(options.identity_files[i]); TAILQ_INSERT_TAIL(&files, id, next); } @@ -1051,9 +1119,13 @@ id = xmalloc(sizeof(*id)); memset(id, 0, sizeof(*id)); id->key = key; + id->pktype = id->key ? id->key->type : KEY_UNSPEC; id->filename = comment; id->ac = ac; TAILQ_INSERT_TAIL(&agent, id, next); + } else { + debug2("ignoring agent key: %s (%p)", + (comment ? comment : ""), (void*)key); } } /* append remaining agent keys */ @@ -1068,6 +1140,9 @@ TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); } + + prepare_allowed(preferred); + TAILQ_FOREACH(id, preferred, next) { debug2("key: %s (%p)", id->filename, id->key); } diff -ruN openssh-4.3p2+x509-5.3/sshd_config openssh-4.3p2+x509-5.4/sshd_config --- openssh-4.3p2+x509-5.3/sshd_config 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/sshd_config 2006-04-26 09:06:00.000000000 +0300 @@ -26,13 +26,11 @@ # 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 @@ -42,6 +40,11 @@ # - "skip" or ""(empty): don`t check purpose. #AllowedCertPurpose sslclient +# Specifies whether self-issued(self-signed) X.509 certificate can be +# allowed only by entry in AutorizedKeysFile that contain matching +# public key or certificate blob. +#KeyAllowSelfIssued no + # Specifies whether CRL must present in store for all certificates in # certificate chain with atribute "cRLDistributionPoints" #MandatoryCRL no diff -ruN openssh-4.3p2+x509-5.3/sshd_config.0 openssh-4.3p2+x509-5.4/sshd_config.0 --- openssh-4.3p2+x509-5.3/sshd_config.0 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/sshd_config.0 2006-04-26 09:06:00.000000000 +0300 @@ -264,6 +264,21 @@ Specifies whether to automatically destroy the user's ticket cache file on logout. Default is ``yes''. + KeyAllowSelfIssued + Specifies whether only public key or certificate blob listed in + AutorizedKeysFile can allow self-issued(self-signed) X.509 cer- + tificate to be used for user authentication. The default is + ``no''. + + A certificate (including self-issued) is accepted for user + authentication if its public key blob, certificate blob or dis- + tinguished name is listed in AutorizedKeysFile, if is valid and + if is verified by certificates from ``X509 store''. See + verify(1). In addition if option is set to ``yes'' self-issued + certificate is accepted when its public key match public key + extracted from entry in AutorizedKeysFile. In this case validity + of certificate is not checked. + KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). The @@ -562,12 +577,10 @@ 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. diff -ruN openssh-4.3p2+x509-5.3/sshd_config.5 openssh-4.3p2+x509-5.4/sshd_config.5 --- openssh-4.3p2+x509-5.3/sshd_config.5 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/sshd_config.5 2006-04-26 09:06:00.000000000 +0300 @@ -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-2005 Roumen Petrov. All rights reserved. +.\" Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -457,6 +457,28 @@ file on logout. Default is .Dq yes . +.It Cm KeyAllowSelfIssued +Specifies whether only public key or certificate blob listed in +.Cm AutorizedKeysFile +can allow self-issued(self-signed) X.509 certificate +to be used for user authentication. +The default is +.Dq no . +.Pp +A certificate (including self-issued) is accepted +for user authentication if its public key blob, +certificate blob or distinguished name is listed in +.Cm AutorizedKeysFile , +if is valid and if is verified by certificates from +.Dq X509 store . +See +.Xr verify 1 . +In addition if option is set to +.Dq yes +self-issued certificate is accepted when its public key +match public key extracted from entry in +.Cm AutorizedKeysFile . +In this case validity of certificate is not checked. .It Cm KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). @@ -956,11 +978,6 @@ .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: @@ -975,11 +992,6 @@ .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. diff -ruN openssh-4.3p2+x509-5.3/ssh-keyscan.0 openssh-4.3p2+x509-5.4/ssh-keyscan.0 --- openssh-4.3p2+x509-5.3/ssh-keyscan.0 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/ssh-keyscan.0 2006-04-26 09:06:00.000000000 +0300 @@ -48,10 +48,9 @@ -t type Specifies the type of the key to fetch from the scanned hosts. The possible values are ``rsa1'' for protocol version 1 and - ``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 + ``ssh-rsa'' , ``ssh-dss'' , ``x509v3-sign-rsa'' or + ``x509v3-sign-dss'' 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 diff -ruN openssh-4.3p2+x509-5.3/ssh-keyscan.1 openssh-4.3p2+x509-5.4/ssh-keyscan.1 --- openssh-4.3p2+x509-5.3/ssh-keyscan.1 2006-02-12 09:06:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/ssh-keyscan.1 2006-04-26 09:06:00.000000000 +0300 @@ -116,12 +116,8 @@ .Dq ssh-dss , .Dq x509v3-sign-rsa -, -.Dq x509v3-sign-dss -, -.Dq x509v3-sign-rsa-sha1 or -.Dq x509v3-sign-dss-sha1 +.Dq x509v3-sign-dss for protocol version 2. Multiple values may be specified by separating them with commas. The default is diff -ruN openssh-4.3p2+x509-5.3/ssh-ocsp.c openssh-4.3p2+x509-5.4/ssh-ocsp.c --- openssh-4.3p2+x509-5.3/ssh-ocsp.c 2004-11-07 23:24:04.000000000 +0200 +++ openssh-4.3p2+x509-5.4/ssh-ocsp.c 2006-03-18 21:52:12.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Roumen Petrov. All rights reserved. + * Copyright (c) 2004-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -263,7 +263,7 @@ ) { X509 *issuer = NULL; OCSP_CERTID *id = NULL; - char subj[X509_NAME_MAXLEN]; + char *subj = NULL; if (cert == NULL) { error("ssh_ocspreq_addcert: cert is NULL"); @@ -313,7 +313,8 @@ error("ssh_ocspreq_addcert: sk_OCSP_CERTID_push fail"); return(0); } - X509_NAME_oneline(X509_get_subject_name(cert), subj, sizeof(subj)); + subj = xmalloc(X509_NAME_MAXLEN); /*fatal on error*/ + X509_NAME_oneline(X509_get_subject_name(cert), subj, X509_NAME_MAXLEN); if (!sk_push(subjs, subj)) { error("ssh_ocspreq_addcert: sk_push(..., subj) fail"); return(0); @@ -517,7 +518,11 @@ goto exit; } - resp = OCSP_sendreq_bio(bio_conn, conn->path, req); + /* + * OCSP_sendreq_bio accpet null as path argument but if path + * is null http request will contain what is incorrect. + */ + resp = OCSP_sendreq_bio(bio_conn, (conn->path ? conn->path : "/") , req); if (resp == NULL) { openssl_error("ssh_ocsp_get_response", "OCSP_sendreq_bio"); } @@ -670,7 +675,7 @@ if (sk_OCSP_CERTID_num(ids) <= 0) { error("ssh_ocsp_check_validity:" " number of ids is %d" - , k); + , sk_OCSP_CERTID_num(ids)); return(-1); } if (sk_OCSP_CERTID_num(subjs) <= 0) { @@ -806,7 +811,7 @@ exit: if (br != NULL) OCSP_BASICRESP_free(br); if (resp != NULL) OCSP_RESPONSE_free(resp); - if (subjs != NULL) sk_free(subjs); + if (subjs != NULL) sk_pop_free(subjs, xfree); if (ids != NULL) sk_OCSP_CERTID_free(ids); if (req != NULL) OCSP_REQUEST_free(req); if (vacrts != NULL) sk_X509_pop_free(vacrts, X509_free); @@ -890,8 +895,7 @@ ASN1_IA5STRING *uri; ssh_ocsp_conn *conn; - if (OBJ_obj2nid(ad->method) != - NID_id_pkix_OCSP_serviceLocator) continue; + if (OBJ_obj2nid(ad->method) != NID_ad_OCSP) continue; gn = ad->location; #if 0 diff -ruN openssh-4.3p2+x509-5.3/ssh-x509.c openssh-4.3p2+x509-5.4/ssh-x509.c --- openssh-4.3p2+x509-5.3/ssh-x509.c 2005-09-15 21:16:03.000000000 +0300 +++ openssh-4.3p2+x509-5.4/ssh-x509.c 2006-03-10 23:35:23.000000000 +0200 @@ -473,8 +473,7 @@ } else { key->type = (key->type == KEY_RSA) ? KEY_X509_RSA : KEY_X509_DSA; - debug("read X509 certificate done: type %.40s", - key ? key_type(key) : ""); + debug("read X509 certificate done: type %.40s", key_type(key)); } } return(key); diff -ruN openssh-4.3p2+x509-5.3/ssh-xkalg.c openssh-4.3p2+x509-5.4/ssh-xkalg.c --- openssh-4.3p2+x509-5.3/ssh-xkalg.c 2005-08-14 00:43:51.000000000 +0300 +++ openssh-4.3p2+x509-5.4/ssh-xkalg.c 2006-03-12 23:34:38.000000000 +0200 @@ -199,38 +199,40 @@ #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 0 + /* "draft-ietf-secsh-x509-NN.txt" where NN <= 03 */ +/* NOT YET FULLY IMPLEMENTED */ if (ssh_add_x509key_alg("x509v3-sign-rsa-sha1,rsa-sha1,ssh-rsa") < 0) fatal("ssh_init_xkalg: oops"); +#endif /*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 0 + /* draft-ietf-secsh-x509-NN.txt where NN <= 03 */ +/* NOT YET FULLY IMPLEMENTED */ if (ssh_add_x509key_alg("x509v3-sign-dss-sha1,dss-raw,ssh-dss") < 0) fatal("ssh_init_xkalg: oops"); +#endif } diff -ruN openssh-4.3p2+x509-5.3/tests/CA/1-cre_cadb.sh openssh-4.3p2+x509-5.4/tests/CA/1-cre_cadb.sh --- openssh-4.3p2+x509-5.3/tests/CA/1-cre_cadb.sh 2005-11-22 20:33:34.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/1-cre_cadb.sh 2006-03-12 22:39:08.000000000 +0200 @@ -1,5 +1,5 @@ -#!/bin/sh -# Copyright (c) 2002-2005 Roumen Petrov, Sofia, Bulgaria +#! /bin/sh +# Copyright (c) 2002-2006 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -68,10 +68,10 @@ ( port=${SSH_VA_BASEPORT} for DIGEST in ${RSA_DIGEST_LIST}; do - printf "serviceLocator;URI:http://${SSHD_LISTENADDRESS}:${port}," + printf "OCSP;URI:http://${SSHD_LISTENADDRESS}:${port}," port=`expr ${port} + 1` done - printf "serviceLocator;URI:http://${SSHD_LISTENADDRESS}:${port}" + printf "OCSP;URI:http://${SSHD_LISTENADDRESS}:${port}" ) fi } diff -ruN openssh-4.3p2+x509-5.3/tests/CA/2-cre_cakeys.sh openssh-4.3p2+x509-5.4/tests/CA/2-cre_cakeys.sh --- openssh-4.3p2+x509-5.3/tests/CA/2-cre_cakeys.sh 2004-03-20 12:40:15.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/2-cre_cakeys.sh 2006-03-12 22:39:54.000000000 +0200 @@ -1,4 +1,4 @@ -#!/bin/sh +#! /bin/sh # Copyright (c) 2002-2004 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # diff -ruN openssh-4.3p2+x509-5.3/tests/CA/3-cre_certs.sh openssh-4.3p2+x509-5.4/tests/CA/3-cre_certs.sh --- openssh-4.3p2+x509-5.3/tests/CA/3-cre_certs.sh 2005-06-03 00:00:11.000000000 +0300 +++ openssh-4.3p2+x509-5.4/tests/CA/3-cre_certs.sh 2006-02-16 22:07:11.000000000 +0200 @@ -1,4 +1,4 @@ -#!/bin/sh +#! /bin/sh # Copyright (c) 2002-2004 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # diff -ruN openssh-4.3p2+x509-5.3/tests/CA/4-cre_crls.sh openssh-4.3p2+x509-5.4/tests/CA/4-cre_crls.sh --- openssh-4.3p2+x509-5.3/tests/CA/4-cre_crls.sh 2004-02-16 21:02:12.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/4-cre_crls.sh 2006-02-16 22:07:09.000000000 +0200 @@ -1,4 +1,4 @@ -#!/bin/sh +#! /bin/sh # Copyright (c) 2002-2004 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # diff -ruN openssh-4.3p2+x509-5.3/tests/CA/5-cre_ldap.sh openssh-4.3p2+x509-5.4/tests/CA/5-cre_ldap.sh --- openssh-4.3p2+x509-5.3/tests/CA/5-cre_ldap.sh 2005-08-30 00:57:02.000000000 +0300 +++ openssh-4.3p2+x509-5.4/tests/CA/5-cre_ldap.sh 2006-02-16 22:07:07.000000000 +0200 @@ -1,4 +1,4 @@ -#!/bin/sh +#! /bin/sh # Copyright (c) 2004-2005 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # diff -ruN openssh-4.3p2+x509-5.3/tests/CA/config openssh-4.3p2+x509-5.4/tests/CA/config --- openssh-4.3p2+x509-5.3/tests/CA/config 2004-11-11 00:14:50.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/config 2006-04-12 01:53:08.000000000 +0300 @@ -1,4 +1,4 @@ -# Copyright (c) 2002-2004 Roumen Petrov, Sofia, Bulgaria +# Copyright (c) 2002-2006 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -65,6 +65,7 @@ dn_auth_path agent crl + self alg ocsp by_ldap @@ -123,6 +124,7 @@ #"yes" or "no" SSHSERVER_USEPRIVILEGESEPARATION="yes" +#SSHSERVER_USEPRIVILEGESEPARATION="no" SSHSERVER_SYSLOGFACILITY=AUTH SSHSERVER_LOGLEVEL=FATAL diff -ruN openssh-4.3p2+x509-5.3/tests/CA/openssh_tests.sh openssh-4.3p2+x509-5.4/tests/CA/openssh_tests.sh --- openssh-4.3p2+x509-5.3/tests/CA/openssh_tests.sh 2005-06-02 22:11:08.000000000 +0300 +++ openssh-4.3p2+x509-5.4/tests/CA/openssh_tests.sh 2006-04-13 01:40:03.000000000 +0300 @@ -1,5 +1,5 @@ -#!/bin/sh -# Copyright (c) 2002-2004 Roumen Petrov, Sofia, Bulgaria +#! /bin/sh +# Copyright (c) 2002-2006 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -34,6 +34,7 @@ test "x$TEST_SSH_SSHD" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHD${norm}" ; exit 1; } test "x$TEST_SSH_SSHAGENT" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHAGENT${norm}" ; exit 1; } test "x$TEST_SSH_SSHADD" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHADD${norm}" ; exit 1; } +test "x$TEST_SSH_SSHKEYGEN" = "x" && { echo "${warn}Please define ${attn}TEST_SSH_SSHKEYGEN${norm}"; exit 1; } #TEST_SSH_SSHKEYSCAN #TEST_SSH_SFTP #TEST_SSH_SFTPSERVER @@ -107,7 +108,8 @@ sed \ -e 's|dn_auth_file||g' \ -e 's|dn_auth_path||g' \ - -e 's|crl||g'` + -e 's|crl||g' \ + -e 's|self||g'` fi echo SSH_LDAP_ENABLED=${SSH_LDAP_ENABLED} if test "x${SSH_LDAP_ENABLED}" = "xno"; then @@ -216,7 +218,7 @@ HostKey ${TEST_SSHD_HOSTKEY} -#X509rsaSigType=md5 +#deprecated#X509rsaSigType=md5 #AllowedCertPurpose sslclient EOF } @@ -230,7 +232,7 @@ StrictHostKeyChecking yes UserKnownHostsFile ${USERKNOWNHOSTSFILE} -#X509rsaSigType=md5 +#deprecated#X509rsaSigType=md5 #AllowedCertPurpose sslserver EOF if test "x${SSH_X509STORE_DISABLED}" != "xyes"; then diff -ruN openssh-4.3p2+x509-5.3/tests/CA/shell.rc openssh-4.3p2+x509-5.4/tests/CA/shell.rc --- openssh-4.3p2+x509-5.3/tests/CA/shell.rc 2004-02-14 22:16:21.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/shell.rc 2006-02-16 22:40:27.000000000 +0200 @@ -1,4 +1,4 @@ -# Copyright (c) 2003-2004 Roumen Petrov, Sofia, Bulgaria +# Copyright (c) 2003-2006 Roumen Petrov, Sofia, Bulgaria # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -22,34 +22,13 @@ # -# === zsh: -if test -n "$ZSH_NAME"; then - unsetopt NOMATCH - # NOMATCH (+3) - # If a pattern for filename generation has no matches, print an - # error, instead of leaving it unchanged in the argument list. This - # also applies to file expansion of an initial `~' or `='. - # Check results from sample script: - # #!/bin/zsh - # for F in *notfound; do - # echo F=$F - # done - - setopt SH_WORD_SPLIT - # SH_WORD_SPLIT (-y) - # Causes field splitting to be performed on unquoted parameter - # expansions. Note that this option has nothing to do with word - # splitting. - # Check results from sample script: - # #!/bin/zsh - # VAR=" - # v1 - # v2 - # " - # for V in ${VAR}; do - # echo V=$V - # done +# Be Bourne compatible (as autoconf do it) +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix fi - - -# === diff -ruN openssh-4.3p2+x509-5.3/tests/CA/test-agent.sh.inc openssh-4.3p2+x509-5.4/tests/CA/test-agent.sh.inc --- openssh-4.3p2+x509-5.3/tests/CA/test-agent.sh.inc 2004-03-09 08:52:32.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/test-agent.sh.inc 2006-02-05 18:24:05.000000000 +0200 @@ -104,8 +104,17 @@ fi fi +# TODO +# Note the current script run ssh with -i option, +# but ssh check existence of file and when file +# don't exit it is excluded form list of identity +# files. When the list is empty ssh will use +# default file names. To avoid this we will +# use /dev/null, until method runTest run ssh +# with -i option +#!!! "use-only-key-from-agent" \ runTest "${type}" \ - "use-only-key-from-agent" \ + "/dev/null" \ "key from agent ..." || killAgent $? diff -ruN openssh-4.3p2+x509-5.3/tests/CA/test-alg.sh.inc openssh-4.3p2+x509-5.4/tests/CA/test-alg.sh.inc --- openssh-4.3p2+x509-5.3/tests/CA/test-alg.sh.inc 2005-08-20 00:45:24.000000000 +0300 +++ openssh-4.3p2+x509-5.4/tests/CA/test-alg.sh.inc 2006-03-13 21:51:14.000000000 +0200 @@ -130,8 +130,6 @@ "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.3p2+x509-5.3/tests/CA/test-self.sh.inc openssh-4.3p2+x509-5.4/tests/CA/test-self.sh.inc --- openssh-4.3p2+x509-5.3/tests/CA/test-self.sh.inc 1970-01-01 02:00:00.000000000 +0200 +++ openssh-4.3p2+x509-5.4/tests/CA/test-self.sh.inc 2006-04-26 00:48:26.000000000 +0300 @@ -0,0 +1,227 @@ +# +# Copyright (c) 2006 Roumen Petrov, Sofia, Bulgaria +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 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. +# +# DESCRIPTION: Test OpenSSH client authentication: +# - "IdentityFile" contain private key and self-issued x509 certificate; +# - "AuthorizedKeysFile" contain certificate BLOB or DN. +# + + +# === +cre_keys() { + echo " creating keys and files for ${extd}self-issued${norm}" + + for keytype in rsa dsa; do + SSH_CLIENTKEY="selfid_${keytype}" + + cat "${SSH_CAKEYDIR}/${CAKEY_PREFIX}-${keytype}.key" \ + > "${SSH_CLIENTKEY}" && + chmod 600 "${SSH_CLIENTKEY}" && + "$TEST_SSH_SSHKEYGEN" -f "${SSH_CLIENTKEY}" -p -P "${KEY_PASS}" -N "" \ + > /dev/null && + "$TEST_SSH_SSHKEYGEN" -f "${SSH_CLIENTKEY}" -y \ + > "${SSH_CLIENTKEY}.pub" && + + for type in ${SSH_SIGN_TYPES}; do + case $keytype in + rsa) + case $type in + *dsa*) continue;; + esac + ;; + dsa) + case $type in + *rsa*) continue;; + esac + ;; + esac + + identity_file="${SSH_CLIENTKEY}-${type}" + ( cat "${SSH_CLIENTKEY}" + $OPENSSL x509 -in "${SSH_CACERTDIR}/${CAKEY_PREFIX}-${type}.crt.pem" \ + -subject -issuer -alias + ) > "${identity_file}" && + chmod 600 "${identity_file}" || return $? + done + done +} + +# === +#args: +# $1 - request to fail flag for blob +# $2 - request to fail flag for DN +test_self() { + + case $1 in + Y|y|Yes|yes|YES|1) + blob_msg="${warn}blob${norm}";; + *) + blob_msg="${extd}blob${norm}";; + esac + case $2 in + Y|y|Yes|yes|YES|1) + dn_msg="${warn}DN${norm}";; + *) + dn_msg="${extd}DN${norm}";; + esac + + for keytype in rsa dsa; do + SSH_CLIENTKEY="selfid_${keytype}" + + for type in ${SSH_SIGN_TYPES}; do + case $keytype in + rsa) + case $type in + *dsa*) continue;; + esac + ;; + dsa) + case $type in + *rsa*) continue;; + esac + ;; + esac + + identity_file="${SSH_CLIENTKEY}-${type}" + + cat "${SSH_CLIENTKEY}.pub" > "${AUTHORIZEDKEYSFILE}" && + runTest "" "${identity_file}" \ + "${type} ${blob_msg}" "$1" \ + || return $? + + sshkeytype=`getSSHkeyType "${identity_file}"` || return $? + subject=`getSubject "${identity_file}"` || return $? + + echo "${sshkeytype} Subject: ${subject}" > "${AUTHORIZEDKEYSFILE}" && + runTest "" "${identity_file}" \ + "${type} ${dn_msg}" "$2" \ + || return $? + done + done +} + +# === + +test_store () { + retval=0 + echo " - ${attn}with${norm} self-issued trusted by ${extd}x509store${norm}:" + printSeparator + + creTestSSHDcfgFile + cat >> "$SSHD_CFG" <> "$SSHD_CFG" <> "$SSHD_CFG" <error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) + ) { + if (ssh_x509flags.key_allow_selfissued) + ok = ssh_is_selfsigned(ctx->cert); + } if (!ok) { char buf[X509_NAME_MAXLEN]; X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf)); @@ -131,7 +137,7 @@ if (ctx->error == X509_V_ERR_INVALID_CA) ok=1; if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1; if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1; - if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1; + if (ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ok=1; #endif } #ifdef SSH_CHECK_REVOKED @@ -201,11 +207,39 @@ } +void +ssh_x509flags_initialize(SSH_X509Flags *flags, int is_server) { + flags->is_server = is_server; + flags->allowedcertpurpose = -1; +#ifndef SSH_X509STORE_DISABLED + flags->key_allow_selfissued = -1; + flags->mandatory_crl = -1; +#endif /*ndef SSH_X509STORE_DISABLED*/ +} -int -ssh_get_default_x509purpose(int _is_server) { - return(ssh_get_x509purpose_s(_is_server, - (_is_server ? __purpose_sslclient[0] : __purpose_sslserver[0]))); + +void +ssh_x509flags_defaults(SSH_X509Flags *flags) { + if (flags->allowedcertpurpose == -1) { + int is_server = flags->is_server; + const char* purpose_synonym = is_server ? __purpose_sslclient[0] : __purpose_sslserver[0]; + + flags->allowedcertpurpose = ssh_get_x509purpose_s(is_server, purpose_synonym); + } +#ifndef SSH_X509STORE_DISABLED + if (flags->key_allow_selfissued == -1) { + flags->key_allow_selfissued = 0; + } +#ifdef SSH_CHECK_REVOKED + if (flags->mandatory_crl == -1) { + flags->mandatory_crl = 0; + } +#else + if (flags->mandatory_crl != -1) { + logit("useless option: mandatory_crl"); + } +#endif +#endif /*ndef SSH_X509STORE_DISABLED*/ } @@ -228,14 +262,24 @@ } -void -ssh_set_x509purpose(int _is_server, int _sshpurpose_index) { - sshpurpose.is_server = _is_server; - sshpurpose.index = _sshpurpose_index; +#ifndef SSH_X509STORE_DISABLED +int/*bool*/ +ssh_is_selfsigned(X509 *_cert) { + char buf[X509_NAME_MAXLEN]; + X509_NAME *issuer, *subject; + + issuer = X509_get_issuer_name(_cert); + X509_NAME_oneline(issuer, buf, sizeof(buf)); + debug3("ssh_is_selfsigned: issuer='%.*s'", (int) sizeof(buf), buf); + + subject = X509_get_subject_name(_cert); + X509_NAME_oneline(subject, buf, sizeof(buf)); + debug3("ssh_is_selfsigned: subject='%.*s'", (int) sizeof(buf), buf); + + return (ssh_X509_NAME_cmp(issuer, subject) == 0); } -#ifndef SSH_X509STORE_DISABLED void ssh_x509store_initialize(X509StoreOptions *options) { options->certificate_file = NULL; @@ -447,28 +491,16 @@ } -int/*bool*/ -ssh_x509store_mandatory_crl(int _mandatory_crl) { -#ifdef SSH_CHECK_REVOKED - x509_mandatory_crl = (_mandatory_crl != 0); - return(x509_mandatory_crl); -#else - logit("useless option: mandatory_crl"); - return(_mandatory_crl != 0); -#endif -} - - static int ssh_verify_cert(X509_STORE_CTX *_csc, X509 *_cert) { X509_STORE_CTX_init(_csc, x509store, _cert, NULL); - if (sshpurpose.index >= 0) { - int def_purpose = ( sshpurpose.is_server + if (ssh_x509flags.allowedcertpurpose >= 0) { + int def_purpose = ( ssh_x509flags.is_server ? X509_PURPOSE_SSL_CLIENT : X509_PURPOSE_SSL_SERVER ); - X509_PURPOSE *xptmp = X509_PURPOSE_get0(sshpurpose.index); + X509_PURPOSE *xptmp = X509_PURPOSE_get0(ssh_x509flags.allowedcertpurpose); int purpose, flag; if (xptmp == NULL) { fatal("ssh_verify_cert: cannot get purpose from index"); @@ -611,8 +643,8 @@ #endif /*def SSH_OCSP_ENABLED*/ #else /*def SSH_X509STORE_DISABLED*/ - if (sshpurpose.index >= 0) { - xptmp = X509_PURPOSE_get0(sshpurpose.index); + if (ssh_x509flags.allowedcertpurpose >= 0) { + xptmp = X509_PURPOSE_get0(ssh_x509flags.allowedcertpurpose); if (xptmp == NULL) { fatal("ssh_x509cert_check: cannot get purpose from index"); return(-1); /* ;-) */ @@ -889,7 +921,7 @@ */ ok = ssh_check_crl(ctx, cert, xobj.data.crl); } else { - if (x509_mandatory_crl) { + if (ssh_x509flags.mandatory_crl == 1) { int loc; loc = X509_get_ext_by_NID(cert, NID_crl_distribution_points, -1); ok = (loc < 0); diff -ruN openssh-4.3p2+x509-5.3/x509store.h openssh-4.3p2+x509-5.4/x509store.h --- openssh-4.3p2+x509-5.3/x509store.h 2005-07-19 22:27:16.000000000 +0300 +++ openssh-4.3p2+x509-5.4/x509store.h 2006-04-25 22:08:01.000000000 +0300 @@ -1,7 +1,7 @@ #ifndef X509STORE_H #define X509STORE_H /* - * Copyright (c) 2002-2005 Roumen Petrov. All rights reserved. + * Copyright (c) 2002-2006 Roumen Petrov. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,14 +33,29 @@ int ssh_x509cert_check(X509 *_cert); -int ssh_get_default_x509purpose(int _is_server); + +typedef struct { + int is_server; + /* allowed client/server certificate purpose */ + int allowedcertpurpose; /* note field contain purpose index */ +#ifndef SSH_X509STORE_DISABLED + int key_allow_selfissued; /* make sense only when x509store is enabled */ + int mandatory_crl; +#endif /*ndef SSH_X509STORE_DISABLED*/ +} SSH_X509Flags; + +extern SSH_X509Flags ssh_x509flags; + +void ssh_x509flags_initialize(SSH_X509Flags *flags, int is_server); +void ssh_x509flags_defaults(SSH_X509Flags *flags); + /* return purpose index, not purpose id (!) */ int ssh_get_x509purpose_s(int _is_server, const char* _purpose_synonym); -void ssh_set_x509purpose(int _is_server, int _sshpurpose_index); #ifndef SSH_X509STORE_DISABLED int ssh_X509_NAME_cmp(X509_NAME *_a, X509_NAME *_b); +int/*bool*/ ssh_is_selfsigned(X509 *_cert); int ssh_x509store_lookup(X509_STORE *store, int type, X509_NAME *name, X509_OBJECT *xobj); @@ -61,7 +76,6 @@ void ssh_x509store_user_defaults(X509StoreOptions *options, uid_t uid); int/*bool*/ ssh_x509store_addlocations(const X509StoreOptions *_locations); -int/*bool*/ ssh_x509store_mandatory_crl(int _mandatory_crl); #endif /*ndef SSH_X509STORE_DISABLED*/