##' Create openssl key pairs in the manner of `ssh-keygen`(1).
##' In general this should not be used (generate keys yourself with
##' `ssh-keygen` at the command line. However this is useful for
##' testing and demonstration so I have included it to make that
##' easier. Once a keypair has been generated it can be used with
##' [cyphr::keypair_openssl()].
##'
##' @title Create ssh keypairs
##' @param path A directory in which to create a keypair. If the path
##' does not exist it will be created.
##' @param password The password for the key. The default will prompt
##' interactively (but without echoing the password). Other valid
##' options are `FALSE` (no password) or a string.
##' @param use_shell Try to use `ssh-keygen` (the shell utility)
##' rather than functions in the `openssl` package. This will
##' be necessary on at least very old versions of OS/X (Yosemite and
##' older at least) where the keys generated by the `openssl`
##' package cannot be read by the system ssh commands (e.g.,
##' `ssh-add`).
##' @return The `path`, invisibly. This is useful in the case
##' where `path` is [tempfile()].
##' @export
##' @examples
##' # Generate a new key in a temporary directory:
##' path <- cyphr::ssh_keygen(password = FALSE)
##' dir(path) # will contain id_rsa and id_rsa.pub
##'
##' # This key can now be used via keypair_openssl:
##' key <- cyphr::keypair_openssl(path, path)
##' secret <- cyphr::encrypt_string("hello", key)
##' cyphr::decrypt_string(secret, key)
##'
##' # Cleanup
##' unlink(path, recursive = TRUE)
ssh_keygen <- function(path = tempfile(), password = TRUE, use_shell = FALSE) {
if (file.exists(path) && !is_directory(path)) {
stop("path exists but is not a directory")
}
dir.create(path, FALSE, TRUE)
dest_key <- file.path(path, "id_rsa")
dest_pub <- file.path(path, "id_rsa.pub")
if (file.exists(dest_key)) {
stop("private key ", dest_key, " exists already -- not overwriting")
}
if (file.exists(dest_pub)) {
stop("public key ", dest_pub, " exists already -- not overwriting")
}
if (isTRUE(password)) {
pw <- get_password_str(TRUE, "Enter passphrase: ")
} else if (identical(password, FALSE)) {
pw <- ""
} else if (is.character(password)) {
pw <- password
} else {
stop("Invalid input for password")
}
if (!nzchar(pw)) {
pw <- if (use_shell) "''" else NULL
}
if (use_shell) {
ssh_keygen <- sys_which("ssh-keygen")
code <- system2(ssh_keygen, c("-q", "-N", pw, "-f", dest_key))
if (code != 0L) {
## This can't be easily triggered so I'll leave this be for now.
stop("Error running ssh-keygen") # nocov
}
} else {
key <- openssl::rsa_keygen()
pub <- as.list(key)$pubkey
openssl::write_pem(key, dest_key, password = pw)
Sys.chmod(dest_key, "600")
openssl::write_ssh(pub, dest_pub)
}
invisible(path)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.