55
66const _ = require ( 'lodash' ) ;
77const base64url = require ( 'base64url' ) ;
8+ const asn = require ( 'asn1.js' ) ;
9+ const util = require ( '../util' ) ;
810
911const OPTIONAL_PRIVATE_PROPS = [
1012 'p' , 'q' , 'dp' , 'dq' , 'qi'
1113] ;
1214
15+ // Define ASN structures
16+ const RSAPrivateKey = asn . define ( 'RSAPrivateKey' , function ( ) {
17+ this . seq ( ) . obj (
18+ this . key ( 'id' ) . int ( ) ,
19+ this . key ( 'n' ) . int ( ) ,
20+ this . key ( 'e' ) . int ( ) ,
21+ this . key ( 'd' ) . int ( ) ,
22+ this . key ( 'p' ) . int ( ) ,
23+ this . key ( 'q' ) . int ( ) ,
24+ this . key ( 'dp' ) . int ( ) ,
25+ this . key ( 'dq' ) . int ( ) ,
26+ this . key ( 'qi' ) . int ( )
27+ ) ;
28+ } ) ;
29+
30+ const RSAPublicKeyHeader = asn . define ( 'RSAPublicKeyHeader' , function ( ) {
31+ this . seq ( ) . obj (
32+ this . key ( 'keyType' ) . objid ( {
33+ '1.2.840.113549.1.1.1' : 'RSA'
34+ } ) ,
35+ this . null_ ( )
36+ ) ;
37+ } ) ;
38+
39+ const RSAPublicKeyParams = asn . define ( 'RSAPublicKeyParams' , function ( ) {
40+ this . seq ( ) . obj (
41+ this . key ( 'n' ) . int ( ) ,
42+ this . key ( 'e' ) . int ( )
43+ ) ;
44+ } ) ;
45+
46+ const RSAPublicKey = asn . define ( 'RSAPublicKey' , function ( ) {
47+ this . seq ( ) . obj (
48+ this . key ( 'header' ) . use ( RSAPublicKeyHeader ) ,
49+ this . key ( 'content' ) . bitstr ( )
50+ ) ;
51+ } ) ;
52+
1353class RSAKey {
1454
15- constructor ( n , e , d , p , q , dp , dq , qi , oth ) {
16- this . _n = n ;
17- this . _e = e ;
18- this . _d = d ;
19- this . _p = p ;
20- this . _q = q ;
21- this . _dp = dp ;
22- this . _dq = dq ;
23- this . _qi = qi ;
24- this . _oth = oth ;
55+ constructor ( n , e , d , p , q , dp , dq , qi , oth , r ) {
56+ this . _data = {
57+ id : 0 ,
58+ n : util . unsigned ( n ) ,
59+ e : util . unsigned ( e ) ,
60+ d : util . unsigned ( d ) ,
61+ p : util . unsigned ( p ) ,
62+ q : util . unsigned ( q ) ,
63+ dp : util . unsigned ( dp ) ,
64+ dq : util . unsigned ( dq ) ,
65+ qi : util . unsigned ( qi ) ,
66+ oth : util . unsigned ( oth ) ,
67+ r : util . unsigned ( r )
68+ } ;
2569 }
2670
2771 get hasPrivateKey ( ) {
28- return ! _ . isNil ( this . _d ) ;
72+ return ! _ . isNil ( this . _data . d ) ;
73+ }
74+
75+ toPublicKeyPEM ( ) {
76+ const keyParams = RSAPublicKeyParams . encode ( this . _data , 'der' ) ;
77+
78+ const params = {
79+ header : {
80+ keyType : 'RSA'
81+ } ,
82+ content : {
83+ data : keyParams
84+ }
85+ } ;
86+ return RSAPublicKey . encode ( params , 'pem' , { label : 'PUBLIC KEY' } ) ;
87+ }
88+
89+ toPrivateKeyPEM ( ) {
90+ if ( ! this . hasPrivateKey ) {
91+ return null ;
92+ }
93+
94+ return RSAPrivateKey . encode ( this . _data , 'pem' , { label : 'RSA PRIVATE KEY' } ) ;
2995 }
3096
3197 static validate ( key ) {
@@ -43,11 +109,18 @@ class RSAKey {
43109 }
44110
45111 static fromKey ( key ) {
46- const x = base64url . toBuffer ( key . x ) ;
47- const y = base64url . toBuffer ( key . y ) ;
48- const d = key . d ? base64url . toBuffer ( key . d ) : undefined ;
112+ const n = base64url . toBuffer ( key . n ) ;
113+ const e = base64url . toBuffer ( key . e ) ;
114+ const d = key . d ? base64url . toBuffer ( key . d ) : null ;
115+ const p = key . p ? base64url . toBuffer ( key . p ) : null ;
116+ const q = key . q ? base64url . toBuffer ( key . q ) : null ;
117+ const dp = key . dp ? base64url . toBuffer ( key . dp ) : null ;
118+ const dq = key . dq ? base64url . toBuffer ( key . dq ) : null ;
119+ const qi = key . qi ? base64url . toBuffer ( key . qi ) : null ;
120+ const oth = key . oth ? base64url . toBuffer ( key . oth ) : null ;
121+ const r = key . r ? base64url . toBuffer ( key . r ) : null ;
49122
50- return new RSAKey ( key . crv , x , y , d ) ;
123+ return new RSAKey ( n , e , d , p , q , dp , dq , qi , oth , r ) ;
51124 }
52125
53126}
0 commit comments