[med-svn] [r-cran-openssl] 02/03: New upstream version 0.9.7

Andreas Tille tille at debian.org
Tue Oct 10 17:14:38 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository r-cran-openssl.

commit 859d8f2ebbdab65fb0d46dfda566d1694725b0f8
Author: Andreas Tille <tille at debian.org>
Date:   Tue Oct 10 19:12:52 2017 +0200

    New upstream version 0.9.7
---
 DESCRIPTION                    |  16 +++---
 LICENSE                        |   2 +-
 MD5                            | 116 +++++++++++++++++++++--------------------
 NAMESPACE                      |   6 ++-
 NEWS                           |  14 +++++
 R/aes.R                        |   2 +-
 R/bignum.R                     |  17 +++++-
 R/cert.R                       |   6 ++-
 R/diffie.R                     |   2 +-
 R/envelope.R                   |   2 +-
 R/read.R                       |  31 +++++++++--
 R/stopifnot.R                  |  10 ++++
 build/vignette.rds             | Bin 355 -> 355 bytes
 configure                      |  37 +++++++++----
 inst/doc/bignum.Rmd            |   2 +-
 inst/doc/bignum.html           |  36 ++++++-------
 inst/doc/crypto_hashing.Rmd    |   2 +-
 inst/doc/crypto_hashing.html   |  16 +++---
 inst/doc/keys.html             |  48 ++++++++---------
 inst/doc/secure_rng.html       |  24 ++++-----
 man/aes_cbc.Rd                 |   3 +-
 man/askpass.Rd                 |   1 -
 man/base64_encode.Rd           |   1 -
 man/bignum.Rd                  |   5 +-
 man/certificates.Rd            |   5 +-
 man/ec_dh.Rd                   |   3 +-
 man/encrypt_envelope.Rd        |   3 +-
 man/fingerprint.Rd             |   1 -
 man/hash.Rd                    |   1 -
 man/keygen.Rd                  |   1 -
 man/my_key.Rd                  |   1 -
 man/openssl.Rd                 |   1 -
 man/openssl_config.Rd          |   1 -
 man/pkcs12.Rd                  |   1 -
 man/rand_bytes.Rd              |   1 -
 man/read_key.Rd                |   3 +-
 man/rsa_encrypt.Rd             |   1 -
 man/signatures.Rd              |   1 -
 man/write_pem.Rd               |   1 -
 src/Makevars.win               |   7 +--
 src/aes.c                      |   4 ++
 src/base64.c                   |   1 +
 src/bignum.c                   |   7 +++
 src/cert.c                     |   1 +
 src/keygen.c                   |  28 ++++------
 src/keys.c                     |  11 ++--
 src/onload.c                   |   4 +-
 src/openssh.c                  |  11 ++--
 src/pem.c                      |  26 +++++++--
 src/pkcs12.c                   |   9 ++--
 src/pkcs7.c                    |   9 ++--
 src/rsa.c                      |   1 +
 src/signing.c                  |  15 ++++--
 src/ssl.c                      |   9 +++-
 src/{onload.c => tests/main.c} |  17 +-----
 src/tests/soname.h             |   5 ++
 tests/testthat/test_bignum.R   |   7 +++
 tests/testthat/test_google.R   |  30 +++++++++++
 tools/winlibs.R                |   8 +--
 vignettes/bignum.Rmd           |   2 +-
 vignettes/crypto_hashing.Rmd   |   2 +-
 61 files changed, 389 insertions(+), 249 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
index 6400da5..f996a20 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -2,9 +2,9 @@ Package: openssl
 Type: Package
 Title: Toolkit for Encryption, Signatures and Certificates Based on
         OpenSSL
-Version: 0.9.6
+Version: 0.9.7
 Authors at R: c(
-    person("Jeroen", "Ooms", , "jeroen.ooms at stat.ucla.edu", role = c("cre", "aut")),
+    person("Jeroen", "Ooms", , "jeroen at berkeley.edu", role = c("cre", "aut")),
     person("Oliver", "Keyes", role = "ctb"))
 Description: Bindings to OpenSSL libssl and libcrypto, plus custom SSH pubkey parsers.
     Supports RSA, DSA and EC curves P-256, P-384 and P-521. Cryptographic signatures
@@ -16,16 +16,16 @@ Description: Bindings to OpenSSL libssl and libcrypto, plus custom SSH pubkey pa
     random number generator, and 'bignum' math methods for manually performing
     crypto calculations on large multibyte integers.
 License: MIT + file LICENSE
-URL: https://github.com/jeroenooms/openssl#readme
-BugReports: https://github.com/jeroenooms/openssl/issues
+URL: https://github.com/jeroen/openssl#readme
+BugReports: https://github.com/jeroen/openssl/issues
 SystemRequirements: OpenSSL >= 1.0.1
 VignetteBuilder: knitr
 Suggests: testthat, digest, knitr, rmarkdown, jsonlite, jose
-RoxygenNote: 5.0.1.9000
+RoxygenNote: 6.0.1
 NeedsCompilation: yes
-Packaged: 2016-12-30 21:26:04 UTC; jeroen
+Packaged: 2017-09-06 15:02:37 UTC; jeroen
 Author: Jeroen Ooms [cre, aut],
   Oliver Keyes [ctb]
-Maintainer: Jeroen Ooms <jeroen.ooms at stat.ucla.edu>
+Maintainer: Jeroen Ooms <jeroen at berkeley.edu>
 Repository: CRAN
-Date/Publication: 2016-12-31 01:41:12
+Date/Publication: 2017-09-06 20:56:56 UTC
diff --git a/LICENSE b/LICENSE
index 019ab7d..7bade8c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,2 +1,2 @@
-YEAR: 2016
+YEAR: 2017
 COPYRIGHT HOLDER: Jeroen Ooms
diff --git a/MD5 b/MD5
index 59cd78b..8e86dc5 100644
--- a/MD5
+++ b/MD5
@@ -1,16 +1,16 @@
-6fa08c0ab0ed08aebbbdf43534cadb67 *DESCRIPTION
-91443a13b3d89ea22bfa1222461b0111 *LICENSE
-31ed63c95b88a309a40dc09625bd24e4 *NAMESPACE
-75553d3044314c14331805d24c33cf11 *NEWS
-156bd963e78beb7896a8dde40c040d87 *R/aes.R
+367dd625cb6e7735028f5dd269055094 *DESCRIPTION
+1ee0683cce6d3479250337954c075d63 *LICENSE
+4126ab68ba48958d9d3f1789efcc175e *NAMESPACE
+8a080dbae14a99d86ba09ab4304ab1fe *NEWS
+3db0fd878b0056ab9f4586d167ce4cea *R/aes.R
 59033eb1b1690ba5a682648924c0dc01 *R/askpass.R
 25bb161cd43a5861b01e425133591e22 *R/base.R
 cc6804a52ad350613a81e2346b817fdf *R/base64.R
-08f06dd3d19d9edb152a9aee864d395f *R/bignum.R
+673c3ac5cc58c1ef2e8743104cbbafdc *R/bignum.R
 5f72eefdfed00a7bdb47aa45bf77bfab *R/build.R
-3bf0a5b72dfc6551ad5fcbaa987fa3d2 *R/cert.R
-0d85897cdc8a00f8c3c20358cab1c3a6 *R/diffie.R
-c606d3fec281684d3d47b88057db3531 *R/envelope.R
+0382d233b421b0a7ffca8bca98563c7e *R/cert.R
+739b40031901e870873603e24a97a4de *R/diffie.R
+1e505c778f2adaa8465a51f5471da80f *R/envelope.R
 6c3fb3d1dab89f2445e55705bbadd57e *R/hash.R
 bdc2a1aae7843d4bf11e1c014108126a *R/info.R
 da023c47b493f35d10f4797c96cd4079 *R/keygen.R
@@ -20,55 +20,56 @@ da023c47b493f35d10f4797c96cd4079 *R/keygen.R
 b81ef27e71a21e15e4bcb7c6967da506 *R/openssl.R
 dbc330a3f5d1fcbf234cec9fa081bb25 *R/pkcs12.R
 19f56327a3d01276a02ecea94f19ee00 *R/rand.R
-fede48c6c412123261e7c3428bf6a365 *R/read.R
+ff216868a9010353ccfedec14f2acf5d *R/read.R
 e39a40bb6ae575d20b739d1a8d623eb3 *R/rsa.R
 422428316cb16391303a8b3358a4b64a *R/signing.R
 5fa6c5d13e176309876292147410885a *R/ssh2.R
+f9c4917446c9696e21152dec2aeadba3 *R/stopifnot.R
 5ecac70bdaf1e7a02da963da3030fdda *R/stream.R
 0b4d07002d68ea8bbf9cb90fae0c0841 *R/write.R
 250578a5040b1769a81d0e0601efe74c *R/writessh.R
-a41ea1cb9e3fb30c340d719ae49e5b22 *build/vignette.rds
+52184593cb4c9b8b7054302578bde264 *build/vignette.rds
 6071edd604dbeb75308cfbedc7790398 *cleanup
-f0694b4a3b6961941199a632e0db388d *configure
+fe266ec3f79256950f48d9c0b6152ca5 *configure
 d41d8cd98f00b204e9800998ecf8427e *configure.win
 8d35a5cef6ce28da07867a0712558067 *inst/cacert.pem
 538ca1f45e2c482e27a792761d92f392 *inst/doc/bignum.R
-a4e5f2bd8377da2198e2920218af2530 *inst/doc/bignum.Rmd
-3b09600561a37b0d2d6c386bfc63c63a *inst/doc/bignum.html
+745cc4ee4a0217d09448b71e583c6de2 *inst/doc/bignum.Rmd
+59ddd550453265aedc20346b4be0763c *inst/doc/bignum.html
 290c8f4ed75f1b80406a241d34906256 *inst/doc/crypto_hashing.R
-b09c484e5db70d1c14c16989744f45f4 *inst/doc/crypto_hashing.Rmd
-39052b09a8b0b604f4f5113f4bb95915 *inst/doc/crypto_hashing.html
+0b17ff80c3353c70f01e43324820eb32 *inst/doc/crypto_hashing.Rmd
+664e1b50e20ad58ee0f4a37f0de0b4b9 *inst/doc/crypto_hashing.html
 65488f0ce9e60ae12fb2d12b87a0d81e *inst/doc/keys.R
 84e4760fec6195d3851b4dc45f7857e6 *inst/doc/keys.Rmd
-edaed2f589b92b53176d72afa1619a24 *inst/doc/keys.html
+41eedda881d94b7db5a19df3962a1a4a *inst/doc/keys.html
 91da732f2fc44700d7816c659df5a2d3 *inst/doc/secure_rng.R
 35ea87007fe89af619623a6d75c0d02d *inst/doc/secure_rng.Rmd
-4029bdb561d1e936ecdb3ef13672146f *inst/doc/secure_rng.html
-74b6933e818c6823f980df0a8188f449 *man/aes_cbc.Rd
-1c13ed2668ebed2de30350511caea7ae *man/askpass.Rd
-1ca678a165f2d0ffb1c5cbf2e5e44045 *man/base64_encode.Rd
-e1a937fa012e57925cbeb3999604c835 *man/bignum.Rd
-545715dec4fb74d120c08dc0ef603d3b *man/certificates.Rd
-87c3686bcbd46853ed1effa125fd1590 *man/ec_dh.Rd
-28ebdd5a99b60ce912506a78c4aeba24 *man/encrypt_envelope.Rd
-8c25de0977573233776fd94989c8b043 *man/fingerprint.Rd
-9e8aaa526774967243a1424a68918bc4 *man/hash.Rd
-b2b38397d228684dd563e752c6dd7e62 *man/keygen.Rd
-67c1362b33ac630956c5df7d847ca36a *man/my_key.Rd
-b4dd35bdd8b9e97d68d6745e98da81fa *man/openssl.Rd
-7de38a9159ca96b99ceaff5b0dcda70d *man/openssl_config.Rd
-de525b970c0bcc21e6406f81a6671b1c *man/pkcs12.Rd
-cb87777861ac150ab8ca40854e3d2c52 *man/rand_bytes.Rd
-787f03c5b1ba59666fa78a92ccb38a74 *man/read_key.Rd
-395e2868987e31182396aae7d129a60a *man/rsa_encrypt.Rd
-f3a08561a51c4b97a5d2754a0d07111a *man/signatures.Rd
-4160b3fa3eaea2d4882282e7b85ef03a *man/write_pem.Rd
+5a9bd14d203ab5992dfc6963c7746f57 *inst/doc/secure_rng.html
+df6b957f2e8f9ada89d209efdb406dd9 *man/aes_cbc.Rd
+821fff86e73411e0b1e01f67c76f0855 *man/askpass.Rd
+f4ea38f39d1aad5b038633a28303454d *man/base64_encode.Rd
+a2642e78528fa3b9b46b1f2ec6f5ddd6 *man/bignum.Rd
+690c09086e665840ccba3c7c0ccd8e5a *man/certificates.Rd
+02c9b936168bec8eac5bde6e81ed1c3d *man/ec_dh.Rd
+0c9ee7d1b6523742361a41656166d0b4 *man/encrypt_envelope.Rd
+ca30e5c3396fee2a34918a142438c62b *man/fingerprint.Rd
+7d43a905fced4c97984268e7b25b5091 *man/hash.Rd
+4f290c0bea0272615cc732aa8226d557 *man/keygen.Rd
+5bc01b277acb08863091c8c4d23a26ee *man/my_key.Rd
+b20452fc7c5e541f9bdd745dbad5ae74 *man/openssl.Rd
+c6dedbe2930fbee38574536ccbda951d *man/openssl_config.Rd
+c2a6a6d405b9335fbe134b228ba18087 *man/pkcs12.Rd
+1ad5dbf07f0de13cf45a025a0b448813 *man/rand_bytes.Rd
+dc75a06e615f7c345fa414c29fdcd120 *man/read_key.Rd
+21acd74a41d2b1da232519ea14328b16 *man/rsa_encrypt.Rd
+6a9263969f452ad21e19ab59afb7f871 *man/signatures.Rd
+61f5bc04814296a77da92b2dad325f0e *man/write_pem.Rd
 63fb8fd20f3b348b80351510e2e5675b *src/Makevars.in
-4b696cb9e4e5ccb5297a1f65819b561d *src/Makevars.win
-ec75a500d0835cc440659acff51884cf *src/aes.c
-d9273b6812a70794e297730111c49a94 *src/base64.c
-789556b3dd7d4b043db77afe01f08ada *src/bignum.c
-6752edae2fc2f733baf351cc1149b22d *src/cert.c
+3efc17839bcae8b88c76d24a1fadf16b *src/Makevars.win
+0eae18ebae65f2ad655b4eb71d0bebcb *src/aes.c
+5db45ff43e7a37c4f59b3ad129d76ce1 *src/base64.c
+eb8f70e61aa88dcfaf6e2c39e9c7edef *src/bignum.c
+4676db7d695df4924de1fd87a54a8a47 *src/cert.c
 c5b03b47b76b7b90629cdcbbdcabdab3 *src/compatibility.c
 8f3be798aec8d2f53f0e30c6c715374b *src/compatibility.h
 0f19e24b658b557428bf8dd2260a9b80 *src/diffie.c
