Skip to content

Commit b2d2910

Browse files
author
John Bland
committed
Move to javasciprt classes, setup test files, partially implement rsa
interfaces are now in a folder called interfaces and use javascript instead of typescript each interface now has a test file that tests its functions rsa is working but I don't have the tests finished yet, need to research how encrypt and decrypt store the message
1 parent 73a21d2 commit b2d2910

File tree

14 files changed

+1057
-85
lines changed

14 files changed

+1057
-85
lines changed

app.js

Lines changed: 20 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,20 @@
1-
//const wolfcrypt = require('./build/Release/wolfcrypt');
2-
const { WolfSSLDecryptor } = require( './WolfSSLDecryptor.ts' )
3-
4-
/*
5-
let aes = Buffer.alloc( 1152 )
6-
let key = Buffer.from( '12345678901234567890123456789012' )
7-
let iv = Buffer.from( '1234567890123456' )
8-
let plainText = Buffer.from( 'testtesttesttest' )
9-
let cipherText = Buffer.alloc( 16 )
10-
let plainAgain = Buffer.alloc( 16 )
11-
let length = 16
12-
13-
let ret = wolfcrypt.MakeAes( aes, key, iv )
14-
15-
if ( ret == 0 )
16-
ret = wolfcrypt.Encrypt( aes, cipherText, plainText, length )
17-
18-
if ( ret == 0 )
19-
ret = wolfcrypt.Decrypt( aes, plainAgain, cipherText, length )
20-
21-
console.log( plainText.toString() )
22-
console.log( cipherText.toString( 'hex' ) )
23-
console.log( plainAgain.toString() )
24-
*/
25-
/*
26-
let length = 0
27-
let finalOutput = []
28-
const key = Buffer.from('12345678901234567890123456789012')
29-
const iv = Buffer.from('1234567890123456');
30-
31-
console.log( wolfcrypt.GetDecryptionSize() )
32-
33-
let decryption = Buffer.alloc( wolfcrypt.GetDecryptionSize() )
34-
wolfcrypt.NewDecryption( decryption, 'AES-256-CBC', key, iv )
35-
36-
let outBuf = Buffer.alloc( 8 )
37-
length = wolfcrypt.UpdateCipher( decryption, outBuf, Buffer.from('24d31b1e41fc8c40', 'hex'), 8 )
38-
console.log( length )
39-
40-
if ( length > 0 )
41-
{
42-
finalOutput.push( outBuf )
43-
}
44-
45-
outBuf = Buffer.alloc( 8 )
46-
length = wolfcrypt.UpdateCipher( decryption, outBuf, Buffer.from('e521531d67c72c20', 'hex'), 8 )
47-
console.log( length )
48-
49-
if ( length > 0 )
50-
{
51-
finalOutput.push( outBuf )
52-
}
53-
54-
outBuf = Buffer.alloc( 16 )
55-
length = wolfcrypt.FinalizeCipher( decryption, outBuf )
56-
console.log( length )
57-
58-
if ( length > 0 )
59-
{
60-
finalOutput.push( outBuf )
61-
}
62-
63-
console.log( Buffer.concat( finalOutput ).toString() )
64-
*/
65-
66-
const key = Buffer.from('12345678901234567890123456789012');
67-
const iv = Buffer.from('1234567890123456');
68-
const decrypt = new WolfSSLDecryptor('AES-256-CBC', key, iv);
69-
const expected = 'test';
70-
71-
const actual = Buffer.concat([
72-
decrypt.update(Buffer.from('24d31b1e41fc8c40', 'hex')),
73-
decrypt.update(Buffer.from('e521531d67c72c20', 'hex')),
74-
decrypt.finalize()
75-
]);
76-
77-
console.log( actual.toString() )
1+
const evp_tests = require( './tests/evp' );
2+
const hmac_tests = require( './tests/hmac' );
3+
const rsa_tests = require( './tests/rsa' );
4+
5+
(async function() {
6+
for ( const key of Object.keys( evp_tests ) )
7+
{
8+
await evp_tests[key]()
9+
}
10+
11+
for ( const key of Object.keys( hmac_tests ) )
12+
{
13+
await hmac_tests[key]()
14+
}
15+
16+
for ( const key of Object.keys( rsa_tests ) )
17+
{
18+
await rsa_tests[key]()
19+
}
20+
})()

