@@ -7,7 +7,95 @@ const PRIVATE_CLOSING_BOUNDARY = '-----END OPENSSH PRIVATE KEY-----';
77
88module . exports = {
99 privateExport : function ( key , options ) {
10- throw Error ( 'Not implemented yet.' ) ;
10+ const nbuf = key . n . toBuffer ( ) ;
11+
12+ let ebuf = Buffer . alloc ( 4 )
13+ ebuf . writeUInt32BE ( key . e , 0 ) ;
14+ //Slice leading zeroes
15+ while ( ebuf [ 0 ] === 0 ) ebuf = ebuf . slice ( 1 ) ;
16+
17+ const dbuf = key . d . toBuffer ( ) ;
18+ const coeffbuf = key . coeff . toBuffer ( ) ;
19+ const pbuf = key . p . toBuffer ( ) ;
20+ const qbuf = key . q . toBuffer ( ) ;
21+ let commentbuf ;
22+ if ( typeof key . sshcomment !== 'undefined' ) {
23+ commentbuf = Buffer . from ( key . sshcomment ) ;
24+ } else {
25+ commentbuf = Buffer . from ( [ ] ) ;
26+ }
27+
28+ const pubkeyLength =
29+ 11 + // 32bit length, 'ssh-rsa'
30+ 4 + ebuf . byteLength +
31+ 4 + nbuf . byteLength ;
32+
33+ const privateKeyLength =
34+ 8 + //64bit unused checksum
35+ 11 + // 32bit length, 'ssh-rsa'
36+ 4 + nbuf . byteLength +
37+ 4 + ebuf . byteLength +
38+ 4 + dbuf . byteLength +
39+ 4 + coeffbuf . byteLength +
40+ 4 + pbuf . byteLength +
41+ 4 + qbuf . byteLength +
42+ 4 + commentbuf . byteLength ;
43+
44+ let length =
45+ 15 + //openssh-key-v1,0x00,
46+ 16 + // 2*(32bit length, 'none')
47+ 4 + // 32bit length, empty string
48+ 4 + // 32bit number of keys
49+ 4 + // 32bit pubkey length
50+ pubkeyLength +
51+ 4 + //32bit private+checksum+comment+padding length
52+ privateKeyLength ;
53+
54+ const paddingLength = Math . ceil ( privateKeyLength / 8 ) * 8 - privateKeyLength ;
55+ length += paddingLength ;
56+
57+ const buf = Buffer . alloc ( length ) ;
58+ const writer = { buf :buf , off : 0 } ;
59+ buf . write ( 'openssh-key-v1' , 'utf8' ) ;
60+ buf . writeUInt8 ( 0 , 14 ) ;
61+ writer . off += 15 ;
62+
63+ writeOpenSSHKeyString ( writer , Buffer . from ( 'none' ) ) ;
64+ writeOpenSSHKeyString ( writer , Buffer . from ( 'none' ) ) ;
65+ writeOpenSSHKeyString ( writer , Buffer . from ( '' ) ) ;
66+
67+ writer . off = writer . buf . writeUInt32BE ( 1 , writer . off ) ;
68+ writer . off = writer . buf . writeUInt32BE ( pubkeyLength , writer . off ) ;
69+
70+ writeOpenSSHKeyString ( writer , Buffer . from ( 'ssh-rsa' ) ) ;
71+ writeOpenSSHKeyString ( writer , ebuf ) ;
72+ writeOpenSSHKeyString ( writer , nbuf ) ;
73+
74+ writer . off = writer . buf . writeUInt32BE (
75+ length - 47 - pubkeyLength ,
76+ writer . off
77+ ) ;
78+ writer . off += 8 ;
79+
80+ writeOpenSSHKeyString ( writer , Buffer . from ( 'ssh-rsa' ) ) ;
81+ writeOpenSSHKeyString ( writer , nbuf ) ;
82+ writeOpenSSHKeyString ( writer , ebuf ) ;
83+ writeOpenSSHKeyString ( writer , dbuf ) ;
84+ writeOpenSSHKeyString ( writer , coeffbuf ) ;
85+ writeOpenSSHKeyString ( writer , pbuf ) ;
86+ writeOpenSSHKeyString ( writer , qbuf ) ;
87+ writeOpenSSHKeyString ( writer , commentbuf ) ;
88+
89+ let pad = 0x01 ;
90+ while ( writer . off < length ) {
91+ writer . off = writer . buf . writeUInt8 ( pad ++ , writer . off ) ;
92+ }
93+
94+ if ( options . type === 'der' ) {
95+ return writer . buf
96+ } else {
97+ return PRIVATE_OPENING_BOUNDARY + '\n' + utils . linebrk ( buf . toString ( 'base64' ) , 70 ) + '\n' + PRIVATE_CLOSING_BOUNDARY ;
98+ }
1199 } ,
12100
13101 privateImport : function ( key , data , options ) {
@@ -110,7 +198,12 @@ module.exports = {
110198 writeOpenSSHKeyString ( writer , nbuf ) ;
111199
112200 let comment = key . sshcomment || '' ;
113- return 'ssh-rsa ' + buf . toString ( 'base64' ) + ' ' + comment ;
201+
202+ if ( options . type === 'der' ) {
203+ return writer . buf
204+ } else {
205+ return 'ssh-rsa ' + buf . toString ( 'base64' ) + ' ' + comment ;
206+ }
114207 } ,
115208
116209 publicImport : function ( key , data , options ) {
0 commit comments