@@ -76,19 +77,21 @@ f500aaadfec8452ef8b15900fe5889d8 *src/envelope.c
 80a12511a5a8f3f85c7b85fe84bc3111 *src/error.c
 885881b0b39fb78467a181be47eacb33 *src/hash.c
 b2eac88701940d8af4d42b47d315b37a *src/info.c
-5349bde8c0f5fd40969108f9ca808eb7 *src/keygen.c
-d7a97e2adce16528f0ee727cd0303121 *src/keys.c
-24ca50752f9b4fd5e77fb1d74e9e9a50 *src/onload.c
-cff1360009c8a4bff591014b57c7a36a *src/openssh.c
+b7f077286f12beda34652c1796011347 *src/keygen.c
+bfaa00d8d44336c760723d59c11cae07 *src/keys.c
+def936f844c66d45fcc8fe7b191807ea *src/onload.c
+a075da5ab7870a2599b27b91d68f2e28 *src/openssh.c
 d7a521f29396b74ed2a3206504865ac6 *src/password.c
-2e931f7bd2eba615eeb182c565ed9253 *src/pem.c
-d17725a19d27e0c13d4fc8043fa1904f *src/pkcs12.c
-ca630c283c9c20103ef87dc212210c9f *src/pkcs7.c
+3b05b72a904973125d51987ba5aa678d *src/pem.c
+027652d6f67934058dd3b546e8b04801 *src/pkcs12.c
+e32daf32ca605f541ee1d0a1f7d73f4f *src/pkcs7.c
 0a38050f3a4e6bd4a8d84d71235a40fe *src/rand.c
-85c1114dce920807918a9ed6a3c24cef *src/rsa.c
-c89b39f64e800a17d383836724a0cb5d *src/signing.c
-905d1cdba52b93c05ea36c4fac1d8c7c *src/ssl.c
+751b3728424ef0482e12d1b68477a62a *src/rsa.c
+b28357489ff481c2eff572384a8e4c95 *src/signing.c
+5a476db6ebd0b8cdd77b81d0d95198b1 *src/ssl.c
 47b98e462e74c32e0de8ef9df32a6c17 *src/stream.c
+6527d02975f16baeece916390f03e30b *src/tests/main.c
+0dd3005581d834a85d42923c60133272 *src/tests/soname.h
 1433f784099134008cae33658e4b7bf7 *src/utils.h
 8d3a14570f0b38da0e4617c229ecc5e1 *src/win32/ipv6.c
 328065f2dd8497384a246e62e357e64f *src/write.c
@@ -157,9 +160,10 @@ a7b9d2b3e21f6a82a775a95cc47e789b *tests/keys/signatures.txt
 946876a3939d38dcf016ab1a78524b18 *tests/keys/testmd5.sig
 155adaa2076d9f03e96e639e35bc83ed *tests/keys/testsha1.sig
 d36c00d3573ddb09feb853bd5f9f6165 *tests/testthat.R
-1859c337baf484e07cb43695d1e45c5c *tests/testthat/test_bignum.R
+e9149badf8f951650580efee09b494e2 *tests/testthat/test_bignum.R
 eac7fe63112e5e54063c31bc6b85dc21 *tests/testthat/test_cert.R
 e5bd1c312bdf61667e0f4bb4e7fa3012 *tests/testthat/test_encrypt.R
+4ef5a90b59cfad7fe11470c59d8673d7 *tests/testthat/test_google.R
 2567bc46f4e180187cbe91e3b29ece7a *tests/testthat/test_hash.R
 3769c5642de0c92a01b0ce26a5c2b564 *tests/testthat/test_hash_error.R
 0b06247d355631b5b8514b1f0c400b28 *tests/testthat/test_hash_output_length.R
@@ -174,8 +178,8 @@ ef3bf5166624f519570629b396a5481f *tests/testthat/test_my_key.R
 41db695299df32c13b94f7e373e4f90d *tests/testthat/test_rand_error.R
 7a3694618b99ad418b4b50245aa4bd47 *tests/testthat/test_salting.R
 0ec27c181a66ce5b72bc8c3940e9e00e *tools/version.c
-fa81790d90a551ba6a6ba9afc61b772b *tools/winlibs.R
-a4e5f2bd8377da2198e2920218af2530 *vignettes/bignum.Rmd
-b09c484e5db70d1c14c16989744f45f4 *vignettes/crypto_hashing.Rmd
+497dfd3cbf113981c70269ce4b31c496 *tools/winlibs.R
+745cc4ee4a0217d09448b71e583c6de2 *vignettes/bignum.Rmd
+0b17ff80c3353c70f01e43324820eb32 *vignettes/crypto_hashing.Rmd
 84e4760fec6195d3851b4dc45f7857e6 *vignettes/keys.Rmd
 35ea87007fe89af619623a6d75c0d02d *vignettes/secure_rng.Rmd
diff --git a/NAMESPACE b/NAMESPACE
index ecb310b..dcf3c9b 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -36,9 +36,11 @@ S3method(.DollarNames,key)
 S3method(.DollarNames,pubkey)
 S3method(as.character,bignum)
 S3method(as.character,hash)
+S3method(as.double,bignum)
 S3method(as.environment,cert)
 S3method(as.environment,key)
 S3method(as.environment,pubkey)
+S3method(as.integer,bignum)
 S3method(as.list,cert)
 S3method(as.list,key)
 S3method(as.list,pubkey)
@@ -118,6 +120,7 @@ useDynLib(openssl,R_base64_decode)
 useDynLib(openssl,R_base64_encode)
 useDynLib(openssl,R_bignum_add)
 useDynLib(openssl,R_bignum_as_character)
+useDynLib(openssl,R_bignum_as_integer)
 useDynLib(openssl,R_bignum_bits)
 useDynLib(openssl,R_bignum_compare)
 useDynLib(openssl,R_bignum_devide)
@@ -164,9 +167,10 @@ useDynLib(openssl,R_parse_der_pubkey)
 useDynLib(openssl,R_parse_pem)
 useDynLib(openssl,R_parse_pem_cert)
 useDynLib(openssl,R_parse_pem_key)
-useDynLib(openssl,R_parse_pem_pkcs1)
+useDynLib(openssl,R_parse_pem_key_pkcs1)
 useDynLib(openssl,R_parse_pem_pkcs7)
 useDynLib(openssl,R_parse_pem_pubkey)
+useDynLib(openssl,R_parse_pem_pubkey_pkcs1)
 useDynLib(openssl,R_parse_pkcs12)
 useDynLib(openssl,R_pem_write_cert)
 useDynLib(openssl,R_pem_write_key)
