1#' X509 certificates 2#' 3#' Read, download, analyze and verify X.509 certificates. 4#' 5#' @useDynLib openssl R_cert_verify_cert R_pubkey_verify_cert 6#' @export 7#' @rdname certificates 8#' @seealso \link{read_cert} 9#' @param cert certificate (or certificate-chain) to be verified. Must be cert or list or path. 10#' @param root trusted pubkey or certificate(s) e.g. CA bundle. 11#' @examples # Verify the r-project HTTPS cert 12#' chain <- download_ssl_cert("cran.r-project.org", 443) 13#' print(chain) 14#' cert_data <- as.list(chain[[1]]) 15#' print(cert_data$pubkey) 16#' print(cert_data$alt_names) 17#' cert_verify(chain, ca_bundle()) 18#' 19#' # Write cert in PEM format 20#' cat(write_pem(chain[[1]])) 21cert_verify <- function(cert, root = ca_bundle()){ 22 if(is.raw(cert)) 23 cert <- list(cert) 24 if(!is.list(cert)) 25 cert <- read_cert_bundle(cert) 26 stopifnot(inherits(cert[[1]], "cert")) 27 if(inherits(root, "cert")) 28 root <- list(root) 29 if(!is.raw(root) && !is.list(root)){ 30 buf <- read_input(root) 31 names <- pem_names(buf) 32 if(any(grepl("CERT", names))){ 33 root <- read_cert_bundle(root) 34 } else { 35 root <- read_pubkey(root) 36 } 37 } 38 if(inherits(root, "pubkey")){ 39 pubkey_verify_cert(cert[[1]], root) 40 } else { 41 stopifnot(all(sapply(root, inherits, "cert"))) 42 cert_verify_cert(cert[[1]], cert[-1], root) 43 } 44} 45 46#' @useDynLib openssl R_download_cert 47#' @export 48#' @rdname certificates 49#' @param host string: hostname of the server to connect to 50#' @param port string or integer: port or protocol to use, e.g: \code{443} or \code{"https"} 51#' @param ipv4_only do not use IPv6 connections 52download_ssl_cert <- function(host = "localhost", port = 443, ipv4_only = FALSE){ 53 if(grepl("https?://", host)) 54 stop("Argument 'host' must be a hostname, not url. Take out the https:// prefix.") 55 stopifnot(is.character(host)) 56 .Call(R_download_cert, host, as.character(port), ipv4_only) 57} 58 59#' @useDynLib openssl R_cert_verify_cert 60cert_verify_cert <- function(cert, chain, root){ 61 .Call(R_cert_verify_cert, cert, chain, root) 62} 63 64#' @useDynLib openssl R_pubkey_verify_cert 65pubkey_verify_cert <- function(cert, pubkey){ 66 .Call(R_pubkey_verify_cert, cert, pubkey) 67} 68 69#' @export 70#' @rdname certificates 71ca_bundle <- function(){ 72 path <- system.file("cacert.pem", package = "openssl") 73 read_cert_bundle(path) 74} 75 76#' @useDynLib openssl R_cert_info 77cert_info <- function(cert, name_format = NULL){ 78 stopifnot(is.raw(cert)) 79 if(length(name_format)) 80 stopifnot(is.integer(name_format)) 81 out <- .Call(R_cert_info, cert, name_format) 82 structure(out, names = c("subject", "issuer", "algorithm", "signature", "validity", "self_signed", "alt_names")) 83} 84