Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow id_ed25519 keypair name #54

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: cyphr
Title: High Level Encryption Wrappers
Version: 1.1.4
Version: 1.1.5
Authors@R: c(person("Rich", "FitzJohn", role = c("aut", "cre"),
email = "[email protected]"),
person("Jai", "Ranganathan", role = "ctb"))
Expand All @@ -22,7 +22,7 @@ Suggests:
knitr,
rmarkdown,
testthat
RoxygenNote: 7.1.1
RoxygenNote: 7.2.1
Roxygen: list(markdown = TRUE)
VignetteBuilder: rmarkdown,
knitr
Expand Down
23 changes: 13 additions & 10 deletions R/openssl.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
##' @title Asymmetric encryption with openssl
##'
##' @param pub An openssl public key. Usually this will be the path
##' to the key, in which case it may either the path to a public key
##' or be the path to a directory containing a file
##' to the key, in which case it may be either the path to a public key
##' or the path to a directory containing a file such as
##' `id_rsa.pub`. If `NULL`, then your public key will be
##' used (found via the environment variable `USER_PUBKEY`,
##' then `~/.ssh/id_rsa.pub`). However, it is not that common
Expand Down Expand Up @@ -170,7 +170,7 @@ openssl_load_pubkey <- function(path) {
openssl_find_key <- function(path) {
if (is.null(path)) {
## NOTE: same logic as the openssl package
path <- Sys.getenv("USER_KEY", "~/.ssh/id_rsa")
path <- Sys.getenv("USER_KEY", guess_key_filename(pub = FALSE))
if (!file.exists(path)) {
openssl_key_error(path, "private")
}
Expand All @@ -179,9 +179,11 @@ openssl_find_key <- function(path) {
stop("Private key does not exist at ", path)
}
if (is_directory(path)) {
path <- file.path(path, "id_rsa")
if (!file.exists(path)) {
stop("did not find id_rsa within path")
path <- guess_key_filename(pub = FALSE, path = path)
if ((is.null(path)) || (!file.exists(path))) {
stop(sprintf("did not find %s within path",
guess_key_options(error = TRUE)))

}
}
path
Expand All @@ -193,7 +195,7 @@ openssl_find_pubkey <- function(path) {
## NOTE: almost same logic as the openssl package (but without the
## automatic derivation bit because that would require loading the
## private key which would trigger a password request).
path <- Sys.getenv("USER_PUBKEY", "~/.ssh/id_rsa.pub")
path <- Sys.getenv("USER_PUBKEY", guess_key_filename(pub = TRUE))
if (!file.exists(path)) {
openssl_key_error(path, "public")
}
Expand All @@ -202,9 +204,10 @@ openssl_find_pubkey <- function(path) {
stop("Public key does not exist at ", path)
}
if (is_directory(path)) {
path <- file.path(path, "id_rsa.pub")
if (!file.exists(path)) {
stop("did not find id_rsa.pub within path")
path <- guess_key_filename(pub = TRUE, path = path)
if ((is.null(path)) || (!file.exists(path))) {
stop(sprintf("did not find %s within path",
guess_key_options(error = TRUE)))
}
}
path
Expand Down
30 changes: 30 additions & 0 deletions R/util.R
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,33 @@ cyphr_file <- function(...) {
file_copy <- function(...) {
stopifnot(file.copy(...))
}

guess_key_options <- function(error = FALSE) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love this bit - particularly that the error is a different sort of thing. Perhaps:

guess_key_error <- function() {
  paste(sprintf("%s[.pub] pair", guess_key()), collapse = " or ")
}

replacing use of guess_key_options(error = TRUE)

Later we might want to generalise this approach and allow setting key priorities?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree - have separated that out so we have one function providing the list of key-stubs and separate error func...

if (error) {
paste0("id_rsa[.pub] pair or ",
"id_ed25519[.pub] pair")
} else {
c("id_rsa",
"id_ed25519")
}
}

guess_key_filename <- function(pub, path = "~/.ssh/") {
for (guess in guess_key_options()) {
keyfile <- sprintf("%s/%s", path, guess)
pubkeyfile <- sprintf("%s/%s.pub", path, guess)

# Ensure both private and public key exist,
# in order to return either.

if (file.exists(keyfile) && file.exists(pubkeyfile)) {
if (pub) {
return(pubkeyfile)
} else {
return(keyfile)
}
}
}

""
}
4 changes: 2 additions & 2 deletions man/keypair_openssl.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/testthat/test-openssl.R
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ test_that("find key", {
expect_error(openssl_find_key(path), "Private key does not exist")
expect_error(openssl_find_pubkey(path), "Public key does not exist")
dir.create(path)
expect_error(openssl_find_key(path), "did not find id_rsa within")
expect_error(openssl_find_pubkey(path), "did not find id_rsa.pub within")
expect_error(openssl_find_key(path), "did not find (.*) within")
expect_error(openssl_find_pubkey(path), "did not find (.*) within")
})

test_that("default key", {
Expand Down