forked from rebolsource/r3
-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FEAT: added
ssh-key
(Secure Shell Key) codec (so far only RSA keys)
- Loading branch information
Showing
4 changed files
with
167 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
REBOL [ | ||
Title: "REBOL 3 codec: Secure Shell Key" | ||
Author: "Oldes" | ||
Rights: "Copyright (C) 2018 Oldes. All rights reserved." | ||
License: "BSD-3" | ||
Test: %tests/units/crypt-test.r3 | ||
Note: { | ||
* it extract (and inits) only RSA keys so far | ||
* encrypted keys only with `AES-128-CBC` encryption | ||
} | ||
] | ||
|
||
wrap [ | ||
init-from-ssh2-key: function [data][ | ||
try [ | ||
binary/read data [ | ||
v: UI32BYTES | ||
e: UI32BYTES | ||
n: UI32BYTES | ||
] | ||
v: to string! v | ||
if v = "ssh-rsa" [ | ||
return rsa-init n e | ||
] | ||
] | ||
print ["Not RSA key! (" v ")"] | ||
none | ||
] | ||
|
||
register-codec [ | ||
name: 'ssh-key | ||
title: "Secure Shell Key" | ||
; not using suffixes as there is no standard! | ||
|
||
decode: function [ | ||
"Decodes and initilize SSH key" | ||
key [binary! string! file!] | ||
/password p [string! binary!] "Optional password" | ||
][ | ||
case [ | ||
file? key [ key: read key ] | ||
string? key [ key: to binary! key ] | ||
] | ||
; try to load key as a PKIX structure | ||
try [ pkix: codecs/pkix/decode key ] | ||
if none? pkix [ | ||
; if failed to load as PKIX, try to treat it as a *.PUB file | ||
return either parse key [ | ||
"ssh-rsa " copy data to [#" " | end] to end | ||
][ init-from-ssh2-key debase data 64 | ||
][ init-from-ssh2-key key ] | ||
] | ||
if "4,ENCRYPTED" = select pkix/header "Proc-Type" [ | ||
print "ENCRYPTED key!" | ||
try/except [ | ||
dek-info: select pkix/header "DEK-Info" | ||
;probe dek-info | ||
parse dek-info [ | ||
"AES-128-CBC" #"," copy iv to end | ||
] | ||
iv: debase iv 16 | ||
unless password [p: ask/hide "Pasword: "] | ||
p: checksum/method | ||
join to binary! p copy/part iv 8 | ||
'md5 | ||
d: aes/key/decrypt p iv | ||
pkix/binary: aes/stream d pkix/binary | ||
][ return none ] | ||
] | ||
|
||
switch pkix/label [ | ||
"SSH2 PUBLIC KEY" [ | ||
return init-from-ssh2-key pkix/binary | ||
] | ||
] | ||
; decode DER structure from decoded PKIX binary | ||
try/except [ | ||
data: codecs/der/decode pkix/binary | ||
][ | ||
print "Failed to decode DER day for RSA key!" | ||
probe system/state/last-error | ||
return none | ||
] | ||
|
||
switch pkix/label [ | ||
"PUBLIC KEY" [ | ||
; resolve RSA public data from the DER structure (PKCS#1) | ||
all [ | ||
parse data [ | ||
'SEQUENCE into [ | ||
'SEQUENCE set v block! ; AlgorithmIdentifier | ||
'BIT_STRING set data binary! ; PublicKey | ||
( | ||
data: codecs/der/decode data | ||
) | ||
] | ||
] | ||
v/OBJECT_IDENTIFIER = #{2A864886F70D010101} ;= rsaEncryption | ||
parse data [ | ||
'SEQUENCE into [ | ||
'INTEGER set n binary! ;modulus | ||
'INTEGER set e binary! ;publicExponent | ||
] | ||
] | ||
] | ||
; resolve RSA handle from parsed data | ||
return rsa-init n e | ||
] | ||
"RSA PUBLIC KEY" [ | ||
; resolve RSA public data from the DER structure (PKCS#1) | ||
parse data [ | ||
'SEQUENCE into [ | ||
'INTEGER set n binary! ;modulus | ||
'INTEGER set e binary! ;publicExponent | ||
] | ||
] | ||
; resolve RSA handle from parsed data | ||
return rsa-init n e | ||
] | ||
"RSA PRIVATE KEY" [ | ||
; resolve RSA private data from the DER structure (PKCS#1) | ||
parse data [ | ||
'SEQUENCE into [ | ||
'INTEGER set v binary! ;version | ||
'INTEGER set n binary! ;modulus | ||
'INTEGER set e binary! ;publicExponent | ||
'INTEGER set d binary! ;privateExponent | ||
'INTEGER set p binary! ;prime1 | ||
'INTEGER set q binary! ;prime2 | ||
'INTEGER set dp binary! ;exponent1 d mod (p-1) | ||
'INTEGER set dq binary! ;exponent2 d mod (q-1) | ||
'INTEGER set inv binary! ;coefficient (inverse of q) mod p | ||
to end | ||
] | ||
to end | ||
] | ||
; resolve RSA handle from parsed data | ||
return rsa-init/private n e d p q dp dq inv | ||
] | ||
] | ||
none ; no success! | ||
] | ||
] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
---- BEGIN SSH2 PUBLIC KEY ---- | ||
Comment: "rsa-key-rebol-test" | ||
AAAAB3NzaC1yc2EAAAABJQAAAQEA8mjwC6ZCwpQCnDXqU7g2tyvMFoWpJV+myfBz | ||
9zbhw7rHxUmFubMtEwCKQhYccQxbPCcWu/KIg5TOhmcf9RK1xIuUrOUiUdM8uOwR | ||
S+e5kitTUgux/wjyMNlpK5laIS1hFHiFhCxecN7Won3bsPDMm5Wi3dBMv1+1jK1r | ||
lDtJYxDDcJE2T59m1UI4AN/Pm7dndr11yCmUdKy6VACf5V7u4OX5uC3fsTEuCV1P | ||
2WwLBqtZMYG3jjzuRTana+s8n2TXk5D9lXoPMc7Tj4/aSw50UUAYhmVpie/8vtVw | ||
A7MhOCA4us6q3+Mx07vq8EmzbLOGtP9taXQkDF6JR6wY4IEXBw== | ||
---- END SSH2 PUBLIC KEY ---- |