1+ var _ = require ( '../utils' ) . _ ;
2+ var utils = require ( '../utils' ) ;
3+ var BigInteger = require ( '../libs/jsbn' ) ;
4+
5+ const PRIVATE_OPENING_BOUNDARY = '-----BEGIN OPENSSH PRIVATE KEY-----' ;
6+ const PRIVATE_CLOSING_BOUNDARY = '-----END OPENSSH PRIVATE KEY-----' ;
7+
8+ module . exports = {
9+ privateExport : function ( key , options ) {
10+ throw Error ( 'Not implemented yet.' ) ;
11+ } ,
12+
13+ privateImport : function ( key , data , options ) {
14+ options = options || { } ;
15+ var buffer ;
16+
17+ if ( options . type !== 'der' ) {
18+ if ( Buffer . isBuffer ( data ) ) {
19+ data = data . toString ( 'utf8' ) ;
20+ }
21+
22+ if ( _ . isString ( data ) ) {
23+ var pem = utils . trimSurroundingText ( data , PRIVATE_OPENING_BOUNDARY , PRIVATE_CLOSING_BOUNDARY )
24+ . replace ( / \s + | \n \r | \n | \r $ / gm, '' ) ;
25+ buffer = Buffer . from ( pem , 'base64' ) ;
26+ } else {
27+ throw Error ( 'Unsupported key format' ) ;
28+ }
29+ } else if ( Buffer . isBuffer ( data ) ) {
30+ buffer = data ;
31+ } else {
32+ throw Error ( 'Unsupported key format' ) ;
33+ }
34+
35+ const reader = { buf :buffer , off :0 } ;
36+
37+ if ( buffer . slice ( 0 , 14 ) . toString ( 'ascii' ) !== 'openssh-key-v1' )
38+ throw 'Invalid file format.' ;
39+
40+ reader . off += 15 ;
41+
42+ //ciphername
43+ if ( readOpenSSHKeyString ( reader ) . toString ( 'ascii' ) !== 'none' )
44+ throw Error ( 'Unsupported key type' ) ;
45+ //kdfname
46+ if ( readOpenSSHKeyString ( reader ) . toString ( 'ascii' ) !== 'none' )
47+ throw Error ( 'Unsupported key type' ) ;
48+ //kdf
49+ if ( readOpenSSHKeyString ( reader ) . toString ( 'ascii' ) !== '' )
50+ throw Error ( 'Unsupported key type' ) ;
51+ //keynum
52+ reader . off += 4 ;
53+
54+ //sshpublengtn
55+ reader . off += 4 ;
56+
57+ //keytype
58+ if ( readOpenSSHKeyString ( reader ) . toString ( 'ascii' ) !== 'ssh-rsa' )
59+ throw Error ( 'Unsupported key type' ) ;
60+ readOpenSSHKeyString ( reader ) ;
61+ readOpenSSHKeyString ( reader ) ;
62+
63+ reader . off += 12 ;
64+ if ( readOpenSSHKeyString ( reader ) . toString ( 'ascii' ) !== 'ssh-rsa' )
65+ throw Error ( 'Unsupported key type' ) ;
66+
67+ const n = readOpenSSHKeyString ( reader ) ;
68+ const e = readOpenSSHKeyString ( reader ) ;
69+ const d = readOpenSSHKeyString ( reader ) ;
70+ const coeff = readOpenSSHKeyString ( reader ) ;
71+ const p = readOpenSSHKeyString ( reader ) ;
72+ const q = readOpenSSHKeyString ( reader ) ;
73+
74+ //Calculate missing values
75+ const dint = new BigInteger ( d ) ;
76+ const qint = new BigInteger ( q ) ;
77+ const pint = new BigInteger ( p ) ;
78+ const dp = dint . mod ( pint . subtract ( BigInteger . ONE ) ) ;
79+ const dq = dint . mod ( qint . subtract ( BigInteger . ONE ) ) ;
80+
81+ key . setPrivate (
82+ n , // modulus
83+ e , // publicExponent
84+ d , // privateExponent
85+ p , // prime1
86+ q , // prime2
87+ dp . toBuffer ( ) , // exponent1 -- d mod (p1)
88+ dq . toBuffer ( ) , // exponent2 -- d mod (q-1)
89+ coeff // coefficient -- (inverse of q) mod p
90+ ) ;
91+ } ,
92+
93+ publicExport : function ( key , options ) {
94+ throw Error ( 'Not implemented yet.' ) ;
95+ } ,
96+
97+ publicImport : function ( key , data , options ) {
98+ throw Error ( 'Not implemented yet.' ) ;
99+ } ,
100+
101+ /**
102+ * Trying autodetect and import key
103+ * @param key
104+ * @param data
105+ */
106+ autoImport : function ( key , data ) {
107+ // [\S\s]* matches zero or more of any character
108+ if ( / ^ [ \S \s ] * - - - - - B E G I N O P E N S S H P R I V A T E K E Y - - - - - \s * (? = ( ( [ A - Z a - z 0 - 9 + / = ] + \s * ) + ) ) \1- - - - - E N D O P E N S S H P R I V A T E K E Y - - - - - [ \S \s ] * $ / g. test ( data ) ) {
109+ module . exports . privateImport ( key , data ) ;
110+ return true ;
111+ }
112+
113+ return false ;
114+ }
115+ } ;
116+
117+ function readOpenSSHKeyString ( reader ) {
118+ const len = reader . buf . readInt32BE ( reader . off ) ;
119+ reader . off += 4 ;
120+ const res = reader . buf . slice ( reader . off , reader . off + len ) ;
121+ reader . off += len ;
122+ return res ;
123+ }
0 commit comments