55 KEYUTIL ,
66 b64utoutf8 ,
77 b64utohex ,
8- utf8tohex
8+ utf8tohex ,
9+ b64tohex ,
10+ ASN1HEX
911} from 'jsrsasign' ;
1012
1113import log from 'loglevel' ;
@@ -28,6 +30,44 @@ export function sign(header,
2830 }
2931}
3032
33+ /**
34+ * This function takes a PEM string with a public key and returns a
35+ * jsrsasign key object (RSAKey, KJUR.crypto.DSA, KJUR.crypto.ECDSA). It also
36+ * handles plain RSA keys not wrapped in a X.509 SubjectPublicKeyInfo
37+ * structure.
38+ * See: https://stackoverflow.com/questions/18039401/how-can-i-transform-between-the-two-styles-of-public-key-format-one-begin-rsa
39+ * @param {String } publicKey The public key as a PEM string.
40+ * @returns {Object } The public key as a jsrsasign key object.
41+ */
42+ function getPublicKeyObject ( publicKey ) {
43+ try {
44+ const startTag = '-----BEGIN RSA PUBLIC KEY-----' ;
45+ const endTag = '-----END RSA PUBLIC KEY-----' ;
46+ const startTagPos = publicKey . indexOf ( startTag ) ;
47+ const endTagPos = publicKey . indexOf ( endTag ) ;
48+
49+ if ( startTagPos !== - 1 && endTagPos !== - 1 ) {
50+ const plainDataBase64 =
51+ publicKey . substr ( 0 , endTagPos )
52+ . substr ( startTagPos + startTag . length ) ;
53+
54+ const plainDataDER = b64tohex ( plainDataBase64 ) ;
55+
56+ const barePublicKey = {
57+ n : ASN1HEX . getVbyList ( plainDataDER , 0 , [ 0 ] , '02' ) ,
58+ e : ASN1HEX . getVbyList ( plainDataDER , 0 , [ 1 ] , '02' )
59+ } ;
60+
61+ return KEYUTIL . getKey ( barePublicKey ) ;
62+ }
63+ } catch ( e ) {
64+ log . error ( 'Failed to make public key into X.509 ' +
65+ 'SubjectPublicKeyInfo key:' , e ) ;
66+ }
67+
68+ return KEYUTIL . getKey ( publicKey ) ;
69+ }
70+
3171export function verify ( jwt , secretOrPublicKeyString , base64Secret = false ) {
3272 if ( ! isToken ( jwt ) ) {
3373 return false ;
@@ -46,11 +86,12 @@ export function verify(jwt, secretOrPublicKeyString, base64Secret = false) {
4686 b64utohex ( secretOrPublicKeyString ) :
4787 utf8tohex ( secretOrPublicKeyString ) ) ;
4888 } else {
49- return jws . JWS . verify ( jwt , secretOrPublicKeyString ) ;
89+ const publicKeyObject = getPublicKeyObject ( secretOrPublicKeyString ) ;
90+ return jws . JWS . verify ( jwt , publicKeyObject ) ;
5091 }
5192 } catch ( e ) {
5293 log . warn ( 'Could not verify token, ' +
53- 'probably due to bad data in it or the keys: ' , e ) ;
94+ 'probably due to bad data in it or the keys: ' , e ) ;
5495 return false ;
5596 }
5697}
0 commit comments