diff -ur openssh-3.4p1+x509c/Makefile.in openssh-3.4p1+x509d/Makefile.in --- openssh-3.4p1+x509c/Makefile.in Thu Jun 27 15:07:02 2002 +++ openssh-3.4p1+x509d/Makefile.in Thu Jul 25 18:30:54 2002 @@ -208,7 +208,7 @@ install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files check-user: - id $(SSH_PRIVSEP_USER) || \ + @id $(SSH_PRIVSEP_USER) > /dev/null || \ echo "WARNING: Privilege separation user \"$(SSH_PRIVSEP_USER)\" does not exist" scard-install: @@ -223,6 +223,8 @@ $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)5 $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 $(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(sshcadir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(piddir) $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH) chmod 0700 $(DESTDIR)$(PRIVSEP_PATH) $(INSTALL) -m 0755 -s ssh $(DESTDIR)$(bindir)/ssh diff -ur openssh-3.4p1+x509c/acconfig.h openssh-3.4p1+x509d/acconfig.h --- openssh-3.4p1+x509c/acconfig.h Wed Jun 26 01:35:16 2002 +++ openssh-3.4p1+x509d/acconfig.h Thu Jul 25 17:40:19 2002 @@ -289,6 +289,9 @@ /* Specify default $PATH */ #undef USER_PATH +/* Specify location of ssh CA root */ +#undef SSHCADIR + /* Specify location of ssh.pid */ #undef _PATH_SSH_PIDDIR diff -ur openssh-3.4p1+x509c/auth2-pubkey.c openssh-3.4p1+x509d/auth2-pubkey.c --- openssh-3.4p1+x509c/auth2-pubkey.c Thu Jun 27 15:14:43 2002 +++ openssh-3.4p1+x509d/auth2-pubkey.c Thu Jun 6 23:27:56 2002 @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD$"); +RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -40,7 +40,6 @@ #include "auth-options.h" #include "canohost.h" #include "monitor_wrap.h" -#include "ssh-x509.h" /* import */ extern ServerOptions options; @@ -83,12 +82,7 @@ pkalg); goto done; } - if (pktype == KEY_X509_RSA || pktype == KEY_X509_DSA) { - key = x509key_from_blob(pkblob, blen); - } - else { - key = key_from_blob(pkblob, blen); - } + key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); goto done; diff -ur openssh-3.4p1+x509c/authfd.c openssh-3.4p1+x509d/authfd.c --- openssh-3.4p1+x509c/authfd.c Wed Jun 26 02:22:55 2002 +++ openssh-3.4p1+x509d/authfd.c Tue Jul 30 12:28:22 2002 @@ -456,6 +456,7 @@ buffer_put_cstring(b, key_ssh_name(key)); switch (key->type) { case KEY_RSA: + case KEY_X509_RSA: buffer_put_bignum2(b, key->rsa->n); buffer_put_bignum2(b, key->rsa->e); buffer_put_bignum2(b, key->rsa->d); @@ -464,6 +465,7 @@ buffer_put_bignum2(b, key->rsa->q); break; case KEY_DSA: + case KEY_X509_DSA: buffer_put_bignum2(b, key->dsa->p); buffer_put_bignum2(b, key->dsa->q); buffer_put_bignum2(b, key->dsa->g); @@ -471,6 +473,21 @@ buffer_put_bignum2(b, key->dsa->priv_key); break; } + if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { + int len; + void* str; + unsigned char *p; + + len = i2d_X509(key->x509, NULL); + str = xmalloc(len); + if (str == NULL) + { error("ssh_encode_identity_ssh2: out of memory"); return; } + + p = str; + i2d_X509(key->x509, &p); + buffer_put_string(b, str, len); + xfree(str); + } buffer_put_cstring(b, comment); } @@ -498,6 +515,8 @@ break; case KEY_RSA: case KEY_DSA: + case KEY_X509_RSA: + case KEY_X509_DSA: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; @@ -550,7 +569,7 @@ buffer_put_int(&msg, BN_num_bits(key->rsa->n)); buffer_put_bignum(&msg, key->rsa->e); buffer_put_bignum(&msg, key->rsa->n); - } else if (key->type == KEY_DSA || key->type == KEY_RSA) { + } else if (key->type == KEY_DSA || key->type == KEY_RSA || key->type == KEY_X509_DSA || key->type == KEY_X509_RSA ) { key_to_blob(key, &blob, &blen); buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); buffer_put_string(&msg, blob, blen); Only in openssh-3.4p1+x509d: autom4te.cache diff -ur openssh-3.4p1+x509c/config.h.in openssh-3.4p1+x509d/config.h.in --- openssh-3.4p1+x509c/config.h.in Wed Jun 26 17:08:19 2002 +++ openssh-3.4p1+x509d/config.h.in Tue Jul 30 13:09:55 2002 @@ -289,6 +289,9 @@ /* Specify default $PATH */ #undef USER_PATH +/* Specify location of ssh CA root */ +#undef SSHCADIR + /* Specify location of ssh.pid */ #undef _PATH_SSH_PIDDIR diff -ur openssh-3.4p1+x509c/configure openssh-3.4p1+x509d/configure --- openssh-3.4p1+x509c/configure Thu Jun 27 15:18:12 2002 +++ openssh-3.4p1+x509d/configure Tue Jul 30 13:09:54 2002 @@ -15874,6 +15874,12 @@ # Where to place ssh CA root sshcadir='${sysconfdir}/ca' +sshcadir=`eval echo ${sshcadir}` +sshcadir=`eval echo ${sshcadir}` +case $sshcadir in + NONE/*) sshcadir=`echo $sshcadir | sed "s~NONE~$ac_default_prefix~"` ;; +esac + # Check whether --with-sshca-dir or --without-sshca-dir was given. if test "${with_sshca_dir+set}" = set; then @@ -17515,14 +17521,13 @@ H=`eval echo ${PRIVSEP_PATH}` ; H=`eval echo ${H}` I=`eval echo ${user_path}` ; I=`eval echo ${I}` J=`eval echo ${superuser_path}` ; J=`eval echo ${J}` -K=`eval echo ${sshcadir}` ; K=`eval echo ${K}` echo "" echo "OpenSSH has been configured with the following options:" echo " User binaries: $B" echo " System binaries: $C" echo " Configuration files: $D" -echo " CA root: $K" +echo " CA root: $sshcadir" echo " Askpass program: $E" echo " Manual pages: $F" echo " PID file: $G" diff -ur openssh-3.4p1+x509c/configure.ac openssh-3.4p1+x509d/configure.ac --- openssh-3.4p1+x509c/configure.ac Thu Jun 27 15:16:46 2002 +++ openssh-3.4p1+x509d/configure.ac Tue Jul 30 13:08:44 2002 @@ -2105,6 +2105,12 @@ # Where to place ssh CA root sshcadir='${sysconfdir}/ca' +sshcadir=`eval echo ${sshcadir}` +sshcadir=`eval echo ${sshcadir}` +case $sshcadir in + NONE/*) sshcadir=`echo $sshcadir | sed "s~NONE~$ac_default_prefix~"` ;; +esac + AC_ARG_WITH(sshca-dir, [ --with-sshca-dir=PATH Specify location of ssh CA root], [ @@ -2394,14 +2400,13 @@ H=`eval echo ${PRIVSEP_PATH}` ; H=`eval echo ${H}` I=`eval echo ${user_path}` ; I=`eval echo ${I}` J=`eval echo ${superuser_path}` ; J=`eval echo ${J}` -K=`eval echo ${sshcadir}` ; K=`eval echo ${K}` echo "" echo "OpenSSH has been configured with the following options:" echo " User binaries: $B" echo " System binaries: $C" echo " Configuration files: $D" -echo " CA root: $K" +echo " CA root: $sshcadir" echo " Askpass program: $E" echo " Manual pages: $F" echo " PID file: $G" diff -ur openssh-3.4p1+x509c/key.c openssh-3.4p1+x509d/key.c --- openssh-3.4p1+x509c/key.c Thu Jun 27 15:41:02 2002 +++ openssh-3.4p1+x509d/key.c Tue Jul 30 13:22:15 2002 @@ -10,6 +10,8 @@ * * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * X509 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 @@ -62,6 +64,7 @@ switch (k->type) { case KEY_RSA1: case KEY_RSA: + case KEY_X509_RSA: if ((rsa = RSA_new()) == NULL) fatal("key_new: RSA_new failed"); if ((rsa->n = BN_new()) == NULL) @@ -69,8 +72,13 @@ if ((rsa->e = BN_new()) == NULL) fatal("key_new: BN_new failed"); k->rsa = rsa; + if (k->type == KEY_X509_RSA) { + if ((k->x509 = X509_new()) == NULL) + fatal("key_new: X509_new failed"); + } break; case KEY_DSA: + case KEY_X509_DSA: if ((dsa = DSA_new()) == NULL) fatal("key_new: DSA_new failed"); if ((dsa->p = BN_new()) == NULL) @@ -82,11 +90,10 @@ if ((dsa->pub_key = BN_new()) == NULL) fatal("key_new: BN_new failed"); k->dsa = dsa; - break; - case KEY_X509_RSA: - case KEY_X509_DSA: - k->x509 = X509_new(); - debug ("key_new: KEY_X509_XXX - more ... ?"); + if (k->type == KEY_X509_DSA) { + if ((k->x509 = X509_new()) == NULL) + fatal("key_new: X509_new failed"); + } break; case KEY_UNSPEC: break; @@ -104,6 +111,7 @@ switch (k->type) { case KEY_RSA1: case KEY_RSA: + case KEY_X509_RSA: if ((k->rsa->d = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); if ((k->rsa->iqmp = BN_new()) == NULL) @@ -116,10 +124,25 @@ fatal("key_new_private: BN_new failed"); if ((k->rsa->dmp1 = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); + if (k->type == KEY_X509_RSA) { + debug3("key_new_private: X509(rsa) MORE ...?"); + /* + if ((k->x509 = X509_new()) == NULL) + fatal("key_new: X509_new failed"); + */ + } break; case KEY_DSA: + case KEY_X509_DSA: if ((k->dsa->priv_key = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); + if (k->type == KEY_X509_DSA) { + debug3("key_new_private: X509(dsa) MORE ...?"); + /* + if ((k->x509 = X509_new()) == NULL) + fatal("key_new: X509_new failed"); + */ + } break; case KEY_UNSPEC: break; @@ -167,30 +190,19 @@ } xfree(k); } + int key_equal(Key *a, Key *b) { if (a == NULL || b == NULL || a->type != b->type) return 0; switch (a->type) { - case KEY_X509_RSA: - if(a->rsa == NULL || b->rsa == NULL) { - return X509_subject_name_cmp(a->x509, b->x509) == 0; - break; - } - /* no break !!!*/ case KEY_RSA1: case KEY_RSA: return a->rsa != NULL && b->rsa != NULL && BN_cmp(a->rsa->e, b->rsa->e) == 0 && BN_cmp(a->rsa->n, b->rsa->n) == 0; break; - case KEY_X509_DSA: - if(a->dsa == NULL || b->dsa == NULL) { - return X509_subject_name_cmp(a->x509, b->x509) == 0; - break; - } - /* no break !!!*/ case KEY_DSA: return a->dsa != NULL && b->dsa != NULL && BN_cmp(a->dsa->p, b->dsa->p) == 0 && @@ -198,6 +210,15 @@ BN_cmp(a->dsa->g, b->dsa->g) == 0 && BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; break; + case KEY_X509_RSA: + case KEY_X509_DSA: + /* we can check only by Subject (Distinguished Name): + - sshd receive from client only x509 certificate !!! + - sshadd -d ... send only x509 certificate !!! + - otherwise Key might contain private key + */ + return X509_subject_name_cmp(a->x509, b->x509) == 0; + break; default: fatal("key_equal: bad key type %d", a->type); break; @@ -481,12 +502,7 @@ xfree(blob); return -1; } - if (type == KEY_X509_RSA || - type == KEY_X509_DSA) { - k = x509key_from_blob(blob, n); - } - else - k = key_from_blob(blob, n); + k = key_from_blob(blob, n); xfree(blob); if (k == NULL) { error("key_read: key_from_blob %s failed", cp); @@ -776,6 +792,9 @@ #ifdef DEBUG_PK dump_base64(stderr, blob, blen); #endif + if ((key = x509key_from_blob(blob, blen)) != NULL) { + return key; + } buffer_init(&b); buffer_append(&b, blob, blen); ktype = buffer_get_string(&b, NULL); diff -ur openssh-3.4p1+x509c/key.h openssh-3.4p1+x509d/key.h --- openssh-3.4p1+x509c/key.h Thu Jun 27 15:37:36 2002 +++ openssh-3.4p1+x509d/key.h Tue Jul 30 13:22:34 2002 @@ -2,6 +2,8 @@ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * X509 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 diff -ur openssh-3.4p1+x509c/monitor.c openssh-3.4p1+x509d/monitor.c --- openssh-3.4p1+x509c/monitor.c Thu Jun 27 15:36:21 2002 +++ openssh-3.4p1+x509d/monitor.c Wed Jun 26 16:27:11 2002 @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD$"); +RCSID("$OpenBSD: monitor.c,v 1.18 2002/06/26 13:20:57 deraadt Exp $"); #include @@ -58,7 +58,6 @@ #include "compat.h" #include "ssh2.h" #include "mpaux.h" -#include "ssh-x509.h" /* Imports */ extern ServerOptions options; @@ -763,9 +762,7 @@ chost = buffer_get_string(m, NULL); blob = buffer_get_string(m, &bloblen); - key = x509key_from_blob(blob, bloblen); - if (key == NULL) - key = key_from_blob(blob, bloblen); + key = key_from_blob(blob, bloblen); if ((compat20 && type == MM_RSAHOSTKEY) || (!compat20 && type != MM_RSAHOSTKEY)) @@ -954,9 +951,7 @@ !monitor_allowed_key(blob, bloblen)) fatal("%s: bad key, not previously allowed", __func__); - key = x509key_from_blob(blob, bloblen); - if (key == NULL) - key = key_from_blob(blob, bloblen); + key = key_from_blob(blob, bloblen); if (key == NULL) fatal("%s: bad public key blob", __func__); diff -ur openssh-3.4p1+x509c/servconf.c openssh-3.4p1+x509d/servconf.c --- openssh-3.4p1+x509c/servconf.c Thu Jun 27 15:33:44 2002 +++ openssh-3.4p1+x509d/servconf.c Tue Jul 30 19:08:56 2002 @@ -39,6 +39,7 @@ #include "cipher.h" #include "kex.h" #include "mac.h" +#include "openssl/x509v3.h" static void add_listen_addr(ServerOptions *, char *, u_short); static void add_one_listen_addr(ServerOptions *, char *, u_short); @@ -122,7 +123,7 @@ options->client_alive_count_max = -1; options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; - options->num_allowedcertpurposes = 0; + options->allowedcertpurpose = -1; options->ca_certificate_file = NULL; options->ca_certificate_path = NULL; options->ca_revocation_file = NULL; @@ -257,7 +258,10 @@ } if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; - /* options->num_allowedcertpurposes is zero by default */ + + if (options->allowedcertpurpose == -1) { + fprintf(stderr, "config warning:option AllowedCertPurpose is \"skip\" or empty or is not set\n"); + } if (options->ca_certificate_file == NULL) options->ca_certificate_file = _PATH_CA_CERTIFICATE_FILE; if (options->ca_certificate_path == NULL) @@ -313,7 +317,7 @@ sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sUsePrivilegeSeparation, - sAllowedCertPurposes, + sAllowedCertPurpose, sCACertificateFile, sCACertificatePath, sCARevocationFile, sCARevocationPath, sDeprecated @@ -393,7 +397,7 @@ { "authorizedkeysfile", sAuthorizedKeysFile }, { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, - { "allowedcertpurposes", sAllowedCertPurposes }, + { "allowedcertpurpose", sAllowedCertPurpose }, { "cacertificatefile", sCACertificateFile }, { "cacertificatepath", sCACertificatePath }, { "carevocationfile", sCARevocationFile }, @@ -923,12 +927,29 @@ intptr = &options->client_alive_count_max; goto parse_int; -#if 0 - case sAllowedCertPurposes: - options->num_allowedcertpurposes = XXXX - options->allowedcertpurposes = XXXX + case sAllowedCertPurpose: + arg = strdelim(&cp); + if (arg && *arg) { + char *purpose = NULL; + int idx; + if (strcasecmp(arg, "SSL client") == 0 ) { + purpose = "sslclient"; + } else if (strcasecmp(arg, "sslclient") == 0 ) { + purpose = "sslclient"; + } else if (strcasecmp(arg, "any purpose") == 0 ) { + purpose = "any"; + } else if (strcasecmp(arg, "any") == 0 ) { + purpose = "any"; + } else if (strcasecmp(arg, "skip") == 0 ) { + break; + } + if (purpose == NULL) + fatal("config error: unsupported purpose '%.30s' in file %s line %d.", arg, filename, linenum); + if ((idx = X509_PURPOSE_get_by_sname(purpose)) < 0) + fatal("config error: X509_PURPOSE_get_by_sname() fail for argument '%.30s' in file %s line %d.", arg, filename, linenum); + options->allowedcertpurpose = idx; + } break; -#endif case sCACertificateFile: case sCACertificatePath: diff -ur openssh-3.4p1+x509c/servconf.h openssh-3.4p1+x509d/servconf.h --- openssh-3.4p1+x509c/servconf.h Thu Jun 27 15:23:48 2002 +++ openssh-3.4p1+x509d/servconf.h Tue Jul 30 17:22:06 2002 @@ -133,8 +133,7 @@ int pam_authentication_via_kbd_int; /* ssh PKI(X509) store */ - int num_allowedcertpurposes; - char *allowedcertpurposes[10]; /* XXXX*/ + int allowedcertpurpose; char *ca_certificate_file; char *ca_certificate_path; char *ca_revocation_file; diff -ur openssh-3.4p1+x509c/ssh-add.c openssh-3.4p1+x509d/ssh-add.c --- openssh-3.4p1+x509c/ssh-add.c Fri Jun 21 03:41:52 2002 +++ openssh-3.4p1+x509d/ssh-add.c Tue Jul 30 13:21:30 2002 @@ -12,6 +12,8 @@ * * SSH2 implementation, * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * X509 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 @@ -49,6 +51,7 @@ #include "pathnames.h" #include "readpass.h" #include "misc.h" +#include "ssh-x509.h" #ifdef HAVE___PROGNAME extern char *__progname; @@ -224,9 +227,16 @@ key_size(key), fp, comment, key_type(key)); xfree(fp); } else { - if (!key_write(key, stdout)) - fprintf(stderr, "key_write failed"); - fprintf(stdout, " %s\n", comment); + if ((key->type == KEY_X509_RSA) || (key->type == KEY_X509_DSA)) { + /* key_write will print x509 certificate in blob format :-( */ + if(!x509key_write_subject(key, stdout)) + fprintf(stderr, "x509key_write_subject failed"); + fprintf(stdout, "\n"); + } else { + if (!key_write(key, stdout)) + fprintf(stderr, "key_write failed"); + fprintf(stdout, " %s\n", comment); + } } key_free(key); xfree(comment); diff -ur openssh-3.4p1+x509c/ssh-agent.c openssh-3.4p1+x509d/ssh-agent.c --- openssh-3.4p1+x509c/ssh-agent.c Wed Jun 26 02:19:13 2002 +++ openssh-3.4p1+x509d/ssh-agent.c Tue Jul 30 18:32:46 2002 @@ -11,6 +11,8 @@ * called by a name other than "ssh" or "Secure Shell". * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * X509 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 @@ -417,6 +419,7 @@ xfree(type_name); switch (type) { case KEY_DSA: + case KEY_X509_DSA: k = key_new_private(type); buffer_get_bignum2(&e->request, k->dsa->p); buffer_get_bignum2(&e->request, k->dsa->q); @@ -425,6 +428,7 @@ buffer_get_bignum2(&e->request, k->dsa->priv_key); break; case KEY_RSA: + case KEY_X509_RSA: k = key_new_private(type); buffer_get_bignum2(&e->request, k->rsa->n); buffer_get_bignum2(&e->request, k->rsa->e); @@ -439,6 +443,24 @@ default: buffer_clear(&e->request); goto send; + } + switch (type) { + case KEY_X509_RSA: + case KEY_X509_DSA: { + u_char *blob = NULL; + u_int blen = 0; + Key *key = NULL; + + blob = buffer_get_string(&e->request, &blen); + key = x509key_from_blob(blob, blen); + if(key == NULL) { + fatal("process_add_identity() x509key_from_blob fail"); + } + k->x509 = key->x509; + key->x509 = NULL; + key_free(key); + } + break; } break; } diff -ur openssh-3.4p1+x509c/ssh-x509.c openssh-3.4p1+x509d/ssh-x509.c --- openssh-3.4p1+x509c/ssh-x509.c Mon Jun 17 21:37:05 2002 +++ openssh-3.4p1+x509d/ssh-x509.c Tue Jul 30 18:34:02 2002 @@ -44,6 +44,7 @@ "subject", "distinguished name", "distinguished_name", + "distinguishedname", "dn", NULL }; @@ -122,7 +123,7 @@ ret = X509_NAME_add_entry_by_NID(_name, nid, V_ASN1_PRINTABLESTRING, p, q-p+1, -1, 0); if(ret <= 0) { int ecode = ERR_get_error(); - error("x509key_from_subject: x509key_str2X509NAME fail %.200s", ERR_error_string(ecode, NULL)); + error("x509key_str2X509NAME: X509_NAME_add_entry_by_NID fail %.200s", ERR_error_string(ecode, NULL)); } } *token = ch; @@ -191,7 +192,7 @@ return key; } else { - debug3("x509_to_key: X509_get_pubkey done!"); + debug3("x509_to_key: X509_get_pubkey done!"); } switch(env_pkey->type) { @@ -216,7 +217,7 @@ break; default: - debug3("x509key_from_blob:unspec key" ); + debug3("x509_to_key: unspec key" ); } return key; @@ -244,7 +245,11 @@ x509 = d2i_X509_bio(mbio,NULL); if (x509 == NULL) { int ecode = ERR_get_error(); - error("x509key_from_blob: read X509 from BIO fail %.200s", ERR_error_string(ecode, NULL)); + /* We will print only debug info !!! + * This method is used in place where we can only check incomming data. + * If data contain x506 certificate blob we will return a key otherwise NULL. + */ + debug3("x509key_from_blob: read X509 from BIO fail %.200s", ERR_error_string(ecode, NULL)); } else { key = x509_to_key(x509); @@ -306,10 +311,10 @@ FILE *f ) { int ret = 0; - Buffer b; - int n; + Buffer b; + int n; - if (!x509key_check("x509key_write", key)) + if (!x509key_check("x509key_write_blob", key)) return ret; buffer_init(&b); @@ -335,6 +340,35 @@ } +int +x509key_write_subject( + Key *key, + FILE *f +) { + BIO *out=NULL; + char buf[512]; + + if (!x509key_check("x509key_write_subject", key)) + return 0; + + out=BIO_new_fp(f, BIO_NOCLOSE); +#ifdef VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + + BIO_puts(out, key_ssh_name(key)); + BIO_puts(out, " Subject:"); + X509_NAME_oneline(X509_get_subject_name(key->x509), buf, sizeof(buf)); + BIO_puts(out, buf); + + BIO_free_all(out); + return 1; +} + + Key* x509key_load_cert( Key *key, @@ -508,7 +542,7 @@ buffer_free(&b); } debug3("ssh_x509_sign() return %d", ret); - return ret; + return ret > 0 ? 0 : -1; } @@ -521,7 +555,6 @@ u_char *sigblob = NULL; uint len = 0; - if (!x509key_check("ssh_x509_verify", key)) return ret; @@ -575,6 +608,7 @@ if (ret <= 0) { int ecode = ERR_get_error(); error("ssh_x509_verify: verify failed: %.200s", ERR_error_string(ecode, NULL)); + ret = 0; } } } @@ -588,5 +622,5 @@ xfree(sigblob); } debug3("ssh_x509_verify() return %d", ret); - return ret; + return ret > 0 ? 1 : (ret < 0 ? -1 : 0); } diff -ur openssh-3.4p1+x509c/ssh-x509.h openssh-3.4p1+x509d/ssh-x509.h --- openssh-3.4p1+x509c/ssh-x509.h Mon Jun 17 15:44:42 2002 +++ openssh-3.4p1+x509d/ssh-x509.h Tue Jul 30 12:51:29 2002 @@ -29,22 +29,26 @@ #include "buffer.h" /* - * This method return a key(x509) only with "Distinguished Name" ! + * This method return a key(x509) only with "Subject"("Distinguished Name") ! */ Key* x509key_from_subject(int _keytype, char* _cp); Key* x509key_from_blob(u_char *blob, int blen); int x509key_to_blob(Key *key, Buffer *b); + + /* write x509 certificate as blob */ int x509key_write(Key *key, FILE *f); + /* write x509 certificate subject */ +int x509key_write_subject(Key *key, FILE *f); Key* x509key_load_cert(Key *key, FILE *fp); int x509key_save_pem(FILE *fp, Key *key, const EVP_CIPHER *cipher, u_char *passphrase, int len); -int ssh_x509_sign(Key *, u_char **, u_int *, u_char *, u_int); -int ssh_x509_verify(Key *key, u_char *signature, u_int signaturelen, u_char *data, u_int datalen); +int ssh_x509_sign(Key *, u_char **, u_int *, u_char *, u_int); +int ssh_x509_verify(Key *key, u_char *signature, u_int signaturelen, u_char *data, u_int datalen); #endif /* SSH_X509_H */ diff -ur openssh-3.4p1+x509c/sshconnect2.c openssh-3.4p1+x509d/sshconnect2.c --- openssh-3.4p1+x509c/sshconnect2.c Thu Jun 27 17:35:36 2002 +++ openssh-3.4p1+x509d/sshconnect2.c Mon Jun 24 00:23:21 2002 @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD$"); +RCSID("$OpenBSD: sshconnect2.c,v 1.105 2002/06/23 03:30:17 deraadt Exp $"); #include "ssh.h" #include "ssh2.h" @@ -47,7 +47,6 @@ #include "canohost.h" #include "msg.h" #include "pathnames.h" -#include "ssh-x509.h" /* import */ extern char *client_version_string; @@ -393,11 +392,7 @@ debug("unknown pkalg %s", pkalg); break; } - if ( (pktype == KEY_X509_RSA) || (pktype == KEY_X509_RSA) ) - key = x509key_from_blob(pkblob, blen); - else - key = key_from_blob(pkblob, blen); - if (key == NULL) { + if ((key = key_from_blob(pkblob, blen)) == NULL) { debug("no key from blob. pkalg %s", pkalg); break; } diff -ur openssh-3.4p1+x509c/sshd.c openssh-3.4p1+x509d/sshd.c --- openssh-3.4p1+x509c/sshd.c Thu Jun 27 15:20:41 2002 +++ openssh-3.4p1+x509d/sshd.c Thu Jul 25 18:05:34 2002 @@ -1201,6 +1201,8 @@ if (f) { fprintf(f, "%ld\n", (long) getpid()); fclose(f); + } else { + error("Could not create pid file: %.400s", options.pid_file); } } diff -ur openssh-3.4p1+x509c/sshd_config openssh-3.4p1+x509d/sshd_config --- openssh-3.4p1+x509c/sshd_config Thu Jun 27 15:24:17 2002 +++ openssh-3.4p1+x509d/sshd_config Tue Jul 30 19:08:06 2002 @@ -21,9 +21,24 @@ #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key -#AllowedCertPurposes XXXX +# X509 certificates: +# The intended use for the certificate. Without this option no chain +# verification will be done. Currently accepted uses are case insensitive: +# - "sslclient" or "SSL client" +# - "any" or "Any Purpose" +# - "skip" or "" +# NOTE: default is empty value - don`t check purpose +#AllowedCertPurpose + +# A file of trusted certificates. The file should contain multiple +# certificates in PEM format concatenated together. #CACertificateFile /etc/ssh/ca/ca-bundle.crt + +# A directory of trusted certificates. The certificates(files) should +# have name of the form: hash. or have symbolic links to them +# of this form. #CACertificatePath /etc/ssh/ca/crt + #CARevocationFile /etc/ssh/ca/ca-bundle.crl #CARevocationPath /etc/ssh/ca/crl diff -ur openssh-3.4p1+x509c/x509store.c openssh-3.4p1+x509d/x509store.c --- openssh-3.4p1+x509c/x509store.c Fri Jun 7 19:15:48 2002 +++ openssh-3.4p1+x509d/x509store.c Tue Jul 30 18:40:43 2002 @@ -31,7 +31,6 @@ extern ServerOptions options; static int x509_store_loaded = 0; static X509_STORE *x509store_ctx = NULL; -int ssh_x509_purpose = -1; static int MS_CALLBACK @@ -39,8 +38,8 @@ if (!ok) { char buf[256]; X509_NAME_oneline( X509_get_subject_name(ctx->current_cert), buf, sizeof(buf)); - error("ssh_x509store_cb() subject:%s\n", buf); - error("ssh_x509store_cb() error %d at %d depth lookup:%s\n", + error("ssh_x509store_cb() subject:'%s', error %d at %d depth lookup:%s\n", + buf, ctx->error, ctx->error_depth, X509_verify_cert_error_string(ctx->error)); @@ -68,15 +67,17 @@ static void ssh_x509store_init () { - int ret=0; X509_LOOKUP *lookup=NULL; x509store_ctx = X509_STORE_new(); -debug("ssh_x509store_init() begin"); + + debug3("ssh_x509store_init() begin"); if (x509store_ctx == NULL) return; X509_STORE_set_verify_cb_func(x509store_ctx, ssh_x509store_cb); lookup = X509_STORE_add_lookup(x509store_ctx, X509_LOOKUP_file()); - if (lookup == NULL) abort(); + if (lookup == NULL) { + fatal("cannot add file lookup !"); + } if (options.ca_certificate_file) { if(!X509_LOOKUP_load_file(lookup, options.ca_certificate_file, X509_FILETYPE_PEM)) { int ecode = ERR_get_error(); @@ -89,7 +90,9 @@ } lookup=X509_STORE_add_lookup(x509store_ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) abort(); + if (lookup == NULL) { + fatal("cannot add hash dir lookup !"); + } if (options.ca_certificate_path) { if(!X509_LOOKUP_add_dir(lookup, options.ca_certificate_path, X509_FILETYPE_PEM)) { int ecode = ERR_get_error(); @@ -102,7 +105,7 @@ } ERR_clear_error(); -debug("ssh_x509store_init() end"); + debug3("ssh_x509store_init() end"); } @@ -112,7 +115,7 @@ if (!x509_store_loaded) ssh_x509store_init(); if (x509store_ctx == NULL) { - printf("ssh_x509_store_check()-mamata\n"); + error("ssh_x509_store_check() context is NULL\n"); ret = 0; } if (ret > 0 ) { @@ -125,7 +128,7 @@ } if (ret > 0) { X509_STORE_CTX_init(csc, x509store_ctx, _cert, NULL); - if(ssh_x509_purpose >= 0) X509_STORE_CTX_set_purpose(csc, ssh_x509_purpose); + if(options.allowedcertpurpose >= 0) X509_STORE_CTX_set_purpose(csc, options.allowedcertpurpose); /* if(issuer_checks) X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CB_ISSUER_CHECK);