1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
parse_ssh_pem <- function(buf){
# extract the ssh2 pubkey text block
text <- rawToChar(buf)
regex <- "([-]+ BEGIN SSH2 PUBLIC KEY [-]+)(.*?)([-]+ END SSH2 PUBLIC KEY [-]+)"
m <- regexpr(regex, text)
if(m < 0)
stop("Failed to find SSH2 public key header/footer")
# strip off text headers and comments
text <- regmatches(text, m)
text <- sub("([-]+ BEGIN SSH2 PUBLIC KEY [-]+)[\\s]*", "", text)
text <- sub("([-]+ END SSH2 PUBLIC KEY [-]+)[\\s]*", "", text)
text <- sub("Comment(.*?)\\n", "", text)
# construct the actual key
ssh_build(text)
}
validate_openssh <- function(str){
is.character(str) && grepl("^(ssh-dss|ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp\\d+)\\s+", str[1])
}
parse_openssh <- function(buf){
text <- rawToChar(buf)
if(!validate_openssh(text))
stop("Unsupported ssh key id format: ", substring(text, 1, 15))
# Extract the base64 part
text <- sub("^\\S+\\s+", "", text)
text <- regmatches(text, regexpr("^\\S*", text))
ssh_build(text)
}
# parse ssh binary format
ssh_build <- function(b64text){
con <- rawConnection(base64_decode(b64text), open = "rb")
on.exit(close(con))
out <- list();
while(length(size <- readBin(con, 1L, endian = "big"))){
if(size == 0) break
buf <- readBin(con, raw(), size)
stopifnot(length(buf) == size)
out <- c(out, list(buf))
}
# extract key format
header <- rawToChar(out[[1]])
switch(header,
"ssh-dss" = dsa_build(out),
"ssh-rsa" = rsa_build(out),
"ssh-ed25519" = ed25519_build(out),
"ecdsa-sha2-nistp256" = ecdsa_build(out),
"ecdsa-sha2-nistp384" = ecdsa_build(out),
"ecdsa-sha2-nistp521" = ecdsa_build(out),
stop("Unsupported keytype: ", header)
)
}
rsa_build <- function(keydata){
exp <- keydata[[2]]
mod <- keydata[[3]]
rsa_pubkey_build(exp, mod)
}
dsa_build <- function(keydata){
p <- keydata[[2]]
q <- keydata[[3]]
g <- keydata[[4]]
y <- keydata[[5]]
dsa_pubkey_build(p, q, g, y)
}
ecdsa_build <- function(keydata){
curve_name <- rawToChar(keydata[[2]])
nist_name <- switch(curve_name,
"nistp256" = "P-256",
"nistp384" = "P-384",
"nistp521" = "P-521",
stop("Unsupported curve type: ", curve_name)
);
ec_point <- keydata[[3]]
if(ec_point[1] != 0x04)
stop("Invalid ecdsa format (not uncompressed?)")
ec_point <- ec_point[-1];
curve_size <- length(ec_point)/2
x <- utils::head(ec_point, curve_size)
y <- utils::tail(ec_point, curve_size)
ecdsa_pubkey_build(x, y, nist_name)
}
ed25519_build <- function(keydata){
structure(keydata[[2]], class = c("pubkey", "ed25519"))
}
|