diff --git a/Makefile.am b/Makefile.am
index f2a89949..fbecea9e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@ include src/include.am
include wolfssh/include.am
include examples/include.am
include test/include.am
-include certs/include.am
+include keys/include.am
TEST_EXTENSIONS = .test
diff --git a/README.md b/README.md
index e87ad597..6e7d6e86 100644
--- a/README.md
+++ b/README.md
@@ -44,8 +44,7 @@ testing notes
After cloning the repository, be sure to make the testing private keys read-
only for the user, otherwise ssh_client will tell you to do it.
- $ chmod 0600 ./certs/key-gretel.pem ./certs/key-hansel.pem \
- ./certs/key-ecc.pem
+ $ chmod 0600 ./certs/key-gretel.pem ./certs/key-hansel.pem
Authentication against the example echoserver can be done with a password or
public key. To use a password the command line:
diff --git a/certs/include.am b/certs/include.am
deleted file mode 100644
index fcbedd3e..00000000
--- a/certs/include.am
+++ /dev/null
@@ -1,16 +0,0 @@
-# vim:ft=automake
-# included from Top Level Makefile.am
-# All paths should be given relative to the root
-
-
-EXTRA_DIST+= \
- certs/key-gretel.pem \
- certs/publickeys.txt \
- certs/server-key.der \
- certs/key-ecc.pem \
- certs/key-hansel.pem \
- certs/server-cert.der \
- certs/server-key.pem \
- certs/key-ecc.pub \
- certs/passwd.txt \
- certs/server-cert.pem
diff --git a/certs/key-ecc.pem b/certs/key-ecc.pem
deleted file mode 100644
index 426658f0..00000000
--- a/certs/key-ecc.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIPIxGlM2XBIY6NulXIJgXdOheM+mZ7ixU8RLaXy2OoJeoAoGCCqGSM49
-AwEHoUQDQgAEpalbz23q5UgbcVHU0uGllXYqEw9kAG/uyCSMfZ1wliKi6tXrs/9p
-WCseyyREeyKmmMqt6WkekGJd54jHPa/Wyw==
------END EC PRIVATE KEY-----
diff --git a/certs/key-ecc.pub b/certs/key-ecc.pub
deleted file mode 100644
index 4d63eaed..00000000
--- a/certs/key-ecc.pub
+++ /dev/null
@@ -1 +0,0 @@
-ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKWpW89t6uVIG3FR1NLhpZV2KhMPZABv7sgkjH2dcJYiourV67P/aVgrHsskRHsippjKrelpHpBiXeeIxz2v1ss= john@johnwork.local
diff --git a/certs/server-cert.der b/certs/server-cert.der
deleted file mode 100644
index d3f75c21..00000000
Binary files a/certs/server-cert.der and /dev/null differ
diff --git a/certs/server-cert.pem b/certs/server-cert.pem
deleted file mode 100644
index 09676a0d..00000000
--- a/certs/server-cert.pem
+++ /dev/null
@@ -1,87 +0,0 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- fa:24:ef:1a:5a:f2:b2:a4
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL Inc., OU=Engineering, CN=wolfssh/emailAddress=info@wolfssl.com
- Validity
- Not Before: Aug 15 19:46:24 2014 GMT
- Not After : May 11 19:46:24 2017 GMT
- Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL Inc., OU=Engineering, CN=wolfssh/emailAddress=info@wolfssl.com
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (2048 bit)
- Modulus (2048 bit):
- 00:c5:7e:5d:0c:c5:47:95:67:ad:89:ff:db:fa:77:
- e8:1f:76:d3:ac:6f:10:8a:93:bf:ee:1b:93:9f:5b:
- 71:79:4c:d8:d5:6d:8e:d0:d2:b9:6b:e8:75:c8:73:
- f5:5d:1c:61:60:27:da:79:40:18:a3:b4:b8:f3:c3:
- 79:4e:12:6f:a2:20:46:6c:29:50:5d:f8:b6:82:89:
- 34:22:2a:14:00:77:38:ad:fa:e3:61:8d:71:c4:ff:
- 76:bc:34:3d:85:b5:ca:96:f8:46:d9:90:0f:e4:05:
- 31:4b:cf:2e:9b:5b:58:f8:2e:fc:88:68:d4:36:e0:
- 01:4c:0b:a4:ee:58:a0:ce:20:ef:78:b3:e6:50:56:
- 51:4d:de:1e:3d:2f:5c:49:6b:3d:78:94:6b:2e:ab:
- ae:0c:c0:b2:e8:29:a8:bc:ec:d2:05:a5:ac:3d:87:
- 50:55:3e:48:55:b4:b7:91:e5:2e:ce:89:51:02:14:
- 60:53:96:d7:7b:3e:61:2b:d3:54:f4:38:8d:55:78:
- 48:f0:ad:67:39:fd:41:34:a3:fa:90:02:a0:d9:d4:
- 01:fe:7a:8b:52:08:c9:0f:8b:5e:89:42:f1:bd:b7:
- 40:35:b0:29:50:3c:66:46:59:31:e3:01:03:9d:16:
- e8:87:8a:13:0b:ab:6e:bf:d9:b8:f0:fd:3d:82:4c:
- cc:2f
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 3C:38:D7:FD:0C:54:14:F4:3A:DB:08:04:44:DB:4F:41:5D:E9:E9:DE
- X509v3 Authority Key Identifier:
- keyid:3C:38:D7:FD:0C:54:14:F4:3A:DB:08:04:44:DB:4F:41:5D:E9:E9:DE
- DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL Inc./OU=Engineering/CN=wolfssh/emailAddress=info@wolfssl.com
- serial:FA:24:EF:1A:5A:F2:B2:A4
-
- X509v3 Basic Constraints:
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- 18:c2:d1:ee:39:b4:6b:24:06:63:13:37:93:18:4f:e1:5f:12:
- 5d:bf:03:88:ef:5b:bb:c8:b6:09:b6:e1:61:a2:df:4c:88:af:
- e0:cf:fd:b9:48:52:6d:1c:91:45:e1:4b:51:c4:c1:c5:11:57:
- 96:4f:74:d0:4d:58:70:4d:82:43:62:bd:e0:42:e1:76:a5:16:
- 55:ca:01:c4:6e:90:ff:09:1c:9e:c9:f3:98:ab:5c:c0:5f:8a:
- c3:80:f2:28:11:bd:99:e9:29:a9:ce:3c:aa:6b:fc:76:cc:93:
- 8b:60:1f:bb:b3:e9:a2:a2:67:c9:3d:cb:e8:20:a4:bd:00:78:
- 23:49:65:4a:96:50:09:db:f1:46:46:c1:08:9d:74:63:10:95:
- b4:ec:da:85:a2:96:50:7b:af:e5:54:aa:96:4e:77:3a:88:8c:
- f6:0e:5e:24:9f:22:ee:bc:a3:86:5d:11:48:63:65:eb:55:30:
- 4b:75:22:5d:e5:14:89:cb:c9:52:21:5f:8f:47:3e:31:2c:58:
- cd:5a:09:19:4d:d6:a4:0d:85:8d:86:ef:fe:fa:77:87:8f:c2:
- 07:1f:20:ad:86:d9:94:91:e8:63:6a:2f:9d:bb:c1:f1:4e:85:
- 02:8e:1d:9a:21:c4:94:28:0a:3d:9a:cb:19:87:4d:e0:a2:4c:
- 0f:11:8a:6c
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIJAPok7xpa8rKkMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
-VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2VhdHRsZTEV
-MBMGA1UEChMMd29sZlNTTCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4G
-A1UEAxMHd29sZnNzaDEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTAe
-Fw0xNDA4MTUxOTQ2MjRaFw0xNzA1MTExOTQ2MjRaMIGUMQswCQYDVQQGEwJVUzET
-MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2VhdHRsZTEVMBMGA1UEChMM
-d29sZlNTTCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHd29s
-ZnNzaDEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAMV+XQzFR5VnrYn/2/p36B9206xvEIqTv+4b
-k59bcXlM2NVtjtDSuWvodchz9V0cYWAn2nlAGKO0uPPDeU4Sb6IgRmwpUF34toKJ
-NCIqFAB3OK3642GNccT/drw0PYW1ypb4RtmQD+QFMUvPLptbWPgu/Iho1DbgAUwL
-pO5YoM4g73iz5lBWUU3eHj0vXElrPXiUay6rrgzAsugpqLzs0gWlrD2HUFU+SFW0
-t5HlLs6JUQIUYFOW13s+YSvTVPQ4jVV4SPCtZzn9QTSj+pACoNnUAf56i1IIyQ+L
-XolC8b23QDWwKVA8ZkZZMeMBA50W6IeKEwurbr/ZuPD9PYJMzC8CAwEAAaOB/DCB
-+TAdBgNVHQ4EFgQUPDjX/QxUFPQ62wgERNtPQV3p6d4wgckGA1UdIwSBwTCBvoAU
-PDjX/QxUFPQ62wgERNtPQV3p6d6hgZqkgZcwgZQxCzAJBgNVBAYTAlVTMRMwEQYD
-VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRUwEwYDVQQKEwx3b2xm
-U1NMIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5nMRAwDgYDVQQDEwd3b2xmc3No
-MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tggkA+iTvGlrysqQwDAYD
-VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAGMLR7jm0ayQGYxM3kxhP4V8S
-Xb8DiO9bu8i2CbbhYaLfTIiv4M/9uUhSbRyRReFLUcTBxRFXlk900E1YcE2CQ2K9
-4ELhdqUWVcoBxG6Q/wkcnsnzmKtcwF+Kw4DyKBG9mekpqc48qmv8dsyTi2Afu7Pp
-oqJnyT3L6CCkvQB4I0llSpZQCdvxRkbBCJ10YxCVtOzahaKWUHuv5VSqlk53OoiM
-9g5eJJ8i7ryjhl0RSGNl61UwS3UiXeUUicvJUiFfj0c+MSxYzVoJGU3WpA2FjYbv
-/vp3h4/CBx8grYbZlJHoY2ovnbvB8U6FAo4dmiHElCgKPZrLGYdN4KJMDxGKbA==
------END CERTIFICATE-----
diff --git a/certs/server-key.der b/certs/server-key.der
deleted file mode 100644
index d6813dd6..00000000
Binary files a/certs/server-key.der and /dev/null differ
diff --git a/certs/server-key.pem b/certs/server-key.pem
deleted file mode 100644
index c9d242c2..00000000
--- a/certs/server-key.pem
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAxX5dDMVHlWetif/b+nfoH3bTrG8QipO/7huTn1txeUzY1W2O
-0NK5a+h1yHP1XRxhYCfaeUAYo7S488N5ThJvoiBGbClQXfi2gok0IioUAHc4rfrj
-YY1xxP92vDQ9hbXKlvhG2ZAP5AUxS88um1tY+C78iGjUNuABTAuk7ligziDveLPm
-UFZRTd4ePS9cSWs9eJRrLquuDMCy6CmovOzSBaWsPYdQVT5IVbS3keUuzolRAhRg
-U5bXez5hK9NU9DiNVXhI8K1nOf1BNKP6kAKg2dQB/nqLUgjJD4teiULxvbdANbAp
-UDxmRlkx4wEDnRboh4oTC6tuv9m48P09gkzMLwIDAQABAoIBACB4WSYbXVyUEjUp
-KuqwQirCJ6UnEYonJpwoTooZx7tQxim4/I0ayD+UlaDiZ8nqO5xKkSH0RtjLgskZ
-L12FrHL0aX+o/zykAqXNlxOy5Vz6PQhlwnKshbME6WmiESdlryxJH6TviZ1MuUEk
-jB4g06ziVMS8r39iLvRoybIiQjYBa/p6ElxNGof1xGxgYEd4kUhuGEF7VWUkoarB
-0XlUN3lNlRJ4AnkWvWjgix6Zc2+YKgX0Cafc6gZ9Dc+J/jmlr2P4k4VjdhfOEMPa
-vB7FfEPMCfCHBHkeF9KYX1MGfpKpITvBSwNug44Z1D78u0Q/yvfIGYFoeJzznh45
-Dwc00rECgYEA9vtYtUk8j08ufW7OUHIRdgZ7dM9tEiDBdDvBoQKUw+GQqXToQydj
-i9UgCCIdX9Rc2u3HY3Mu4CblUHKCckw6miV9EG08r+HktqZL+hPlBO/7osLNkMzc
-feJVKQt7bjTzat3RSns+7DOP85GWpm2v2Br0i+7Eu+FJQoln/8bK2WcCgYEAzLRt
-fVTyZMOjenTKL8qw4mNbry1iguqYO0pdzvcB3QT085OvWfDunEto8hOPNuWPhTX3
-IhXHQ9KryThJgIR/pdZXLdKm+DkKGy1ZTylfnB7eDnzStRgVWBvW6iqzES4Psoob
-lFTMpy0yV/tWlzpmxh33BtPeEuRbH2Fan1nEkfkCgYBynx2BLNb1L2tE/Tq0rOub
-mdCL2oQlCJyfY+gt4DPIYJOxgTcVi18wkx2FiMeXJMhfNkD1z4vurT55Qlt1zhjY
-VxOenwOuIKjzd2QFUFxWGUXwOHYMgHbH2VVqchC7icl6TC2IYoBGQHvLL0L6RCd6
-pK/fjVUyWJCWV4yzcL/NewKBgEGNif53xIPGLsTZP6IcW5az0LmBZCmebI+YGgBc
-E2mu265g3eeEgzTj5UCYSOWAj/xNss1kggJTJZXzg343cBUwVYykB7o3sefQFuiF
-zEtXiy7ChEtf4f3sNF+auutGf9ph5cETgtIKZDPOlgUpu524HNI/6L7OB+w9peKf
-wZYpAoGAEeuFwcwVfvscoz17th/J43qOyAWT+vAk7qZdyGBEF98jg8kA2OcWykI1
-q/KdTLW9dXz0NVWzA2eoLv3SDxD3NgAXdcXq4NhJiNI9/Zrk7kybAcMstPJKtquK
-xXYH/xv41HqJ2IpfYjqqifV+HG6e37HeCWQDj1zyZulEMyrRN1s=
------END RSA PRIVATE KEY-----
diff --git a/configure.ac b/configure.ac
index e650145f..e4636a0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,14 @@ fi
AM_CONDITIONAL([BUILD_INLINE], [test "x$ENABLED_INLINE" = "xyes"])
+# Key Generation
+AC_ARG_ENABLE([keygen],
+ [AS_HELP_STRING([--enable-keygen],[Enable key generation (default: disabled)])],
+ [ENABLED_KEYGEN=$enableval],[ENABLED_KEYGEN=no])
+
+AS_IF([test "x$ENABLED_KEYGEN" = "xyes"],
+ [AM_CFLAGS="$AM_CFLAGS -DWOLFSSH_KEYGEN"])
+
# Checks for typedefs, structures, and compiler characteristics.
if test "$ac_cv_sizeof_long" = "8"; then
@@ -142,4 +150,7 @@ echo " * C Flags: $CFLAGS"
echo " * CPP Flags: $CPPFLAGS"
echo " * Linker Flags: $LDFLAGS"
echo " * LIB Flags: $LIB"
+echo
+echo " Features "
+echo " * keygen: $ENABLED_KEYGEN"
diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c
index 338780bc..2d46fb45 100644
--- a/examples/echoserver/echoserver.c
+++ b/examples/echoserver/echoserver.c
@@ -640,18 +640,7 @@ int main(void)
uint8_t buf[SCRATCH_BUFFER_SIZE];
uint32_t bufSz;
- bufSz = load_file("./certs/server-cert.der", buf, SCRATCH_BUFFER_SIZE);
- if (bufSz == 0) {
- fprintf(stderr, "Couldn't load certificate file.\n");
- exit(EXIT_FAILURE);
- }
- if (wolfSSH_CTX_UseCert_buffer(ctx,
- buf, bufSz, WOLFSSH_FORMAT_ASN1) < 0) {
- fprintf(stderr, "Couldn't use certificate buffer.\n");
- exit(EXIT_FAILURE);
- }
-
- bufSz = load_file("./certs/server-key.der", buf, SCRATCH_BUFFER_SIZE);
+ bufSz = load_file("./keys/server-key.der", buf, SCRATCH_BUFFER_SIZE);
if (bufSz == 0) {
fprintf(stderr, "Couldn't load key file.\n");
exit(EXIT_FAILURE);
diff --git a/examples/include.am b/examples/include.am
index d1bbde15..d9060ccb 100644
--- a/examples/include.am
+++ b/examples/include.am
@@ -3,4 +3,3 @@
# All paths should be given relative to the root
include examples/echoserver/include.am
-include examples/server/include.am
diff --git a/keys/include.am b/keys/include.am
new file mode 100644
index 00000000..f5fa27ae
--- /dev/null
+++ b/keys/include.am
@@ -0,0 +1,12 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+
+EXTRA_DIST+= \
+ keys/server-key.der \
+ keys/server-key.pem \
+ keys/key-hansel.pem \
+ keys/key-gretel.pem \
+ keys/publickeys.txt \
+ keys/passwd.txt
diff --git a/certs/key-gretel.pem b/keys/key-gretel.pem
similarity index 100%
rename from certs/key-gretel.pem
rename to keys/key-gretel.pem
diff --git a/certs/key-hansel.pem b/keys/key-hansel.pem
similarity index 100%
rename from certs/key-hansel.pem
rename to keys/key-hansel.pem
diff --git a/certs/passwd.txt b/keys/passwd.txt
similarity index 100%
rename from certs/passwd.txt
rename to keys/passwd.txt
diff --git a/certs/publickeys.txt b/keys/publickeys.txt
similarity index 100%
rename from certs/publickeys.txt
rename to keys/publickeys.txt
diff --git a/keys/server-key.der b/keys/server-key.der
new file mode 100644
index 00000000..a1012e45
Binary files /dev/null and b/keys/server-key.der differ
diff --git a/keys/server-key.pem b/keys/server-key.pem
new file mode 100644
index 00000000..c9b7a02d
--- /dev/null
+++ b/keys/server-key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA2l2tJRR2FVnzQP08uGIws23A+ezsi4MenkKcykFq04rhUjTg
+DRNiftQPrlxNBPGN+sWtd6paBcrv+I2r/4opCUwEwvUZy+0fsbQp08NsqSPfo6Dl
+CN6tjHH5NIhs7Tvwb6UPrFn/azPxcPuMpLNFIo2dd3rlKV+EFNmZ6urOLVHz41j6
+WwIPybUqvLJe08Iwuzyxw+9Y81CUKIvEZUr3ANmX2WtNjZWhimIGtFARIoO06irn
+0KggR0//Rq7FE+E4i/hUrzpNL/gf14SQ2JMFBsJ9kNvjnNDEZVoDrQCsWqLN2j+J
+WDdTvytGeqyJQStaLuh2517jKYWjY+rmhmB8LQIDAQABAoH/D5EeBsaupFcFQFzN
+N1fIoQHx/98j/c4bIK0fAEwpkWsVJQcf8c6v9tqnQ4bQ9slBld8BvsYmJMOS1+VB
+nbX7tu30aPGQJTmCSOjPEomb9XLZPpD5wugc9yYo3dXb7g2X1l2uAFtqGfpZ+/Py
+0sr04sG1uA7Kx2hHwjTBBD449IIBWfKKbvdrWwq8BaknN7n5BoBU6HAatDKTa/Um
+x4b0WAVD+XKP7EKgO7o1Yszs9LMEouuuPIdAjv6P3RS+vYPJyRjKgXwG+eOZLuwp
+xSdW6h6TxugMRMpzaEp/rhYlHRIlFCrsQWklw13mruRZgB36vZ8zNpOdiNaIyVsn
+ewthAoGBAN4Bq/pl0vrSb/4/V211f4zmvf4IvccTNGIOh7J6LKnNypPYMZGBLdZo
+lqol47h+pZio6BU8wM7e9auAsfW6r6ycwbNDNK4i9xhBhmOiRI4bQZ0tdW8NWxAZ
+XRSqgB/uAj74tvbsZY44iQ0LUOQRSYY5gttz5ToPEyKrraB4m5QhAoGBAPvNTFJJ
+PyyAlJFKOOwPSn06jrwEkBUlhPvTaL3voEf+zlu/HSqUJ/xRcP/J6bq+K6BQJdPh
+oVczzFzHfQn23PtylD3KWVJz4GxFCtnaMN8rM9dSGEEB8N8bAcHTt5sm+ByP/8gZ
+/TbQE6VyQqMwWVe02ioJ5UVaOW1wIgy6UyaNAoGBALE8wnDwk8Q89r4TEZhIguEZ
+YbsKfYAOO/bAxOLfGQMjUURBCCmy6MZQz1/dSfUD3u6GgmpaC0/cvmMCJpEYTqHO
+r/GOiOMw9PX/cevfIz4UUojKPwO+tOGgbihOimVzXYWqiF+PkPA/AGNSkmzRxFIN
+XgQXfXyhhlRanQ4M26AhAoGBAOr+G54nsYdssDovlJPpaVEZlx+s+nJhw4vpLrUj
+rufBywAgia20+uQldVmiLDkVRU2lvsfQqGvjcXOc0Pq9ologAmzwLRAgCG/Ct2+8
+iyObBBSNDwmMMClm4OrtFUr8wUyWrtUmPAQtiEg9LCdz9c0+gOP+vDNPEo0puv05
+3mP5AoGBAIsfR6KQS4I7iS3pa+Eo5SKHg9DeHg2MzIRDPSONnWy8xMbaRER5ILY+
+78+KxDiw5dpFrFrMe2K6qXMfuidcgvitMR7e8zdyy0fSzff4fwA5240qyk7BzuIV
+idY6Ya6dojClha446kZ03AI6rOlfo8ZzT3OBkFbDzndfW7psQvEh
+-----END RSA PRIVATE KEY-----
diff --git a/src/include.am b/src/include.am
index 289765f1..ea8a167f 100644
--- a/src/include.am
+++ b/src/include.am
@@ -6,6 +6,7 @@
lib_LTLIBRARIES+= src/libwolfssh.la
src_libwolfssh_la_SOURCES = src/ssh.c \
src/internal.c \
+ src/keygen.c \
src/memory.c \
src/log.c \
src/io.c \
diff --git a/src/internal.c b/src/internal.c
index 1bcff7c7..f0fca6c3 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -174,10 +174,8 @@ void CtxResourceFree(WOLFSSH_CTX* ctx)
if (ctx->privateKey) {
ForceZero(ctx->privateKey, ctx->privateKeySz);
- WFREE(ctx->privateKey, ctx->heap, DYNTYPE_KEY);
+ WFREE(ctx->privateKey, ctx->heap, DYNTYPE_PRIVKEY);
}
- WFREE(ctx->cert, ctx->heap, DYNTYPE_CERT);
- WFREE(ctx->caCert, ctx->heap, DYNTYPE_CA);
}
diff --git a/src/keygen.c b/src/keygen.c
new file mode 100644
index 00000000..2bdb09ef
--- /dev/null
+++ b/src/keygen.c
@@ -0,0 +1,102 @@
+/* keygen.c
+ *
+ * Copyright (C) 2014-2016 wolfSSL Inc.
+ *
+ * This file is part of wolfSSH.
+ *
+ * wolfSSH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfSSH. If not, see .
+ */
+
+
+/*
+ * The keygen module contains utility functions wrapping the wolfCrypt
+ * key generation functions to product SSH friendly keys.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+ #include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef WOLFSSH_KEYGEN
+
+#ifdef NO_INLINE
+ #include
+#else
+ #define WOLFSSH_MISC_INCLUDED
+ #include "src/misc.c"
+#endif
+
+
+int wolfSSH_MakeRsaKey(uint8_t* out, uint32_t outSz,
+ uint32_t size, uint32_t e)
+{
+ int ret = WS_SUCCESS;
+ WC_RNG rng;
+
+ WLOG(WS_LOG_DEBUG, "Entering wolfSSH_MakeRsaKey()");
+
+ if (wc_InitRng(&rng) != 0) {
+ WLOG(WS_LOG_DEBUG, "Couldn't create RNG");
+ ret = WS_CRYPTO_FAILED;
+ }
+
+ if (ret == WS_SUCCESS) {
+ RsaKey key;
+
+ if (wc_InitRsaKey(&key, NULL) != 0)
+ ret = WS_CRYPTO_FAILED;
+
+ if (ret == WS_SUCCESS) {
+ if (wc_MakeRsaKey(&key, size, e, &rng) != 0) {
+ WLOG(WS_LOG_DEBUG, "RSA key generation failed");
+ ret = WS_CRYPTO_FAILED;
+ }
+ }
+
+ if (ret == WS_SUCCESS) {
+ int keySz;
+
+ keySz = wc_RsaKeyToDer(&key, out, outSz);
+ if (keySz < 0) {
+ WLOG(WS_LOG_DEBUG, "RSA key to DER failed");
+ ret = WS_CRYPTO_FAILED;
+ }
+ else
+ ret = keySz;
+ }
+
+ if (wc_FreeRsaKey(&key) != 0) {
+ WLOG(WS_LOG_DEBUG, "RSA key free failed");
+ ret = WS_CRYPTO_FAILED;
+ }
+
+ if (wc_FreeRng(&rng) != 0) {
+ WLOG(WS_LOG_DEBUG, "Couldn't free RNG");
+ ret = WS_CRYPTO_FAILED;
+ }
+ }
+
+ WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_MakeRsaKey(), ret = %d", ret);
+ return ret;
+}
+
+#endif
diff --git a/src/ssh.c b/src/ssh.c
index cbfff9eb..bb186c23 100644
--- a/src/ssh.c
+++ b/src/ssh.c
@@ -474,7 +474,7 @@ static int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz,
else if (type == BUFTYPE_CERT)
dynamicType = DYNTYPE_CERT;
else if (type == BUFTYPE_PRIVKEY)
- dynamicType = DYNTYPE_KEY;
+ dynamicType = DYNTYPE_PRIVKEY;
else
return WS_BAD_ARGUMENT;
@@ -493,13 +493,7 @@ static int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz,
/* Maybe decrypt */
- if (type == BUFTYPE_CERT) {
- if (ctx->cert)
- WFREE(ctx->cert, heap, dynamicType);
- ctx->cert = der;
- ctx->certSz = derSz;
- }
- else if (type == BUFTYPE_PRIVKEY) {
+ if (type == BUFTYPE_PRIVKEY) {
if (ctx->privateKey)
WFREE(ctx->privateKey, heap, dynamicType);
ctx->privateKey = der;
@@ -531,27 +525,11 @@ static int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz,
int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX* ctx,
const uint8_t* in, uint32_t inSz, int format)
{
- WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_use_private_key_buffer()");
+ WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_UsePrivateKey_buffer()");
return ProcessBuffer(ctx, in, inSz, format, BUFTYPE_PRIVKEY);
}
-int wolfSSH_CTX_UseCert_buffer(WOLFSSH_CTX* ctx,
- const uint8_t* in, uint32_t inSz, int format)
-{
- WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_use_certificate_buffer()");
- return ProcessBuffer(ctx, in, inSz, format, BUFTYPE_CERT);
-}
-
-
-int wolfSSH_CTX_UseCaCert_buffer(WOLFSSH_CTX* ctx,
- const uint8_t* in, uint32_t inSz, int format)
-{
- WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_use_ca_certificate_buffer()");
- return ProcessBuffer(ctx, in, inSz, format, BUFTYPE_CA);
-}
-
-
int wolfSSH_KDF(uint8_t hashId, uint8_t keyId,
uint8_t* key, uint32_t keySz,
const uint8_t* k, uint32_t kSz,
diff --git a/test/unit.c b/test/unit.c
index 7b4d6e5a..025b1cba 100644
--- a/test/unit.c
+++ b/test/unit.c
@@ -21,146 +21,95 @@
#include
#include
+#include
-static int test_KDF(void);
-static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz,
- const char* h2, uint8_t** b2, uint32_t* b2Sz,
- const char* h3, uint8_t** b3, uint32_t* b3Sz,
- const char* h4, uint8_t** b4, uint32_t* b4Sz);
-static void FreeBins(uint8_t* b1, uint8_t* b2, uint8_t* b3, uint8_t* b4);
-static int Base16_Decode(const uint8_t* in, uint32_t inLen,
- uint8_t* out, uint32_t* outLen);
+/* Utility functions */
+#define BAD 0xFF
-int main(void)
+const uint8_t hexDecode[] =
{
- int testResult = 0, unitResult = 0;
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+ 10, 11, 12, 13, 14, 15, /* upper case A-F */
+ BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+ BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+ BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
+ BAD, BAD, /* G - ` */
+ 10, 11, 12, 13, 14, 15 /* lower case a-f */
+}; /* A starts at 0x41 not 0x3A */
- unitResult = test_KDF();
- printf("KDF: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
- testResult = testResult || unitResult;
- return (testResult ? 1 : 0);
+static int Base16_Decode(const uint8_t* in, uint32_t inLen,
+ uint8_t* out, uint32_t* outLen)
+{
+ uint32_t inIdx = 0;
+ uint32_t outIdx = 0;
+
+ if (inLen == 1 && *outLen && in) {
+ uint8_t b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
+
+ /* sanity check */
+ if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
+ return -1;
+
+ b = hexDecode[b];
+
+ if (b == BAD)
+ return -1;
+
+ out[outIdx++] = b;
+
+ *outLen = outIdx;
+ return 0;
+ }
+
+ if (inLen % 2)
+ return -1;
+
+ if (*outLen < (inLen / 2))
+ return -1;
+
+ while (inLen) {
+ uint8_t b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
+ uint8_t b2 = in[inIdx++] - 0x30;
+
+ /* sanity checks */
+ if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
+ return -1;
+ if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
+ return -1;
+
+ b = hexDecode[b];
+ b2 = hexDecode[b2];
+
+ if (b == BAD || b2 == BAD)
+ return -1;
+
+ out[outIdx++] = (uint8_t)((b << 4) | b2);
+ inLen -= 2;
+ }
+
+ *outLen = outIdx;
+ return 0;
}
-typedef struct {
- uint8_t hashId;
- uint8_t keyId;
- const char* k;
- const char* h;
- const char* sessionId;
- const char* expectedKey;
-} KdfTestVector;
-
-
-/** Test Vector Set #1 **/
-const char kdfTvSet1k[] =
- "35618FD3AABF980A5F766408961600D4933C60DD7B22D69EEB4D7A987C938F6F"
- "7BB2E60E0F638BB4289297B588E6109057325F010D021DF60EBF8BE67AD9C3E2"
- "6376A326A16210C7AF07B3FE562B8DD1DCBECB17AA7BFAF38708B0136120B2FC"
- "723E93EF4237AC3737BAE3A16EC03F605C7EEABFD526B38C826B506BBAECD2F7"
- "9932F1371AEABFBEB4F8222313506677330C714A2A6FDC70CB859B581AA18625"
- "ECCB6BA9DDEEAECF0E41D9E5076B899B477112E59DDADC4B4D9C13E9F07E1107"
- "B560FEFDC146B8ED3E73441D05345031C35F9E6911B00319481D80015855BE4D"
- "1C7D7ACC8579B1CC2E5F714109C0882C3B57529ABDA1F2255D2B27C4A83AE11E";
-const char kdfTvSet1h[] = "40555741F6DE70CDC4E740104A97E75473F49064";
-const char kdfTvSet1sessionId[] = "40555741F6DE70CDC4E740104A97E75473F49064";
-const char kdfTvSet1a[] = "B2EC4CF6943632C39972EE2801DC7393";
-const char kdfTvSet1b[] = "BC92238B6FA69ECC10B2B013C2FC9785";
-const char kdfTvSet1c[] = "9EF0E2053F66C56F3E4503DA1C2FBD6B";
-const char kdfTvSet1d[] = "47C8395B08277020A0645DA3959FA1A9";
-const char kdfTvSet1e[] = "EE436BFDABF9B0313224EC800E7390445E2F575E";
-const char kdfTvSet1f[] = "FB9FDEEC78B0FB258F1A4F47F6BCE166680994BB";
-
-/** Test Vector Set #2 **/
-const char kdfTvSet2k[] =
- "19FA2B7C7F4FE7DE61CDE17468C792CCEAB0E3F2CE37CDE2DAA0974BCDFFEDD4"
- "A29415CDB330FA6A97ECA742359DC1223B581D8AC61B43CFFDF66D20952840B0"
- "2593B48354E352E2A396BDF7F1C9D414FD31C2BF47E6EED306069C4F4F5F66C3"
- "003A90E85412A1FBE89CDFB457CDA0D832E8DA701627366ADEC95B70E8A8B7BF"
- "3F85775CCF36E40631B83B32CF643088F01A82C97C5C3A820EB4149F551CAF8C"
- "C98EE6B3065E6152FF877823F7C618C1CD93CE26DB9FAAFED222F1C93E8F4068"
- "BFDA4480432E14F98FFC821F05647693040B07D71DC273121D53866294434D46"
- "0E95CFA4AB4414705BF1F8224655F907A418A6A893F2A71019225869CB7FE988";
-const char kdfTvSet2h[] = "DFB748905CC8647684C3E0B7F26A3E8E7414AC51";
-const char kdfTvSet2sessionId[] = "DFB748905CC8647684C3E0B7F26A3E8E7414AC51";
-const char kdfTvSet2a[] = "52EDBFD5E414A3CC6C7F7A0F4EA60503";
-const char kdfTvSet2b[] = "926C6987696C5FFCC6511BFE34557878";
-const char kdfTvSet2c[] = "CB6D56EC5B9AFECD326D544DA2D22DED";
-const char kdfTvSet2d[] = "F712F6451F1BD6CE9BAA597AC87C5A24";
-const char kdfTvSet2e[] = "E42FC62C76B76B37818F78292D3C2226D0264760";
-const char kdfTvSet2f[] = "D14BE4DD0093A3E759580233C80BB8399CE4C4E7";
-
-static const KdfTestVector kdfTestVectors[] = {
- {0, 'A', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1a},
- {0, 'B', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1b},
- {0, 'C', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1c},
- {0, 'D', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1d},
- {0, 'E', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1e},
- {0, 'F', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1f},
- {0, 'A', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2a},
- {0, 'B', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2b},
- {0, 'C', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2c},
- {0, 'D', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2d},
- {0, 'E', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2e},
- {0, 'F', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2f}
-};
-
-int test_KDF(void)
+static void FreeBins(uint8_t* b1, uint8_t* b2, uint8_t* b3, uint8_t* b4)
{
- int result = 0;
- uint32_t i;
- uint32_t tc = sizeof(kdfTestVectors)/sizeof(KdfTestVector);
- const KdfTestVector* tv = NULL;
- uint8_t* k = NULL;
- uint8_t* h = NULL;
- uint8_t* sId = NULL;
- uint8_t* eKey = NULL;
- uint32_t kSz, hSz, sIdSz, eKeySz;
- uint8_t cKey[20]; /* Greater of SHA_DIGEST_SIZE and AES_BLOCK_SIZE */
- /* sId - Session ID, eKey - Expected Key, cKey - Calculated Key */
-
- for (i = 0, tv = kdfTestVectors; i < tc; i++, tv++) {
-
- result = ConvertHexToBin(tv->k, &k, &kSz,
- tv->h, &h, &hSz,
- tv->sessionId, &sId, &sIdSz,
- tv->expectedKey, &eKey, &eKeySz);
- if (result != 0) {
- printf("KDF: Could not convert test vector %u.\n", i);
- return -100;
- }
-
- result = wolfSSH_KDF(tv->hashId, tv->keyId, cKey, eKeySz,
- k, kSz, h, hSz, sId, sIdSz);
-
- if (result != 0) {
- printf("KDF: Could not derive key.\n");
- result = -101;
- }
- else {
- if (memcmp(cKey, eKey, eKeySz) != 0) {
- printf("KDF: Calculated Key does not match Expected Key.\n");
- result = -102;
- }
- }
-
- FreeBins(k, h, sId, eKey);
-
- if (result != 0) break;
- }
-
- return result;
+ if (b1 != NULL) free(b1);
+ if (b2 != NULL) free(b2);
+ if (b3 != NULL) free(b3);
+ if (b4 != NULL) free(b4);
}
/* convert hex string to binary, store size, 0 success (free mem on failure) */
-int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz,
- const char* h2, uint8_t** b2, uint32_t* b2Sz,
- const char* h3, uint8_t** b3, uint32_t* b3Sz,
- const char* h4, uint8_t** b4, uint32_t* b4Sz)
+static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz,
+ const char* h2, uint8_t** b2, uint32_t* b2Sz,
+ const char* h3, uint8_t** b3, uint32_t* b3Sz,
+ const char* h4, uint8_t** b4, uint32_t* b4Sz)
{
int ret;
@@ -230,82 +179,158 @@ int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz,
}
-void FreeBins(uint8_t* b1, uint8_t* b2, uint8_t* b3, uint8_t* b4)
+/* Key Derivation Function (KDF) Unit Test */
+
+typedef struct {
+ uint8_t hashId;
+ uint8_t keyId;
+ const char* k;
+ const char* h;
+ const char* sessionId;
+ const char* expectedKey;
+} KdfTestVector;
+
+
+/** Test Vector Set #1 **/
+const char kdfTvSet1k[] =
+ "35618FD3AABF980A5F766408961600D4933C60DD7B22D69EEB4D7A987C938F6F"
+ "7BB2E60E0F638BB4289297B588E6109057325F010D021DF60EBF8BE67AD9C3E2"
+ "6376A326A16210C7AF07B3FE562B8DD1DCBECB17AA7BFAF38708B0136120B2FC"
+ "723E93EF4237AC3737BAE3A16EC03F605C7EEABFD526B38C826B506BBAECD2F7"
+ "9932F1371AEABFBEB4F8222313506677330C714A2A6FDC70CB859B581AA18625"
+ "ECCB6BA9DDEEAECF0E41D9E5076B899B477112E59DDADC4B4D9C13E9F07E1107"
+ "B560FEFDC146B8ED3E73441D05345031C35F9E6911B00319481D80015855BE4D"
+ "1C7D7ACC8579B1CC2E5F714109C0882C3B57529ABDA1F2255D2B27C4A83AE11E";
+const char kdfTvSet1h[] = "40555741F6DE70CDC4E740104A97E75473F49064";
+const char kdfTvSet1sessionId[] = "40555741F6DE70CDC4E740104A97E75473F49064";
+const char kdfTvSet1a[] = "B2EC4CF6943632C39972EE2801DC7393";
+const char kdfTvSet1b[] = "BC92238B6FA69ECC10B2B013C2FC9785";
+const char kdfTvSet1c[] = "9EF0E2053F66C56F3E4503DA1C2FBD6B";
+const char kdfTvSet1d[] = "47C8395B08277020A0645DA3959FA1A9";
+const char kdfTvSet1e[] = "EE436BFDABF9B0313224EC800E7390445E2F575E";
+const char kdfTvSet1f[] = "FB9FDEEC78B0FB258F1A4F47F6BCE166680994BB";
+
+/** Test Vector Set #2 **/
+const char kdfTvSet2k[] =
+ "19FA2B7C7F4FE7DE61CDE17468C792CCEAB0E3F2CE37CDE2DAA0974BCDFFEDD4"
+ "A29415CDB330FA6A97ECA742359DC1223B581D8AC61B43CFFDF66D20952840B0"
+ "2593B48354E352E2A396BDF7F1C9D414FD31C2BF47E6EED306069C4F4F5F66C3"
+ "003A90E85412A1FBE89CDFB457CDA0D832E8DA701627366ADEC95B70E8A8B7BF"
+ "3F85775CCF36E40631B83B32CF643088F01A82C97C5C3A820EB4149F551CAF8C"
+ "C98EE6B3065E6152FF877823F7C618C1CD93CE26DB9FAAFED222F1C93E8F4068"
+ "BFDA4480432E14F98FFC821F05647693040B07D71DC273121D53866294434D46"
+ "0E95CFA4AB4414705BF1F8224655F907A418A6A893F2A71019225869CB7FE988";
+const char kdfTvSet2h[] = "DFB748905CC8647684C3E0B7F26A3E8E7414AC51";
+const char kdfTvSet2sessionId[] = "DFB748905CC8647684C3E0B7F26A3E8E7414AC51";
+const char kdfTvSet2a[] = "52EDBFD5E414A3CC6C7F7A0F4EA60503";
+const char kdfTvSet2b[] = "926C6987696C5FFCC6511BFE34557878";
+const char kdfTvSet2c[] = "CB6D56EC5B9AFECD326D544DA2D22DED";
+const char kdfTvSet2d[] = "F712F6451F1BD6CE9BAA597AC87C5A24";
+const char kdfTvSet2e[] = "E42FC62C76B76B37818F78292D3C2226D0264760";
+const char kdfTvSet2f[] = "D14BE4DD0093A3E759580233C80BB8399CE4C4E7";
+
+static const KdfTestVector kdfTestVectors[] = {
+ {0, 'A', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1a},
+ {0, 'B', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1b},
+ {0, 'C', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1c},
+ {0, 'D', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1d},
+ {0, 'E', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1e},
+ {0, 'F', kdfTvSet1k, kdfTvSet1h, kdfTvSet1sessionId, kdfTvSet1f},
+ {0, 'A', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2a},
+ {0, 'B', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2b},
+ {0, 'C', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2c},
+ {0, 'D', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2d},
+ {0, 'E', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2e},
+ {0, 'F', kdfTvSet2k, kdfTvSet2h, kdfTvSet2sessionId, kdfTvSet2f}
+};
+
+
+static int test_KDF(void)
{
- if (b1 != NULL) free(b1);
- if (b2 != NULL) free(b2);
- if (b3 != NULL) free(b3);
- if (b4 != NULL) free(b4);
+ int result = 0;
+ uint32_t i;
+ uint32_t tc = sizeof(kdfTestVectors)/sizeof(KdfTestVector);
+ const KdfTestVector* tv = NULL;
+ uint8_t* k = NULL;
+ uint8_t* h = NULL;
+ uint8_t* sId = NULL;
+ uint8_t* eKey = NULL;
+ uint32_t kSz, hSz, sIdSz, eKeySz;
+ uint8_t cKey[20]; /* Greater of SHA_DIGEST_SIZE and AES_BLOCK_SIZE */
+ /* sId - Session ID, eKey - Expected Key, cKey - Calculated Key */
+
+ for (i = 0, tv = kdfTestVectors; i < tc; i++, tv++) {
+
+ result = ConvertHexToBin(tv->k, &k, &kSz,
+ tv->h, &h, &hSz,
+ tv->sessionId, &sId, &sIdSz,
+ tv->expectedKey, &eKey, &eKeySz);
+ if (result != 0) {
+ printf("KDF: Could not convert test vector %u.\n", i);
+ return -100;
+ }
+
+ result = wolfSSH_KDF(tv->hashId, tv->keyId, cKey, eKeySz,
+ k, kSz, h, hSz, sId, sIdSz);
+
+ if (result != 0) {
+ printf("KDF: Could not derive key.\n");
+ result = -101;
+ }
+ else {
+ if (memcmp(cKey, eKey, eKeySz) != 0) {
+ printf("KDF: Calculated Key does not match Expected Key.\n");
+ result = -102;
+ }
+ }
+
+ FreeBins(k, h, sId, eKey);
+
+ if (result != 0) break;
+ }
+
+ return result;
}
-#define BAD 0xFF
+/* Key Generation Unit Test */
-const uint8_t hexDecode[] =
+#ifdef WOLFSSH_KEYGEN
+
+static int test_RsaKeyGen(void)
{
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- BAD, BAD, BAD, BAD, BAD, BAD, BAD,
- 10, 11, 12, 13, 14, 15, /* upper case A-F */
- BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
- BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
- BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
- BAD, BAD, /* G - ` */
- 10, 11, 12, 13, 14, 15 /* lower case a-f */
-}; /* A starts at 0x41 not 0x3A */
+ int result = 0;
+ uint8_t der[1200];
+ int derSz;
-
-static int Base16_Decode(const uint8_t* in, uint32_t inLen,
- uint8_t* out, uint32_t* outLen)
-{
- uint32_t inIdx = 0;
- uint32_t outIdx = 0;
-
- if (inLen == 1 && *outLen && in) {
- uint8_t b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
-
- /* sanity check */
- if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
- return -1;
-
- b = hexDecode[b];
-
- if (b == BAD)
- return -1;
-
- out[outIdx++] = b;
-
- *outLen = outIdx;
- return 0;
+ derSz = wolfSSH_MakeRsaKey(der, sizeof(der),
+ WOLFSSH_RSAKEY_DEFAULT_SZ,
+ WOLFSSH_RSAKEY_DEFAULT_E);
+ if (derSz < 0) {
+ printf("RsaKeyGen: MakeRsaKey failed\n");
+ result = -103;
}
- if (inLen % 2)
- return -1;
-
- if (*outLen < (inLen / 2))
- return -1;
-
- while (inLen) {
- uint8_t b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */
- uint8_t b2 = in[inIdx++] - 0x30;
-
- /* sanity checks */
- if (b >= sizeof(hexDecode)/sizeof(hexDecode[0]))
- return -1;
- if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0]))
- return -1;
-
- b = hexDecode[b];
- b2 = hexDecode[b2];
-
- if (b == BAD || b2 == BAD)
- return -1;
-
- out[outIdx++] = (uint8_t)((b << 4) | b2);
- inLen -= 2;
- }
-
- *outLen = outIdx;
- return 0;
+ return result;
}
+#endif
+
+
+int main(void)
+{
+ int testResult = 0, unitResult = 0;
+
+ unitResult = test_KDF();
+ printf("KDF: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
+ testResult = testResult || unitResult;
+
+#ifdef WOLFSSH_KEYGEN
+ unitResult = test_RsaKeyGen();
+ printf("RsaKeyGen: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
+ testResult = testResult || unitResult;
+#endif
+
+ return (testResult ? 1 : 0);
+}
diff --git a/wolfssh/include.am b/wolfssh/include.am
index e8a8e3ed..0fa6c9ed 100644
--- a/wolfssh/include.am
+++ b/wolfssh/include.am
@@ -6,6 +6,7 @@
nobase_include_HEADERS+= \
wolfssh/version.h \
wolfssh/ssh.h \
+ wolfssh/keygen.h \
wolfssh/port.h \
wolfssh/memory.h \
wolfssh/settings.h \
diff --git a/wolfssh/internal.h b/wolfssh/internal.h
index 1b23b1aa..a84b843d 100644
--- a/wolfssh/internal.h
+++ b/wolfssh/internal.h
@@ -141,10 +141,6 @@ struct WOLFSSH_CTX {
WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */
WS_CallbackHighwater highwaterCb; /* Data Highwater Mark Callback */
- uint8_t* cert; /* Owned by CTX */
- uint32_t certSz;
- uint8_t* caCert; /* Owned by CTX */
- uint32_t caCertSz;
uint8_t* privateKey; /* Owned by CTX */
uint32_t privateKeySz;
uint32_t countHighwater;
@@ -388,7 +384,8 @@ enum WS_DynamicTypes {
DYNTYPE_HS,
DYNTYPE_CA,
DYNTYPE_CERT,
- DYNTYPE_KEY,
+ DYNTYPE_PRIVKEY,
+ DYNTYPE_PUBKEY,
DYNTYPE_DH,
DYNTYPE_RNG,
DYNTYPE_STRING
@@ -398,7 +395,8 @@ enum WS_DynamicTypes {
enum WS_BufferTypes {
BUFTYPE_CA,
BUFTYPE_CERT,
- BUFTYPE_PRIVKEY
+ BUFTYPE_PRIVKEY,
+ BUFTYPE_PUBKEY
};
diff --git a/wolfssh/keygen.h b/wolfssh/keygen.h
new file mode 100644
index 00000000..ca55d7b7
--- /dev/null
+++ b/wolfssh/keygen.h
@@ -0,0 +1,52 @@
+/* keygen.h
+ *
+ * Copyright (C) 2014-2016 wolfSSL Inc.
+ *
+ * This file is part of wolfSSH.
+ *
+ * wolfSSH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfSSH. If not, see .
+ */
+
+
+/*
+ * The keygen module contains utility functions wrapping the wolfCrypt
+ * key generation functions to product SSH friendly keys.
+ */
+
+
+#pragma once
+
+#ifndef WOLFSSH_KEYGEN_H
+#define WOLFSSH_KEYGEN_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define WOLFSSH_RSAKEY_DEFAULT_SZ 2048
+#define WOLFSSH_RSAKEY_DEFAULT_E 65537
+
+
+WOLFSSH_API int wolfSSH_MakeRsaKey(uint8_t*, uint32_t, uint32_t, uint32_t);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h
index 7394a01a..a6f8827b 100644
--- a/wolfssh/ssh.h
+++ b/wolfssh/ssh.h
@@ -126,10 +126,6 @@ WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*);
WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*,
const uint8_t*, uint32_t, int);
-WOLFSSH_API int wolfSSH_CTX_UseCert_buffer(WOLFSSH_CTX*,
- const uint8_t*, uint32_t, int);
-WOLFSSH_API int wolfSSH_CTX_UseCaCert_buffer(WOLFSSH_CTX*,
- const uint8_t*, uint32_t, int);
WOLFSSH_API int wolfSSH_accept(WOLFSSH*);
WOLFSSH_API int wolfSSH_stream_read(WOLFSSH*, uint8_t*, uint32_t);