@@ -6,8 +6,10 @@ import (
66 "bufio"
77 "crypto/rsa"
88 "crypto/x509"
9+ "encoding/binary"
910 "encoding/pem"
1011 "errors"
12+ "io/ioutil"
1113 "log"
1214 "os"
1315 "time"
@@ -117,66 +119,126 @@ func (keys *RSAKeyPair) GetTokenRemainingValidity(timestamp interface{}) int {
117119 return expireOffset
118120}
119121
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 )
122125 if err != nil {
123- panic ( err )
126+ return nil , err
124127 }
128+ reader := bufio .NewReaderSize (osFile , 4 )
125129
126- pemfileinfo , _ := privateKeyFile .Stat ()
127- var size int64 = pemfileinfo .Size ()
128- pembytes := make ([]byte , size )
130+ return ioutil .ReadAll (reader )
131+ }
129132
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 )
131145 _ , err = buffer .Read (pembytes )
132146
133147 data , _ := pem .Decode ([]byte (pembytes ))
148+ return data .Bytes , err
149+ }
134150
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 )
139153
140154 if err != nil {
141155 panic (err )
142156 }
143157
144- privateKeyImported , ok := key .(* rsa.PrivateKey )
158+ rsaPrivate , ok := key .(* rsa.PrivateKey )
145159 if ! ok {
146160 log .Fatalf ("expected key to be of type *ecdsa.PrivateKey, but actual was %T" , key )
147161 }
148162
149- return privateKeyImported
163+ return rsaPrivate
150164}
151165
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+
154169 if err != nil {
155170 panic (err )
156171 }
157172
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+ }
161177
162- buffer := bufio . NewReader ( publicKeyFile )
163- _ , err = buffer . Read ( pembytes )
178+ return rsaPub
179+ }
164180
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+ }
166194
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+ }
168208
169- publicKeyImported , err := x509 .ParsePKIXPublicKey (data .Bytes )
209+ return "" , errors .New ("undermined format" )
210+ }
170211
212+ func getDataFromKeyFile (file string ) ([]byte , error ) {
213+ format , err := fileFormat (file )
171214 if err != nil {
172- panic ( err )
215+ return nil , err
173216 }
174217
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+ }
176227
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 )
179232 }
180233
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 )
182244}
0 commit comments