diff --git a/.gitignore b/.gitignore index 747c78e..ccba8e2 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ pam_ssh_agent_auth-0.9.2.tar.bz2 /openssh-7.9p1.tar.gz.asc /openssh-8.0p1.tar.gz /openssh-8.0p1.tar.gz.asc +/openssh-8.1p1.tar.gz +/openssh-8.1p1.tar.gz.asc diff --git a/openssh-6.6.1p1-log-in-chroot.patch b/openssh-6.6.1p1-log-in-chroot.patch index b009d99..f3f7cad 100644 --- a/openssh-6.6.1p1-log-in-chroot.patch +++ b/openssh-6.6.1p1-log-in-chroot.patch @@ -210,8 +210,8 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c fd_set *rset, *wset; int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; @@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv, + extern char *__progname; - ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); - log_init(__progname, log_level, log_facility, log_stderr); + log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); diff --git a/openssh-6.6.1p1-scp-non-existing-directory.patch b/openssh-6.6.1p1-scp-non-existing-directory.patch index 5412bc5..bb55c0b 100644 --- a/openssh-6.6.1p1-scp-non-existing-directory.patch +++ b/openssh-6.6.1p1-scp-non-existing-directory.patch @@ -10,5 +10,5 @@ + } omode = mode; mode |= S_IWUSR; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { -- diff --git a/openssh-7.2p2-k5login_directory.patch b/openssh-7.2p2-k5login_directory.patch index 600117f..242294a 100644 --- a/openssh-7.2p2-k5login_directory.patch +++ b/openssh-7.2p2-k5login_directory.patch @@ -28,14 +28,15 @@ diff --git a/auth.h b/auth.h index f9d191c..c432d2f 100644 --- a/auth.h +++ b/auth.h -@@ -222,5 +222,7 @@ int sys_auth_passwd(Authctxt *, const char *); +@@ -222,6 +222,8 @@ int sys_auth_passwd(Authctxt *, const char *); + #if defined(KRB5) && !defined(HEIMDAL) - #include krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); +krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx, + char **k5login_directory); #endif - #endif + + #endif /* AUTH_H */ diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c index a7c0c5f..df8cc9a 100644 --- a/gss-serv-krb5.c diff --git a/openssh-7.2p2-s390-closefrom.patch b/openssh-7.2p2-s390-closefrom.patch index 301a523..363538c 100644 --- a/openssh-7.2p2-s390-closefrom.patch +++ b/openssh-7.2p2-s390-closefrom.patch @@ -48,5 +48,5 @@ Author: Harald Freudenberger +#endif } (void) closedir(dirp); - } else + return; diff --git a/openssh-7.2p2-x11.patch b/openssh-7.2p2-x11.patch index 48ce840..0a19ecb 100644 --- a/openssh-7.2p2-x11.patch +++ b/openssh-7.2p2-x11.patch @@ -14,7 +14,7 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c + if (len <= 0) + return -1; sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) + if (sock == -1) error("socket: %.100s", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; diff --git a/openssh-7.3p1-x11-max-displays.patch b/openssh-7.3p1-x11-max-displays.patch index 94dac8f..c8a147b 100644 --- a/openssh-7.3p1-x11-max-displays.patch +++ b/openssh-7.3p1-x11-max-displays.patch @@ -59,7 +59,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c ssh_gai_strerror(gaierr)); @@ -4457,7 +4463,7 @@ x11_connect_display(void) /* Connect it to the display. */ - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { debug2("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); + X11_PORT_MIN + display_number, strerror(errno)); @@ -197,7 +197,7 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 +.Cm X11MaxDisplays , .Cm X11Forwarding and - .Cm X11UseLocalHost . + .Cm X11UseLocalhost . @@ -1566,6 +1567,12 @@ Specifies the first display number avail X11 forwarding. This prevents sshd from interfering with real X11 servers. diff --git a/openssh-7.5p1-sandbox.patch b/openssh-7.5p1-sandbox.patch index 7190813..7217c64 100644 --- a/openssh-7.5p1-sandbox.patch +++ b/openssh-7.5p1-sandbox.patch @@ -69,29 +69,6 @@ index 6e7de31..e86aa2c 100644 SC_ALLOW(__NR_getrandom), #endif -- 1.9.1 - -The EP11 crypto card needs to make an ioctl call, which receives an -specific argument. This crypto card is for s390 only. - -Signed-off-by: Eduardo Barretto ---- - sandbox-seccomp-filter.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index e86aa2c..98062f1 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -250,6 +250,8 @@ static const struct sock_filter preauth_insns[] = { - SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK), - SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), - SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), -+ /* Allow ioctls for EP11 crypto card on s390 */ -+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), - #endif - #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) - /* --- 1.9.1 diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-seccomp-filter.c --- openssh-7.6p1/sandbox-seccomp-filter.c.sandbox 2017-12-12 13:59:30.563874059 +0100 @@ -107,40 +84,3 @@ diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-se SC_ALLOW(__NR_getrandom), #endif - -From ef34ea4521b042dd8a9c4c7455f5d1a8f8ee5bb2 Mon Sep 17 00:00:00 2001 -From: Harald Freudenberger -Date: Fri, 24 May 2019 10:11:15 +0200 -Subject: [PATCH] allow s390 specific ioctl for ecc hardware support - -Adding another s390 specific ioctl to be able to support ECC hardware acceleration -to the sandbox seccomp filter rules. - -Now the ibmca openssl engine provides elliptic curve cryptography support with the -help of libica and CCA crypto cards. This is done via jet another ioctl call to the zcrypt -device driver and so there is a need to enable this on the openssl sandbox. - -Code is s390 specific and has been tested, verified and reviewed. - -Please note that I am also the originator of the previous changes in that area. -I posted these changes to Eduardo and he forwarded the patches to the openssl -community. - -Signed-off-by: Harald Freudenberger -Reviewed-by: Joerg Schmidbauer ---- - sandbox-seccomp-filter.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c -index 5edbc6946..56eb9317f 100644 ---- a/sandbox-seccomp-filter.c -+++ b/sandbox-seccomp-filter.c -@@ -252,6 +252,7 @@ static const struct sock_filter preauth_insns[] = { - SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), - /* Allow ioctls for EP11 crypto card on s390 */ - SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), -+ SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB), - #endif - #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) - /* diff --git a/openssh-7.6p1-audit.patch b/openssh-7.6p1-audit.patch index 01e509e..a59cfc2 100644 --- a/openssh-7.6p1-audit.patch +++ b/openssh-7.6p1-audit.patch @@ -941,8 +941,8 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_CIPHER_ALG_MATCH; + } if ((enc->cipher = cipher_by_name(name)) == NULL) { + error("%s: unsupported cipher %s", __func__, name); free(name); - return SSH_ERR_INTERNAL_ERROR; @@ -783,8 +788,12 @@ choose_mac(struct ssh *ssh, struct sshma { char *name = match_list(client, server, NULL); @@ -955,8 +955,8 @@ diff -up openssh/kex.c.audit openssh/kex.c return SSH_ERR_NO_MAC_ALG_MATCH; + } if (mac_setup(mac, name) < 0) { + error("%s: unsupported MAC %s", __func__, name); free(name); - return SSH_ERR_INTERNAL_ERROR; @@ -796,12 +805,16 @@ choose_mac(struct ssh *ssh, struct sshma } @@ -1659,9 +1659,9 @@ diff -up openssh/packet.c.audit openssh/packet.c #include "xmalloc.h" +#include "audit.h" - #include "crc32.h" #include "compat.h" #include "ssh2.h" + #include "cipher.h" @@ -510,6 +511,13 @@ ssh_packet_get_connection_out(struct ssh return ssh->state->connection_out; } @@ -2309,8 +2309,8 @@ diff -up openssh/sshkey.h.audit openssh/sshkey.h --- openssh/sshkey.h.audit 2019-04-03 17:02:20.657885510 +0200 +++ openssh/sshkey.h 2019-04-03 17:02:20.718886088 +0200 @@ -148,6 +148,7 @@ u_int sshkey_size(const struct sshkey - int sshkey_generate(int type, u_int bits, struct sshkey **keyp); - int sshkey_from_private(const struct sshkey *, struct sshkey **); + int sshkey_unshield_private(struct sshkey *); + int sshkey_type_from_name(const char *); +int sshkey_is_private(const struct sshkey *); int sshkey_is_cert(const struct sshkey *); diff --git a/openssh-7.7p1-fips.patch b/openssh-7.7p1-fips.patch index bbd644a..36af30a 100644 --- a/openssh-7.7p1-fips.patch +++ b/openssh-7.7p1-fips.patch @@ -152,9 +152,9 @@ diff -up openssh-8.0p1/Makefile.in.fips openssh-8.0p1/Makefile.in - $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o -- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o sshsig.o +- $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keygen.o sshsig.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o uidswap.o compat.o - $(LD) -o $@ ssh-keysign.o readconf.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -169,8 +169,8 @@ diff -up openssh-8.0p1/Makefile.in.fips openssh-8.0p1/Makefile.in - $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o - $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-realpath.o sftp-server-main.o + $(LD) -o $@ sftp-server.o sftp-common.o sftp-realpath.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h --- openssh-8.0p1/myproposal.h.fips 2019-04-18 00:52:57.000000000 +0200 +++ openssh-8.0p1/myproposal.h 2019-07-23 14:55:45.402526411 +0200 @@ -229,7 +229,7 @@ diff -up openssh-8.0p1/myproposal.h.fips openssh-8.0p1/myproposal.h + /* Not a KEX value, but here so all the algorithm defaults are together */ #define SSH_ALLOWED_CA_SIGALGS \ - "ecdsa-sha2-nistp256," \ + HOSTKEY_ECDSA_METHODS \ diff -up openssh-8.0p1/readconf.c.fips openssh-8.0p1/readconf.c --- openssh-8.0p1/readconf.c.fips 2019-07-23 14:55:45.334525723 +0200 +++ openssh-8.0p1/readconf.c 2019-07-23 14:55:45.402526411 +0200 @@ -526,13 +526,13 @@ diff -up openssh-8.0p1/sshkey.c.fips openssh-8.0p1/sshkey.c #include "crypto_api.h" @@ -57,6 +58,7 @@ + #define SSHKEY_INTERNAL #include "sshkey.h" - #include "sshkey-xmss.h" #include "match.h" +#include "log.h" - #include "xmss_fast.h" - + #ifdef WITH_XMSS + #include "sshkey-xmss.h" @@ -1591,6 +1593,8 @@ rsa_generate_private_key(u_int bits, RSA } if (!BN_set_word(f4, RSA_F4) || @@ -546,9 +546,9 @@ diff -up openssh-8.0p1/ssh-keygen.c.fips openssh-8.0p1/ssh-keygen.c --- openssh-8.0p1/ssh-keygen.c.fips 2019-07-23 14:55:45.391526300 +0200 +++ openssh-8.0p1/ssh-keygen.c 2019-07-23 14:57:54.118830056 +0200 @@ -199,6 +199,12 @@ type_bits_valid(int type, const char *na - OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; - if (*bitsp > maxbits) - fatal("key bits exceeds maximum %d", maxbits); + #endif + } + #ifdef WITH_OPENSSL + if (FIPS_mode()) { + if (type == KEY_DSA) + fatal("DSA keys are not allowed in FIPS mode"); diff --git a/openssh-7.7p1-gssapi-new-unique.patch b/openssh-7.7p1-gssapi-new-unique.patch index 2eea250..9386249 100644 --- a/openssh-7.7p1-gssapi-new-unique.patch +++ b/openssh-7.7p1-gssapi-new-unique.patch @@ -336,14 +336,15 @@ index 29491df9..fdab5040 100644 #endif struct sshbuf *loginmsg; -@@ -243,6 +244,6 @@ int sys_auth_passwd(struct ssh *, const char *); +@@ -238,7 +239,7 @@ int sys_auth_passwd(struct ssh *, const char *); + int sys_auth_passwd(struct ssh *, const char *); #if defined(KRB5) && !defined(HEIMDAL) - #include -krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); +krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); #endif - #endif + + #endif /* AUTH_H */ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c --- openssh-7.9p1/gss-serv-krb5.c.ccache_name 2019-03-01 15:17:42.708611802 +0100 +++ openssh-7.9p1/gss-serv-krb5.c 2019-03-01 15:17:42.713611844 +0100 diff --git a/openssh-7.8p1-role-mls.patch b/openssh-7.8p1-role-mls.patch index 84ba9b3..da0abd7 100644 --- a/openssh-7.8p1-role-mls.patch +++ b/openssh-7.8p1-role-mls.patch @@ -141,7 +141,7 @@ diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c +do_pam_putenv(char *name, const char *value) { int ret = 1; - #ifdef HAVE_PAM_PUTENV + char *compound; diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h --- openssh/auth-pam.h.role-mls 2018-08-20 07:57:29.000000000 +0200 +++ openssh/auth-pam.h 2018-08-22 11:14:56.817430932 +0200 diff --git a/openssh-8.0p1-agent-certs-sha2.patch b/openssh-8.0p1-agent-certs-sha2.patch deleted file mode 100644 index b9888d9..0000000 --- a/openssh-8.0p1-agent-certs-sha2.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2317ce4b0ed7d8c4b0c684e2d47bff5006bd1178 Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Fri, 14 Jun 2019 03:51:47 +0000 -Subject: [PATCH] upstream: process agent requests for RSA certificate private - keys using - -correct signature algorithm when requested. Patch from Jakub Jelen in bz3016 -ok dtucker markus - -OpenBSD-Commit-ID: 61f86efbeb4a1857a3e91298c1ccc6cf49b79624 ---- - ssh-agent.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/ssh-agent.c b/ssh-agent.c -index 034f31387..4669b679c 100644 ---- a/ssh-agent.c -+++ b/ssh-agent.c -@@ -269,6 +269,11 @@ agent_decode_alg(struct sshkey *key, u_int flags) - return "rsa-sha2-256"; - else if (flags & SSH_AGENT_RSA_SHA2_512) - return "rsa-sha2-512"; -+ } else if (key->type == KEY_RSA_CERT) { -+ if (flags & SSH_AGENT_RSA_SHA2_256) -+ return "rsa-sha2-256-cert-v01@openssh.com"; -+ else if (flags & SSH_AGENT_RSA_SHA2_512) -+ return "rsa-sha2-512-cert-v01@openssh.com"; - } - return NULL; - } - diff --git a/openssh-8.0p1-crypto-policies.patch b/openssh-8.0p1-crypto-policies.patch index ffd4bae..37263a5 100644 --- a/openssh-8.0p1-crypto-policies.patch +++ b/openssh-8.0p1-crypto-policies.patch @@ -32,9 +32,9 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 .It Cm HashKnownHosts Indicates that @@ -1123,16 +1123,10 @@ If the specified value begins with a - .Sq - - character, then the specified methods (including wildcards) will be removed - from the default set instead of replacing them. + .Sq ^ + character, then the specified methods will be placed at the head of the + default set. -The default is: -.Bd -literal -offset indent -curve25519-sha256,curve25519-sha256@libssh.org, @@ -72,9 +72,9 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -1361,17 +1351,10 @@ If the specified value begins with a - .Sq - - character, then the specified key types (including wildcards) will be removed - from the default set instead of replacing them. + .Sq ^ + character, then the specified key types will be placed at the head of the + default set. -The default for this option is: -.Bd -literal -offset 3n -ecdsa-sha2-nistp256-cert-v01@openssh.com, @@ -187,9 +187,9 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 The list of available MAC algorithms may also be obtained using .Qq ssh -Q mac . @@ -1455,17 +1440,10 @@ If the specified value begins with a - .Sq - - character, then the specified key types (including wildcards) will be removed - from the default set instead of replacing them. + .Sq ^ + character, then the specified key types will be placed at the head of the + default set. -The default for this option is: -.Bd -literal -offset 3n -ecdsa-sha2-nistp256-cert-v01@openssh.com, diff --git a/openssh-8.0p1-gssapi-keyex.patch b/openssh-8.0p1-gssapi-keyex.patch index fe3e7a6..631c824 100644 --- a/openssh-8.0p1-gssapi-keyex.patch +++ b/openssh-8.0p1-gssapi-keyex.patch @@ -17,7 +17,7 @@ index 6f001bb3..c31821ac 100644 - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - sftp-server.o sftp-common.o \ + sftp-server.o sftp-common.o sftp-realpath.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff --git a/auth.c b/auth.c index 332b6220..7664aaac 100644 @@ -60,7 +60,7 @@ index 332b6220..7664aaac 100644 - fromlen = sizeof(from); - memset(&from, 0, sizeof(from)); - if (getpeername(ssh_packet_get_connection_in(ssh), -- (struct sockaddr *)&from, &fromlen) < 0) { +- (struct sockaddr *)&from, &fromlen) == -1) { - debug("getpeername failed: %.100s", strerror(errno)); - return strdup(ntop); - } @@ -279,7 +279,7 @@ index f71a0856..404731d2 100644 + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(ssh_packet_get_connection_in(ssh), -+ (struct sockaddr *)&from, &fromlen) < 0) { ++ (struct sockaddr *)&from, &fromlen) == -1) { + debug("getpeername failed: %.100s", strerror(errno)); + return strdup(ntop); + } @@ -1258,18 +1258,6 @@ index ab3a15f0..6ce56e92 100644 } /* Privileged */ -diff --git a/hmac.c b/hmac.c -index 1c879640..a29f32c5 100644 ---- a/hmac.c -+++ b/hmac.c -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - #include "sshbuf.h" - #include "digest.h" diff --git a/kex.c b/kex.c index 34808b5c..a2a4794e 100644 --- a/kex.c @@ -1293,7 +1281,7 @@ index 34808b5c..a2a4794e 100644 static int kex_input_newkeys(int, u_int32_t, struct ssh *); @@ -113,15 +118,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, -1, -1, -1}, + { NULL, 0, -1, -1}, }; +static const struct kexalg gss_kexalgs[] = { +#ifdef GSSAPI @@ -1306,7 +1294,7 @@ index 34808b5c..a2a4794e 100644 + NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, +#endif -+ { NULL, -1, -1, -1 }, ++ { NULL, 0, -1, -1 }, +}; -char * @@ -2585,18 +2573,6 @@ index 00000000..60bc02de + return r; +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ -diff --git a/mac.c b/mac.c -index 51dc11d7..3d11eba6 100644 ---- a/mac.c -+++ b/mac.c -@@ -29,6 +29,7 @@ - - #include - #include -+#include - - #include "digest.h" - #include "hmac.h" diff --git a/monitor.c b/monitor.c index 60e52944..669cdb4a 100644 --- a/monitor.c diff --git a/openssh-8.0p1-openssl-pem.patch b/openssh-8.0p1-openssl-pem.patch deleted file mode 100644 index 7e4fa81..0000000 --- a/openssh-8.0p1-openssl-pem.patch +++ /dev/null @@ -1,324 +0,0 @@ -From eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a Mon Sep 17 00:00:00 2001 -From: "djm@openbsd.org" -Date: Mon, 15 Jul 2019 13:16:29 +0000 -Subject: [PATCH] upstream: support PKCS8 as an optional format for storage of - -private keys, enabled via "ssh-keygen -m PKCS8" on operations that save -private keys to disk. - -The OpenSSH native key format remains the default, but PKCS8 is a -superior format to PEM if interoperability with non-OpenSSH software -is required, as it may use a less terrible KDF (IIRC PEM uses a single -round of MD5 as a KDF). - -adapted from patch by Jakub Jelen via bz3013; ok markus - -OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1 ---- - authfile.c | 6 ++-- - ssh-keygen.1 | 9 +++--- - ssh-keygen.c | 25 +++++++++-------- - sshkey.c | 78 +++++++++++++++++++++++++++++++++++++--------------- - sshkey.h | 11 ++++++-- - 5 files changed, 87 insertions(+), 42 deletions(-) - -diff --git a/authfile.c b/authfile.c -index 2166c1689..851c1a8a1 100644 ---- a/authfile.c -+++ b/authfile.c -@@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) - int - sshkey_save_private(struct sshkey *key, const char *filename, - const char *passphrase, const char *comment, -- int force_new_format, const char *new_format_cipher, int new_format_rounds) -+ int format, const char *openssh_format_cipher, int openssh_format_rounds) - { - struct sshbuf *keyblob = NULL; - int r; -@@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename, - if ((keyblob = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; - if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, -- force_new_format, new_format_cipher, new_format_rounds)) != 0) -+ format, openssh_format_cipher, openssh_format_rounds)) != 0) - goto out; - if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) - goto out; -diff --git a/ssh-keygen.1 b/ssh-keygen.1 -index f42127c60..8184a1797 100644 ---- a/ssh-keygen.1 -+++ b/ssh-keygen.1 -@@ -419,11 +419,12 @@ The supported key formats are: - .Dq RFC4716 - (RFC 4716/SSH2 public or private key), - .Dq PKCS8 --(PEM PKCS8 public key) -+(PKCS8 public or private key) - or - .Dq PEM - (PEM public key). --The default conversion format is -+By default OpenSSH will write newly-generated private keys in its own -+format, but when converting public keys for export the default format is - .Dq RFC4716 . - Setting a format of - .Dq PEM -diff --git a/ssh-keygen.c b/ssh-keygen.c -index b019a02ff..5dcad1f61 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -147,11 +147,11 @@ static char *key_type_name = NULL; - /* Load key from this PKCS#11 provider */ - static char *pkcs11provider = NULL; - --/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ --static int use_new_format = 1; -+/* Format for writing private keys */ -+static int private_key_format = SSHKEY_PRIVATE_OPENSSH; - - /* Cipher for new-format private keys */ --static char *new_format_cipher = NULL; -+static char *openssh_format_cipher = NULL; - - /* - * Number of KDF rounds to derive new format keys / -@@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw) - snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, - hostname); - if ((r = sshkey_save_private(private, prv_tmp, "", -- comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ comment, private_key_format, openssh_format_cipher, -+ rounds)) != 0) { - error("Saving key \"%s\" failed: %s", - prv_tmp, ssh_err(r)); - goto failnext; -@@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw) - - /* Save the file using the new passphrase. */ - if ((r = sshkey_save_private(private, identity_file, passphrase1, -- comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { - error("Saving key \"%s\" failed: %s.", - identity_file, ssh_err(r)); - explicit_bzero(passphrase1, strlen(passphrase1)); -@@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment) - } - - if (private->type != KEY_ED25519 && private->type != KEY_XMSS && -- !use_new_format) { -+ private_key_format != SSHKEY_PRIVATE_OPENSSH) { - error("Comments are only supported for keys stored in " - "the new format (-o)."); - explicit_bzero(passphrase, strlen(passphrase)); -@@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment) - - /* Save the file using the new passphrase. */ - if ((r = sshkey_save_private(private, identity_file, passphrase, -- new_comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ new_comment, private_key_format, openssh_format_cipher, -+ rounds)) != 0) { - error("Saving key \"%s\" failed: %s", - identity_file, ssh_err(r)); - explicit_bzero(passphrase, strlen(passphrase)); -@@ -2525,11 +2527,12 @@ main(int argc, char **argv) - } - if (strcasecmp(optarg, "PKCS8") == 0) { - convert_format = FMT_PKCS8; -+ private_key_format = SSHKEY_PRIVATE_PKCS8; - break; - } - if (strcasecmp(optarg, "PEM") == 0) { - convert_format = FMT_PEM; -- use_new_format = 0; -+ private_key_format = SSHKEY_PRIVATE_PEM; - break; - } - fatal("Unsupported conversion format \"%s\"", optarg); -@@ -2567,7 +2570,7 @@ main(int argc, char **argv) - add_cert_option(optarg); - break; - case 'Z': -- new_format_cipher = optarg; -+ openssh_format_cipher = optarg; - break; - case 'C': - identity_comment = optarg; -@@ -2912,7 +2915,7 @@ main(int argc, char **argv) - - /* Save the key with the given passphrase and comment. */ - if ((r = sshkey_save_private(private, identity_file, passphrase1, -- comment, use_new_format, new_format_cipher, rounds)) != 0) { -+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { - error("Saving key \"%s\" failed: %s", - identity_file, ssh_err(r)); - explicit_bzero(passphrase1, strlen(passphrase1)); -diff --git a/sshkey.c b/sshkey.c -index 6b5ff0485..a0cea9257 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -3975,10 +3975,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, - - - #ifdef WITH_OPENSSL --/* convert SSH v2 key in OpenSSL PEM format */ -+/* convert SSH v2 key to PEM or PKCS#8 format */ - static int --sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, -- const char *_passphrase, const char *comment) -+sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *blob, -+ int format, const char *_passphrase, const char *comment) - { - int success, r; - int blen, len = strlen(_passphrase); -@@ -3988,26 +3988,46 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; - char *bptr; - BIO *bio = NULL; -+ EVP_PKEY *pkey = NULL; - - if (len > 0 && len <= 4) - return SSH_ERR_PASSPHRASE_TOO_SHORT; -- if ((bio = BIO_new(BIO_s_mem())) == NULL) -- return SSH_ERR_ALLOC_FAIL; -+ if ((bio = BIO_new(BIO_s_mem())) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } - - switch (key->type) { - case KEY_DSA: -- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, -- cipher, passphrase, len, NULL, NULL); -+ if (format == SSHKEY_PRIVATE_PEM) { -+ success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, -+ cipher, passphrase, len, NULL, NULL); -+ } else { -+ success = EVP_PKEY_set1_DSA(pkey, key->dsa); -+ } - break; - #ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, -- cipher, passphrase, len, NULL, NULL); -+ if (format == SSHKEY_PRIVATE_PEM) { -+ success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, -+ cipher, passphrase, len, NULL, NULL); -+ } else { -+ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); -+ } - break; - #endif - case KEY_RSA: -- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, -- cipher, passphrase, len, NULL, NULL); -+ if (format == SSHKEY_PRIVATE_PEM) { -+ success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, -+ cipher, passphrase, len, NULL, NULL); -+ } else { -+ success = EVP_PKEY_set1_RSA(pkey, key->rsa); -+ } - break; - default: - success = 0; -@@ -4023,6 +4040,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -+ if (format == SSHKEY_PRIVATE_PKCS8) { -+ if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher, -+ passphrase, len, NULL, NULL)) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ } - if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { - r = SSH_ERR_INTERNAL_ERROR; - goto out; -@@ -4035,6 +4059,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - goto out; - r = 0; - out: -+ EVP_PKEY_free(pkey); - BIO_free(bio); - return r; - } -@@ -4046,29 +4071,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, - int - sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, - const char *passphrase, const char *comment, -- int force_new_format, const char *new_format_cipher, int new_format_rounds) -+ int format, const char *openssh_format_cipher, int openssh_format_rounds) - { - switch (key->type) { - #ifdef WITH_OPENSSL - case KEY_DSA: - case KEY_ECDSA: - case KEY_RSA: -- if (force_new_format) { -- return sshkey_private_to_blob2(key, blob, passphrase, -- comment, new_format_cipher, new_format_rounds); -- } -- return sshkey_private_pem_to_blob(key, blob, -- passphrase, comment); -+ break; /* see below */ - #endif /* WITH_OPENSSL */ - case KEY_ED25519: - #ifdef WITH_XMSS - case KEY_XMSS: - #endif /* WITH_XMSS */ - return sshkey_private_to_blob2(key, blob, passphrase, -- comment, new_format_cipher, new_format_rounds); -+ comment, openssh_format_cipher, openssh_format_rounds); - default: - return SSH_ERR_KEY_TYPE_UNKNOWN; - } -+ -+#ifdef WITH_OPENSSL -+ switch (format) { -+ case SSHKEY_PRIVATE_OPENSSH: -+ return sshkey_private_to_blob2(key, blob, passphrase, -+ comment, openssh_format_cipher, openssh_format_rounds); -+ case SSHKEY_PRIVATE_PEM: -+ case SSHKEY_PRIVATE_PKCS8: -+ return sshkey_private_to_blob_pem_pkcs8(key, blob, -+ format, passphrase, comment); -+ default: -+ return SSH_ERR_INVALID_ARGUMENT; -+ } -+#endif /* WITH_OPENSSL */ - } - - -diff --git a/sshkey.h b/sshkey.h -index 41d159a1b..d30a69cc9 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -88,6 +88,13 @@ enum sshkey_serialize_rep { - SSHKEY_SERIALIZE_INFO = 254, - }; - -+/* Private key disk formats */ -+enum sshkey_private_format { -+ SSHKEY_PRIVATE_OPENSSH = 0, -+ SSHKEY_PRIVATE_PEM = 1, -+ SSHKEY_PRIVATE_PKCS8 = 2, -+}; -+ - /* key is stored in external hardware */ - #define SSHKEY_FLAG_EXT 0x0001 - -@@ -221,7 +228,7 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); - /* private key file format parsing and serialisation */ - int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, - const char *passphrase, const char *comment, -- int force_new_format, const char *new_format_cipher, int new_format_rounds); -+ int format, const char *openssh_format_cipher, int openssh_format_rounds); - int sshkey_parse_private_fileblob(struct sshbuf *buffer, - const char *passphrase, struct sshkey **keyp, char **commentp); - int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, - diff --git a/openssh-8.0p1-pkcs11-uri.patch b/openssh-8.0p1-pkcs11-uri.patch index 41b138a..cd7d0e5 100644 --- a/openssh-8.0p1-pkcs11-uri.patch +++ b/openssh-8.0p1-pkcs11-uri.patch @@ -1,9 +1,9 @@ diff --git a/Makefile.in b/Makefile.in -index 6f001bb3..c9424f1e 100644 +index adb1977e..9b01a017 100644 --- a/Makefile.in +++ b/Makefile.in @@ -93,7 +93,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - atomicio.o dispatch.o mac.o uuencode.o misc.o utf8.o \ + atomicio.o dispatch.o mac.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ @@ -11,7 +11,7 @@ index 6f001bb3..c9424f1e 100644 poly1305.o chacha.o cipher-chachapoly.o \ ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ -@@ -250,6 +250,8 @@ clean: regressclean +@@ -255,6 +255,8 @@ clean: regressclean rm -f regress/unittests/match/test_match$(EXEEXT) rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8$(EXEEXT) @@ -20,7 +20,7 @@ index 6f001bb3..c9424f1e 100644 rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (cd openbsd-compat && $(MAKE) clean) -@@ -280,6 +282,8 @@ distclean: regressclean +@@ -285,6 +287,8 @@ distclean: regressclean rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 @@ -29,7 +29,7 @@ index 6f001bb3..c9424f1e 100644 rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT) (cd openbsd-compat && $(MAKE) distclean) -@@ -442,6 +446,7 @@ regress-prep: +@@ -447,6 +451,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/kex $(MKDIR_P) `pwd`/regress/unittests/match $(MKDIR_P) `pwd`/regress/unittests/utf8 @@ -37,7 +37,7 @@ index 6f001bb3..c9424f1e 100644 $(MKDIR_P) `pwd`/regress/misc/kexfuzz [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile -@@ -565,6 +570,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ +@@ -570,6 +575,16 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) @@ -54,32 +54,19 @@ index 6f001bb3..c9424f1e 100644 MISC_KEX_FUZZ_OBJS=\ regress/misc/kexfuzz/kexfuzz.o -@@ -585,6 +600,7 @@ regress-binaries: regress/modpipe$(EXEEXT) \ +@@ -593,6 +608,7 @@ regress-unit-binaries: regress-prep $(REGRESSLIBS) \ regress/unittests/kex/test_kex$(EXEEXT) \ regress/unittests/match/test_match$(EXEEXT) \ regress/unittests/utf8/test_utf8$(EXEEXT) \ + regress/unittests/pkcs11/test_pkcs11$(EXEEXT) \ regress/misc/kexfuzz/kexfuzz$(EXEEXT) - tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) -diff --git a/authfd.c b/authfd.c -index 95348abf..5383df92 100644 ---- a/authfd.c -+++ b/authfd.c -@@ -312,6 +312,8 @@ ssh_free_identitylist(struct ssh_identitylist *idl) - if (idl->comments != NULL) - free(idl->comments[i]); - } -+ free(idl->keys); -+ free(idl->comments); - free(idl); - } - + tests: file-tests t-exec interop-tests unit diff --git a/configure.ac b/configure.ac -index 30be6c18..82459746 100644 +index 3e93c027..351f0ba5 100644 --- a/configure.ac +++ b/configure.ac -@@ -1854,12 +1854,14 @@ AC_LINK_IFELSE( +@@ -1861,12 +1861,14 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) @@ -94,7 +81,7 @@ index 30be6c18..82459746 100644 fi ] ) -@@ -1875,6 +1877,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then +@@ -1882,6 +1884,40 @@ if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then ) fi @@ -135,7 +122,7 @@ index 30be6c18..82459746 100644 # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ AC_DEFINE([HAVE_GAI_STRERROR]) -@@ -5256,6 +5292,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" +@@ -5229,6 +5265,7 @@ echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" @@ -144,24 +131,20 @@ index 30be6c18..82459746 100644 echo "" diff --git a/regress/Makefile b/regress/Makefile -index 925edf71..94bb25e9 100644 +index 34c47e8c..d693aa4a 100644 --- a/regress/Makefile +++ b/regress/Makefile -@@ -109,9 +109,11 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ +@@ -115,7 +115,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ - pidfile putty.rsa2 ready regress.log \ -- remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \ -+ remote_pid revoked-* rsa rsa-agent rsa-agent.pub \ -+ rsa-agent-cert.pub rsa.pub \ - rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ -- rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ -+ pkcs11*.crt pkcs11*.key \ -+ pkcs11.info rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ + pidfile putty.rsa2 ready regress.log remote_pid \ +- revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \ ++ revoked-* rsa rsa-agent rsa-agent.pub rsa-agent-cert.pub \ ++ rsa.pub rsa_ssh2_cr.prv pkcs11*.crt pkcs11*.key pkcs11.info \ + rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ - ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ -@@ -231,6 +233,7 @@ unit: +@@ -245,6 +246,7 @@ unit: V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ @@ -170,24 +153,10 @@ index 925edf71..94bb25e9 100644 $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ -d ${.CURDIR}/unittests/sshkey/testdata ; \ diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh -index 5205d906..5ca49be5 100644 +index 5205d906..bfbaeb65 100644 --- a/regress/agent-pkcs11.sh +++ b/regress/agent-pkcs11.sh -@@ -29,6 +29,13 @@ fi - - test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" - -+# requires ssh-agent built with correct path to ssh-pkcs11-helper -+# otherwise it fails to start the helper -+strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" -+if [ $? -ne 0 ]; then -+ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" -+fi -+ - # setup environment for softhsm2 token - DIR=$OBJ/SOFTHSM - rm -rf $DIR -@@ -113,7 +120,7 @@ else +@@ -113,7 +113,7 @@ else done trace "remove pkcs11 keys" @@ -198,10 +167,10 @@ index 5205d906..5ca49be5 100644 fail "ssh-add -e failed: exit code $r" diff --git a/regress/pkcs11.sh b/regress/pkcs11.sh new file mode 100644 -index 00000000..19fc8169 +index 00000000..f2d6c41c --- /dev/null +++ b/regress/pkcs11.sh -@@ -0,0 +1,352 @@ +@@ -0,0 +1,345 @@ +# +# Copyright (c) 2017 Red Hat +# @@ -247,13 +216,6 @@ index 00000000..19fc8169 + +test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" + -+# requires ssh-agent built with correct path to ssh-pkcs11-helper -+# otherwise it fails to start the helper -+strings ${TEST_SSH_SSHAGENT} | grep "$TEST_SSH_SSHPKCS11HELPER" -+if [ $? -ne 0 ]; then -+ fatal "Needs to reconfigure with --libexecdir=\`pwd\` or so" -+fi -+ +# setup environment for softhsm token +DIR=$OBJ/SOFTHSM +rm -rf $DIR @@ -555,15 +517,15 @@ index 00000000..19fc8169 + ${SSHAGENT} -k > /dev/null +fi diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile -index e464b085..a0e5a37c 100644 +index 4e56e110..2690ebeb 100644 --- a/regress/unittests/Makefile +++ b/regress/unittests/Makefile @@ -2,6 +2,6 @@ REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion --SUBDIR+=authopt -+SUBDIR+=pkcs11 authopt +-SUBDIR+=authopt misc ++SUBDIR+=authopt misc pkcs11 .include diff --git a/regress/unittests/pkcs11/tests.c b/regress/unittests/pkcs11/tests.c @@ -910,10 +872,10 @@ index 00000000..b637cb13 + test_generate_valid(); +} diff --git a/ssh-add.c b/ssh-add.c -index ac9c808d..f039e00e 100644 +index ebfb8a32..c32d1cb5 100644 --- a/ssh-add.c +++ b/ssh-add.c -@@ -64,6 +64,7 @@ +@@ -66,6 +66,7 @@ #include "misc.h" #include "ssherr.h" #include "digest.h" @@ -921,32 +883,55 @@ index ac9c808d..f039e00e 100644 /* argv0 */ extern char *__progname; -@@ -188,6 +189,24 @@ delete_all(int agent_fd, int qflag) +@@ -190,6 +191,32 @@ delete_all(int agent_fd, int qflag) return ret; } +#ifdef ENABLE_PKCS11 -+static int update_card(int, int, const char *, int); ++static int update_card(int, int, const char *, int, char *); + +int +update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) +{ ++ char *pin = NULL; + struct pkcs11_uri *uri; + + /* dry-run parse to make sure the URI is valid and to report errors */ + uri = pkcs11_uri_init(); + if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) + fatal("Failed to parse PKCS#11 URI"); ++ if (uri->pin != NULL) { ++ pin = strdup(uri->pin); ++ if (pin == NULL) { ++ fatal("Failed to dupplicate string"); ++ } ++ /* pin is freed in the update_card() */ ++ } + pkcs11_uri_cleanup(uri); + -+ return update_card(agent_fd, adding, pkcs11_uri, qflag); ++ return update_card(agent_fd, adding, pkcs11_uri, qflag, pin); +} +#endif + static int add_file(int agent_fd, const char *filename, int key_only, int qflag) { -@@ -529,6 +548,13 @@ lock_agent(int agent_fd, int lock) +@@ -392,12 +419,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag) + } + + static int +-update_card(int agent_fd, int add, const char *id, int qflag) ++update_card(int agent_fd, int add, const char *id, int qflag, char *pin) + { +- char *pin = NULL; + int r, ret = -1; + +- if (add) { ++ if (add && pin == NULL) { + if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", + RP_ALLOW_STDIN)) == NULL) + return -1; +@@ -531,6 +557,13 @@ lock_agent(int agent_fd, int lock) static int do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) { @@ -960,11 +945,20 @@ index ac9c808d..f039e00e 100644 if (deleting) { if (delete_file(agent_fd, file, key_only, qflag) == -1) return -1; +@@ -709,7 +742,7 @@ main(int argc, char **argv) + } + if (pkcs11provider != NULL) { + if (update_card(agent_fd, !deleting, pkcs11provider, +- qflag) == -1) ++ qflag, NULL) == -1) + ret = 1; + goto done; + } diff --git a/ssh-agent.c b/ssh-agent.c -index d06ecfd9..9c1b328f 100644 +index 9c6680a2..e3336073 100644 --- a/ssh-agent.c +++ b/ssh-agent.c -@@ -548,10 +548,72 @@ no_identities(SocketEntry *e) +@@ -556,10 +556,72 @@ no_identities(SocketEntry *e) } #ifdef ENABLE_PKCS11 @@ -1038,7 +1032,7 @@ index d06ecfd9..9c1b328f 100644 int r, i, count = 0, success = 0, confirm = 0; u_int seconds; time_t death = 0; -@@ -587,28 +649,23 @@ process_add_smartcard_key(SocketEntry *e) +@@ -595,28 +657,23 @@ process_add_smartcard_key(SocketEntry *e) goto send; } } @@ -1075,7 +1069,7 @@ index d06ecfd9..9c1b328f 100644 id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&idtab->idlist, id, next); -@@ -622,6 +679,7 @@ process_add_smartcard_key(SocketEntry *e) +@@ -630,6 +687,7 @@ process_add_smartcard_key(SocketEntry *e) send: free(pin); free(provider); @@ -1083,7 +1077,7 @@ index d06ecfd9..9c1b328f 100644 free(keys); send_status(e, success); } -@@ -629,7 +687,7 @@ send: +@@ -637,7 +695,7 @@ send: static void process_remove_smartcard_key(SocketEntry *e) { @@ -1092,7 +1086,7 @@ index d06ecfd9..9c1b328f 100644 int r, success = 0; Identity *id, *nxt; -@@ -640,30 +698,29 @@ process_remove_smartcard_key(SocketEntry *e) +@@ -648,30 +706,29 @@ process_remove_smartcard_key(SocketEntry *e) } free(pin); @@ -1130,10 +1124,10 @@ index d06ecfd9..9c1b328f 100644 } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-keygen.c b/ssh-keygen.c -index 3898b281..91c43b14 100644 +index e039be30..6770fafb 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c -@@ -798,6 +798,7 @@ do_download(struct passwd *pw) +@@ -829,6 +829,7 @@ do_download(struct passwd *pw) free(fp); } else { (void) sshkey_write(keys[i], stdout); /* XXX check */ @@ -1638,7 +1632,7 @@ index 00000000..942a5a5a +char *pkcs11_uri_get(struct pkcs11_uri *uri); + diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c -index 70f06bff..59332945 100644 +index 09f1ea34..fceddfe3 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -54,8 +54,8 @@ struct pkcs11_slotinfo { @@ -1900,11 +1894,11 @@ index 70f06bff..59332945 100644 static void pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, @@ -208,6 +347,7 @@ pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, - if (k11->provider) - pkcs11_provider_unref(k11->provider); - free(k11->keyid); + if (k11->provider) + pkcs11_provider_unref(k11->provider); + free(k11->keyid); + free(k11->label); - free(k11); + free(k11); } @@ -222,8 +362,8 @@ pkcs11_find(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE *attr, @@ -1918,18 +1912,40 @@ index 70f06bff..59332945 100644 if ((rv = f->C_FindObjectsInit(session, attr, nattr)) != CKR_OK) { error("C_FindObjectsInit failed (nattr %lu): %lu", nattr, rv); return (-1); -@@ -252,8 +392,8 @@ pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) +@@ -267,7 +407,7 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + return (-1); /* bail out */ + } + } +- rv = provider->function_list->C_Login(si->session, type, (u_char *)pin, ++ rv = provider->module->function_list->C_Login(si->session, type, (u_char *)pin, + (pin != NULL) ? strlen(pin) : 0); + if (pin != NULL) + freezero(pin, strlen(pin)); +@@ -282,13 +422,14 @@ pkcs11_login_slot(struct pkcs11_provider *provider, struct pkcs11_slotinfo *si, + static int + pkcs11_login(struct pkcs11_key *k11, CK_USER_TYPE type) + { +- if (k11 == NULL || k11->provider == NULL || !k11->provider->valid) { ++ if (k11 == NULL || k11->provider == NULL || !k11->provider->valid || ++ k11->provider->module == NULL || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); return (-1); } -- f = k11->provider->function_list; -- si = &k11->provider->slotinfo[k11->slotidx]; -+ f = k11->provider->module->function_list; -+ si = &k11->provider->module->slotinfo[k11->slotidx]; + return pkcs11_login_slot(k11->provider, +- &k11->provider->slotinfo[k11->slotidx], type); ++ &k11->provider->module->slotinfo[k11->slotidx], type); + } + + +@@ -304,13 +445,14 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, - if (!pkcs11_interactive) { - error("need pin entry%s", -@@ -300,8 +440,8 @@ pkcs11_check_obj_bool_attrib(struct pkcs11_key *k11, CK_OBJECT_HANDLE obj, + *val = 0; + +- if (!k11->provider || !k11->provider->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { + error("no pkcs11 (valid) provider found"); return (-1); } @@ -1940,13 +1956,13 @@ index 70f06bff..59332945 100644 attr.type = type; attr.pValue = &flag; -@@ -332,13 +472,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) +@@ -341,13 +483,14 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) int always_auth = 0; int did_login = 0; - if (!k11->provider || !k11->provider->valid) { -+ if (!k11->provider || !k11->provider->valid || !k11->provider->module -+ || !k11->provider->module->valid) { ++ if (!k11->provider || !k11->provider->valid || ++ !k11->provider->module || !k11->provider->module->valid) { error("no pkcs11 (valid) provider found"); return (-1); } @@ -1958,7 +1974,7 @@ index 70f06bff..59332945 100644 if ((si->token.flags & CKF_LOGIN_REQUIRED) && !si->logged_in) { if (pkcs11_login(k11, CKU_USER) < 0) { -@@ -415,8 +556,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, +@@ -424,8 +567,8 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, return (-1); } @@ -1969,7 +1985,7 @@ index 70f06bff..59332945 100644 tlen = RSA_size(rsa); /* XXX handle CKR_BUFFER_TOO_SMALL */ -@@ -460,7 +601,7 @@ pkcs11_rsa_start_wrapper(void) +@@ -469,7 +612,7 @@ pkcs11_rsa_start_wrapper(void) /* redirect private key operations for rsa key to pkcs11 token */ static int pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -1978,7 +1994,7 @@ index 70f06bff..59332945 100644 { struct pkcs11_key *k11; -@@ -478,6 +619,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -487,6 +630,12 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } @@ -1991,7 +2007,7 @@ index 70f06bff..59332945 100644 RSA_set_method(rsa, rsa_method); RSA_set_ex_data(rsa, rsa_idx, k11); return (0); -@@ -508,8 +655,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, +@@ -517,8 +666,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, return (NULL); } @@ -2002,7 +2018,7 @@ index 70f06bff..59332945 100644 siglen = ECDSA_size(ec); sig = xmalloc(siglen); -@@ -574,7 +721,7 @@ pkcs11_ecdsa_start_wrapper(void) +@@ -583,7 +732,7 @@ pkcs11_ecdsa_start_wrapper(void) static int pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, @@ -2011,7 +2027,7 @@ index 70f06bff..59332945 100644 { struct pkcs11_key *k11; -@@ -590,6 +737,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, +@@ -599,6 +748,12 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); @@ -2024,26 +2040,18 @@ index 70f06bff..59332945 100644 EC_KEY_set_method(ec, ec_key_method); EC_KEY_set_ex_data(ec, ec_key_idx, k11); -@@ -624,47 +777,26 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, - CK_FUNCTION_LIST *f; - CK_RV rv; +@@ -635,8 +790,8 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, CK_SESSION_HANDLE session; -- int login_required, have_pinpad, ret; -- char prompt[1024], *xpin = NULL; -+ int login_required, ret; + int login_required, ret; - f = p->function_list; - si = &p->slotinfo[slotidx]; + f = p->module->function_list; + si = &p->module->slotinfo[slotidx]; -- have_pinpad = si->token.flags & CKF_PROTECTED_AUTHENTICATION_PATH; login_required = si->token.flags & CKF_LOGIN_REQUIRED; - /* fail early before opening session */ -- if (login_required && !have_pinpad && !pkcs11_interactive && -+ if (login_required && !pkcs11_interactive && - (pin == NULL || strlen(pin) == 0)) { +@@ -646,9 +801,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin, error("pin required"); return (-SSH_PKCS11_ERR_PIN_REQUIRED); } @@ -2054,33 +2062,8 @@ index 70f06bff..59332945 100644 + error("C_OpenSession failed for slot %lu: %lu", slotidx, rv); return (-1); } -- if (login_required) { -- if (have_pinpad && (pin == NULL || strlen(pin) == 0)) { -- /* defer PIN entry to the reader keypad */ -- rv = f->C_Login(session, CKU_USER, NULL_PTR, 0); -- } else { -- if (pkcs11_interactive) { -- snprintf(prompt, sizeof(prompt), -- "Enter PIN for '%s': ", si->token.label); -- if ((xpin = read_passphrase(prompt, -- RP_ALLOW_EOF)) == NULL) { -- debug("%s: no pin specified", -- __func__); -- return (-SSH_PKCS11_ERR_PIN_REQUIRED); -- } -- pin = xpin; -- } -- rv = f->C_Login(session, CKU_USER, -- (u_char *)pin, strlen(pin)); -- if (xpin != NULL) -- freezero(xpin, strlen(xpin)); -- } -+ if (login_required && pin != NULL && strlen(pin) != 0) { -+ rv = f->C_Login(session, user, (u_char *)pin, strlen(pin)); - if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { - error("C_Login failed: %lu", rv); - ret = (rv == CKR_PIN_LOCKED) ? -@@ -696,7 +828,8 @@ static struct sshkey * + if (login_required && pin != NULL && strlen(pin) != 0) { +@@ -684,7 +839,8 @@ static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2090,7 +2073,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -710,14 +843,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -698,14 +854,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2111,13 +2094,12 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -730,19 +863,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. +@@ -717,18 +874,19 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ -- if (key_attr[1].ulValueLen == 0 || + if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || ++ key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2135,7 +2117,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -752,8 +887,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -740,8 +898,8 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2146,7 +2128,7 @@ index 70f06bff..59332945 100644 if (group == NULL) { ossl_error("d2i_ECPKParameters failed"); goto fail; -@@ -764,13 +899,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -752,13 +910,13 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2163,7 +2145,7 @@ index 70f06bff..59332945 100644 if (octet == NULL) { ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; -@@ -787,7 +922,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -775,7 +933,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2172,7 +2154,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -803,7 +938,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -791,7 +949,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, ec = NULL; /* now owned by key */ fail: @@ -2181,7 +2163,7 @@ index 70f06bff..59332945 100644 free(key_attr[i].pValue); if (ec) EC_KEY_free(ec); -@@ -820,7 +955,8 @@ static struct sshkey * +@@ -808,7 +966,8 @@ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2191,7 +2173,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -831,14 +967,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -819,14 +978,15 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -2212,13 +2194,12 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -850,19 +987,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, - * ensure that none of the others are zero length. +@@ -838,18 +998,19 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ -- if (key_attr[1].ulValueLen == 0 || + if (key_attr[1].ulValueLen == 0 || - key_attr[2].ulValueLen == 0) { -+ if (key_attr[2].ulValueLen == 0 || ++ key_attr[2].ulValueLen == 0 || + key_attr[3].ulValueLen == 0) { error("invalid attribute length"); return (NULL); @@ -2236,7 +2217,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -873,8 +1011,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -861,8 +1022,8 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2247,7 +2228,7 @@ index 70f06bff..59332945 100644 if (rsa_n == NULL || rsa_e == NULL) { error("BN_bin2bn failed"); goto fail; -@@ -883,7 +1021,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -871,7 +1032,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal("%s: set key", __func__); rsa_n = rsa_e = NULL; /* transferred */ @@ -2256,7 +2237,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -898,7 +1036,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -886,7 +1047,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, rsa = NULL; /* now owned by key */ fail: @@ -2265,7 +2246,7 @@ index 70f06bff..59332945 100644 free(key_attr[i].pValue); RSA_free(rsa); -@@ -909,7 +1047,8 @@ static struct sshkey * +@@ -897,7 +1058,8 @@ static struct sshkey * pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) { @@ -2275,7 +2256,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -926,14 +1065,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -916,14 +1078,15 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, memset(&cert_attr, 0, sizeof(cert_attr)); cert_attr[0].type = CKA_ID; @@ -2296,7 +2277,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); return (NULL); -@@ -945,18 +1085,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -935,18 +1098,19 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, * XXX assumes CKA_ID is always first. */ if (cert_attr[1].ulValueLen == 0 || @@ -2319,7 +2300,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_GetAttributeValue failed: %lu", rv); goto fail; -@@ -968,8 +1109,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -958,8 +1122,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2330,7 +2311,7 @@ index 70f06bff..59332945 100644 error("d2i_x509 failed"); goto fail; } -@@ -990,7 +1131,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -980,7 +1144,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2339,7 +2320,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -1020,7 +1161,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1010,7 +1174,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } @@ -2348,7 +2329,7 @@ index 70f06bff..59332945 100644 goto fail; key = sshkey_new(KEY_UNSPEC); -@@ -1039,7 +1180,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1029,7 +1193,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, error("unknown certificate key type"); fail: @@ -2357,7 +2338,7 @@ index 70f06bff..59332945 100644 free(cert_attr[i].pValue); X509_free(x509); RSA_free(rsa); -@@ -1066,11 +1207,12 @@ have_rsa_key(const RSA *rsa) +@@ -1058,11 +1222,12 @@ have_rsa_key(const RSA *rsa) */ static int pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2372,7 +2353,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1086,10 +1228,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1078,10 +1243,23 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2399,7 +2380,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1163,11 +1318,12 @@ fail: +@@ -1155,11 +1333,12 @@ fail: */ static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -2414,7 +2395,7 @@ index 70f06bff..59332945 100644 CK_SESSION_HANDLE session; CK_FUNCTION_LIST *f = NULL; CK_RV rv; -@@ -1183,10 +1339,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1175,10 +1354,23 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, key_attr[0].pValue = &key_class; key_attr[0].ulValueLen = sizeof(key_class); @@ -2441,7 +2422,7 @@ index 70f06bff..59332945 100644 if (rv != CKR_OK) { error("C_FindObjectsInit failed: %lu", rv); goto fail; -@@ -1443,15 +1612,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, +@@ -1435,15 +1627,10 @@ pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, } #endif /* WITH_PKCS11_KEYGEN */ @@ -2459,7 +2440,7 @@ index 70f06bff..59332945 100644 int ret = -1; struct pkcs11_provider *p = NULL; void *handle = NULL; -@@ -1460,148 +1624,285 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, +@@ -1452,161 +1639,298 @@ pkcs11_register_provider(char *provider_id, char *pin, struct sshkey ***keyp, CK_FUNCTION_LIST *f = NULL; CK_TOKEN_INFO *token; CK_ULONG i; @@ -2547,17 +2528,17 @@ index 70f06bff..59332945 100644 error("C_GetInfo for provider %s failed: %lu", - provider_id, rv); + provider_module, rv); - goto fail; - } -- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); -- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); ++ goto fail; ++ } + rmspace(m->info.manufacturerID, sizeof(m->info.manufacturerID)); + if (uri->lib_manuf != NULL && + strcmp(uri->lib_manuf, m->info.manufacturerID)) { + debug("%s: Skipping provider %s not matching library_manufacturer", + __func__, m->info.manufacturerID); -+ goto fail; -+ } + goto fail; + } +- rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); +- rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); + rmspace(m->info.libraryDescription, sizeof(m->info.libraryDescription)); debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" " libraryDescription <%s> libraryVersion %d.%d", @@ -2583,7 +2564,7 @@ index 70f06bff..59332945 100644 } - if (p->nslots == 0) { + if (m->nslots == 0) { - error("%s: provider %s returned no slots", __func__, + debug("%s: provider %s returned no slots", __func__, - provider_id); + provider_module); ret = -SSH_PKCS11_ERR_NO_SLOTS; @@ -2720,26 +2701,43 @@ index 70f06bff..59332945 100644 + * open session if not yet openend, login with pin and + * retrieve public keys (if keyp is provided) */ -- if ((ret = pkcs11_open_session(p, i, pin, user)) == 0) { -+ if (p->module->slotinfo[i].session != 0 || -+ (ret = pkcs11_open_session(p, i, pin, user)) == 0) { - if (keyp == NULL) +- if ((ret = pkcs11_open_session(p, i, pin, user)) != 0 || ++ if ((p->module->slotinfo[i].session != 0 || ++ (ret = pkcs11_open_session(p, i, pin, user)) != 0) && /* ??? */ + keyp == NULL) + continue; +- pkcs11_fetch_keys(p, i, keyp, &nkeys); +- pkcs11_fetch_certs(p, i, keyp, &nkeys); +- if (nkeys == 0 && !p->slotinfo[i].logged_in && ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ if (nkeys == 0 && !p->module->slotinfo[i].logged_in && + pkcs11_interactive) { + /* + * Some tokens require login before they will + * expose keys. + */ +- if (pkcs11_login_slot(p, &p->slotinfo[i], ++ if (pkcs11_login_slot(p, &p->module->slotinfo[i], + CKU_USER) < 0) { + error("login failed"); continue; + } - pkcs11_fetch_keys(p, i, keyp, &nkeys); - pkcs11_fetch_certs(p, i, keyp, &nkeys); + pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); + pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); -+ if (nkeys == 0 && uri->object != NULL) { -+ debug3("%s: No keys found. Retrying without label (%s) ", -+ __func__, token->label); -+ /* Try once more without the label filter */ -+ char *label = uri->object; -+ uri->object = NULL; /* XXX clone uri? */ -+ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); -+ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); -+ uri->object = label; -+ } } ++ if (nkeys == 0 && uri->object != NULL) { ++ debug3("%s: No keys found. Retrying without label (%s) ", ++ __func__, uri->object); ++ /* Try once more without the label filter */ ++ char *label = uri->object; ++ uri->object = NULL; /* XXX clone uri? */ ++ pkcs11_fetch_keys(p, i, keyp, &nkeys, uri); ++ pkcs11_fetch_certs(p, i, keyp, &nkeys, uri); ++ uri->object = label; ++ } + pin = NULL; /* Will be cleaned up with URI */ } @@ -2816,7 +2814,7 @@ index 70f06bff..59332945 100644 /* no keys found or some other error, de-register provider */ if (nkeys <= 0 && p != NULL) { -@@ -1611,7 +1912,36 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) +@@ -1616,7 +1940,36 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) } if (nkeys == 0) debug("%s: provider %s returned no keys", __func__, @@ -2854,7 +2852,7 @@ index 70f06bff..59332945 100644 return (nkeys); } -@@ -1633,8 +1963,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, +@@ -1638,8 +1991,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, if ((p = pkcs11_provider_lookup(provider_id)) != NULL) debug("%s: provider \"%s\" available", __func__, provider_id); @@ -2864,7 +2862,7 @@ index 70f06bff..59332945 100644 debug("%s: could not register provider %s", __func__, provider_id); goto out; -@@ -1705,8 +2034,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, +@@ -1710,8 +2062,7 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, if ((p = pkcs11_provider_lookup(provider_id)) != NULL) { debug("%s: using provider \"%s\"", __func__, provider_id); @@ -2894,7 +2892,7 @@ index b9038450..5a855338 100644 struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, diff --git a/ssh.c b/ssh.c -index 91e7c351..47f4f299 100644 +index ee51823c..2268755b 100644 --- a/ssh.c +++ b/ssh.c @@ -772,6 +772,14 @@ main(int ac, char **av) @@ -2910,9 +2908,9 @@ index 91e7c351..47f4f299 100644 + } +#endif p = tilde_expand_filename(optarg, getuid()); - if (stat(p, &st) < 0) + if (stat(p, &st) == -1) fprintf(stderr, "Warning: Identity file %s " -@@ -1521,6 +1529,7 @@ main(int ac, char **av) +@@ -1524,6 +1532,7 @@ main(int ac, char **av) free(options.certificate_files[i]); options.certificate_files[i] = NULL; } @@ -2920,7 +2918,7 @@ index 91e7c351..47f4f299 100644 skip_connect: exit_status = ssh_session2(ssh, pw); -@@ -1994,6 +2003,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) +@@ -1997,6 +2006,45 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) options.escape_char : SSH_ESCAPECHAR_NONE, id); } @@ -2966,7 +2964,7 @@ index 91e7c351..47f4f299 100644 /* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(struct passwd *pw) -@@ -2008,10 +2056,6 @@ load_public_identity_files(struct passwd *pw) +@@ -2011,10 +2059,6 @@ load_public_identity_files(struct passwd *pw) char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; @@ -2977,7 +2975,7 @@ index 91e7c351..47f4f299 100644 n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); -@@ -2024,32 +2068,46 @@ load_public_identity_files(struct passwd *pw) +@@ -2027,32 +2071,46 @@ load_public_identity_files(struct passwd *pw) sizeof(certificate_file_userprovided)); #ifdef ENABLE_PKCS11 @@ -3043,10 +3041,10 @@ index 91e7c351..47f4f299 100644 "u", pw->pw_name, "l", thishost, "h", host, "r", options.user, (char *)NULL); diff --git a/ssh_config.5 b/ssh_config.5 -index 41262963..a211034e 100644 +index 02a87892..41acfa33 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -952,6 +952,21 @@ may also be used in conjunction with +@@ -964,6 +964,21 @@ may also be used in conjunction with .Cm CertificateFile in order to provide any certificate also needed for authentication with the identity. @@ -3068,69 +3066,3 @@ index 41262963..a211034e 100644 .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. - -commit 1efe98998408593861fdcd4da392dd10820f0fde -Author: Jakub Jelen -Date: Wed Jun 12 14:30:30 2019 +0200 - - Allow to specify the pin also for the ssh-add - -diff --git a/ssh-add.c b/ssh-add.c -index f039e00e..adc4e5c9 100644 ---- a/ssh-add.c -+++ b/ssh-add.c -@@ -190,20 +190,28 @@ delete_all(int agent_fd, int qflag) - } - - #ifdef ENABLE_PKCS11 --static int update_card(int, int, const char *, int); -+static int update_card(int, int, const char *, int, char *); - - int - update_pkcs11_uri(int agent_fd, int adding, const char *pkcs11_uri, int qflag) - { -+ char *pin = NULL; - struct pkcs11_uri *uri; - - /* dry-run parse to make sure the URI is valid and to report errors */ - uri = pkcs11_uri_init(); - if (pkcs11_uri_parse((char *) pkcs11_uri, uri) != 0) - fatal("Failed to parse PKCS#11 URI"); -+ if (uri->pin != NULL) { -+ pin = strdup(uri->pin); -+ if (pin == NULL) { -+ fatal("Failed to dupplicate string"); -+ } -+ /* pin is freed in the update_card() */ -+ } - pkcs11_uri_cleanup(uri); - -- return update_card(agent_fd, adding, pkcs11_uri, qflag); -+ return update_card(agent_fd, adding, pkcs11_uri, qflag, pin); - } - #endif - -@@ -409,12 +417,11 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag) - } - - static int --update_card(int agent_fd, int add, const char *id, int qflag) -+update_card(int agent_fd, int add, const char *id, int qflag, char *pin) - { -- char *pin = NULL; - int r, ret = -1; - -- if (add) { -+ if (add && pin == NULL) { - if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", - RP_ALLOW_STDIN)) == NULL) - return -1; -@@ -734,7 +741,7 @@ main(int argc, char **argv) - } - if (pkcs11provider != NULL) { - if (update_card(agent_fd, !deleting, pkcs11provider, -- qflag) == -1) -+ qflag, NULL) == -1) - ret = 1; - goto done; - } diff --git a/openssh-8.0p1-scp-tests.patch b/openssh-8.0p1-scp-tests.patch deleted file mode 100644 index e0a63c4..0000000 --- a/openssh-8.0p1-scp-tests.patch +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh -index 59f1ff63..dd48a482 100644 ---- a/regress/scp-ssh-wrapper.sh -+++ b/regress/scp-ssh-wrapper.sh -@@ -51,6 +51,18 @@ badserver_4) - echo "C755 2 file" - echo "X" - ;; -+badserver_5) -+ echo "D0555 0 " -+ echo "X" -+ ;; -+badserver_6) -+ echo "D0555 0 ." -+ echo "X" -+ ;; -+badserver_7) -+ echo "C0755 2 extrafile" -+ echo "X" -+ ;; - *) - set -- $arg - shift -diff --git a/regress/scp.sh b/regress/scp.sh -index 57cc7706..104c89e1 100644 ---- a/regress/scp.sh -+++ b/regress/scp.sh -@@ -25,6 +25,7 @@ export SCP # used in scp-ssh-wrapper.scp - scpclean() { - rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} - mkdir ${DIR} ${DIR2} -+ chmod 755 ${DIR} ${DIR2} - } - - verbose "$tid: simple copy local file to local file" -@@ -101,7 +102,7 @@ if [ ! -z "$SUDO" ]; then - $SUDO rm ${DIR2}/copy - fi - --for i in 0 1 2 3 4; do -+for i in 0 1 2 3 4 5 6 7; do - verbose "$tid: disallow bad server #$i" - SCPTESTMODE=badserver_$i - export DIR SCPTESTMODE -@@ -113,6 +114,15 @@ for i in 0 1 2 3 4; do - scpclean - $SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null - [ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" -+ -+ scpclean -+ $SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null -+ [ ! -w ${DIR2} ] && fail "allows target root attribute change" -+ -+ scpclean -+ $SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null -+ [ -e ${DIR2}/extrafile ] && fail "allows extranous object creation" -+ rm -f ${DIR2}/extrafile - done - - verbose "$tid: detect non-directory target" - diff --git a/openssh.spec b/openssh.spec index f705c45..8f10cc3 100644 --- a/openssh.spec +++ b/openssh.spec @@ -65,15 +65,15 @@ %endif # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 -%global openssh_ver 8.0p1 -%global openssh_rel 8 +%global openssh_ver 8.1p1 +%global openssh_rel 1 %global pam_ssh_agent_ver 0.10.3 -%global pam_ssh_agent_rel 7 +%global pam_ssh_agent_rel 8 Summary: An open source implementation of SSH protocol version 2 Name: openssh Version: %{openssh_ver} -Release: %{openssh_rel}%{?dist}%{?rescue_rel}.1 +Release: %{openssh_rel}%{?dist}%{?rescue_rel} URL: http://www.openssh.com/portable.html #URL1: http://pamsshagentauth.sourceforge.net Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz @@ -196,6 +196,7 @@ Patch949: openssh-7.6p1-cleanup-selinux.patch # Sandbox adjustments for s390 and audit Patch950: openssh-7.5p1-sandbox.patch # PKCS#11 URIs (upstream #2817, 2nd iteration) +# git diff upstream/master > ~/devel/fedora/openssh/openssh-8.0p1-pkcs11-uri.patch Patch951: openssh-8.0p1-pkcs11-uri.patch # Unbreak scp between two IPv6 hosts (#1620333) Patch953: openssh-7.8p1-scp-ipv6.patch @@ -203,19 +204,12 @@ Patch953: openssh-7.8p1-scp-ipv6.patch # - do not return 0 if the write fails (full disk) # - shellcheck reports (upstream #2902) Patch958: openssh-7.9p1-ssh-copy-id.patch -# Verify the SCP vulnerabilities are fixed in the package testsuite -# https://bugzilla.mindrot.org/show_bug.cgi?id=3007 -Patch961: openssh-8.0p1-scp-tests.patch # Mention crypto-policies in manual pages (#1668325) Patch962: openssh-8.0p1-crypto-policies.patch # Use OpenSSL high-level API to produce and verify signatures (#1707485) Patch963: openssh-8.0p1-openssl-evp.patch # Use OpenSSL KDF (#1631761) Patch964: openssh-8.0p1-openssl-kdf.patch -# Use new OpenSSL for PEM export to avoid MD5 dependency (#1712436) -Patch965: openssh-8.0p1-openssl-pem.patch -# Properly encode SHA2 certificate types in ssh-agent -Patch966: openssh-8.0p1-agent-certs-sha2.patch License: BSD Requires: /sbin/nologin @@ -413,12 +407,9 @@ popd %patch951 -p1 -b .pkcs11-uri %patch953 -p1 -b .scp-ipv6 %patch958 -p1 -b .ssh-copy-id -%patch961 -p1 -b .scp-tests %patch962 -p1 -b .crypto-policies %patch963 -p1 -b .openssl-evp %patch964 -p1 -b .openssl-kdf -%patch965 -p1 -b .openssl-pem -%patch966 -p1 -b .agent-cert-sha2 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -721,6 +712,9 @@ getent passwd sshd >/dev/null || \ %endif %changelog +* Wed Oct 09 2019 Jakub Jelen - 8.1p1-1 + 0.10.3-8 +- New upstream release (#1759750) + * Thu Jul 25 2019 Fedora Release Engineering - 8.0p1-8.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild diff --git a/sources b/sources index 849fc69..7575af1 100644 --- a/sources +++ b/sources @@ -1,4 +1,4 @@ -SHA512 (openssh-8.0p1.tar.gz) = e280fa2d56f550efd37c5d2477670326261aa8b94d991f9eb17aad90e0c6c9c939efa90fe87d33260d0f709485cb05c379f0fd1bd44fc0d5190298b6398c9982 -SHA512 (openssh-8.0p1.tar.gz.asc) = fe9e7383d9467e869762864f2b719165d9a3f2c5316c07067df1d45fc7819bd2cb8ef758454865595688804a4c160dd3d3aaee4c5f887859555d2c7bb8c4592b +SHA512 (openssh-8.1p1.tar.gz) = b987ea4ffd4ab0c94110723860273b06ed8ffb4d21cbd99ca144a4722dc55f4bf86f6253d500386b6bee7af50f066e2aa2dd095d50746509a10e11221d39d925 +SHA512 (openssh-8.1p1.tar.gz.asc) = f36458ef8822376a5b305cfbc971f5d2db8bf2f48fea9a957e02ef2fc27a48bacb59495587fee81fa2d89bca6250a8fb407e1f5a7dae7ceb361ab332c0771344 SHA512 (DJM-GPG-KEY.gpg) = db1191ed9b6495999e05eed2ef863fb5179bdb63e94850f192dad68eed8579836f88fbcfffd9f28524fe1457aff8cd248ee3e0afc112c8f609b99a34b80ecc0d SHA512 (pam_ssh_agent_auth-0.10.3.tar.bz2) = d75062c4e46b0b011f46aed9704a99049995fea8b5115ff7ee26dad7e93cbcf54a8af7efc6b521109d77dc03c6f5284574d2e1b84c6829cec25610f24fb4bd66