diff --git a/NEWS b/NEWS
index f1a0078..0e964cb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,16 @@
+0.9.7
+ - Configure script checks SHLIB_VERSION_NUMBER to find matching lib
+ - Added internal stopifnot() replacement to give more helpful error mesasges
+ - Add live SSL unit tests from https://pki.goog
+ - Fix for OpenBSD/FreeBSD (#41)
+ - Added as.integer.bignum() method
+ - Update maintainer email address
+ - Add symbol registration call in R_init_openssl
+ - Reject empty digests when signing (#44)
+ - Use OPENSSL_free to free OpenSSL's allocations (#44)
+ - Cleanups for ec_keygen() (#44)
+ - Windows: update OpenSSL to 1.1.0f
+
 0.9.6
  - Add read_p7b() and write_p7b() for certificate bundles
  - Rename read_pkcs12 / write_pkcs12 to read_p12 / write_p12
@@ -7,6 +20,7 @@
  - Sync bundled cacert.pem with Mozilla as of: Wed Sep 14 03:12:05 2016
  - Added blake2b and blake2s hash functions (only available in libssl 1.1)
  - Fix support for LibreSSL
+ - Windows: update libssl/libcrypto to 1.1.0c
 
 0.9.5
  - Support for new API in OpenSSL 1.1.0
diff --git a/R/aes.R b/R/aes.R
index f8a0e0d..087fbc3 100644
--- a/R/aes.R
+++ b/R/aes.R
@@ -3,7 +3,7 @@
 #' Low-level symmetric encryption/decryption using the AES block cipher in CBC mode.
 #' The key is a raw vector, for example a hash of some secret. When no shared
 #' secret is available, a random key can be used which is exchanged via an
-#' asymettric protocol such as RSA. See \code{\link{rsa_encrypt}} for a worked example
+#' asymmetric protocol such as RSA. See \code{\link{rsa_encrypt}} for a worked example
 #' or \code{\link{encrypt_envelope}} for a high-level wrapper combining AES and RSA.
 #'
 #' @export
diff --git a/R/bignum.R b/R/bignum.R
index 1b1cbcd..85a1c1e 100644
--- a/R/bignum.R
+++ b/R/bignum.R
@@ -1,12 +1,12 @@
 #' Big number arithmetic
 #'
 #' Basic operations for working with large integers. The \code{bignum}
-#' funtion converts a positive integer, string or raw vector into a bignum type.
+#' function converts a positive integer, string or raw vector into a bignum type.
 #' All basic \link{Arithmetic} and \link{Comparison} operators such as
 #' \code{+}, \code{-}, \code{*}, \code{^}, \code{\%\%}, \code{\%/\%}, \code{==},
 #' \code{!=}, \code{<}, \code{<=}, \code{>} and \code{>=} are implemented for
 #' bignum objects. The
-#' \href{https://en.wikipedia.org/wiki/Modular_exponentiation}{Modular exponenent}
+#' \href{https://en.wikipedia.org/wiki/Modular_exponentiation}{Modular exponent}
 #' (\code{a^b \%\% m}) can be calculated using \code{\link{bignum_mod_exp}}
 #' when \code{b} is too large for calculating \code{a^b} directly.
 #'
@@ -69,6 +69,19 @@ as.character.bignum <- function(x, hex = FALSE, ...){
 }
 
 #' @export
+as.double.bignum <- function(x, ...){
+  if(any(x > bignum("9007199254740992")))
+    warning("loss of precision for coersing bignum to double")
+  as.numeric(as.character(x))
+}
+
+#' @export
+#' @useDynLib openssl R_bignum_as_integer
+as.integer.bignum <- function(x, ...){
+  .Call(R_bignum_as_integer, x)
+}
+
+#' @export
 #' @useDynLib openssl R_bignum_add
 `+.bignum` <- function(x, y){
   .Call(R_bignum_add, bn(x), bn(y))
diff --git a/R/cert.R b/R/cert.R
index d1265d6..ef008d3 100644
--- a/R/cert.R
+++ b/R/cert.R
@@ -1,6 +1,6 @@
 #' X509 certificates
 #'
-#' Read, download, analyize and verify X.509 certificates.
+#' Read, download, analyze and verify X.509 certificates.
 #'
 #' If https verification fails and you can't figure out why, have a look
 #' at \url{https://ssldecoder.org}.
@@ -9,7 +9,7 @@
 #' @export
 #' @rdname certificates
 #' @seealso \link{read_cert}
-#' @param cert certficate (or certificate-chain) to be verified. Must be cert or list or path.
+#' @param cert certificate (or certificate-chain) to be verified. Must be cert or list or path.
 #' @param root trusted pubkey or certificate(s) e.g. CA bundle.
 #' @examples # Verify the r-project HTTPS cert
 #' chain <- download_ssl_cert("www.r-project.org", 443)
@@ -30,6 +30,8 @@ cert_verify <- function(cert, root = ca_bundle()){
   if(!is.list(cert))
     cert <- read_cert_bundle(cert)
   stopifnot(inherits(cert[[1]], "cert"))
+  if(inherits(root, "cert"))
+    root <- list(root)
   if(!is.raw(root) && !is.list(root)){
     buf <- read_input(root)
     names <- pem_names(buf)
diff --git a/R/diffie.R b/R/diffie.R
index 6eea6da..3316b0c 100644
--- a/R/diffie.R
+++ b/R/diffie.R
@@ -1,7 +1,7 @@
 #' Diffie-Hellman Key Agreement
 #'
 #' Key agreement is one-step method of creating a shared secret between two
-#' peers. Both peers can indendently derive the joined secret by combining
+#' peers. Both peers can independently derive the joined secret by combining
 #' his or her private key with the public key from the peer.
 #'
 #' Currently only Elliptic Curve Diffie Hellman (ECDH) is implemented.
diff --git a/R/envelope.R b/R/envelope.R
index ba6d5b7..cc526ac 100644
--- a/R/envelope.R
+++ b/R/envelope.R
@@ -1,7 +1,7 @@
 #' Envelope encryption
 #'
 #' An \href{https://wiki.openssl.org/index.php/EVP_Asymmetric_Encryption_and_Decryption_of_an_Envelope}{envelope}
-#' contains ciphertext along with an encrypted session key and optionally and initialiation
+#' contains ciphertext along with an encrypted session key and optionally and initialization
 #' vector. The \code{\link{encrypt_envelope}} generates a random IV and session-key which is
 #' used to encrypt the \code{data} with \code{\link[openssl:aes_cbc]{AES}} stream cipher. The
 #' session key itself is encrypted using the given RSA key (see \code{\link{rsa_encrypt}}) and
diff --git a/R/read.R b/R/read.R
index aee20c2..a438429 100644
--- a/R/read.R
+++ b/R/read.R
@@ -10,7 +10,7 @@
 #' conform to the X509 standard.
 #'
 #' The \code{password} argument is needed when reading keys that are protected with a
-#' passphrase. It can either be a string containing the passphrase, or a custom calback
+#' passphrase. It can either be a string containing the passphrase, or a custom callback
 #' function that will be called by OpenSSL to read the passphrase. The function should
 #' take one argument (a string with a message) and return a string. The default is to
 #' use \code{readline} which will prompt the user in an interactive R session.
@@ -55,7 +55,14 @@ read_key <- function(file, password = askpass, der = is.raw(file)){
       stop("Input is a certificate. Use read_cert() to read.")
     if(!any(grepl("PRIVATE", names)))
       stop("Invalid input: ", names)
-    parse_pem_key(buf, password)
+    if(any(grepl("RSA PRIVATE", names))){
+      # Try the modern format first, PKCS1 is very uncommon nowadays
+      tryCatch(parse_pem_key(buf, password), error = function(e){
+        parse_legacy_key(buf, password)
+      })
+    } else {
+      parse_pem_key(buf, password)
+    }
   }
   structure(key, class = c("key", pubkey_type(derive_pubkey(key))))
 }
@@ -115,9 +122,16 @@ read_cert_bundle <- function(file){
 }
 
 read_input <- function(x){
+  if(is.character(x) && grepl("^https?://", x)){
+    x <- url(x)
+  }
   if(is.raw(x)){
     x
   } else if(inherits(x, "connection")){
+    if(!isOpen(x)){
+      open(x, "rb")
+      on.exit(close(x))
+    }
     if(summary(x)$text == "text") {
       charToRaw(paste(readLines(x), collapse = "\n"))
     } else {
@@ -168,6 +182,15 @@ parse_pem_key <- function(buf, password = readline){
   .Call(R_parse_pem_key, buf, password)
 }
 
+#' @useDynLib openssl R_parse_pem_key_pkcs1
+parse_legacy_key <- function(buf, password){
+  tryCatch({
+    .Call(R_parse_pem_key_pkcs1, buf, password)
+  }, error = function(e){
+    parse_pem_key(buf, password)
+  })
+}
+
 #' @useDynLib openssl R_parse_der_key
 parse_der_key <- function(buf){
   .Call(R_parse_der_key, buf)
@@ -178,11 +201,11 @@ parse_pem_pubkey <- function(buf){
   .Call(R_parse_pem_pubkey, buf)
 }
 
-#' @useDynLib openssl R_parse_pem_pkcs1
+#' @useDynLib openssl R_parse_pem_pubkey_pkcs1
 parse_legacy_pubkey <- function(buf){
   # It is a common problem that clients add the wrong header
   tryCatch({
-    .Call(R_parse_pem_pkcs1, buf)
+    .Call(R_parse_pem_pubkey_pkcs1, buf)
   }, error = function(e){
     out <- gsub("RSA PUBLIC", "PUBLIC", rawToChar(buf), fixed = TRUE)
     parse_pem_pubkey(charToRaw(out))
diff --git a/R/stopifnot.R b/R/stopifnot.R
new file mode 100644
index 0000000..54812ed
--- /dev/null
+++ b/R/stopifnot.R
@@ -0,0 +1,10 @@
+# custom stopifnot() that includes a stack trace
+stopifnot <- function(...){
+  expr <- as.list(match.call(expand.dots = TRUE)[-1])
+  values <- vapply(list(...), isTRUE, logical(1))
+  if(!all(values)){
+    cl <- utils::tail(sys.calls(), 2)[[1]]
+    err <- sprintf("check failed: (%s)", deparse(expr[[which(!values)[1]]]))
+    stop(simpleError(err, call = cl))
+  }
+}
diff --git a/build/vignette.rds b/build/vignette.rds
index d885b89..dadb5f5 100644
Binary files a/build/vignette.rds and b/build/vignette.rds differ
diff --git a/configure b/configure
index ab12978..fc52244 100755
--- a/configure
+++ b/configure
@@ -36,13 +36,8 @@ else
   if [ $? -eq 0 ]; then
     BREWDIR=`brew --prefix`
   else
-    BREWDIR="/tmp/homebrew"
-    rm -Rf $BREWDIR
-    mkdir -p $BREWDIR
-    echo "Auto-brewing $PKG_BREW_NAME in $BREWDIR..."
-    curl -fsSL https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C $BREWDIR
-    HOMEBREW_CACHE="/tmp" $BREWDIR/bin/brew install --force-bottle $PKG_BREW_NAME 2>&1 | perl -pe 's/Warning/Note/gi'
-    rm -f $BREWDIR/opt/$PKG_BREW_NAME/lib/*.dylib
+    curl -sfL https://jeroen.github.io/autobrew/openssl > $TMPDIR/autobrew
+    source $TMPDIR/autobrew
   fi
   PKG_CFLAGS="-I$BREWDIR/opt/openssl at 1.1/include -I$BREWDIR/opt/openssl/include"
   PKG_LIBS="-L$BREWDIR/opt/openssl at 1.1/lib -L$BREWDIR/opt/openssl/lib $PKG_LIBS"
@@ -50,15 +45,14 @@ else
   esac
 fi
 
-# For debugging
-echo "Using PKG_CFLAGS=$PKG_CFLAGS"
-echo "Using PKG_LIBS=$PKG_LIBS"
-
 # Find compiler
 CC=`${R_HOME}/bin/R CMD config CC`
 CFLAGS=`${R_HOME}/bin/R CMD config CFLAGS`
 CPPFLAGS=`${R_HOME}/bin/R CMD config CPPFLAGS`
 
+# For debugging
+echo "Using PKG_CFLAGS=$PKG_CFLAGS"
+
 # Test configuration
 ${CC} ${CPPFLAGS} ${PKG_CFLAGS} ${CFLAGS} -E ${PKG_TEST_FILE} >/dev/null 2>&1
 
@@ -78,6 +72,27 @@ if [ $? -ne 0 ]; then
   exit 1;
 fi
 
+# Try to link against the correct OpenSSL version
+if [ -z "$AUTOBREW" ]; then
+SONAME=`${CC} -E ${PKG_CFLAGS} src/tests/soname.h | sh | xargs`
+if [ "$SONAME" ]; then
+case "$OSTYPE" in
+  "darwin"*)
+  PKG_LIBS_VERSIONED=`echo "${PKG_LIBS}" | sed "s/-lssl/-lssl.${SONAME}/" | sed "s/-lcrypto/-lcrypto.${SONAME}/"`
+  ;;
+  *)
+  PKG_LIBS_VERSIONED=`echo "${PKG_LIBS}" | sed "s/-lssl/-l:libssl.so.${SONAME}/" | sed "s/-lcrypto/-l:libcrypto.so.${SONAME}/"`
+  ;;
+esac
+
+# Test if versioned linking works
+${CC} ${PKG_CFLAGS} src/tests/main.c ${PKG_LIBS_VERSIONED} -o src/main.exe 2>/dev/null
+if [ $? -eq 0 ]; then PKG_LIBS="${PKG_LIBS_VERSIONED}"; fi
+fi #SONAME
+fi #AUTOBREW
+
+echo "Using PKG_LIBS=$PKG_LIBS"
+
 # Write to Makevars
 sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars
 
diff --git a/inst/doc/bignum.Rmd b/inst/doc/bignum.Rmd
index 3693f4d..9bef2f3 100644
--- a/inst/doc/bignum.Rmd
+++ b/inst/doc/bignum.Rmd
@@ -17,7 +17,7 @@ knitr::opts_chunk$set(echo = TRUE)
 
 Primitive types such as `int` or `double` store numbers in exactly one or two bytes, with finite precision. This suffices for most applications, but cryptographic methods require arithmetic on much larger numbers and without loss of precision. Therefore OpenSSL provides a __bignum__ data type which holds arbitrary sized integers and implements all basic arithmetic and comparison operators such as `+`, `-`, `*`, `^`, `%%`, `%/%`, `==`, `!=`, `<`, `<=`, `>` and `>=`.
 
-One special case, the [__modular exponenent__](https://en.wikipedia.org/wiki/Modular_exponentiation) `a^b %% m` can be calculated using `bignum_mod_exp` when `b` is too large for calculating `a^b`.
+One special case, the [__modular exponent__](https://en.wikipedia.org/wiki/Modular_exponentiation) `a^b %% m` can be calculated using `bignum_mod_exp` when `b` is too large for calculating `a^b`.
 
 ```{r}
 # create a bignum
diff --git a/inst/doc/bignum.html b/inst/doc/bignum.html
index e7cee61..a3156db 100644
--- a/inst/doc/bignum.html
+++ b/inst/doc/bignum.html
@@ -4,13 +4,13 @@
 
 <head>
 
-<meta charset="utf-8">
+<meta charset="utf-8" />
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="pandoc" />
 
 
 
-<meta name="date" content="2016-12-30" />
+<meta name="date" content="2017-09-06" />
 
 <title>Fun with bignum: how RSA encryption works</title>
 
@@ -20,7 +20,7 @@
 <script src="data:application/x-javascript;base64,LyohCiAqIEJvb3RzdHJhcCB2My4zLjUgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKQogKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy4KICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlCiAqLwppZigidW5kZWZpbmVkIj09dHlwZW9mIGpRdWVyeSl0aHJvdyBuZXcgRXJyb3IoIkJvb3RzdHJhcCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5Iik7K2Z1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0Ijt2YXIgYj1hLmZuLmpxdWVyeS5zcGxpdCgiICIpWzBdLnNwbGl0KCIuIik7aWYoYlswXTwyJiZiWzFdPDl8fDE9PWJbMF0mJjk9PWJbMV0mJmJbMl08MSl0aHJvdy [...]
 <script src="data:application/x-javascript;base64,LyoqCiogQHByZXNlcnZlIEhUTUw1IFNoaXYgMy43LjIgfCBAYWZhcmthcyBAamRhbHRvbiBAam9uX25lYWwgQHJlbSB8IE1JVC9HUEwyIExpY2Vuc2VkCiovCi8vIE9ubHkgcnVuIHRoaXMgY29kZSBpbiBJRSA4CmlmICghIXdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKCJNU0lFIDgiKSkgewohZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKGEsYil7dmFyIGM9YS5jcmVhdGVFbGVtZW50KCJwIiksZD1hLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF18fGEuZG9jdW1lbnRFbGVtZW50O3JldHVybiBjLmlubmVySFRNTD0ieDxzdHlsZT4iK2IrIjwvc3R5bGU+IixkLm [...]
 <script src="data:application/x-javascript;base64,LyohIFJlc3BvbmQuanMgdjEuNC4yOiBtaW4vbWF4LXdpZHRoIG1lZGlhIHF1ZXJ5IHBvbHlmaWxsICogQ29weXJpZ2h0IDIwMTMgU2NvdHQgSmVobAogKiBMaWNlbnNlZCB1bmRlciBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRqZWhsL1Jlc3BvbmQvYmxvYi9tYXN0ZXIvTElDRU5TRS1NSVQKICogICovCgovLyBPbmx5IHJ1biB0aGlzIGNvZGUgaW4gSUUgOAppZiAoISF3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgiTVNJRSA4IikpIHsKIWZ1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0IjthLm1hdGNoTWVkaWE9YS5tYXRjaE1lZGlhfHxmdW5jdGlvbihhKXt2YXIgYixjPWEuZG [...]
-<script src="data:application/x-javascript;base64,Cgp3aW5kb3cuYnVpbGRUYWJzZXRzID0gZnVuY3Rpb24odG9jSUQpIHsKCiAgLy8gYnVpbGQgYSB0YWJzZXQgZnJvbSBhIHNlY3Rpb24gZGl2IHdpdGggdGhlIC50YWJzZXQgY2xhc3MKICBmdW5jdGlvbiBidWlsZFRhYnNldCh0YWJzZXQpIHsKCiAgICAvLyBjaGVjayBmb3IgZmFkZSBhbmQgcGlsbHMgb3B0aW9ucwogICAgdmFyIGZhZGUgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1mYWRlIik7CiAgICB2YXIgcGlsbHMgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1waWxscyIpOwogICAgdmFyIG5hdkNsYXNzID0gcGlsbHMgPyAibmF2LXBpbGxzIiA6ICJuYXYtdGFicyI7CgogIC [...]
+<script src="data:application/x-javascript;base64,CgovKioKICogalF1ZXJ5IFBsdWdpbjogU3RpY2t5IFRhYnMKICoKICogQGF1dGhvciBBaWRhbiBMaXN0ZXIgPGFpZGFuQHBocC5uZXQ+CiAqIGFkYXB0ZWQgYnkgUnViZW4gQXJzbGFuIHRvIGFjdGl2YXRlIHBhcmVudCB0YWJzIHRvbwogKiBodHRwOi8vd3d3LmFpZGFubGlzdGVyLmNvbS8yMDE0LzAzL3BlcnNpc3RpbmctdGhlLXRhYi1zdGF0ZS1pbi1ib290c3RyYXAvCiAqLwooZnVuY3Rpb24oJCkgewogICJ1c2Ugc3RyaWN0IjsKICAkLmZuLnJtYXJrZG93blN0aWNreVRhYnMgPSBmdW5jdGlvbigpIHsKICAgIHZhciBjb250ZXh0ID0gdGhpczsKICAgIC8vIFNob3cgdGhlIHRhYi [...]
 <link href="data:text/css;charset=utf-8,pre%20%2Eoperator%2C%0Apre%20%2Eparen%20%7B%0Acolor%3A%20rgb%28104%2C%20118%2C%20135%29%0A%7D%0Apre%20%2Eliteral%20%7B%0Acolor%3A%20%23990073%0A%7D%0Apre%20%2Enumber%20%7B%0Acolor%3A%20%23099%3B%0A%7D%0Apre%20%2Ecomment%20%7B%0Acolor%3A%20%23998%3B%0Afont%2Dstyle%3A%20italic%0A%7D%0Apre%20%2Ekeyword%20%7B%0Acolor%3A%20%23900%3B%0Afont%2Dweight%3A%20bold%0A%7D%0Apre%20%2Eidentifier%20%7B%0Acolor%3A%20rgb%280%2C%200%2C%200%29%3B%0A%7D%0Apre%20%2Estri [...]
 <script src="data:application/x-javascript;base64,dmFyIGhsanM9bmV3IGZ1bmN0aW9uKCl7ZnVuY3Rpb24gbShwKXtyZXR1cm4gcC5yZXBsYWNlKC8mL2dtLCImYW1wOyIpLnJlcGxhY2UoLzwvZ20sIiZsdDsiKX1mdW5jdGlvbiBmKHIscSxwKXtyZXR1cm4gUmVnRXhwKHEsIm0iKyhyLmNJPyJpIjoiIikrKHA/ImciOiIiKSl9ZnVuY3Rpb24gYihyKXtmb3IodmFyIHA9MDtwPHIuY2hpbGROb2Rlcy5sZW5ndGg7cCsrKXt2YXIgcT1yLmNoaWxkTm9kZXNbcF07aWYocS5ub2RlTmFtZT09IkNPREUiKXtyZXR1cm4gcX1pZighKHEubm9kZVR5cGU9PTMmJnEubm9kZVZhbHVlLm1hdGNoKC9ccysvKSkpe2JyZWFrfX19ZnVuY3Rpb24gaCh0LH [...]
 
@@ -117,13 +117,13 @@ $(document).ready(function () {
 
 
 <h1 class="title toc-ignore">Fun with bignum: how RSA encryption works</h1>
-<h4 class="date"><em>2016-12-30</em></h4>
+<h4 class="date"><em>2017-09-06</em></h4>
 
 </div>
 
 
 <p>Primitive types such as <code>int</code> or <code>double</code> store numbers in exactly one or two bytes, with finite precision. This suffices for most applications, but cryptographic methods require arithmetic on much larger numbers and without loss of precision. Therefore OpenSSL provides a <strong>bignum</strong> data type which holds arbitrary sized integers and implements all basic arithmetic and comparison operators such as <code>+</code>, <code>-</code>, <code>*</code>, <code> [...]
-<p>One special case, the <a href="https://en.wikipedia.org/wiki/Modular_exponentiation"><strong>modular exponenent</strong></a> <code>a^b %% m</code> can be calculated using <code>bignum_mod_exp</code> when <code>b</code> is too large for calculating <code>a^b</code>.</p>
+<p>One special case, the <a href="https://en.wikipedia.org/wiki/Modular_exponentiation"><strong>modular exponent</strong></a> <code>a^b %% m</code> can be calculated using <code>bignum_mod_exp</code> when <code>b</code> is too large for calculating <code>a^b</code>.</p>
 <pre class="r"><code># create a bignum
 y <- bignum("123456789123456789")
 z <- bignum("D41D8CD98F00B204E9800998ECF8427E", hex = TRUE)
@@ -151,10 +151,10 @@ stopifnot(div < z)</code></pre>
 <p>OpenSSL has a key generator that does these things for us.</p>
 <pre class="r"><code>(key <- rsa_keygen(512))</code></pre>
 <pre><code>## [512-bit rsa private key]
-## md5: c4c39ba29f28517eec49c6b2755be69c</code></pre>
+## md5: f3e9e0a6ec5b2c719bf09764a513e6c9</code></pre>
 <pre class="r"><code>(pubkey <- key$pubkey)</code></pre>
 <pre><code>## [512-bit rsa public key]
-## md5: c4c39ba29f28517eec49c6b2755be69c</code></pre>
+## md5: f3e9e0a6ec5b2c719bf09764a513e6c9</code></pre>
 <p>Usually we would use <code>rsa_encrypt</code> and <code>rsa_decrypt</code> to perform the encryption:</p>
 <pre class="r"><code>msg <- charToRaw("hello world")
 ciphertext <- rsa_encrypt(msg, pubkey)
@@ -169,25 +169,25 @@ rawToChar(rsa_decrypt(ciphertext, key))</code></pre>
 <pre><code>## $e
 ## [b] 65537
 ## $n
-## [b] 10569026565286155820720744523231748863822088228516641890189557970400740945053483041322691870588364647828869510740348759232483548879935360746654051791408149
+## [b] 11506376768338105178752846727294481883562616201581937369061648167799257547871616092773250565261426119531931897418845260453439169557232181417713802699552101
 ## $p
-## [b] 104561422052657818321305572918830068873573672192479059216414484631900340164947
+## [b] 114249337979811507156446710737174305407329147065865218427468300430068102465743
 ## $q
-## [b] 101079598553695307281587615375424174526793348449800289774735773171041152946167
+## [b] 100712852886476645392074969523321593562788723066792728000503924696327841383307
 ## $d
-## [b] 9722046576564015802556572372599081133642287392711380691061194474046853958413366923679924705437273484878878791185414862207468314595922482404144058842071453
+## [b] 9018539992053701706165944090222861145810166874081196527710906532727229846674554249883658592279959649798538304802957511773146552053224587844967534718101205
 ## $dp
-## [b] 18054183925841522683734285413575248476026666990098616569158586876033145388201
+## [b] 20089558125629000541234598692878781383250089121977368160857907657599597369657
 ## $dq
-## [b] 87431531544194570687987529798465685117946523901342429875493561034529820989857
+## [b] 36864681445499309494033697665364018920270056268204079405589035957401293726355
 ## $qi
-## [b] 35189962504388150911189634866142836821114269709182565183863384271658676836525</code></pre>
+## [b] 22029586051221831378804972338158649429574626573505831131307284714314542027140</code></pre>
 <p>You can verify that the equations above hold for this key. The public key is simply a subset of the key which only contains <span class="math inline">\(n\)</span> and <span class="math inline">\(e\)</span>:</p>
 <pre class="r"><code>pubkey$data</code></pre>
 <pre><code>## $e
 ## [b] 65537
 ## $n
-## [b] 10569026565286155820720744523231748863822088228516641890189557970400740945053483041322691870588364647828869510740348759232483548879935360746654051791408149</code></pre>
+## [b] 11506376768338105178752846727294481883562616201581937369061648167799257547871616092773250565261426119531931897418845260453439169557232181417713802699552101</code></pre>
 <p>In order to encrypt a message into ciphertext we have to treat the message data as an integer. The message cannot be larger than the key size. For example convert the text <code>hello world</code> into an integer:</p>
 <pre class="r"><code>m <- bignum(charToRaw("hello world"))
 print(m)</code></pre>
@@ -197,10 +197,10 @@ print(m)</code></pre>
 n <- pubkey$data$n
 c <- (m ^ e) %% n
 print(c)</code></pre>
-<pre><code>## [b] 3325659323980215257106509330346053668176374408427813427001691391003696397464298082936759956359781182102881980395262788263285765465327517193833561164790947</code></pre>
+<pre><code>## [b] 9241055974344934160718068070000374111648747760075110185628533019005269897816259320179651071168313053580748146348517105430877230612978850667781810423060370</code></pre>
 <p>This is number represents out encrypted message! It is usually exchanged using base64 notation for human readability:</p>
 <pre class="r"><code>base64_encode(c)</code></pre>
-<pre><code>## [1] "P3978g+Eg158DwmcpWl5VcPbXKv790cz5p/ozD5uNTGnMd21igOnEhOhaKGveZIAvKXwTVkaNYVefdobMxq8ow=="</code></pre>
+<pre><code>## [1] "sHFXN6kIjahykYvchlShu9lU/QTrj1aEFrg0BkH08W7ACz169J9EYXZmb8eVFPelKxdtBT5w6aLZVSGZmwPXkg=="</code></pre>
 <p>The ciphertext can be decrypted using <span class="math inline">\(d\)</span> from the corresponding private key via <span class="math inline">\(m = c^d \pmod{n}\)</span>. Note that <code>c^d</code> is too large to calculate directly so we need to use <code>bignum_mod_exp</code> instead.</p>
 <pre class="r"><code>d <- key$data$d
 out <- bignum_mod_exp(c, d, n)
@@ -232,7 +232,7 @@ $(document).ready(function () {
   (function () {
     var script = document.createElement("script");
     script.type = "text/javascript";
-    script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
     document.getElementsByTagName("head")[0].appendChild(script);
   })();
 </script>
diff --git a/inst/doc/crypto_hashing.Rmd b/inst/doc/crypto_hashing.Rmd
index 69603bb..b23d5e4 100644
--- a/inst/doc/crypto_hashing.Rmd
+++ b/inst/doc/crypto_hashing.Rmd
@@ -28,7 +28,7 @@ Functions are fully vectorized for the case of character vectors: a vector with
 md5(c("foo", "bar", "baz"))
 ```
 
-Besides character and raw vectors we can pass a connection object (e.g. a file, socket or url). In this case the function will stream-hash the binary contents of the conection.
+Besides character and raw vectors we can pass a connection object (e.g. a file, socket or url). In this case the function will stream-hash the binary contents of the connection.
 
 ```{r}
 # Stream-hash a file
diff --git a/inst/doc/crypto_hashing.html b/inst/doc/crypto_hashing.html
index 27d1fc6..36e9f18 100644
--- a/inst/doc/crypto_hashing.html
+++ b/inst/doc/crypto_hashing.html
@@ -4,13 +4,13 @@
 
 <head>
 
-<meta charset="utf-8">
+<meta charset="utf-8" />
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="pandoc" />
 
 
 
-<meta name="date" content="2016-12-30" />
+<meta name="date" content="2017-09-06" />
 
 <title>Cryptographic Hashing in R</title>
 
@@ -20,7 +20,7 @@
 <script src="data:application/x-javascript;base64,LyohCiAqIEJvb3RzdHJhcCB2My4zLjUgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKQogKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy4KICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlCiAqLwppZigidW5kZWZpbmVkIj09dHlwZW9mIGpRdWVyeSl0aHJvdyBuZXcgRXJyb3IoIkJvb3RzdHJhcCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5Iik7K2Z1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0Ijt2YXIgYj1hLmZuLmpxdWVyeS5zcGxpdCgiICIpWzBdLnNwbGl0KCIuIik7aWYoYlswXTwyJiZiWzFdPDl8fDE9PWJbMF0mJjk9PWJbMV0mJmJbMl08MSl0aHJvdy [...]
 <script src="data:application/x-javascript;base64,LyoqCiogQHByZXNlcnZlIEhUTUw1IFNoaXYgMy43LjIgfCBAYWZhcmthcyBAamRhbHRvbiBAam9uX25lYWwgQHJlbSB8IE1JVC9HUEwyIExpY2Vuc2VkCiovCi8vIE9ubHkgcnVuIHRoaXMgY29kZSBpbiBJRSA4CmlmICghIXdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKCJNU0lFIDgiKSkgewohZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKGEsYil7dmFyIGM9YS5jcmVhdGVFbGVtZW50KCJwIiksZD1hLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF18fGEuZG9jdW1lbnRFbGVtZW50O3JldHVybiBjLmlubmVySFRNTD0ieDxzdHlsZT4iK2IrIjwvc3R5bGU+IixkLm [...]
 <script src="data:application/x-javascript;base64,LyohIFJlc3BvbmQuanMgdjEuNC4yOiBtaW4vbWF4LXdpZHRoIG1lZGlhIHF1ZXJ5IHBvbHlmaWxsICogQ29weXJpZ2h0IDIwMTMgU2NvdHQgSmVobAogKiBMaWNlbnNlZCB1bmRlciBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRqZWhsL1Jlc3BvbmQvYmxvYi9tYXN0ZXIvTElDRU5TRS1NSVQKICogICovCgovLyBPbmx5IHJ1biB0aGlzIGNvZGUgaW4gSUUgOAppZiAoISF3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgiTVNJRSA4IikpIHsKIWZ1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0IjthLm1hdGNoTWVkaWE9YS5tYXRjaE1lZGlhfHxmdW5jdGlvbihhKXt2YXIgYixjPWEuZG [...]
-<script src="data:application/x-javascript;base64,Cgp3aW5kb3cuYnVpbGRUYWJzZXRzID0gZnVuY3Rpb24odG9jSUQpIHsKCiAgLy8gYnVpbGQgYSB0YWJzZXQgZnJvbSBhIHNlY3Rpb24gZGl2IHdpdGggdGhlIC50YWJzZXQgY2xhc3MKICBmdW5jdGlvbiBidWlsZFRhYnNldCh0YWJzZXQpIHsKCiAgICAvLyBjaGVjayBmb3IgZmFkZSBhbmQgcGlsbHMgb3B0aW9ucwogICAgdmFyIGZhZGUgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1mYWRlIik7CiAgICB2YXIgcGlsbHMgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1waWxscyIpOwogICAgdmFyIG5hdkNsYXNzID0gcGlsbHMgPyAibmF2LXBpbGxzIiA6ICJuYXYtdGFicyI7CgogIC [...]
+<script src="data:application/x-javascript;base64,CgovKioKICogalF1ZXJ5IFBsdWdpbjogU3RpY2t5IFRhYnMKICoKICogQGF1dGhvciBBaWRhbiBMaXN0ZXIgPGFpZGFuQHBocC5uZXQ+CiAqIGFkYXB0ZWQgYnkgUnViZW4gQXJzbGFuIHRvIGFjdGl2YXRlIHBhcmVudCB0YWJzIHRvbwogKiBodHRwOi8vd3d3LmFpZGFubGlzdGVyLmNvbS8yMDE0LzAzL3BlcnNpc3RpbmctdGhlLXRhYi1zdGF0ZS1pbi1ib290c3RyYXAvCiAqLwooZnVuY3Rpb24oJCkgewogICJ1c2Ugc3RyaWN0IjsKICAkLmZuLnJtYXJrZG93blN0aWNreVRhYnMgPSBmdW5jdGlvbigpIHsKICAgIHZhciBjb250ZXh0ID0gdGhpczsKICAgIC8vIFNob3cgdGhlIHRhYi [...]
 <link href="data:text/css;charset=utf-8,pre%20%2Eoperator%2C%0Apre%20%2Eparen%20%7B%0Acolor%3A%20rgb%28104%2C%20118%2C%20135%29%0A%7D%0Apre%20%2Eliteral%20%7B%0Acolor%3A%20%23990073%0A%7D%0Apre%20%2Enumber%20%7B%0Acolor%3A%20%23099%3B%0A%7D%0Apre%20%2Ecomment%20%7B%0Acolor%3A%20%23998%3B%0Afont%2Dstyle%3A%20italic%0A%7D%0Apre%20%2Ekeyword%20%7B%0Acolor%3A%20%23900%3B%0Afont%2Dweight%3A%20bold%0A%7D%0Apre%20%2Eidentifier%20%7B%0Acolor%3A%20rgb%280%2C%200%2C%200%29%3B%0A%7D%0Apre%20%2Estri [...]
 <script src="data:application/x-javascript;base64,dmFyIGhsanM9bmV3IGZ1bmN0aW9uKCl7ZnVuY3Rpb24gbShwKXtyZXR1cm4gcC5yZXBsYWNlKC8mL2dtLCImYW1wOyIpLnJlcGxhY2UoLzwvZ20sIiZsdDsiKX1mdW5jdGlvbiBmKHIscSxwKXtyZXR1cm4gUmVnRXhwKHEsIm0iKyhyLmNJPyJpIjoiIikrKHA/ImciOiIiKSl9ZnVuY3Rpb24gYihyKXtmb3IodmFyIHA9MDtwPHIuY2hpbGROb2Rlcy5sZW5ndGg7cCsrKXt2YXIgcT1yLmNoaWxkTm9kZXNbcF07aWYocS5ub2RlTmFtZT09IkNPREUiKXtyZXR1cm4gcX1pZighKHEubm9kZVR5cGU9PTMmJnEubm9kZVZhbHVlLm1hdGNoKC9ccysvKSkpe2JyZWFrfX19ZnVuY3Rpb24gaCh0LH [...]
 
@@ -117,7 +117,7 @@ $(document).ready(function () {
 
 
 <h1 class="title toc-ignore">Cryptographic Hashing in R</h1>
-<h4 class="date"><em>2016-12-30</em></h4>
+<h4 class="date"><em>2017-09-06</em></h4>
 
 </div>
 
@@ -132,7 +132,7 @@ $(document).ready(function () {
 md5(c("foo", "bar", "baz"))</code></pre>
 <pre><code>[1] "acbd18db4cc2f85cedef654fccc4a4d8" "37b51d194a7513e45b56f6524f2d51f2"
 [3] "73feffa4b7f6bb68e44cf984c85f6e88"</code></pre>
-<p>Besides character and raw vectors we can pass a connection object (e.g. a file, socket or url). In this case the function will stream-hash the binary contents of the conection.</p>
+<p>Besides character and raw vectors we can pass a connection object (e.g. a file, socket or url). In this case the function will stream-hash the binary contents of the connection.</p>
 <pre class="r"><code># Stream-hash a file
 myfile <- system.file("CITATION")
 md5(file(myfile))</code></pre>
@@ -154,9 +154,9 @@ Attaching package: 'digest'</code></pre>
 <pre><code>[1] "acbd18db4cc2f85cedef654fccc4a4d8"</code></pre>
 <pre class="r"><code># Other way around
 digest(cars, skip = 0)</code></pre>
-<pre><code>[1] "ceb7f0b7e120fe0f6e6141ea36b67dcb"</code></pre>
+<pre><code>[1] "1952fbc796e1b9e8a634006f5c6e5770"</code></pre>
 <pre class="r"><code>md5(serialize(cars, NULL))</code></pre>
-<pre><code>md5 ce:b7:f0:b7:e1:20:fe:0f:6e:61:41:ea:36:b6:7d:cb </code></pre>
+<pre><code>md5 19:52:fb:c7:96:e1:b9:e8:a6:34:00:6f:5c:6e:57:70 </code></pre>
 </div>
 
 
@@ -182,7 +182,7 @@ $(document).ready(function () {
   (function () {
     var script = document.createElement("script");
     script.type = "text/javascript";
-    script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
     document.getElementsByTagName("head")[0].appendChild(script);
   })();
 </script>
diff --git a/inst/doc/keys.html b/inst/doc/keys.html
index fb45483..7888050 100644
--- a/inst/doc/keys.html
+++ b/inst/doc/keys.html
@@ -4,13 +4,13 @@
 
 <head>
 
-<meta charset="utf-8">
+<meta charset="utf-8" />
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="pandoc" />
 
 
 
-<meta name="date" content="2016-12-30" />
+<meta name="date" content="2017-09-06" />
 
 <title>Importing and exporting RSA/DSA/EC keys</title>
 
@@ -20,7 +20,7 @@
 <script src="data:application/x-javascript;base64,LyohCiAqIEJvb3RzdHJhcCB2My4zLjUgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKQogKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy4KICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlCiAqLwppZigidW5kZWZpbmVkIj09dHlwZW9mIGpRdWVyeSl0aHJvdyBuZXcgRXJyb3IoIkJvb3RzdHJhcCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5Iik7K2Z1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0Ijt2YXIgYj1hLmZuLmpxdWVyeS5zcGxpdCgiICIpWzBdLnNwbGl0KCIuIik7aWYoYlswXTwyJiZiWzFdPDl8fDE9PWJbMF0mJjk9PWJbMV0mJmJbMl08MSl0aHJvdy [...]
 <script src="data:application/x-javascript;base64,LyoqCiogQHByZXNlcnZlIEhUTUw1IFNoaXYgMy43LjIgfCBAYWZhcmthcyBAamRhbHRvbiBAam9uX25lYWwgQHJlbSB8IE1JVC9HUEwyIExpY2Vuc2VkCiovCi8vIE9ubHkgcnVuIHRoaXMgY29kZSBpbiBJRSA4CmlmICghIXdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKCJNU0lFIDgiKSkgewohZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKGEsYil7dmFyIGM9YS5jcmVhdGVFbGVtZW50KCJwIiksZD1hLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF18fGEuZG9jdW1lbnRFbGVtZW50O3JldHVybiBjLmlubmVySFRNTD0ieDxzdHlsZT4iK2IrIjwvc3R5bGU+IixkLm [...]
 <script src="data:application/x-javascript;base64,LyohIFJlc3BvbmQuanMgdjEuNC4yOiBtaW4vbWF4LXdpZHRoIG1lZGlhIHF1ZXJ5IHBvbHlmaWxsICogQ29weXJpZ2h0IDIwMTMgU2NvdHQgSmVobAogKiBMaWNlbnNlZCB1bmRlciBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRqZWhsL1Jlc3BvbmQvYmxvYi9tYXN0ZXIvTElDRU5TRS1NSVQKICogICovCgovLyBPbmx5IHJ1biB0aGlzIGNvZGUgaW4gSUUgOAppZiAoISF3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgiTVNJRSA4IikpIHsKIWZ1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0IjthLm1hdGNoTWVkaWE9YS5tYXRjaE1lZGlhfHxmdW5jdGlvbihhKXt2YXIgYixjPWEuZG [...]
-<script src="data:application/x-javascript;base64,Cgp3aW5kb3cuYnVpbGRUYWJzZXRzID0gZnVuY3Rpb24odG9jSUQpIHsKCiAgLy8gYnVpbGQgYSB0YWJzZXQgZnJvbSBhIHNlY3Rpb24gZGl2IHdpdGggdGhlIC50YWJzZXQgY2xhc3MKICBmdW5jdGlvbiBidWlsZFRhYnNldCh0YWJzZXQpIHsKCiAgICAvLyBjaGVjayBmb3IgZmFkZSBhbmQgcGlsbHMgb3B0aW9ucwogICAgdmFyIGZhZGUgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1mYWRlIik7CiAgICB2YXIgcGlsbHMgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1waWxscyIpOwogICAgdmFyIG5hdkNsYXNzID0gcGlsbHMgPyAibmF2LXBpbGxzIiA6ICJuYXYtdGFicyI7CgogIC [...]
+<script src="data:application/x-javascript;base64,CgovKioKICogalF1ZXJ5IFBsdWdpbjogU3RpY2t5IFRhYnMKICoKICogQGF1dGhvciBBaWRhbiBMaXN0ZXIgPGFpZGFuQHBocC5uZXQ+CiAqIGFkYXB0ZWQgYnkgUnViZW4gQXJzbGFuIHRvIGFjdGl2YXRlIHBhcmVudCB0YWJzIHRvbwogKiBodHRwOi8vd3d3LmFpZGFubGlzdGVyLmNvbS8yMDE0LzAzL3BlcnNpc3RpbmctdGhlLXRhYi1zdGF0ZS1pbi1ib290c3RyYXAvCiAqLwooZnVuY3Rpb24oJCkgewogICJ1c2Ugc3RyaWN0IjsKICAkLmZuLnJtYXJrZG93blN0aWNreVRhYnMgPSBmdW5jdGlvbigpIHsKICAgIHZhciBjb250ZXh0ID0gdGhpczsKICAgIC8vIFNob3cgdGhlIHRhYi [...]
 <link href="data:text/css;charset=utf-8,pre%20%2Eoperator%2C%0Apre%20%2Eparen%20%7B%0Acolor%3A%20rgb%28104%2C%20118%2C%20135%29%0A%7D%0Apre%20%2Eliteral%20%7B%0Acolor%3A%20%23990073%0A%7D%0Apre%20%2Enumber%20%7B%0Acolor%3A%20%23099%3B%0A%7D%0Apre%20%2Ecomment%20%7B%0Acolor%3A%20%23998%3B%0Afont%2Dstyle%3A%20italic%0A%7D%0Apre%20%2Ekeyword%20%7B%0Acolor%3A%20%23900%3B%0Afont%2Dweight%3A%20bold%0A%7D%0Apre%20%2Eidentifier%20%7B%0Acolor%3A%20rgb%280%2C%200%2C%200%29%3B%0A%7D%0Apre%20%2Estri [...]
 <script src="data:application/x-javascript;base64,dmFyIGhsanM9bmV3IGZ1bmN0aW9uKCl7ZnVuY3Rpb24gbShwKXtyZXR1cm4gcC5yZXBsYWNlKC8mL2dtLCImYW1wOyIpLnJlcGxhY2UoLzwvZ20sIiZsdDsiKX1mdW5jdGlvbiBmKHIscSxwKXtyZXR1cm4gUmVnRXhwKHEsIm0iKyhyLmNJPyJpIjoiIikrKHA/ImciOiIiKSl9ZnVuY3Rpb24gYihyKXtmb3IodmFyIHA9MDtwPHIuY2hpbGROb2Rlcy5sZW5ndGg7cCsrKXt2YXIgcT1yLmNoaWxkTm9kZXNbcF07aWYocS5ub2RlTmFtZT09IkNPREUiKXtyZXR1cm4gcX1pZighKHEubm9kZVR5cGU9PTMmJnEubm9kZVZhbHVlLm1hdGNoKC9ccysvKSkpe2JyZWFrfX19ZnVuY3Rpb24gaCh0LH [...]
 
@@ -117,7 +117,7 @@ $(document).ready(function () {
 
 
 <h1 class="title toc-ignore">Importing and exporting RSA/DSA/EC keys</h1>
-<h4 class="date"><em>2016-12-30</em></h4>
+<h4 class="date"><em>2017-09-06</em></h4>
 
 </div>
 
@@ -144,13 +144,13 @@ pubkey <- key$pubkey
 bin <- write_der(pubkey)
 print(bin)</code></pre>
 <pre><code> [1] 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07
-[24] 03 42 00 04 36 52 16 0f 87 c1 2c 21 e0 68 38 aa f0 0e c0 b2 39 f7 a0
-[47] e0 f4 6b 45 70 46 00 f7 e9 84 1e f7 1d a0 f2 87 ea eb de 65 52 0c 56
-[70] c8 6a c1 a5 dd 70 54 15 31 0e 78 2b ad a5 83 a3 44 8f a0 51 3d 2e</code></pre>
+[24] 03 42 00 04 48 6a e8 ff 74 9b ad 96 fa 14 d8 f8 cd 9b 51 71 5c 46 f6
+[47] 3f 6a b7 b2 98 02 7d df 3a 94 4f 68 f2 2d f8 ef 4b 46 48 80 fb 29 2a
+[70] 5e f5 b3 71 fa 21 48 24 59 01 90 57 57 c4 6b 00 0c f8 f5 09 f0 cc</code></pre>
 <p>To read a DER key use <code>read_key</code> or <code>read_pubkey</code> with <code>der = TRUE</code>.</p>
 <pre class="r"><code>read_pubkey(bin, der = TRUE)</code></pre>
 <pre><code>[256-bit ecdsa public key]
-md5: f159c220b15ae8a04217efd0b7c4ba3f</code></pre>
+md5: 71367a50d9dd7bba67ca617f12f8c74b</code></pre>
 <p>Users typically don’t need to worry about the key’s underlying primes, but have a look at <code>key$data</code> if you are curious.</p>
 </div>
 <div id="the-pem-format" class="section level3">
@@ -158,23 +158,23 @@ md5: f159c220b15ae8a04217efd0b7c4ba3f</code></pre>
 <p>In practice the user rarely encounters DER because it is mainly for internal use. When humans exchange keys and certificates they typically use the PEM format. PEM is simply <strong>base64 encoded DER data, plus a header</strong>. The header identifies the key (and possibly encryption) type.</p>
 <pre class="r"><code>cat(write_pem(pubkey))</code></pre>
 <pre><code>-----BEGIN PUBLIC KEY-----
-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENlIWD4fBLCHgaDiq8A7Asjn3oOD0
-a0VwRgD36YQe9x2g8ofq695lUgxWyGrBpd1wVBUxDngrraWDo0SPoFE9Lg==
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESGro/3SbrZb6FNj4zZtRcVxG9j9q
+t7KYAn3fOpRPaPIt+O9LRkiA+ykqXvWzcfohSCRZAZBXV8RrAAz49QnwzA==
 -----END PUBLIC KEY-----</code></pre>
 <pre class="r"><code>cat(write_pem(key, password = NULL))</code></pre>
 <pre><code>-----BEGIN PRIVATE KEY-----
-MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgv0i+oeC3fRS5L6OZ
-8CK6cfu54oPVCwfnHQQzeYaq+t2hRANCAAQ2UhYPh8EsIeBoOKrwDsCyOfeg4PRr
-RXBGAPfphB73HaDyh+rr3mVSDFbIasGl3XBUFTEOeCutpYOjRI+gUT0u
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg7qsPzcAJo4JPPFyh
+bUivYE3NEQ0Jfo5roK6klNdPdjqhRANCAARIauj/dJutlvoU2PjNm1FxXEb2P2q3
+spgCfd86lE9o8i3470tGSID7KSpe9bNx+iFIJFkBkFdXxGsADPj1CfDM
 -----END PRIVATE KEY-----</code></pre>
 <p>The PEM format allows for protecting private keys with a password. R will prompt you for the password when reading such a protected key.</p>
 <pre class="r"><code>cat(write_pem(key, password = "supersecret"))</code></pre>
 <pre><code>-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAi+mtQXMC/b2QICCAAw
-DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQItJD+GcKlpYUEgZDl1neZ41iwNxnt
-HmYdCeoPUo4CD3GZXTUz9d16TKxgqd9jhm601z5aNg4PQXTMtctTFc7KP1glUXJo
-ZcTOlRqRDeD1JkR9jt+CXf3cZmx3jP4cLxWgR+J0b+MOwu1qPvMLs7nQGyzHZFJK
-P9fessusSWJPp0KUnOmW0CqZ3Vb7Y1K2yOZDRS2edH3Dnrw2emc=
+MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAhF9/pDLyI5ZwICCAAw
+DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIRyZAzghjgmAEgZCm1EoHoWP3wgT9
+3Kw3aVvGd9ZlXukkE6c0UFYCKby+Rg9THEJmXXu+hYzTouxKHxFrXM2pLEAuG1rt
+Os3RVgMiz8NLJhfFN/QrMpubL1bzPNZcHUOTqbeTcFVf+IbCZvQixgEqulFCQzWv
+Hem5Eg9CTVta+FDEbt2o/hcKmTWRv2QITdtfuvRcCHG891Vm46c=
 -----END ENCRYPTED PRIVATE KEY-----</code></pre>
 </div>
 <div id="the-openssh-format" class="section level3">
@@ -182,11 +182,11 @@ P9fessusSWJPp0KUnOmW0CqZ3Vb7Y1K2yOZDRS2edH3Dnrw2emc=
 <p>For better or worse, OpenSSH uses a custom format for <strong>public keys</strong>. The advantage of this format is that it fits on a single line which is nice for e.g. your <code>~/.ssh/known_hosts</code> file. There is no special format for private keys, OpenSSH uses PEM as well.</p>
 <pre class="r"><code>str <- write_ssh(pubkey)
 print(str)</code></pre>
-<pre><code>[1] "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDZSFg+HwSwh4Gg4qvAOwLI596Dg9GtFcEYA9+mEHvcdoPKH6uveZVIMVshqwaXdcFQVMQ54K62lg6NEj6BRPS4="</code></pre>
+<pre><code>[1] "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEhq6P90m62W+hTY+M2bUXFcRvY/areymAJ93zqUT2jyLfjvS0ZIgPspKl71s3H6IUgkWQGQV1fEawAM+PUJ8Mw="</code></pre>
 <p>The <code>read_pubkey</code> function will automatically detect if a file contains a <code>PEM</code> or <code>SSH</code> key.</p>
 <pre class="r"><code>read_pubkey(str)</code></pre>
 <pre><code>[256-bit ecdsa public key]
-md5: f159c220b15ae8a04217efd0b7c4ba3f</code></pre>
+md5: 71367a50d9dd7bba67ca617f12f8c74b</code></pre>
 </div>
 <div id="the-json-web-key-jwk-format" class="section level3">
 <h3>The JSON Web Key (JWK) format</h3>
@@ -197,8 +197,8 @@ jsonlite::prettify(json)</code></pre>
 <pre><code>{
     "kty": "EC",
     "crv": "P-256",
-    "x": "NlIWD4fBLCHgaDiq8A7Asjn3oOD0a0VwRgD36YQe9x0",
-    "y": "oPKH6uveZVIMVshqwaXdcFQVMQ54K62lg6NEj6BRPS4"
+    "x": "SGro_3SbrZb6FNj4zZtRcVxG9j9qt7KYAn3fOpRPaPI",
+    "y": "LfjvS0ZIgPspKl71s3H6IUgkWQGQV1fEawAM-PUJ8Mw"
 }
  </code></pre>
 <p>Keys from <code>jose</code> and <code>openssl</code> are the same.</p>
@@ -207,7 +207,7 @@ identical(mykey, pubkey)</code></pre>
 <pre><code>[1] TRUE</code></pre>
 <pre class="r"><code>print(mykey)</code></pre>
 <pre><code>[256-bit ecdsa public key]
-md5: f159c220b15ae8a04217efd0b7c4ba3f</code></pre>
+md5: 71367a50d9dd7bba67ca617f12f8c74b</code></pre>
 </div>
 
 
@@ -233,7 +233,7 @@ $(document).ready(function () {
   (function () {
     var script = document.createElement("script");
     script.type = "text/javascript";
-    script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
     document.getElementsByTagName("head")[0].appendChild(script);
   })();
 </script>
diff --git a/inst/doc/secure_rng.html b/inst/doc/secure_rng.html
index 470b181..5c359c4 100644
--- a/inst/doc/secure_rng.html
+++ b/inst/doc/secure_rng.html
@@ -4,13 +4,13 @@
 
 <head>
 
-<meta charset="utf-8">
+<meta charset="utf-8" />
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="pandoc" />
 
 
 
-<meta name="date" content="2016-12-30" />
+<meta name="date" content="2017-09-06" />
 
 <title>Generating Secure Random Numbers in R</title>
 
@@ -20,7 +20,7 @@
 <script src="data:application/x-javascript;base64,LyohCiAqIEJvb3RzdHJhcCB2My4zLjUgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKQogKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy4KICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlCiAqLwppZigidW5kZWZpbmVkIj09dHlwZW9mIGpRdWVyeSl0aHJvdyBuZXcgRXJyb3IoIkJvb3RzdHJhcCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5Iik7K2Z1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0Ijt2YXIgYj1hLmZuLmpxdWVyeS5zcGxpdCgiICIpWzBdLnNwbGl0KCIuIik7aWYoYlswXTwyJiZiWzFdPDl8fDE9PWJbMF0mJjk9PWJbMV0mJmJbMl08MSl0aHJvdy [...]
 <script src="data:application/x-javascript;base64,LyoqCiogQHByZXNlcnZlIEhUTUw1IFNoaXYgMy43LjIgfCBAYWZhcmthcyBAamRhbHRvbiBAam9uX25lYWwgQHJlbSB8IE1JVC9HUEwyIExpY2Vuc2VkCiovCi8vIE9ubHkgcnVuIHRoaXMgY29kZSBpbiBJRSA4CmlmICghIXdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKCJNU0lFIDgiKSkgewohZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKGEsYil7dmFyIGM9YS5jcmVhdGVFbGVtZW50KCJwIiksZD1hLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF18fGEuZG9jdW1lbnRFbGVtZW50O3JldHVybiBjLmlubmVySFRNTD0ieDxzdHlsZT4iK2IrIjwvc3R5bGU+IixkLm [...]
 <script src="data:application/x-javascript;base64,LyohIFJlc3BvbmQuanMgdjEuNC4yOiBtaW4vbWF4LXdpZHRoIG1lZGlhIHF1ZXJ5IHBvbHlmaWxsICogQ29weXJpZ2h0IDIwMTMgU2NvdHQgSmVobAogKiBMaWNlbnNlZCB1bmRlciBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRqZWhsL1Jlc3BvbmQvYmxvYi9tYXN0ZXIvTElDRU5TRS1NSVQKICogICovCgovLyBPbmx5IHJ1biB0aGlzIGNvZGUgaW4gSUUgOAppZiAoISF3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgiTVNJRSA4IikpIHsKIWZ1bmN0aW9uKGEpeyJ1c2Ugc3RyaWN0IjthLm1hdGNoTWVkaWE9YS5tYXRjaE1lZGlhfHxmdW5jdGlvbihhKXt2YXIgYixjPWEuZG [...]
-<script src="data:application/x-javascript;base64,Cgp3aW5kb3cuYnVpbGRUYWJzZXRzID0gZnVuY3Rpb24odG9jSUQpIHsKCiAgLy8gYnVpbGQgYSB0YWJzZXQgZnJvbSBhIHNlY3Rpb24gZGl2IHdpdGggdGhlIC50YWJzZXQgY2xhc3MKICBmdW5jdGlvbiBidWlsZFRhYnNldCh0YWJzZXQpIHsKCiAgICAvLyBjaGVjayBmb3IgZmFkZSBhbmQgcGlsbHMgb3B0aW9ucwogICAgdmFyIGZhZGUgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1mYWRlIik7CiAgICB2YXIgcGlsbHMgPSB0YWJzZXQuaGFzQ2xhc3MoInRhYnNldC1waWxscyIpOwogICAgdmFyIG5hdkNsYXNzID0gcGlsbHMgPyAibmF2LXBpbGxzIiA6ICJuYXYtdGFicyI7CgogIC [...]
+<script src="data:application/x-javascript;base64,CgovKioKICogalF1ZXJ5IFBsdWdpbjogU3RpY2t5IFRhYnMKICoKICogQGF1dGhvciBBaWRhbiBMaXN0ZXIgPGFpZGFuQHBocC5uZXQ+CiAqIGFkYXB0ZWQgYnkgUnViZW4gQXJzbGFuIHRvIGFjdGl2YXRlIHBhcmVudCB0YWJzIHRvbwogKiBodHRwOi8vd3d3LmFpZGFubGlzdGVyLmNvbS8yMDE0LzAzL3BlcnNpc3RpbmctdGhlLXRhYi1zdGF0ZS1pbi1ib290c3RyYXAvCiAqLwooZnVuY3Rpb24oJCkgewogICJ1c2Ugc3RyaWN0IjsKICAkLmZuLnJtYXJrZG93blN0aWNreVRhYnMgPSBmdW5jdGlvbigpIHsKICAgIHZhciBjb250ZXh0ID0gdGhpczsKICAgIC8vIFNob3cgdGhlIHRhYi [...]
 <link href="data:text/css;charset=utf-8,pre%20%2Eoperator%2C%0Apre%20%2Eparen%20%7B%0Acolor%3A%20rgb%28104%2C%20118%2C%20135%29%0A%7D%0Apre%20%2Eliteral%20%7B%0Acolor%3A%20%23990073%0A%7D%0Apre%20%2Enumber%20%7B%0Acolor%3A%20%23099%3B%0A%7D%0Apre%20%2Ecomment%20%7B%0Acolor%3A%20%23998%3B%0Afont%2Dstyle%3A%20italic%0A%7D%0Apre%20%2Ekeyword%20%7B%0Acolor%3A%20%23900%3B%0Afont%2Dweight%3A%20bold%0A%7D%0Apre%20%2Eidentifier%20%7B%0Acolor%3A%20rgb%280%2C%200%2C%200%29%3B%0A%7D%0Apre%20%2Estri [...]
 <script src="data:application/x-javascript;base64,dmFyIGhsanM9bmV3IGZ1bmN0aW9uKCl7ZnVuY3Rpb24gbShwKXtyZXR1cm4gcC5yZXBsYWNlKC8mL2dtLCImYW1wOyIpLnJlcGxhY2UoLzwvZ20sIiZsdDsiKX1mdW5jdGlvbiBmKHIscSxwKXtyZXR1cm4gUmVnRXhwKHEsIm0iKyhyLmNJPyJpIjoiIikrKHA/ImciOiIiKSl9ZnVuY3Rpb24gYihyKXtmb3IodmFyIHA9MDtwPHIuY2hpbGROb2Rlcy5sZW5ndGg7cCsrKXt2YXIgcT1yLmNoaWxkTm9kZXNbcF07aWYocS5ub2RlTmFtZT09IkNPREUiKXtyZXR1cm4gcX1pZighKHEubm9kZVR5cGU9PTMmJnEubm9kZVZhbHVlLm1hdGNoKC9ccysvKSkpe2JyZWFrfX19ZnVuY3Rpb24gaCh0LH [...]
 
@@ -117,7 +117,7 @@ $(document).ready(function () {
 
 
 <h1 class="title toc-ignore">Generating Secure Random Numbers in R</h1>
-<h4 class="date"><em>2016-12-30</em></h4>
+<h4 class="date"><em>2017-09-06</em></h4>
 
 </div>
 
@@ -125,30 +125,30 @@ $(document).ready(function () {
 <p>The <code>rand_bytes</code> function binds to <a href="https://www.openssl.org/docs/manmaster/man3/RAND_bytes.html">RAND_bytes</a> in OpenSSL to generate cryptographically strong pseudo-random bytes. See the OpenSSL documentation for what this means.</p>
 <pre class="r"><code>rnd <- rand_bytes(10)
 print(rnd)</code></pre>
-<pre><code> [1] 0a 10 91 01 64 e4 39 ff e4 0b</code></pre>
+<pre><code> [1] 67 79 cc 0d a1 c7 10 4c d7 cb</code></pre>
 <p>Bytes are 8 bit and hence can have <code>2^8 = 256</code> possible values.</p>
 <pre class="r"><code>as.numeric(rnd)</code></pre>
-<pre><code> [1]  10  16 145   1 100 228  57 255 228  11</code></pre>
+<pre><code> [1] 103 121 204  13 161 199  16  76 215 203</code></pre>
 <p>Each random byte can be decomposed into 8 random bits (booleans)</p>
 <pre class="r"><code>x <- rand_bytes(1)
 as.logical(rawToBits(x))</code></pre>
-<pre><code>[1]  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE  TRUE</code></pre>
+<pre><code>[1] FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE</code></pre>
 <div id="secure-random-numbers" class="section level2">
 <h2>Secure Random Numbers</h2>
 <p><code>rand_num</code> is a simple (2 lines) wrapper to <code>rand_bytes</code> to generate random numbers (doubles) between 0 and 1.</p>
 <pre class="r"><code>rand_num(10)</code></pre>
-<pre><code> [1] 0.51264049 0.26298265 0.52894224 0.45853923 0.91369995 0.06634984
- [7] 0.34697549 0.77925962 0.32352883 0.36852364</code></pre>
+<pre><code> [1] 0.1434106 0.2961425 0.3155963 0.9416567 0.5237373 0.6298659 0.5982151
+ [8] 0.2486845 0.5146982 0.9181494</code></pre>
 <p>To map random draws from [0,1] into a probability density, we can use a <a href="http://en.wikipedia.org/wiki/Cumulative_distribution_function">Cumulative Distribution Function</a>. For example we can combine <code>qnorm</code> and <code>rand_num</code> to simulate <code>rnorm</code>:</p>
 <pre class="r"><code># Secure rnorm
 x <- qnorm(rand_num(1000), mean = 100, sd = 15)
 hist(x)</code></pre>
-<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUAAAAPACAYAAAD0ZtPZAAAEDWlDQ1BJQ0MgUHJvZmlsZQAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia [...]
+<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUAAAAPACAYAAAD0ZtPZAAAEDWlDQ1BJQ0MgUHJvZmlsZQAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia [...]
 <p>Same for discrete distributions:</p>
 <pre class="r"><code># Secure rbinom
 y <- qbinom(rand_num(1000), size = 20, prob = 0.1)
 hist(y, breaks = -.5:(max(y)+1))</code></pre>
-<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUAAAAPACAYAAAD0ZtPZAAAEDWlDQ1BJQ0MgUHJvZmlsZQAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia [...]
+<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUAAAAPACAYAAAD0ZtPZAAAEDWlDQ1BJQ0MgUHJvZmlsZQAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia [...]
 </div>
 
 
@@ -174,7 +174,7 @@ $(document).ready(function () {
   (function () {
     var script = document.createElement("script");
     script.type = "text/javascript";
-    script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
     document.getElementsByTagName("head")[0].appendChild(script);
   })();
 </script>
diff --git a/man/aes_cbc.Rd b/man/aes_cbc.Rd
index 969a1e9..56b3eed 100644
--- a/man/aes_cbc.Rd
+++ b/man/aes_cbc.Rd
@@ -39,7 +39,7 @@ is not secret but should be random}
 Low-level symmetric encryption/decryption using the AES block cipher in CBC mode.
 The key is a raw vector, for example a hash of some secret. When no shared
 secret is available, a random key can be used which is exchanged via an
-asymettric protocol such as RSA. See \code{\link{rsa_encrypt}} for a worked example
+asymmetric protocol such as RSA. See \code{\link{rsa_encrypt}} for a worked example
 or \code{\link{encrypt_envelope}} for a high-level wrapper combining AES and RSA.
 }
 \examples{
@@ -53,4 +53,3 @@ y <- aes_cbc_encrypt(x, key = key)
 x2 <- aes_cbc_decrypt(y, key = key)
 stopifnot(identical(x, x2))
 }
-
diff --git a/man/askpass.Rd b/man/askpass.Rd
index 7469e5f..ef6f3d4 100644
--- a/man/askpass.Rd
+++ b/man/askpass.Rd
@@ -14,4 +14,3 @@ Function to prompt the user for a password to read a protected private key.
 Frontends can provide a custom password entry widget by setting the \code{askpass}
 option. If no such option is specified we default to \code{\link{readline}}.
 }
-
diff --git a/man/base64_encode.Rd b/man/base64_encode.Rd
index aeedb7a..d8e6bcb 100644
--- a/man/base64_encode.Rd
+++ b/man/base64_encode.Rd
@@ -26,4 +26,3 @@ message <- base64_encode(input)
 output <- base64_decode(message)
 identical(output, input)
 }
-
diff --git a/man/bignum.Rd b/man/bignum.Rd
index 887be6f..85e40f4 100644
--- a/man/bignum.Rd
+++ b/man/bignum.Rd
@@ -25,12 +25,12 @@ bignum_mod_inv(a, m)
 }
 \description{
 Basic operations for working with large integers. The \code{bignum}
-funtion converts a positive integer, string or raw vector into a bignum type.
+function converts a positive integer, string or raw vector into a bignum type.
 All basic \link{Arithmetic} and \link{Comparison} operators such as
 \code{+}, \code{-}, \code{*}, \code{^}, \code{\%\%}, \code{\%/\%}, \code{==},
 \code{!=}, \code{<}, \code{<=}, \code{>} and \code{>=} are implemented for
 bignum objects. The
-\href{https://en.wikipedia.org/wiki/Modular_exponentiation}{Modular exponenent}
+\href{https://en.wikipedia.org/wiki/Modular_exponentiation}{Modular exponent}
 (\code{a^b \%\% m}) can be calculated using \code{\link{bignum_mod_exp}}
 when \code{b} is too large for calculating \code{a^b} directly.
 }
@@ -47,4 +47,3 @@ z2 <- div * y + mod
 stopifnot(z2 == z)
 stopifnot(div < z)
 }
-
diff --git a/man/certificates.Rd b/man/certificates.Rd
index 3de6cf5..e8cba33 100644
--- a/man/certificates.Rd
+++ b/man/certificates.Rd
@@ -13,7 +13,7 @@ download_ssl_cert(host = "localhost", port = 443)
 ca_bundle()
 }
 \arguments{
-\item{cert}{certficate (or certificate-chain) to be verified. Must be cert or list or path.}
+\item{cert}{certificate (or certificate-chain) to be verified. Must be cert or list or path.}
 
 \item{root}{trusted pubkey or certificate(s) e.g. CA bundle.}
 
@@ -22,7 +22,7 @@ ca_bundle()
 \item{port}{string or integer: port or protocol to use, e.g: \code{443} or \code{"https"}}
 }
 \description{
-Read, download, analyize and verify X.509 certificates.
+Read, download, analyze and verify X.509 certificates.
 }
 \details{
 If https verification fails and you can't figure out why, have a look
@@ -46,4 +46,3 @@ write_pem(ocpu)
 \seealso{
 \link{read_cert}
 }
-
diff --git a/man/ec_dh.Rd b/man/ec_dh.Rd
index b3a7e27..58a62ba 100644
--- a/man/ec_dh.Rd
+++ b/man/ec_dh.Rd
@@ -15,7 +15,7 @@ ec_dh(key = my_key(), peerkey, password = askpass)
 }
 \description{
 Key agreement is one-step method of creating a shared secret between two
-peers. Both peers can indendently derive the joined secret by combining
+peers. Both peers can independently derive the joined secret by combining
 his or her private key with the public key from the peer.
 }
 \details{
@@ -40,4 +40,3 @@ ec_dh(bob_key, alice_pub)
 \url{https://wiki.openssl.org/index.php/EVP_Key_Agreement},
 \url{https://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman}
 }
-
diff --git a/man/encrypt_envelope.Rd b/man/encrypt_envelope.Rd
index 163bab9..ec754b8 100644
--- a/man/encrypt_envelope.Rd
+++ b/man/encrypt_envelope.Rd
@@ -26,7 +26,7 @@ If \code{hash == NULL} then \code{data} must be a hash string or raw vector.}
 }
 \description{
 An \href{https://wiki.openssl.org/index.php/EVP_Asymmetric_Encryption_and_Decryption_of_an_Envelope}{envelope}
-contains ciphertext along with an encrypted session key and optionally and initialiation
+contains ciphertext along with an encrypted session key and optionally and initialization
 vector. The \code{\link{encrypt_envelope}} generates a random IV and session-key which is
 used to encrypt the \code{data} with \code{\link[openssl:aes_cbc]{AES}} stream cipher. The
 session key itself is encrypted using the given RSA key (see \code{\link{rsa_encrypt}}) and
@@ -50,4 +50,3 @@ stopifnot(identical(msg, orig))
 \references{
 \url{https://wiki.openssl.org/index.php/EVP_Asymmetric_Encryption_and_Decryption_of_an_Envelope}
 }
-
diff --git a/man/fingerprint.Rd b/man/fingerprint.Rd
index b0c7141..2c3a15f 100644
--- a/man/fingerprint.Rd
+++ b/man/fingerprint.Rd
@@ -30,4 +30,3 @@ fingerprint(pubkey, sha256)
 # Other key types
 fingerprint(dsa_keygen())
 }
-
diff --git a/man/hash.Rd b/man/hash.Rd
index 5d9f5ac..aca94cb 100644
--- a/man/hash.Rd
+++ b/man/hash.Rd
@@ -105,4 +105,3 @@ sha256(c("john", "mary", "john"), key = "random_salt_value")
 \references{
 Digest types: \url{https://www.openssl.org/docs/manmaster/man1/dgst.html}
 }
-
diff --git a/man/keygen.Rd b/man/keygen.Rd
index 4c9beed..f2295e9 100644
--- a/man/keygen.Rd
+++ b/man/keygen.Rd
@@ -32,4 +32,3 @@ pubkey <- as.list(key)$pubkey
 write_pem(key, "id_rsa", password = "supersecret")
 read_key("id_rsa", password = "supersecret")
 }
-
diff --git a/man/my_key.Rd b/man/my_key.Rd
index dce3eca..4777dab 100644
--- a/man/my_key.Rd
+++ b/man/my_key.Rd
@@ -31,4 +31,3 @@ Sys.setenv("USER_KEY" = tmp)
 print(my_key())
 print(my_pubkey())
 }
-
diff --git a/man/openssl.Rd b/man/openssl.Rd
index 92129ed..a2b47e5 100644
--- a/man/openssl.Rd
+++ b/man/openssl.Rd
@@ -24,4 +24,3 @@ calculations on large multibyte integers.
 \author{
 Jeroen Ooms, Oliver Keyes
 }
-
diff --git a/man/openssl_config.Rd b/man/openssl_config.Rd
index edb9180..8b73b52 100644
--- a/man/openssl_config.Rd
+++ b/man/openssl_config.Rd
@@ -9,4 +9,3 @@ openssl_config()
 \description{
 Shows libssl version and configuration information.
 }
-
diff --git a/man/pkcs12.Rd b/man/pkcs12.Rd
index 35301f4..413d296 100644
--- a/man/pkcs12.Rd
+++ b/man/pkcs12.Rd
@@ -52,4 +52,3 @@ used to import and export certificates with their private keys.
 The PKCS formats also allow for including signatures and CRLs but this is quite rare
 and these are currently ignored.
 }
-
diff --git a/man/rand_bytes.Rd b/man/rand_bytes.Rd
index 43afc11..a497815 100644
--- a/man/rand_bytes.Rd
+++ b/man/rand_bytes.Rd
@@ -41,4 +41,3 @@ hist(y)
 \references{
 OpenSSL manual: \url{https://www.openssl.org/docs/manmaster/man3/RAND_bytes.html}
 }
-
diff --git a/man/read_key.Rd b/man/read_key.Rd
index 934d237..26e2257 100644
--- a/man/read_key.Rd
+++ b/man/read_key.Rd
@@ -45,7 +45,7 @@ Most versions of OpenSSL support at least RSA, DSA and ECDSA keys. Certificates
 conform to the X509 standard.
 
 The \code{password} argument is needed when reading keys that are protected with a
-passphrase. It can either be a string containing the passphrase, or a custom calback
+passphrase. It can either be a string containing the passphrase, or a custom callback
 function that will be called by OpenSSL to read the passphrase. The function should
 take one argument (a string with a message) and return a string. The default is to
 use \code{readline} which will prompt the user in an interactive R session.
@@ -68,4 +68,3 @@ print(bundle)
 \seealso{
 \link{download_ssl_cert}
 }
-
diff --git a/man/rsa_encrypt.Rd b/man/rsa_encrypt.Rd
index 5332ef1..746328c 100644
--- a/man/rsa_encrypt.Rd
+++ b/man/rsa_encrypt.Rd
@@ -45,4 +45,3 @@ tempkey <- rsa_decrypt(ciphertext, key)
 message <- aes_cbc_decrypt(blob, tempkey, iv)
 out <- rawToChar(message)
 }
-
diff --git a/man/signatures.Rd b/man/signatures.Rd
index ef05720..19dd488 100644
--- a/man/signatures.Rd
+++ b/man/signatures.Rd
@@ -48,4 +48,3 @@ md <- md5(data)
 sig <- signature_create(md, hash = NULL, key = key)
 stopifnot(signature_verify(md, sig, hash = NULL, pubkey = pubkey))
 }
-
diff --git a/man/write_pem.Rd b/man/write_pem.Rd
index 901c3d2..36a506c 100644
--- a/man/write_pem.Rd
+++ b/man/write_pem.Rd
@@ -36,4 +36,3 @@ write_ssh(pubkey)
 write_pem(pubkey)
 write_pem(key, password = "super secret")
 }
-
diff --git a/src/Makevars.win b/src/Makevars.win
index 27959ca..fb479aa 100644
--- a/src/Makevars.win
+++ b/src/Makevars.win
@@ -1,5 +1,6 @@
-PKG_CPPFLAGS= -I../windows/openssl-1.1.0c/include
-PKG_LIBS= $(WIN32FIX) -L../windows/openssl-1.1.0c/lib${R_ARCH} -lssl -lcrypto -lws2_32 -lgdi32 -lcrypt32
+VERSION=1.1.0f
+PKG_CPPFLAGS= -I../windows/openssl-$(VERSION)/include
+PKG_LIBS= $(WIN32FIX) -L../windows/openssl-$(VERSION)/lib${R_ARCH} -lssl -lcrypto -lws2_32 -lgdi32 -lcrypt32
 WIN32FIX=win32/ipv6.o
 
 all: clean winlibs $(WIN32FIX)
@@ -8,4 +9,4 @@ clean:
 	rm -f $(SHLIB) $(OBJECTS) $(WIN32FIX)
 
 winlibs:
-	"${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" "../tools/winlibs.R"
+	"${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" "../tools/winlibs.R" $(VERSION)
diff --git a/src/aes.c b/src/aes.c
index 7bb1902..f0417d7 100644
--- a/src/aes.c
+++ b/src/aes.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include "utils.h"
 
@@ -20,6 +21,9 @@ SEXP R_aes_any(SEXP x, SEXP key, SEXP iv, SEXP encrypt, SEXP cipher) {
 
 #ifdef EVP_CIPH_GCM_MODE //openssl 1.0.0 does not have GCM
   if(EVP_CIPHER_mode(cph) == EVP_CIPH_GCM_MODE){
+    if(LENGTH(iv) != 12){
+      Rf_error("aes-gcm requires an iv of length 12");
+    }
     //GCM mode has shorter IV from the others
     bail(EVP_CipherInit_ex(ctx, cph, NULL, NULL, NULL, asLogical(encrypt)));
     bail(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, LENGTH(iv), NULL));
diff --git a/src/base64.c b/src/base64.c
index dd59ec1..a79ef40 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/bio.h>
 #include <openssl/evp.h>
 #include <openssl/buffer.h>
 #include "utils.h"
diff --git a/src/bignum.c b/src/bignum.c
index 2754039..7cace53 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/bn.h>
 #include "utils.h"
 
@@ -48,6 +49,12 @@ SEXP R_bignum_as_character(SEXP x, SEXP hex){
   return res;
 }
 
+SEXP R_bignum_as_integer(SEXP x){
+  BIGNUM *val = r2bignum(x);
+  int res = BN_div_word(val, (BN_ULONG) INT_MAX + 1);
+  return ScalarInteger(BN_num_bits(val) ? NA_INTEGER : res);
+}
+
 SEXP R_bignum_add(SEXP x, SEXP y){
   BIGNUM *val1 = r2bignum(x);
   BIGNUM *val2 = r2bignum(y);
diff --git a/src/cert.c b/src/cert.c
index 30fb079..0d0a19c 100644
--- a/src/cert.c
+++ b/src/cert.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/pem.h>
 #include <openssl/bn.h>
 #include <openssl/x509v3.h>
diff --git a/src/keygen.c b/src/keygen.c
index dbbb81f..ff4ac90 100644
--- a/src/keygen.c
+++ b/src/keygen.c
@@ -1,5 +1,6 @@
 #include <Rinternals.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -23,7 +24,7 @@ SEXP R_keygen_rsa(SEXP bits){
   EVP_PKEY_CTX_free(ctx);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -37,34 +38,27 @@ SEXP R_keygen_dsa(SEXP bits){
   DSA_free(dsa);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
 SEXP R_keygen_ecdsa(SEXP curve){
 #ifndef OPENSSL_NO_EC
   int nid = my_nist2nid(CHAR(STRING_ELT(curve, 0)));
-  EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
-  bail(!!pctx);
-  EVP_PKEY_paramgen_init(pctx);
-  bail(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid));
-  EVP_PKEY *params = EVP_PKEY_new();
-  bail(EVP_PKEY_paramgen(pctx, &params));
-  EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL);
-  bail(EVP_PKEY_keygen_init(kctx) > 0);
+  EC_KEY *eckey = EC_KEY_new_by_curve_name(nid);
+  bail(!!eckey);
+  bail(EC_KEY_generate_key(eckey) > 0);
+  EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
   EVP_PKEY *pkey = EVP_PKEY_new();
-  bail(EVP_PKEY_keygen(kctx, &pkey) > 0);
-  EC_KEY_set_asn1_flag(EVP_PKEY_get1_EC_KEY(pkey), OPENSSL_EC_NAMED_CURVE);
+  bail(!!pkey);
+  bail(EVP_PKEY_assign_EC_KEY(pkey, eckey) > 0);
   unsigned char *buf = NULL;
   int len = i2d_PrivateKey(pkey, &buf);
-  bail(len);
+  bail(len > 0);
   EVP_PKEY_free(pkey);
-  EVP_PKEY_free(params);
-  EVP_PKEY_CTX_free(kctx);
-  EVP_PKEY_CTX_free(pctx);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 #else //OPENSSL_NO_EC
   Rf_error("OpenSSL has been configured without EC support");
diff --git a/src/keys.c b/src/keys.c
index 0054e97..ae985ba 100644
--- a/src/keys.c
+++ b/src/keys.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/pem.h>
 #include "utils.h"
 #include "compatibility.h"
@@ -14,7 +15,7 @@ SEXP R_parse_der_pubkey(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -28,7 +29,7 @@ SEXP R_parse_der_key(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -41,7 +42,7 @@ SEXP R_parse_der_cert(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -56,7 +57,7 @@ SEXP R_derive_pubkey(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -72,7 +73,7 @@ SEXP R_cert_pubkey(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
diff --git a/src/onload.c b/src/onload.c
index 117cd31..c89f2b4 100644
--- a/src/onload.c
+++ b/src/onload.c
@@ -11,6 +11,8 @@
 
 
 void R_init_openssl(DllInfo *info) {
+  R_registerRoutines(info, NULL, NULL, NULL, NULL);
+  R_useDynamicSymbols(info, TRUE);
 #ifdef _WIN32
   WSADATA wsaData;
   WSAStartup(MAKEWORD(2, 2), &wsaData);
@@ -23,7 +25,7 @@ void R_init_openssl(DllInfo *info) {
   SSL_library_init();
 }
 
-void R_unload_curl(DllInfo *info) {
+void R_unload_openssl(DllInfo *info) {
   ERR_free_strings();
   EVP_cleanup();
 }
diff --git a/src/openssh.c b/src/openssh.c
index 7860ab8..f4eaa34 100644
--- a/src/openssh.c
+++ b/src/openssh.c
@@ -1,5 +1,6 @@
 #include <Rinternals.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/pem.h>
 #include <openssl/bn.h>
 #include "utils.h"
@@ -46,7 +47,7 @@ SEXP R_rsa_pubkey_build(SEXP expdata, SEXP moddata){
   RSA_free(rsa);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -62,7 +63,7 @@ SEXP R_rsa_key_build(SEXP e, SEXP n, SEXP p, SEXP q, SEXP d, SEXP dp, SEXP dq, S
   RSA_free(rsa);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -111,7 +112,7 @@ SEXP R_dsa_pubkey_build(SEXP p, SEXP q, SEXP g, SEXP y){
   DSA_free(dsa);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -198,7 +199,7 @@ SEXP R_ecdsa_pubkey_build(SEXP x, SEXP y, SEXP nist){
   EC_KEY_free(pubkey);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 #else //OPENSSL_NO_EC
   Rf_error("OpenSSL has been configured without EC support");
@@ -220,7 +221,7 @@ SEXP R_ecdsa_key_build(SEXP x, SEXP y, SEXP d, SEXP nist){
   EC_KEY_free(key);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 #else //OPENSSL_NO_EC
   Rf_error("OpenSSL has been configured without EC support");
diff --git a/src/pem.c b/src/pem.c
index 366bcb0..e0a60ea 100644
--- a/src/pem.c
+++ b/src/pem.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include "utils.h"
@@ -45,7 +46,7 @@ SEXP R_parse_pem_key(SEXP input, SEXP password){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -59,7 +60,7 @@ SEXP R_parse_pem_pubkey(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -71,12 +72,12 @@ SEXP R_parse_pem_cert(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
 /* Legacy pubkey format */
-SEXP R_parse_pem_pkcs1(SEXP input){
+SEXP R_parse_pem_pubkey_pkcs1(SEXP input){
   BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
   RSA *rsa = PEM_read_bio_RSAPublicKey(mem, NULL, password_cb, NULL);
   bail(!!rsa);
@@ -85,6 +86,21 @@ SEXP R_parse_pem_pkcs1(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
+  return res;
+}
+
+/* Legacy rsa key format */
+SEXP R_parse_pem_key_pkcs1(SEXP input){
+  BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
+  RSA *rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, password_cb, NULL);
+  bail(!!rsa);
+  unsigned char *buf = NULL;
+  int len = i2d_RSAPrivateKey(rsa, &buf);
+  bail(len);
+  RSA_free(rsa);
+  SEXP res = allocVector(RAWSXP, len);
+  memcpy(RAW(res), buf, len);
+  OPENSSL_free(buf);
   return res;
 }
diff --git a/src/pkcs12.c b/src/pkcs12.c
index 12df881..754277a 100644
--- a/src/pkcs12.c
+++ b/src/pkcs12.c
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <Rinternals.h>
+#include <openssl/crypto.h>
 #include <openssl/pkcs12.h>
 #include "utils.h"
 
@@ -54,7 +55,7 @@ SEXP R_write_pkcs12(SEXP keydata, SEXP certdata, SEXP cadata, SEXP namedata, SEX
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -89,7 +90,7 @@ SEXP R_parse_pkcs12(SEXP input, SEXP pass){
     bail(len);
     SET_VECTOR_ELT(res, 0, allocVector(RAWSXP, len));
     memcpy(RAW(VECTOR_ELT(res, 0)), buf, len);
-    free(buf);
+    OPENSSL_free(buf);
     buf = NULL;
   }
   if(pkey != NULL){
@@ -98,7 +99,7 @@ SEXP R_parse_pkcs12(SEXP input, SEXP pass){
     bail(len);
     SET_VECTOR_ELT(res, 1, allocVector(RAWSXP, len));
     memcpy(RAW(VECTOR_ELT(res, 1)), buf, len);
-    free(buf);
+    OPENSSL_free(buf);
     buf = NULL;
   }
   if(ca && sk_X509_num(ca)){
@@ -110,7 +111,7 @@ SEXP R_parse_pkcs12(SEXP input, SEXP pass){
       bail(len);
       SET_VECTOR_ELT(bundle, i, allocVector(RAWSXP, len));
       memcpy(RAW(VECTOR_ELT(bundle, i)), buf, len);
-      free(buf);
+      OPENSSL_free(buf);
       buf = NULL;
     }
     sk_X509_pop_free(ca, X509_free);
diff --git a/src/pkcs7.c b/src/pkcs7.c
index f39a6f5..04e0490 100644
--- a/src/pkcs7.c
+++ b/src/pkcs7.c
@@ -4,6 +4,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs7.h>
 #include "utils.h"
@@ -17,7 +18,7 @@ SEXP R_parse_pem_pkcs7(SEXP input){
   bail(len);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -39,7 +40,7 @@ SEXP R_write_pkcs7(SEXP cadata){
   PKCS7_free(p7);
   SEXP res = allocVector(RAWSXP, len);
   memcpy(RAW(res), buf, len);
-  free(buf);
+  OPENSSL_free(buf);
   return res;
 }
 
@@ -79,7 +80,7 @@ SEXP R_parse_der_pkcs7(SEXP input){
       bail(len);
       SET_VECTOR_ELT(bundle, i, allocVector(RAWSXP, len));
       memcpy(RAW(VECTOR_ELT(bundle, i)), buf, len);
-      free(buf);
+      OPENSSL_free(buf);
       buf = NULL;
     }
     SET_VECTOR_ELT(out, 0, bundle);
@@ -95,7 +96,7 @@ SEXP R_parse_der_pkcs7(SEXP input){
       bail(len);
       SET_VECTOR_ELT(bundle, i, allocVector(RAWSXP, len));
       memcpy(RAW(VECTOR_ELT(bundle, i)), buf, len);
-      free(buf);
+      OPENSSL_free(buf);
       buf = NULL;
     }
     SET_VECTOR_ELT(out, 1, bundle);
diff --git a/src/rsa.c b/src/rsa.c
index d26e206..7bd3254 100644
--- a/src/rsa.c
+++ b/src/rsa.c
@@ -1,6 +1,7 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/pem.h>
 #include "utils.h"
 
diff --git a/src/signing.c b/src/signing.c
index 06746f4..451ce97 100644
--- a/src/signing.c
+++ b/src/signing.c
@@ -1,11 +1,14 @@
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/hmac.h>
 #include "utils.h"
 
-const EVP_MD* guess_hashfun(int length){
+static const EVP_MD* guess_hashfun(int length){
   switch(length){
   case 16:
     return EVP_md5();
@@ -20,7 +23,7 @@ const EVP_MD* guess_hashfun(int length){
   case 64:
     return EVP_sha512();
   }
-  return EVP_md_null();
+  return NULL;
 }
 
 SEXP R_hash_sign(SEXP md, SEXP key){
@@ -32,7 +35,9 @@ SEXP R_hash_sign(SEXP md, SEXP key){
   bail(!!ctx);
   bail(EVP_PKEY_sign_init(ctx) > 0);
   //bail(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) >= 0);
-  bail(EVP_PKEY_CTX_set_signature_md(ctx, guess_hashfun(LENGTH(md))) > 0);
+  const EVP_MD *md_func = guess_hashfun(LENGTH(md));
+  bail(!!md_func);
+  bail(EVP_PKEY_CTX_set_signature_md(ctx, md_func) > 0);
 
   //detemine buffer length (this is really required, over/under estimate can crash)
   size_t siglen;
@@ -57,7 +62,9 @@ SEXP R_hash_verify(SEXP md, SEXP sig, SEXP pubkey){
   bail(!!ctx);
   bail(EVP_PKEY_verify_init(ctx) > 0);
   //bail(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) >= 0);
-  bail(EVP_PKEY_CTX_set_signature_md(ctx, guess_hashfun(LENGTH(md))) > 0);
+  const EVP_MD *md_func = guess_hashfun(LENGTH(md));
+  bail(!!md_func);
+  bail(EVP_PKEY_CTX_set_signature_md(ctx, md_func) > 0);
   int res = EVP_PKEY_verify(ctx, RAW(sig), LENGTH(sig), RAW(md), LENGTH(md));
   bail(res >= 0);
   if(res == 0)
diff --git a/src/ssl.c b/src/ssl.c
index aa95dd9..6d217dc 100644
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -3,6 +3,11 @@
 #define _POSIX_C_SOURCE 200112L
 #endif
 
+//see https://github.com/jeroen/openssl/issues/41
+#if defined(__FreeBSD__) && !defined(__BSD_VISIBLE)
+#define __BSD_VISIBLE 1
+#endif
+
 #include <Rinternals.h>
 #include <stdlib.h>
 #include <string.h>
@@ -22,6 +27,8 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
 #include <arpa/inet.h>
 #endif
 
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
 #include <openssl/ssl.h>
 #include "utils.h"
 
@@ -135,7 +142,7 @@ SEXP R_download_cert(SEXP hostname, SEXP service) {
     SET_VECTOR_ELT(res, i, allocVector(RAWSXP, len));
     memcpy(RAW(VECTOR_ELT(res, i)), buf, len);
     setAttrib(VECTOR_ELT(res, i), R_ClassSymbol, mkString("cert"));
-    free(buf);
+    OPENSSL_free(buf);
     buf = NULL;
   }
 
diff --git a/src/onload.c b/src/tests/main.c
similarity index 52%
copy from src/onload.c
copy to src/tests/main.c
index 117cd31..055c09b 100644
--- a/src/onload.c
+++ b/src/tests/main.c
@@ -1,20 +1,10 @@
-#include <R_ext/Rdynload.h>
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 #include <openssl/engine.h>
 #include <openssl/hmac.h>
 
-#ifdef _WIN32
-#include <winsock2.h>
-#endif
-
-
-void R_init_openssl(DllInfo *info) {
-#ifdef _WIN32
-  WSADATA wsaData;
-  WSAStartup(MAKEWORD(2, 2), &wsaData);
-#endif
+int main(){
   OpenSSL_add_all_digests();
   OpenSSL_add_all_algorithms();
   OpenSSL_add_all_ciphers();
@@ -22,8 +12,3 @@ void R_init_openssl(DllInfo *info) {
   SSL_load_error_strings();
   SSL_library_init();
 }
-
-void R_unload_curl(DllInfo *info) {
-  ERR_free_strings();
-  EVP_cleanup();
-}
diff --git a/src/tests/soname.h b/src/tests/soname.h
new file mode 100644
index 0000000..3d7dd21
--- /dev/null
+++ b/src/tests/soname.h
@@ -0,0 +1,5 @@
+#include "openssl/opensslv.h"
+
+#define XSTR(x) STR(x)
+#define STR(x) #x
+echo XSTR(SHLIB_VERSION_NUMBER)
diff --git a/tests/testthat/test_bignum.R b/tests/testthat/test_bignum.R
index 4331538..06124ef 100644
--- a/tests/testthat/test_bignum.R
+++ b/tests/testthat/test_bignum.R
@@ -40,3 +40,10 @@ test_that("Bignum arithmetic", {
   expect_equal(z2, z)
   expect_true(div < z)
 })
+
+test_that("Bignum to integer", {
+  for(x in c(0, 123, .Machine$integer.max)){
+    expect_equal(x, as.integer(bignum(x)))
+  }
+  expect_equal(as.integer(bignum(.Machine$integer.max + 1)), NA_integer_)
+})
diff --git a/tests/testthat/test_google.R b/tests/testthat/test_google.R
new file mode 100644
index 0000000..eeb6161
--- /dev/null
+++ b/tests/testthat/test_google.R
@@ -0,0 +1,30 @@
+context("Google SSL tests")
+
+# Certificates from https://pki.goog/
+
+test_that("google certs validate", {
+  cert <- download_ssl_cert('good.r1demo.pki.goog')
+  ca <- read_cert('https://pki.goog/gtsr1/GTSR1.crt')
+  expect_true(cert_verify(cert, ca))
+
+  cert <- download_ssl_cert('good.r2demo.pki.goog')
+  ca <- read_cert('https://pki.goog/gtsr2/GTSR2.crt')
+  expect_true(cert_verify(cert, ca))
+
+  cert <- download_ssl_cert('good.r3demo.pki.goog')
+  ca <- read_cert('https://pki.goog/gtsr3/GTSR3.crt')
+  expect_true(cert_verify(cert, ca))
+
+  cert <- download_ssl_cert('good.r4demo.pki.goog')
+  ca <- read_cert('https://pki.goog/gtsr4/GTSR4.crt')
+  expect_true(cert_verify(cert, ca))
+
+  # Google messed up, server doesn't work
+  #cert <- download_ssl_cert('2021.globalsign.com')
+  #ca <- read_cert('https://pki.goog/gsr2/GSR2.crt')
+  #expect_true(cert_verify(cert, ca))
+
+  cert <- download_ssl_cert('2038r4.globalsign.com')
+  ca <- read_cert('https://pki.goog/gsr4/GSR4.crt')
+  expect_true(cert_verify(cert, ca))
+})
diff --git a/tools/winlibs.R b/tools/winlibs.R
index d108a7a..4b0597e 100644
--- a/tools/winlibs.R
+++ b/tools/winlibs.R
@@ -1,7 +1,9 @@
-# Build against openssl libraries that were compiled with the Rtools gcc toolchain.
-if(!file.exists("../windows/openssl-1.1.0c/include/openssl/ssl.h")){
+# Build against mingw-w64 build of openssl
+VERSION <- commandArgs(TRUE)
+if(!file.exists(sprintf("../windows/openssl-%s/include/openssl/ssl.h", VERSION))){
   if(getRversion() < "3.3.0") setInternet2()
-  download.file("https://github.com/rwinlib/openssl/archive/v1.1.0c.zip", "lib.zip", quiet = TRUE)
+  download.file(sprintf("https://github.com/rwinlib/openssl/archive/v%s.zip", VERSION),
+                "lib.zip", quiet = TRUE)
   dir.create("../windows", showWarnings = FALSE)
   unzip("lib.zip", exdir = "../windows")
   unlink("lib.zip")
diff --git a/vignettes/bignum.Rmd b/vignettes/bignum.Rmd
index 3693f4d..9bef2f3 100644
--- a/vignettes/bignum.Rmd
+++ b/vignettes/bignum.Rmd
@@ -17,7 +17,7 @@ knitr::opts_chunk$set(echo = TRUE)
 
 Primitive types such as `int` or `double` store numbers in exactly one or two bytes, with finite precision. This suffices for most applications, but cryptographic methods require arithmetic on much larger numbers and without loss of precision. Therefore OpenSSL provides a __bignum__ data type which holds arbitrary sized integers and implements all basic arithmetic and comparison operators such as `+`, `-`, `*`, `^`, `%%`, `%/%`, `==`, `!=`, `<`, `<=`, `>` and `>=`.
 
-One special case, the [__modular exponenent__](https://en.wikipedia.org/wiki/Modular_exponentiation) `a^b %% m` can be calculated using `bignum_mod_exp` when `b` is too large for calculating `a^b`.
+One special case, the [__modular exponent__](https://en.wikipedia.org/wiki/Modular_exponentiation) `a^b %% m` can be calculated using `bignum_mod_exp` when `b` is too large for calculating `a^b`.
 
 ```{r}
 # create a bignum
diff --git a/vignettes/crypto_hashing.Rmd b/vignettes/crypto_hashing.Rmd
index 69603bb..b23d5e4 100644
--- a/vignettes/crypto_hashing.Rmd
+++ b/vignettes/crypto_hashing.Rmd
@@ -28,7 +28,7 @@ Functions are fully vectorized for the case of character vectors: a vector with
 md5(c("foo", "bar", "baz"))
 ```
 
-Besides character and raw vectors we can pass a connection object (e.g. a file, socket or url). In this case the function will stream-hash the binary contents of the conection.
+Besides character and raw vectors we can pass a connection object (e.g. a file, socket or url). In this case the function will stream-hash the binary contents of the connection.
 
 ```{r}
 # Stream-hash a file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-openssl.git



More information about the debian-med-commit mailing list