binding.gyp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"sources": [
77
"wolfbind/main.cpp",
88
"wolfbind/evp.cpp",
9-
"wolfbind/hmac.cpp"
9+
"wolfbind/hmac.cpp",
10+
"wolfbind/rsa.cpp"
1011
],
1112
'include_dirs': [
1213
"<!@(node -p \"require('node-addon-api').include\")"

interfaces/evp.js

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
const wolfcrypt = require( '../build/Release/wolfcrypt' );
2+
const stream = require( 'stream' );
3+
4+
class WolfSSLEVP
5+
{
6+
/**
7+
* Creates a new evp cipher by calling EVP_CIPHER_CTX_new
8+
*
9+
* @remarks finalize or free must be called to free the cipher
10+
*/
11+
constructor()
12+
{
13+
this.totalInputLength = 0
14+
this.evp = wolfcrypt.EVP_CIPHER_CTX_new()
15+
}
16+
17+
/**
18+
* Updates the internal state with data for cipher.
19+
*
20+
* @param data The data that will be added to the cipher.
21+
*
22+
* @returns The result data if possible.
23+
*
24+
* @throws {Error} If the cipher update fails.
25+
*
26+
* @remarks This function can be called multiple times.
27+
*/
28+
update( data )
29+
{
30+
if ( this.evp == null )
31+
{
32+
throw 'Cipher is not allocated'
33+
}
34+
35+
if ( typeof data == 'string' )
36+
{
37+
data = Buffer.from( data )
38+
}
39+
40+
this.totalInputLength += data.length
41+
42+
let outBuffer = Buffer.alloc( this.totalInputLength )
43+
44+
let ret = wolfcrypt.EVP_CipherUpdate( this.evp, outBuffer, data, data.length )
45+
46+
if ( ret < 0 )
47+
{
48+
throw 'Failed to update cipher'
49+
}
50+
51+
if ( ret > 0 )
52+
{
53+
this.totalInputLength -= ret;
54+
55+
return outBuffer.subarray( 0, ret )
56+
}
57+
58+
return Buffer.alloc( 0 )
59+
}
60+
61+
/**
62+
* Finalize the encryption/decryption process.
63+
*
64+
* @returns The last block of data.
65+
*
66+
* @throws {Error} If the EVP_CipherFinal fails.
67+
*
68+
* @remarks This function should be called once to finalize the
69+
* encryption/decryption process.
70+
*/
71+
finalize()
72+
{
73+
if ( this.evp == null )
74+
{
75+
throw 'Cipher is not allocated'
76+
}
77+
78+
if ( this.totalInputLength % 16 != 0 )
79+
{
80+
this.totalInputLength += ( 16 - this.totalInputLength % 16 )
81+
}
82+
83+
let outBuffer = Buffer.alloc( this.totalInputLength )
84+
this.totalInputLength = 0;
85+
86+
let ret = wolfcrypt.EVP_CipherFinal( this.evp, outBuffer )
87+
88+
this.free()
89+
90+
if ( ret < 0 )
91+
{
92+
throw 'Failed to finalize cipher'
93+
}
94+
95+
if ( ret > 0 )
96+
{
97+
return outBuffer.subarray( 0, ret )
98+
}
99+
100+
return Buffer.alloc( 0 )
101+
}
102+
103+
/**
104+
* Frees the evp ctx
105+
*
106+
* @throws {Error} If the evp pointer is set to null
107+
*
108+
* @remarks This function should be called if the caller
109+
* no longer wants to use the cipher, update and finalize
110+
* will throw errors if free has been called
111+
*/
112+
free()
113+
{
114+
if ( this.evp != null )
115+
{
116+
wolfcrypt.EVP_CIPHER_CTX_free( this.evp )
117+
this.evp = null
118+
}
119+
else
120+
{
121+
throw 'Cipher is not allocated'
122+
}
123+
}
124+
}
125+
126+
class WolfSSLEncryptor extends WolfSSLEVP
127+
{
128+
/**
129+
* Initializes the evp cipher for encryption by calling EVP_CipherInit
130+
*
131+
* @param cipher the cipher to be used
132+
* @param key aes key
133+
* @param iv aes initialization vector
134+
*/
135+
constructor( cipher, key, iv )
136+
{
137+
super()
138+
wolfcrypt.EVP_CipherInit( this.evp, cipher, key, iv, 1 )
139+
}
140+
}
141+
142+
exports.WolfSSLEncryptor = WolfSSLEncryptor
143+
144+
class WolfSSLDecryptor extends WolfSSLEVP
145+
{
146+
/**
147+
* Initializes the evp cipher for decryption by calling EVP_CipherInit
148+
*
149+
* @param cipher the cipher to be used
150+
* @param key aes key
151+
* @param iv aes initialization vector
152+
*/
153+
constructor( cipher, key, iv )
154+
{
155+
super()
156+
wolfcrypt.EVP_CipherInit( this.evp, cipher, key, iv, 0 )
157+
}
158+
}
159+
160+
exports.WolfSSLDecryptor = WolfSSLDecryptor
161+
162+
class WolfSSLEVPStream extends stream.Transform
163+
{
164+
constructor()
165+
{
166+
super()
167+
}
168+
169+
/**
170+
* Transforms input data by encrypting or decrypting it with cipher.update
171+
*
172+
* @param chunk the data to be encrypted
173+
* @param enc encoding of the chunk
174+
* @param cb the callback function that handles
175+
* the next task of the stream
176+
*/
177+
_transform( chunk, enc, cb )
178+
{
179+
let buffer = Buffer.isBuffer( chunk ) ? chunk: new Buffer( chunk, enc )
180+
181+
let ret_buffer = this.cipher.update( chunk )
182+
183+
if ( ret_buffer.length > 0 )
184+
{
185+
this.push( ret_buffer )
186+
}
187+
188+
cb()
189+
}
190+
191+
/**
192+
* Called when the end of input is reached, call cipher.finalize
193+
* to finish the encryption
194+
*
195+
* @param cb the callback function that handles
196+
* the next task of the stream
197+
*/
198+
_flush( cb )
199+
{
200+
let ret_buffer = this.cipher.finalize()
201+
202+
if ( ret_buffer.length > 0 )
203+
{
204+
this.push( ret_buffer )
205+
}
206+
207+
cb()
208+
}
209+
}
210+
211+
class WolfSSLEncryptionStream extends WolfSSLEVPStream
212+
{
213+
/**
214+
* Creates a new encryptor and sets it to cipher, can then be used
215+
* by the generic stream methods
216+
*
217+
* @param cipher the cipher to be used
218+
* @param key aes key
219+
* @param iv aes initialization vector
220+
*/
221+
constructor( cipher, key, iv )
222+
{
223+
super()
224+
this.cipher = new WolfSSLEncryptor( cipher, key, iv )
225+
}
226+
}
227+
228+
exports.WolfSSLEncryptionStream = WolfSSLEncryptionStream
229+
230+
class WolfSSLDecryptionStream extends WolfSSLEVPStream
231+
{
232+
/**
233+
* Creates a new encryptor and sets it to cipher, can then be used
234+
* by the generic stream methods
235+
*
236+
* @param cipher the cipher to be used
237+
* @param key aes key
238+
* @param iv aes initialization vector
239+
*/
240+
constructor( cipher, key, iv )
241+
{
242+
super()
243+
this.cipher = new WolfSSLDecryptor( cipher, key, iv )
244+
}
245+
}
246+
247+
exports.WolfSSLDecryptionStream = WolfSSLDecryptionStream

0 commit comments

Comments
 (0)