@@ -6,6 +6,14 @@ if (!common.hasCrypto)
6
6
7
7
const assert = require ( 'assert' ) ;
8
8
const crypto = require ( 'crypto' ) ;
9
+ const {
10
+ createSign,
11
+ createVerify,
12
+ publicEncrypt,
13
+ privateDecrypt,
14
+ sign,
15
+ verify,
16
+ } = crypto ;
9
17
10
18
// The values below (modp2/modp2buf) are for a 1024 bits long prime from
11
19
// RFC 2412 E.2, see https://tools.ietf.org/html/rfc2412. */
@@ -42,7 +50,83 @@ function testDH({ publicKey: alicePublicKey, privateKey: alicePrivateKey },
42
50
assert . deepStrictEqual ( buf1 , expectedValue ) ;
43
51
}
44
52
53
+ // Asserts that the size of the given key (in chars or bytes) is within 10% of
54
+ // the expected size.
55
+ function assertApproximateSize ( key , expectedSize ) {
56
+ const u = typeof key === 'string' ? 'chars' : 'bytes' ;
57
+ const min = Math . floor ( 0.9 * expectedSize ) ;
58
+ const max = Math . ceil ( 1.1 * expectedSize ) ;
59
+ assert ( key . length >= min ,
60
+ `Key (${ key . length } ${ u } ) is shorter than expected (${ min } ${ u } )` ) ;
61
+ assert ( key . length <= max ,
62
+ `Key (${ key . length } ${ u } ) is longer than expected (${ max } ${ u } )` ) ;
63
+ }
64
+
65
+ // Tests that a key pair can be used for encryption / decryption.
66
+ function testEncryptDecrypt ( publicKey , privateKey ) {
67
+ const message = 'Hello Node.js world!' ;
68
+ const plaintext = Buffer . from ( message , 'utf8' ) ;
69
+ for ( const key of [ publicKey , privateKey ] ) {
70
+ const ciphertext = publicEncrypt ( key , plaintext ) ;
71
+ const received = privateDecrypt ( privateKey , ciphertext ) ;
72
+ assert . strictEqual ( received . toString ( 'utf8' ) , message ) ;
73
+ }
74
+ }
75
+
76
+ // Tests that a key pair can be used for signing / verification.
77
+ function testSignVerify ( publicKey , privateKey ) {
78
+ const message = Buffer . from ( 'Hello Node.js world!' ) ;
79
+
80
+ function oldSign ( algo , data , key ) {
81
+ return createSign ( algo ) . update ( data ) . sign ( key ) ;
82
+ }
83
+
84
+ function oldVerify ( algo , data , key , signature ) {
85
+ return createVerify ( algo ) . update ( data ) . verify ( key , signature ) ;
86
+ }
87
+
88
+ for ( const signFn of [ sign , oldSign ] ) {
89
+ const signature = signFn ( 'SHA256' , message , privateKey ) ;
90
+ for ( const verifyFn of [ verify , oldVerify ] ) {
91
+ for ( const key of [ publicKey , privateKey ] ) {
92
+ const okay = verifyFn ( 'SHA256' , message , key , signature ) ;
93
+ assert ( okay ) ;
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ // Constructs a regular expression for a PEM-encoded key with the given label.
100
+ function getRegExpForPEM ( label , cipher ) {
101
+ const head = `\\-\\-\\-\\-\\-BEGIN ${ label } \\-\\-\\-\\-\\-` ;
102
+ const rfc1421Header = cipher == null ? '' :
103
+ `\nProc-Type: 4,ENCRYPTED\nDEK-Info: ${ cipher } ,[^\n]+\n` ;
104
+ const body = '([a-zA-Z0-9\\+/=]{64}\n)*[a-zA-Z0-9\\+/=]{1,64}' ;
105
+ const end = `\\-\\-\\-\\-\\-END ${ label } \\-\\-\\-\\-\\-` ;
106
+ return new RegExp ( `^${ head } ${ rfc1421Header } \n${ body } \n${ end } \n$` ) ;
107
+ }
108
+
109
+ const pkcs1PubExp = getRegExpForPEM ( 'RSA PUBLIC KEY' ) ;
110
+ const pkcs1PrivExp = getRegExpForPEM ( 'RSA PRIVATE KEY' ) ;
111
+ const pkcs1EncExp = ( cipher ) => getRegExpForPEM ( 'RSA PRIVATE KEY' , cipher ) ;
112
+ const spkiExp = getRegExpForPEM ( 'PUBLIC KEY' ) ;
113
+ const pkcs8Exp = getRegExpForPEM ( 'PRIVATE KEY' ) ;
114
+ const pkcs8EncExp = getRegExpForPEM ( 'ENCRYPTED PRIVATE KEY' ) ;
115
+ const sec1Exp = getRegExpForPEM ( 'EC PRIVATE KEY' ) ;
116
+ const sec1EncExp = ( cipher ) => getRegExpForPEM ( 'EC PRIVATE KEY' , cipher ) ;
117
+
45
118
module . exports = {
46
119
modp2buf,
47
120
testDH,
121
+ assertApproximateSize,
122
+ testEncryptDecrypt,
123
+ testSignVerify,
124
+ pkcs1PubExp,
125
+ pkcs1PrivExp,
126
+ pkcs1EncExp, // used once
127
+ spkiExp,
128
+ pkcs8Exp, // used once
129
+ pkcs8EncExp, // used once
130
+ sec1Exp,
131
+ sec1EncExp,
48
132
} ;
0 commit comments