@@ -6,8 +6,10 @@ import (
6
6
"bufio"
7
7
"crypto/rsa"
8
8
"crypto/x509"
9
+ "encoding/binary"
9
10
"encoding/pem"
10
11
"errors"
12
+ "io/ioutil"
11
13
"log"
12
14
"os"
13
15
"time"
@@ -117,66 +119,126 @@ func (keys *RSAKeyPair) GetTokenRemainingValidity(timestamp interface{}) int {
117
119
return expireOffset
118
120
}
119
121
120
- func getPrivateKey (privateKeyPath string ) * rsa.PrivateKey {
121
- privateKeyFile , err := os .Open (privateKeyPath )
122
+ // supports pk12 jks binary format
123
+ func readPK12 (file string ) ([]byte , error ) {
124
+ osFile , err := os .Open (file )
122
125
if err != nil {
123
- panic ( err )
126
+ return nil , err
124
127
}
128
+ reader := bufio .NewReaderSize (osFile , 4 )
125
129
126
- pemfileinfo , _ := privateKeyFile .Stat ()
127
- var size int64 = pemfileinfo .Size ()
128
- pembytes := make ([]byte , size )
130
+ return ioutil .ReadAll (reader )
131
+ }
129
132
130
- buffer := bufio .NewReader (privateKeyFile )
133
+ // decode PEM format to array of bytes
134
+ func decodePEM (pemFilePath string ) ([]byte , error ) {
135
+ keyFile , err := os .Open (pemFilePath )
136
+ defer keyFile .Close ()
137
+ if err != nil {
138
+ return nil , err
139
+ }
140
+
141
+ pemfileinfo , _ := keyFile .Stat ()
142
+ pembytes := make ([]byte , pemfileinfo .Size ())
143
+
144
+ buffer := bufio .NewReader (keyFile )
131
145
_ , err = buffer .Read (pembytes )
132
146
133
147
data , _ := pem .Decode ([]byte (pembytes ))
148
+ return data .Bytes , err
149
+ }
134
150
135
- privateKeyFile .Close ()
136
-
137
- // PKCS8 comply with Pulsar Java generated private key
138
- key , err := x509 .ParsePKCS8PrivateKey (data .Bytes )
151
+ func parseX509PKCS8PrivateKey (data []byte ) * rsa.PrivateKey {
152
+ key , err := x509 .ParsePKCS8PrivateKey (data )
139
153
140
154
if err != nil {
141
155
panic (err )
142
156
}
143
157
144
- privateKeyImported , ok := key .(* rsa.PrivateKey )
158
+ rsaPrivate , ok := key .(* rsa.PrivateKey )
145
159
if ! ok {
146
160
log .Fatalf ("expected key to be of type *ecdsa.PrivateKey, but actual was %T" , key )
147
161
}
148
162
149
- return privateKeyImported
163
+ return rsaPrivate
150
164
}
151
165
152
- func getPublicKey (publicKeyPath string ) * rsa.PublicKey {
153
- publicKeyFile , err := os .Open (publicKeyPath )
166
+ func parseX509PKIXPublicKey (data []byte ) * rsa.PublicKey {
167
+ publicKeyImported , err := x509 .ParsePKIXPublicKey (data )
168
+
154
169
if err != nil {
155
170
panic (err )
156
171
}
157
172
158
- pemfileinfo , _ := publicKeyFile .Stat ()
159
- var size int64 = pemfileinfo .Size ()
160
- pembytes := make ([]byte , size )
173
+ rsaPub , ok := publicKeyImported .(* rsa.PublicKey )
174
+ if ! ok {
175
+ panic (err )
176
+ }
161
177
162
- buffer := bufio . NewReader ( publicKeyFile )
163
- _ , err = buffer . Read ( pembytes )
178
+ return rsaPub
179
+ }
164
180
165
- data , _ := pem .Decode ([]byte (pembytes ))
181
+ // Since we support PEM And binary fomat of PKCS12/X509 keys,
182
+ // this function tries to determine which format
183
+ func fileFormat (file string ) (string , error ) {
184
+ osFile , err := os .Open (file )
185
+ if err != nil {
186
+ return "" , err
187
+ }
188
+ reader := bufio .NewReaderSize (osFile , 4 )
189
+ // attempt to guess based on first 4 bytes of input
190
+ data , err := reader .Peek (4 )
191
+ if err != nil {
192
+ return "" , err
193
+ }
166
194
167
- publicKeyFile .Close ()
195
+ magic := binary .BigEndian .Uint32 (data )
196
+ if magic == 0x2D2D2D2D || magic == 0x434f4e4e {
197
+ // Starts with '----' or 'CONN' (what s_client prints...)
198
+ return "PEM" , nil
199
+ }
200
+ if magic & 0xFFFF0000 == 0x30820000 {
201
+ // Looks like the input is DER-encoded, so it's either PKCS12 or X.509.
202
+ if magic & 0x0000FF00 == 0x0300 {
203
+ // Probably X.509
204
+ return "DER" , nil
205
+ }
206
+ return "PKCS12" , nil
207
+ }
168
208
169
- publicKeyImported , err := x509 .ParsePKIXPublicKey (data .Bytes )
209
+ return "" , errors .New ("undermined format" )
210
+ }
170
211
212
+ func getDataFromKeyFile (file string ) ([]byte , error ) {
213
+ format , err := fileFormat (file )
171
214
if err != nil {
172
- panic ( err )
215
+ return nil , err
173
216
}
174
217
175
- rsaPub , ok := publicKeyImported .(* rsa.PublicKey )
218
+ switch format {
219
+ case "PEM" :
220
+ return decodePEM (file )
221
+ case "PKCS12" :
222
+ return readPK12 (file )
223
+ default :
224
+ return nil , errors .New ("unsupported format" )
225
+ }
226
+ }
176
227
177
- if ! ok {
178
- panic (err )
228
+ func getPrivateKey (file string ) * rsa.PrivateKey {
229
+ data , err := getDataFromKeyFile (file )
230
+ if err != nil {
231
+ log .Fatal (err )
179
232
}
180
233
181
- return rsaPub
234
+ return parseX509PKCS8PrivateKey (data )
235
+ }
236
+
237
+ func getPublicKey (file string ) * rsa.PublicKey {
238
+ data , err := getDataFromKeyFile (file )
239
+ if err != nil {
240
+ log .Fatal (err )
241
+ }
242
+
243
+ return parseX509PKIXPublicKey (data )
182
244
}
0 commit comments