@@ -4,17 +4,24 @@ var crypto = require('crypto');
44var ece = require ( './ece.js' ) ;
55var base64 = require ( 'urlsafe-base64' ) ;
66var assert = require ( 'assert' ) ;
7+ var fs = require ( 'fs' ) ;
78
8- // Usage: node <this> <iterations> <maxsize>
9+ var DUMP_FILE = '../encrypt_data.json' ;
10+ var dump_data = { } ;
11+
12+ // Usage: node <this> <iterations> <maxsize> <dump>
913var count = parseInt ( process . argv [ 2 ] , 10 ) || 20 ;
1014var maxLen = 100 ;
1115var plaintext = null ;
16+ var dump = false ; // flag to dump encrypt/decrypted values to JSON file for cross library checks.
17+
1218if ( process . argv . length >= 4 ) {
1319 if ( ! isNaN ( parseInt ( process . argv [ 3 ] , 10 ) ) ) {
1420 maxLen = parseInt ( process . argv [ 3 ] , 10 ) ;
1521 } else {
1622 plaintext = new Buffer ( process . argv [ 3 ] , 'ascii' ) ;
1723 }
24+ dump = ( process . argv . indexOf ( 'dump' ) != - 1 )
1825}
1926var log ;
2027if ( count === 1 ) {
@@ -32,16 +39,26 @@ function logbuf(msg, buf) {
3239 }
3340}
3441
42+ // Validate that the encryption function only accepts Buffers
3543function validate ( ) {
3644 [ 'hello' , null , 1 , NaN , [ ] , { } ] . forEach ( function ( v ) {
3745 try {
38- encrypt ( 'hello' , { } ) ;
39- throw new Error ( 'should insist on a buffer' ) ;
40- } catch ( e ) { }
46+ ece . encrypt ( v , { } ) ;
47+ } catch ( e ) {
48+ if ( e . toString ( ) != "Error: buffer argument must be a Buffer" ) {
49+ throw new Error ( "encrypt failed to reject " + JSON . stringify ( v ) ) ;
50+ }
51+ }
4152 } ) ;
4253}
4354
44- function encryptDecrypt ( length , encryptParams , decryptParams ) {
55+ function dumpData ( data ) {
56+ var version = data . version ;
57+ delete ( data . version ) ;
58+ dump_data [ version ] = data ;
59+ }
60+
61+ function encryptDecrypt ( length , encryptParams , decryptParams , version , keyData ) {
4562 decryptParams = decryptParams || encryptParams ;
4663 logbuf ( 'Salt' , encryptParams . salt ) ;
4764 var input = plaintext || crypto . randomBytes ( Math . min ( length , maxLen ) ) ;
@@ -51,22 +68,37 @@ function encryptDecrypt(length, encryptParams, decryptParams) {
5168 logbuf ( 'Encrypted' , encrypted ) ;
5269 var decrypted = ece . decrypt ( encrypted , decryptParams ) ;
5370 logbuf ( 'Decrypted' , decrypted ) ;
71+ if ( dump ) {
72+ var data = {
73+ version : version ,
74+ input : base64 . encode ( input ) ,
75+ encrypted : base64 . encode ( encrypted ) ,
76+ params : {
77+ encrypted : encryptParams ,
78+ decrypt : decryptParams ,
79+ }
80+ } ;
81+ if ( keyData ) {
82+ data . keys = keyData ;
83+ }
84+ dumpData ( data ) ;
85+ }
5486 assert . equal ( Buffer . compare ( input , decrypted ) , 0 ) ;
5587 log ( '----- OK' ) ;
5688}
5789
58- function useExplicitKey ( ) {
90+ function useExplicitKey ( version ) {
5991 var length = crypto . randomBytes ( 4 ) ;
6092 var params = {
6193 key : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
6294 salt : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
6395 rs : length . readUInt16BE ( 0 ) + 1
6496 } ;
6597 logbuf ( 'Key' , params . key ) ;
66- encryptDecrypt ( length . readUInt16BE ( 2 ) , params ) ;
98+ encryptDecrypt ( length . readUInt16BE ( 2 ) , params , params , version ) ;
6799}
68100
69- function authenticationSecret ( ) {
101+ function authenticationSecret ( version ) {
70102 var length = crypto . randomBytes ( 4 ) ;
71103 var params = {
72104 key : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
@@ -76,20 +108,20 @@ function authenticationSecret() {
76108 } ;
77109 logbuf ( 'Key' , params . key ) ;
78110 logbuf ( 'Context' , params . authSecret ) ;
79- encryptDecrypt ( length . readUInt16BE ( 2 ) , params ) ;
111+ encryptDecrypt ( length . readUInt16BE ( 2 ) , params , params , version ) ;
80112}
81113
82- function exactlyOneRecord ( ) {
114+ function exactlyOneRecord ( version ) {
83115 var length = Math . min ( crypto . randomBytes ( 2 ) . readUInt16BE ( 0 ) , maxLen ) ;
84116 var params = {
85117 key : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
86118 salt : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
87119 rs : length + 1
88120 } ;
89- encryptDecrypt ( length , params ) ;
121+ encryptDecrypt ( length , params , params , version ) ;
90122}
91123
92- function detectTruncation ( ) {
124+ function detectTruncation ( version ) {
93125 var length = Math . min ( crypto . randomBytes ( 2 ) . readUInt16BE ( 0 ) , maxLen ) ;
94126 var params = {
95127 key : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
@@ -104,7 +136,7 @@ function detectTruncation() {
104136 logbuf ( 'Encrypted' , encrypted ) ;
105137 var ok = false ;
106138 try {
107- ece . decrypt ( encrypted , params ) ;
139+ ece . decrypt ( encrypted , params , params , version ) ;
108140 } catch ( e ) {
109141 log ( '----- OK: ' + e ) ;
110142 ok = true ;
@@ -114,7 +146,7 @@ function detectTruncation() {
114146 }
115147}
116148
117- function useKeyId ( ) {
149+ function useKeyId ( version ) {
118150 var length = crypto . randomBytes ( 4 ) ;
119151 var keyid = base64 . encode ( crypto . randomBytes ( 16 ) ) ;
120152 var key = crypto . randomBytes ( 16 ) ;
@@ -124,15 +156,15 @@ function useKeyId() {
124156 salt : base64 . encode ( crypto . randomBytes ( 16 ) ) ,
125157 rs : length . readUInt16BE ( 0 ) + 1
126158 } ;
127- encryptDecrypt ( length . readUInt16BE ( 2 ) , params ) ;
159+ encryptDecrypt ( length . readUInt16BE ( 2 ) , params , params , version ) ;
128160}
129161
130- function useDH ( ) {
162+ function useDH ( version ) {
131163 // the static key is used by the receiver
132164 var staticKey = crypto . createECDH ( 'prime256v1' ) ;
133165 staticKey . generateKeys ( ) ;
134166 assert . equal ( staticKey . getPublicKey ( ) [ 0 ] , 4 , 'is an uncompressed point' ) ;
135- var staticKeyId = staticKey . getPublicKey ( ) . toString ( 'hex' )
167+ var staticKeyId = staticKey . getPublicKey ( ) . toString ( 'hex' ) ;
136168 ece . saveKey ( staticKeyId , staticKey , 'P-256' ) ;
137169
138170 logbuf ( 'Receiver private' , staticKey . getPrivateKey ( ) ) ;
@@ -161,22 +193,44 @@ function useDH() {
161193 salt : encryptParams . salt ,
162194 rs : encryptParams . rs
163195 } ;
164- encryptDecrypt ( length . readUInt16BE ( 2 ) , encryptParams , decryptParams ) ;
196+ // keyData is used for cross library verification dumps
197+ var keyData = {
198+ sender : {
199+ private : base64 . encode ( ephemeralKey . getPrivateKey ( ) ) ,
200+ public : base64 . encode ( ephemeralKey . getPublicKey ( ) )
201+ } ,
202+ receiver : {
203+ private : base64 . encode ( staticKey . getPrivateKey ( ) ) ,
204+ public : base64 . encode ( staticKey . getPublicKey ( ) )
205+ }
206+ } ;
207+ encryptDecrypt ( length . readUInt16BE ( 2 ) , encryptParams , decryptParams , version , keyData ) ;
165208}
166209
167210validate ( ) ;
168- var i ;
169- for ( i = 0 ; i < count ; ++ i ) {
170- [ useExplicitKey ,
171- authenticationSecret ,
172- exactlyOneRecord ,
173- detectTruncation ,
174- useKeyId ,
175- useDH ,
176- ] . forEach ( function ( f ) {
177- log ( 'Test: ' + f . name ) ;
178- f ( ) ;
179- } ) ;
180- }
181211
212+ for ( var version of [ 'aes128gcm' , 'aesgcm' , 'aesgcm128' ] ) {
213+ for ( var i = 0 ; i < count ; ++ i ) {
214+ [ useExplicitKey ,
215+ authenticationSecret ,
216+ exactlyOneRecord ,
217+ detectTruncation ,
218+ useKeyId ,
219+ useDH ,
220+ ] . forEach ( function ( f ) {
221+ log ( 'Test: ' + f . name ) ;
222+ f ( version ) ;
223+ } ) ;
224+ }
225+ }
182226console . log ( 'All tests passed.' ) ;
227+
228+ if ( dump ) {
229+ fs . open ( DUMP_FILE , 'w' , function ( err ) {
230+ if ( err ) {
231+ fs . unlink ( DUMP_FILE )
232+ }
233+
234+ fs . writeFile ( DUMP_FILE , JSON . stringify ( dump_data , undefined , ' ' ) ) ;
235+ } )
236+ }
0 commit comments