@@ -7,7 +7,95 @@ const PRIVATE_CLOSING_BOUNDARY = '-----END OPENSSH PRIVATE KEY-----';
7
7
8
8
module . exports = {
9
9
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
+ }
11
99
} ,
12
100
13
101
privateImport : function ( key , data , options ) {
@@ -110,7 +198,12 @@ module.exports = {
110
198
writeOpenSSHKeyString ( writer , nbuf ) ;
111
199
112
200
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
+ }
114
207
} ,
115
208
116
209
publicImport : function ( key , data , options ) {
0 commit comments