From c11c7e3bbdd9db5c21c347c5a861e556ab742675 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 30 Sep 2022 23:56:59 -0600 Subject: [PATCH 1/4] rename user cert and add renew script --- keys/ca-cert-ecc.der | Bin 664 -> 810 bytes keys/ca-cert-ecc.pem | 52 +++++++++++++------------ keys/fred-cert.der | Bin 0 -> 805 bytes keys/fred-cert.pem | 55 +++++++++++++++++++++++++++ keys/{john-key.der => fred-key.der} | Bin keys/{john-key.pem => fred-key.pem} | 0 keys/john-cert.der | Bin 591 -> 0 bytes keys/john-cert.pem | 15 -------- keys/renewcerts.cnf | 57 ++++++++++++++++++++++++++++ keys/renewcerts.sh | 19 ++++++++++ keys/server-cert.der | Bin 676 -> 798 bytes keys/server-cert.pem | 56 +++++++++++++-------------- 12 files changed, 186 insertions(+), 68 deletions(-) create mode 100644 keys/fred-cert.der create mode 100644 keys/fred-cert.pem rename keys/{john-key.der => fred-key.der} (100%) rename keys/{john-key.pem => fred-key.pem} (100%) delete mode 100644 keys/john-cert.der delete mode 100644 keys/john-cert.pem create mode 100644 keys/renewcerts.cnf create mode 100755 keys/renewcerts.sh diff --git a/keys/ca-cert-ecc.der b/keys/ca-cert-ecc.der index e3c0c8e79e2a48cc6c465aec3de9ac102a7b62c8..e79d644cfe01fdfb2a37a54077ab0285a6bc57b6 100644 GIT binary patch delta 338 zcmbQix{6KSpov+{po!_s0%j&gCMHHU11>fWtu~Kywk*s{28~lEzA1N~syy`#JgitHYm{DjGB%0?8}0 zH10BJ+}?my&BDgnOB!cDY*oZFc4-U(e38 znA=+0oqpnLpjTAKHv2@2?D>LBiVPp8a+qkl8%^#J@b>lA*7lv3k&{tOATuv5-=RD|C#|?RM=v=)*Fa93*T~4g$k5c# z$kf2dBnrqiF$4h!7h;SIK4T_lFeWf38zfFX�gv&&C`otIQ%{Al4uf);H_$2d8@y zJ6%Kbeoj9B>hR~Kijy}p>3O&_7`QMgRJ`?(S+2X;lv~zqvAH347pvt74Z{f2k2Ah| t7aj0_R?nos^odj3>Y>@B{SjHrLb{dD_OiJq?&Pz4IOoF(J#M+4O#lZ4TxJD>0NX5Ce%a^YE9Km+OJl78mE}CFkcF${I+saRQyu_MMlJlTnN>Ing1t zA~ClhClw@ZAScdiWMpVyU}#`!YGPs%CC+PXWMFAz0p%JrcA&Z&>In`Wrf^4?>yX?F zbsZNEH`Kifo_WbQ+{|mh4RJGzTTyC?p}c`CvO@*ZfPyGajWiHuV+RK)6C*TanHkxc zofuez?ucC!Z(PRofnRXKZll&TzA}cSHLD))RFlzqr19hKjY|6iOmP=49{p#N{8fIP zuy^LE7jM6q?MiyE@Pvebcj&{#O^kvDO^m!i7chs)^0A1qh|F2foc8qt%O9owJ_R)g zcgAzqs(K9?4}s*BSsHg4G;VJY3G176_=D3uiJh*Yc|Rwge|7ltQpJUhvzIi^7_8CV z#K>l#4)TK_i-LjN0vR?gZ8k<0#wK$SCgufvJUqx@j+}g%Js1pJnG_lBP2Fu3a=0^=Y{|P literal 0 HcmV?d00001 diff --git a/keys/fred-cert.pem b/keys/fred-cert.pem new file mode 100644 index 00000000..21998f9c --- /dev/null +++ b/keys/fred-cert.pem @@ -0,0 +1,55 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 7 (0x7) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = ca@example.com + Validity + Not Before: Oct 1 05:54:44 2022 GMT + Not After : Sep 28 05:54:44 2032 GMT + Subject: C = US, ST = WA, L = Seattle, O = wolfSSL Inc, OU = Development, CN = Fred, emailAddress = fred@example.com + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:12:dc:16:d1:17:81:a6:02:f0:0f:11:90:bb:32: + 85:66:0e:76:00:62:ac:aa:e3:b9:26:1c:2a:e2:28: + f8:dd:d8:79:3f:c0:02:5e:d1:d1:c5:fe:3c:63:f5: + 1f:ae:13:4b:69:ca:e8:ed:f4:36:ba:62:e0:a1:c8: + 18:10:4b:55:e1 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Subject Key Identifier: + 9C:AF:03:66:F5:F0:04:FC:22:8F:8E:20:26:40:47:01:CE:D6:7A:8D + X509v3 Authority Key Identifier: + keyid:56:8E:9A:C3:F0:42:DE:18:B9:45:55:6E:F9:93:CF:EA:C3:F3:A5:21 + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=ca@example.com + serial:06 + + X509v3 Subject Alternative Name: + othername: + Signature Algorithm: ecdsa-with-SHA256 + 30:45:02:21:00:de:95:bb:3a:54:c3:81:6e:f2:89:da:2f:99: + 37:e7:40:13:be:40:5c:93:84:0f:36:2e:80:d6:8a:f5:e3:6a: + 0c:02:20:55:6b:3a:c8:ed:ce:d1:29:15:b5:32:21:3c:a5:0e: + bc:84:08:db:a3:ef:c1:c5:c3:79:1f:07:c9:c0:bb:b0:f5 +-----BEGIN CERTIFICATE----- +MIIDITCCAsegAwIBAgIBBzAKBggqhkjOPQQDAjCBlTELMAkGA1UEBhMCVVMxEzAR +BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv +bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz +bC5jb20xHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tMB4XDTIyMTAwMTA1 +NTQ0NFoXDTMyMDkyODA1NTQ0NFowgYgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJX +QTEQMA4GA1UEBwwHU2VhdHRsZTEUMBIGA1UECgwLd29sZlNTTCBJbmMxFDASBgNV +BAsMC0RldmVsb3BtZW50MQ0wCwYDVQQDDARGcmVkMR8wHQYJKoZIhvcNAQkBFhBm +cmVkQGV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEtwW0ReB +pgLwDxGQuzKFZg52AGKsquO5Jhwq4ij43dh5P8ACXtHRxf48Y/UfrhNLacro7fQ2 +umLgocgYEEtV4aOCAREwggENMB0GA1UdDgQWBBScrwNm9fAE/CKPjiAmQEcBztZ6 +jTCBwgYDVR0jBIG6MIG3gBRWjprD8ELeGLlFVW75k8/qw/OlIaGBm6SBmDCBlTEL +MAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0 +bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYD +VQQDDA93d3cud29sZnNzbC5jb20xHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUu +Y29tggEGMCcGA1UdEQQgMB6gHAYKKwYBBAGCNxQCA6AODAxmcmVkQGV4YW1wbGUw +CgYIKoZIzj0EAwIDSAAwRQIhAN6VuzpUw4Fu8onaL5k350ATvkBck4QPNi6A1or1 +42oMAiBVazrI7c7RKRW1MiE8pQ68hAjbo+/BxcN5HwfJwLuw9Q== +-----END CERTIFICATE----- diff --git a/keys/john-key.der b/keys/fred-key.der similarity index 100% rename from keys/john-key.der rename to keys/fred-key.der diff --git a/keys/john-key.pem b/keys/fred-key.pem similarity index 100% rename from keys/john-key.pem rename to keys/fred-key.pem diff --git a/keys/john-cert.der b/keys/john-cert.der deleted file mode 100644 index a5fc4944ba8988de64d8fd960edf427b84509fb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 591 zcmXqLV)8a`w>d&#P>j_DtM>i;Y98&EuRc3p0~J<8(uA z15P&PP!={}rqEzRVFN)Bhl7VJJh3<JD>0NX5Ce%a^YE9Km+OJl78mE}CFkcF${WbC zaRQyu_MMlJlTl0{GcPUQ0ZD;@k_5kzfe{Fq85tQG85>7|1&j^M4UM1z28|O@T@UpN z2M<%YBg~CRu78qmy)?95IKEJAn0E{ZoUWBR}^IAOO@YZ_k}L(-a6k9VrcXg$*SarZ{0 z{Q;)9ix-dnvq}CczfRaY^VEyCU(9wTJy>``Lclxp;bLHz8At^=YJY d8cY{iYJBHG-ciN&`+<#h{s9i{iUxjX3IPE!tM&i@ diff --git a/keys/john-cert.pem b/keys/john-cert.pem deleted file mode 100644 index 31a286c6..00000000 --- a/keys/john-cert.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICSzCCAfGgAwIBAgIQUg79CEuTa/LBX88kspbmFzAKBggqhkjOPQQDAjCBlzEL -MAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0 -bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYD -VQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNz -bC5jb20wIhgPMjAyMjAyMjYyMjEyMzNaGA8yMDIzMDcxMjIyMTIzM1owgZExCzAJ -BgNVBAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEUMBIGA1UE -CgwLd29sZlNTTCBJbmMxFDASBgNVBAsMC0RldmVsb3BtZW50MRYwFAYDVQQDDA1K -b2huIFNhZnJhbmVrMR8wHQYJKoZIhvcNAQkBFhBqb2huQHdvbGZzc2wuY29tMFkw -EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEtwW0ReBpgLwDxGQuzKFZg52AGKsquO5 -Jhwq4ij43dh5P8ACXtHRxf48Y/UfrhNLacro7fQ2umLgocgYEEtV4aMfMB0wGwYD -VR0RBBQwEoEQam9obkB3b2xmc3NsLmNvbTAKBggqhkjOPQQDAgNIADBFAiEAtsaS -gxyAAWzJ+nSku+VnVz821mL5tnw2rxTUKnWYg10CIE8/UF6OKGcJMJcUpTPc4G7F -IYffUYF+T1BAhyEwTsxx ------END CERTIFICATE----- diff --git a/keys/renewcerts.cnf b/keys/renewcerts.cnf new file mode 100644 index 00000000..e6746888 --- /dev/null +++ b/keys/renewcerts.cnf @@ -0,0 +1,57 @@ +HOME = . +RANDFILE = $ENV::HOME/.rnd + +[ ca ] +default_ca = CA_default # The default ca section + +[ CA_default ] +dir = $HOME +database = $dir/index.txt # database index file. +certs = $dir/ +new_certs_dir = $dir/ +certificate = $dir/ca-cert-ecc.pem +serial = $dir/serial +default_md = default +policy = policy_match +email_in_dn = no +RANDFILE = $dir/.rand + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = supplied +organizationName = supplied +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +x509_extensions = v3_ca # The extensions to add to the self signed cert +distinguished_name = req_distinguished_name +prompt = no + +# Extensions for a typical CA +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints = critical,CA:true +keyUsage = critical, digitalSignature, keyCertSign, cRLSign + +# Extensions for fred cert +[ v3_fred ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +subjectAltName = @fred_altnames + +[ fred_altnames ] +otherName = msUPN;UTF8:fred@example + +# Extensions for server cert +[ v3_server ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +subjectAltName = DNS:example, IP:127.0.0.1 + + +[ req_distinguished_name ] + diff --git a/keys/renewcerts.sh b/keys/renewcerts.sh new file mode 100755 index 00000000..2aadb714 --- /dev/null +++ b/keys/renewcerts.sh @@ -0,0 +1,19 @@ +touch index.txt + +# renew CA +openssl req -subj '/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com/emailAddress=ca@example.com' -key ca-key-ecc.pem -text -out ca-cert-ecc.pem -config renewcerts.cnf -new -nodes -x509 -extensions v3_ca -days 3650 -set_serial 6 +openssl x509 -in ca-cert-ecc.pem -outform DER -out ca-cert-ecc.der + +# renew fred-cert +openssl req -subj '/C=US/ST=WA/L=Seattle/O=wolfSSL Inc/OU=Development/CN=Fred/emailAddress=fred@example.com' -key fred-key.pem -out fred-cert.csr -config renewcerts.cnf -new -nodes + +openssl x509 -req -in fred-cert.csr -days 3650 -extfile renewcerts.cnf -extensions v3_fred -CA ca-cert-ecc.pem -CAkey ca-key-ecc.pem -text -out fred-cert.pem -set_serial 7 +openssl x509 -in fred-cert.pem -outform DER -out fred-cert.der + +# renew server-cert +openssl req -subj '/C=US/ST=Washington/L=Seattle/O=Eliptic/OU=ECC/CN=www.wolfssl.com/emailAddress=server@example.com' -key server-key.pem -out server-cert.csr -config renewcerts.cnf -new -nodes + +openssl x509 -req -in server-cert.csr -days 3650 -extfile renewcerts.cnf -extensions v3_server -CA ca-cert-ecc.pem -CAkey ca-key-ecc.pem -text -out server-cert.pem -set_serial 8 +openssl x509 -in server-cert.pem -outform DER -out server-cert.der + +rm index.* diff --git a/keys/server-cert.der b/keys/server-cert.der index fcecf41af7e84d7aab360f626df2d1370cf75eb5..16fee2e94a0f5a551a5fb3870f220477b2032d4d 100644 GIT binary patch delta 353 zcmZ3&I*(1>pov+^po!_g0%j&gCMHG>11>fWtu~Kywk*s{28~lE%9lIJ8c4Ho0>#?C z^D=TWit!~UI;2)4<`(3n>Lusr8pw(B8W|ZH7#JFunwprHM2Yhn8yQ#{SwOi4jT0xz z+fSBYG>}s?kViI1s5rH#EVT$`*yI$(1hytdMuWzGlTR`#=rkT;V-A&7W@+4I(73%p zB&=`N;SWytBzC%n=KY*}{?*~nOBEM3&R)_u1LDkj{LXA*WHXQe87RmiXu#jZ4)sAh zOFaVvBeJKNJs1pJnG~FEESUOym0$ATfV}LVGbZe_bqUUpPP?nLSg5>UO4#itCPjvG m5}O1z>1yq)yi%5OUqfi3a_?lNm)@`HJ^fy%o;%UD>o)-UmvjIC delta 346 zcmbQowuDvQpowV#5W6p6W@2PwVq`YpV&l+i^EhYA!pvmQIDMjgxwE{1EE^|KtnE85 zBPXMnKxSTAzC(F_PFitsj$U$pu7R95uaTjlk&%Isv4OdfX%vuaVqj@#3gsF!_D__z zpDe~`AcN1S$tjEptc{%pjct=pF)Gx{voVLtDziu!h&70W_02l`!RemFPS?=9pOeqO zI{bO5q5%&`fiNTEe- Date: Sat, 1 Oct 2022 00:00:28 -0600 Subject: [PATCH 2/4] check on user name in UPN if exists add check on host IP address in certificate alt names --- apps/wolfsshd/auth.c | 88 +++++++++++++++++++++------- examples/client/client.c | 121 +++++++++++++++++++++++++++++++++++---- keys/include.am | 5 +- 3 files changed, 182 insertions(+), 32 deletions(-) diff --git a/apps/wolfsshd/auth.c b/apps/wolfsshd/auth.c index 188c8ea0..f66ed997 100644 --- a/apps/wolfsshd/auth.c +++ b/apps/wolfsshd/auth.c @@ -39,6 +39,10 @@ #include #include +#ifdef WOLFSSL_FPKI +#include +#endif + #ifdef NO_INLINE #include #else @@ -740,29 +744,73 @@ static int RequestAuthentication(WS_UserAuthData* authData, if (ret == WOLFSSH_USERAUTH_SUCCESS && authData->type == WOLFSSH_USERAUTH_PUBLICKEY) { - /* if this is a certificate and no specific authorized keys file has - * been set then rely on CA to have verified the cert */ - if (authData->sf.publicKey.isCert && - !wolfSSHD_ConfigGetAuthKeysFileSet(authCtx->conf)) { - wolfSSH_Log(WS_LOG_INFO, - "[SSHD] Relying on CA for public key check"); - ret = WOLFSSH_USERAUTH_SUCCESS; - } - else { - /* if not a certificate then parse through authorized key file */ - rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey, - wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf)); - if (rc == WSSHD_AUTH_SUCCESS) { - wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok."); - ret = WOLFSSH_USERAUTH_SUCCESS; - } - else if (rc == WSSHD_AUTH_FAILURE) { - wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key not authorized."); + #ifdef WOLFSSL_FPKI + /* compare user name to UPN in certificate */ + if (authData->sf.publicKey.isCert) { + DecodedCert dCert; + + wc_InitDecodedCert(&dCert, authData->sf.publicKey.publicKey, + authData->sf.publicKey.publicKeySz, NULL); + if (wc_ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL) != 0) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to parse peer cert."); ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY; } else { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error checking public key."); - ret = WOLFSSH_USERAUTH_FAILURE; + int usrMatch = 0; + DNS_entry* current = dCert.altNames; + + while (current != NULL) { + if (current->type == ASN_OTHER_TYPE && + current->oidSum == UPN_OID) { + /* found UPN oid, check name against user */ + int idx; + + for (idx = 0; idx < current->len; idx++) { + if (current->name[idx] == '@') break; + } + + if ((int)XSTRLEN(usr) == idx && + XSTRNCMP(usr, current->name, idx) == 0) { + usrMatch = 1; + } + } + current = current->next; + } + + if (usrMatch == 0) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] incorrect user cert sent"); + ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY; + } + } + FreeDecodedCert(&dCert); + } + #endif + + if (ret == WOLFSSH_USERAUTH_SUCCESS) { + /* if this is a certificate and no specific authorized keys file has + * been set then rely on CA to have verified the cert */ + if (authData->sf.publicKey.isCert && + !wolfSSHD_ConfigGetAuthKeysFileSet(authCtx->conf)) { + wolfSSH_Log(WS_LOG_INFO, + "[SSHD] Relying on CA for public key check"); + ret = WOLFSSH_USERAUTH_SUCCESS; + } + else { + /* if not a certificate then parse through authorized key file */ + rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey, + wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf)); + if (rc == WSSHD_AUTH_SUCCESS) { + wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok."); + ret = WOLFSSH_USERAUTH_SUCCESS; + } + else if (rc == WSSHD_AUTH_FAILURE) { + wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key not authorized."); + ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY; + } + else { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error checking public key."); + ret = WOLFSSH_USERAUTH_FAILURE; + } } } } diff --git a/examples/client/client.c b/examples/client/client.c index af4c8894..1239d806 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -60,6 +60,10 @@ #include #endif +#ifdef WOLFSSH_CERTS + #include +#endif + #ifndef NO_WOLFSSH_CLIENT @@ -471,8 +475,71 @@ static int wsUserAuth(byte authType, } +#if defined(WOLFSSH_AGENT) || defined(WOLFSSH_CERTS) +static inline void ato32(const byte* c, word32* u32) +{ + *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; +} +#endif + + +#ifdef WOLFSSH_CERTS +static int ParseRFC6187(const byte* in, word32 inSz, byte** leafOut, + word32* leafOutSz) +{ + int ret = WS_SUCCESS; + word32 l = 0, m = 0; + + if (inSz < sizeof(word32)) { + printf("inSz %d too small for holding cert name\n", inSz); + return WS_BUFFER_E; + } + + /* Skip the name */ + ato32(in, &l); + m += l + sizeof(word32); + + /* Get the cert count */ + if (ret == WS_SUCCESS) { + word32 count; + + if (inSz - m < sizeof(word32)) + return WS_BUFFER_E; + + ato32(in + m, &count); + m += sizeof(word32); + if (ret == WS_SUCCESS && count == 0) + ret = WS_FATAL_ERROR; /* need at least one cert */ + } + + if (ret == WS_SUCCESS) { + word32 certSz = 0; + + if (inSz - m < sizeof(word32)) + return WS_BUFFER_E; + + ato32(in + m, &certSz); + m += sizeof(word32); + if (ret == WS_SUCCESS) { + /* store leaf cert size to present to user callback */ + *leafOutSz = certSz; + *leafOut = (byte*)in + m; + } + + if (inSz - m < certSz) + return WS_BUFFER_E; + + } + + return ret; +} +#endif /* WOLFSSH_CERTS */ + + static int wsPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx) { + int ret = 0; + #ifdef DEBUG_WOLFSSH printf("Sample public key check callback\n" " public key = %p\n" @@ -483,7 +550,49 @@ static int wsPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx) (void)pubKeySz; (void)ctx; #endif - return 0; + +#ifdef WOLFSSH_CERTS +#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME) + /* try to parse the certificate and check it's IP address */ + if (pubKeySz > 0) { + DecodedCert dCert; + byte* der = NULL; + word32 derSz = 0; + + if (ParseRFC6187(pubKey, pubKeySz, &der, &derSz) == WS_SUCCESS) { + wc_InitDecodedCert(&dCert, der, derSz, NULL); + if (wc_ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL) != 0) { + printf("public key not a cert\n"); + } + else { + int ipMatch = 0; + DNS_entry* current = dCert.altNames; + + while (current != NULL) { + if (current->type == ASN_IP_TYPE) { + printf("host cert alt. name IP : %s\n", + current->ipString); + printf("\texpecting host IP : %s\n", (char*)ctx); + if (XSTRCMP(ctx, current->ipString) == 0) { + printf("\tmatched!\n"); + ipMatch = 1; + } + } + current = current->next; + } + + if (ipMatch == 0) { + printf("IP did not match expected IP\n"); + ret = -1; + } + } + FreeDecodedCert(&dCert); + } + } +#endif +#endif + + return ret; } @@ -581,14 +690,6 @@ static THREAD_RET readInput(void* in) } -#ifdef WOLFSSH_AGENT -static inline void ato32(const byte* c, word32* u32) -{ - *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; -} -#endif - - static THREAD_RET readPeer(void* in) { byte buf[80]; @@ -1161,7 +1262,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args) #endif /* WOLFSSH_CERTS */ wolfSSH_CTX_SetPublicKeyCheck(ctx, wsPublicKeyCheck); - wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)"You've been sampled!"); + wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)host); ret = wolfSSH_SetUsername(ssh, username); if (ret != WS_SUCCESS) diff --git a/keys/include.am b/keys/include.am index bb5c2030..5f314bb0 100644 --- a/keys/include.am +++ b/keys/include.am @@ -20,6 +20,7 @@ EXTRA_DIST+= \ keys/pubkeys-rsa.txt keys/passwd.txt keys/ca-cert-ecc.der \ keys/ca-cert-ecc.pem keys/ca-key-ecc.der keys/ca-key-ecc.pem \ keys/server-cert.der keys/server-cert.pem \ - keys/john-cert.der keys/john-cert.pem \ - keys/server-key.pem keys/john-key.der keys/john-key.pem + keys/fred-cert.der keys/fred-cert.pem \ + keys/server-key.pem keys/fred-key.der keys/fred-key.pem \ + keys/renewcerts.sh keys/renewcerts.cnf From 0f9304d70d541a1484f486ca84ee72a4cf5425ff Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 19 Oct 2022 12:52:59 -0700 Subject: [PATCH 3/4] update client macro guard and add small stack dcert --- apps/wolfsshd/auth.c | 80 +++++++++++++++++++++++++--------------- examples/client/client.c | 3 +- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/apps/wolfsshd/auth.c b/apps/wolfsshd/auth.c index f66ed997..25da452a 100644 --- a/apps/wolfsshd/auth.c +++ b/apps/wolfsshd/auth.c @@ -747,42 +747,64 @@ static int RequestAuthentication(WS_UserAuthData* authData, #ifdef WOLFSSL_FPKI /* compare user name to UPN in certificate */ if (authData->sf.publicKey.isCert) { - DecodedCert dCert; + DecodedCert* dCert; + #ifdef WOLFSSH_SMALL_STACK + dCert = (DecodedCert*)WMALLOC(sizeof(DecodedCert), NULL, + DYNTYPE_CERT); + #else + DecodedCert sdCert; + dCert = &sdCert; + #endif - wc_InitDecodedCert(&dCert, authData->sf.publicKey.publicKey, - authData->sf.publicKey.publicKeySz, NULL); - if (wc_ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL) != 0) { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to parse peer cert."); + if (dCert == NULL) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error creating cert struct"); ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY; } else { - int usrMatch = 0; - DNS_entry* current = dCert.altNames; - - while (current != NULL) { - if (current->type == ASN_OTHER_TYPE && - current->oidSum == UPN_OID) { - /* found UPN oid, check name against user */ - int idx; - - for (idx = 0; idx < current->len; idx++) { - if (current->name[idx] == '@') break; - } - - if ((int)XSTRLEN(usr) == idx && - XSTRNCMP(usr, current->name, idx) == 0) { - usrMatch = 1; - } - } - current = current->next; - } - - if (usrMatch == 0) { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] incorrect user cert sent"); + wc_InitDecodedCert(dCert, authData->sf.publicKey.publicKey, + authData->sf.publicKey.publicKeySz, NULL); + if (wc_ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL) != 0) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to parse peer " + "cert."); ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY; } + else { + int usrMatch = 0; + DNS_entry* current = dCert->altNames; + + while (current != NULL) { + if (current->type == ASN_OTHER_TYPE && + current->oidSum == UPN_OID) { + /* found UPN oid, check name against user */ + int idx; + + for (idx = 0; idx < current->len; idx++) { + if (current->name[idx] == '@') break; + /* UPN format is user @ domain, since currently + * not doing any checks on domain it is not + * treatied as an error if only the user name + * is present without the domain */ + } + + if ((int)XSTRLEN(usr) == idx && + XSTRNCMP(usr, current->name, idx) == 0) { + usrMatch = 1; + } + } + current = current->next; + } + + if (usrMatch == 0) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] incorrect user cert " + "sent"); + ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY; + } + } + FreeDecodedCert(dCert); + #ifdef WOLFSSH_SMALL_STACK + WFREE(dCert, NULL, DYNTYPE_CERT); + #endif } - FreeDecodedCert(&dCert); } #endif diff --git a/examples/client/client.c b/examples/client/client.c index 1239d806..56e2f759 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -483,7 +483,8 @@ static inline void ato32(const byte* c, word32* u32) #endif -#ifdef WOLFSSH_CERTS +#if defined(WOLFSSH_CERTS) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)) static int ParseRFC6187(const byte* in, word32 inSz, byte** leafOut, word32* leafOutSz) { From 49256a2e40c6d12b7cbd1162fb85b2b8dfe7848b Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 19 Oct 2022 13:31:06 -0700 Subject: [PATCH 4/4] update comment --- apps/wolfsshd/auth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/wolfsshd/auth.c b/apps/wolfsshd/auth.c index 25da452a..bab50384 100644 --- a/apps/wolfsshd/auth.c +++ b/apps/wolfsshd/auth.c @@ -780,10 +780,11 @@ static int RequestAuthentication(WS_UserAuthData* authData, for (idx = 0; idx < current->len; idx++) { if (current->name[idx] == '@') break; - /* UPN format is user @ domain, since currently - * not doing any checks on domain it is not - * treatied as an error if only the user name - * is present without the domain */ + /* UPN format is @ + * since currently not doing any checks on + * domain it is not treated as an error if only + * the user name is present without the domain + */ } if ((int)XSTRLEN(usr) == idx &&