Skip to content

Commit 4039839

Browse files
authored
Merge pull request #2 from jpbland1/main
Hmac typescript wrapper
2 parents 3f4d65b + 73a21d2 commit 4039839

File tree

12 files changed

+708
-77
lines changed

12 files changed

+708
-77
lines changed

WolfSSLEVP.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ var wolfcrypt = require('./build/Release/wolfcrypt');
2020
var stream = require('stream');
2121
var WolfSSLEVP = /** @class */ (function () {
2222
function WolfSSLEVP() {
23-
this.evp = Buffer.alloc(wolfcrypt.sizeof_EVP_CIPHER_CTX());
23+
// actually holds a pointer but nodejs has no pointer type
24+
this.evp = null;
25+
this.totalInputLength = 0;
26+
this.evp = wolfcrypt.EVP_CIPHER_CTX_new();
2427
this.totalInputLength = 0;
2528
}
2629
/**
@@ -35,6 +38,9 @@ var WolfSSLEVP = /** @class */ (function () {
3538
* @remarks This function should be called multiple times.
3639
*/
3740
WolfSSLEVP.prototype.update = function (data) {
41+
if (this.evp == null) {
42+
throw 'Cipher is not allocated';
43+
}
3844
this.totalInputLength += data.length;
3945
var outBuffer = Buffer.alloc(this.totalInputLength);
4046
var ret = wolfcrypt.EVP_CipherUpdate(this.evp, outBuffer, data, data.length);
@@ -58,12 +64,17 @@ var WolfSSLEVP = /** @class */ (function () {
5864
* process.
5965
*/
6066
WolfSSLEVP.prototype.finalize = function () {
67+
if (this.evp == null) {
68+
throw 'Cipher is not allocated';
69+
}
6170
if (this.totalInputLength % 16 != 0) {
6271
this.totalInputLength += (16 - this.totalInputLength % 16);
6372
}
6473
var outBuffer = Buffer.alloc(this.totalInputLength);
6574
this.totalInputLength = 0;
6675
var ret = wolfcrypt.EVP_CipherFinal(this.evp, outBuffer);
76+
wolfcrypt.EVP_CIPHER_CTX_free(this.evp);
77+
this.evp = null;
6778
if (ret < 0) {
6879
throw 'Failed to finalize cipher';
6980
}
@@ -72,6 +83,15 @@ var WolfSSLEVP = /** @class */ (function () {
7283
}
7384
return Buffer.alloc(0);
7485
};
86+
WolfSSLEVP.prototype.free = function () {
87+
if (this.evp != null) {
88+
wolfcrypt.EVP_CIPHER_CTX_free(this.evp);
89+
this.evp = null;
90+
}
91+
else {
92+
throw 'Cipher is not allocated';
93+
}
94+
};
7595
return WolfSSLEVP;
7696
}());
7797
var WolfSSLEncryptor = /** @class */ (function (_super) {

WolfSSLEVP.ts

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
const wolfcrypt = require( './build/Release/wolfcrypt' );
22
const stream = require( 'stream' );
33

4-
class WolfSSLEVP {
5-
protected evp: Buffer
6-
protected totalInputLength: number
4+
class WolfSSLEVP
5+
{
6+
// actually holds a pointer but nodejs has no pointer type
7+
protected evp: number = null
8+
protected totalInputLength: number = 0
79

8-
public constructor() {
9-
this.evp = Buffer.alloc( wolfcrypt.sizeof_EVP_CIPHER_CTX() )
10+
public constructor()
11+
{
12+
this.evp = wolfcrypt.EVP_CIPHER_CTX_new()
1013
this.totalInputLength = 0
1114
}
1215

@@ -21,7 +24,13 @@ class WolfSSLEVP {
2124
*
2225
* @remarks This function should be called multiple times.
2326
*/
24-
public update(data: Buffer): Buffer {
27+
public update(data: Buffer): Buffer
28+
{
29+
if ( this.evp == null )
30+
{
31+
throw 'Cipher is not allocated'
32+
}
33+
2534
this.totalInputLength += data.length
2635

2736
let outBuffer = Buffer.alloc( this.totalInputLength )
@@ -53,7 +62,13 @@ class WolfSSLEVP {
5362
* @remarks This function should be called once to finalize the decryption
5463
* process.
5564
*/
56-
public finalize(): Buffer {
65+
public finalize(): Buffer
66+
{
67+
if ( this.evp == null )
68+
{
69+
throw 'Cipher is not allocated'
70+
}
71+
5772
if ( this.totalInputLength % 16 != 0 )
5873
{
5974
this.totalInputLength += ( 16 - this.totalInputLength % 16 )
@@ -64,6 +79,9 @@ class WolfSSLEVP {
6479

6580
let ret = wolfcrypt.EVP_CipherFinal( this.evp, outBuffer )
6681

82+
wolfcrypt.EVP_CIPHER_CTX_free( this.evp )
83+
this.evp = null
84+
6785
if ( ret < 0 )
6886
{
6987
throw 'Failed to finalize cipher'
@@ -77,6 +95,19 @@ class WolfSSLEVP {
7795
return Buffer.alloc( 0 )
7896
}
7997

98+
public free()
99+
{
100+
if ( this.evp != null )
101+
{
102+
wolfcrypt.EVP_CIPHER_CTX_free( this.evp )
103+
this.evp = null
104+
}
105+
else
106+
{
107+
throw 'Cipher is not allocated'
108+
}
109+
}
110+
80111
/**
81112
* Enables the FIPS mode.
82113
*/
@@ -89,7 +120,8 @@ class WolfSSLEVP {
89120
*/
90121
}
91122

92-
export class WolfSSLEncryptor extends WolfSSLEVP {
123+
export class WolfSSLEncryptor extends WolfSSLEVP
124+
{
93125
/**
94126
* Initializes a new instance of the WolfSSLEncryptor class.
95127
*
@@ -100,7 +132,8 @@ export class WolfSSLEncryptor extends WolfSSLEVP {
100132
* @throws {Error} If cipher is not available or unknown.
101133
* @throws {Error} If the creation of the Decryption object failed.
102134
*/
103-
public constructor(cipher: string, key: Buffer, iv: Buffer) {
135+
public constructor(cipher: string, key: Buffer, iv: Buffer)
136+
{
104137
super()
105138
wolfcrypt.EVP_CipherInit( this.evp, cipher, key, iv, 1 )
106139
}
@@ -117,13 +150,15 @@ export class WolfSSLDecryptor extends WolfSSLEVP {
117150
* @throws {Error} If cipher is not available or unknown.
118151
* @throws {Error} If the creation of the Decryption object failed.
119152
*/
120-
public constructor(cipher: string, key: Buffer, iv: Buffer) {
153+
public constructor(cipher: string, key: Buffer, iv: Buffer)
154+
{
121155
super()
122156
wolfcrypt.EVP_CipherInit( this.evp, cipher, key, iv, 0 )
123157
}
124158
}
125159

126-
export class WolfSSLEncryptionStream extends stream.Transform {
160+
export class WolfSSLEncryptionStream extends stream.Transform
161+
{
127162
private encryptor: WolfSSLEncryptor
128163
/**
129164
* Initializes a new instance of the WolfSSLEncryptionStream class.
@@ -135,7 +170,8 @@ export class WolfSSLEncryptionStream extends stream.Transform {
135170
* @throws {Error} If cipher is not available or unknown.
136171
* @throws {Error} If the creation of the Decryption object failed.
137172
*/
138-
public constructor(cipher: string, key: Buffer, iv: Buffer) {
173+
public constructor(cipher: string, key: Buffer, iv: Buffer)
174+
{
139175
super()
140176
this.encryptor = new WolfSSLEncryptor( cipher, key, iv )
141177
}
@@ -179,7 +215,8 @@ export class WolfSSLDecryptionStream extends stream.Transform {
179215
* @throws {Error} If cipher is not available or unknown.
180216
* @throws {Error} If the creation of the Decryption object failed.
181217
*/
182-
public constructor(cipher: string, key: Buffer, iv: Buffer) {
218+
public constructor(cipher: string, key: Buffer, iv: Buffer)
219+
{
183220
super()
184221
this.encryptor = new WolfSSLDecryptor( cipher, key, iv )
185222
}

WolfSSLHmac.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
"use strict";
2+
var __extends = (this && this.__extends) || (function () {
3+
var extendStatics = function (d, b) {
4+
extendStatics = Object.setPrototypeOf ||
5+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7+
return extendStatics(d, b);
8+
};
9+
return function (d, b) {
10+
if (typeof b !== "function" && b !== null)
11+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12+
extendStatics(d, b);
13+
function __() { this.constructor = d; }
14+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15+
};
16+
})();
17+
exports.__esModule = true;
18+
exports.WolfSSLHmacStream = exports.WolfSSLHmac = void 0;
19+
var wolfcrypt = require('./build/Release/wolfcrypt');
20+
var stream = require('stream');
21+
var WolfSSLHmac = /** @class */ (function () {
22+
function WolfSSLHmac(type, key) {
23+
// actually holds a pointer but nodejs has no pointer type
24+
this.hmac = null;
25+
this.hashType = -1;
26+
this.digestLength = -1;
27+
this.hmac = Buffer.alloc(wolfcrypt.sizeof_Hmac());
28+
this.hashType = wolfcrypt.typeof_Hmac(type);
29+
this.digestLength = wolfcrypt.Hmac_digest_length(this.hashType);
30+
wolfcrypt.wc_HmacSetKey(this.hmac, this.hashType, key, key.length);
31+
}
32+
/**
33+
* Updates the internal state with data for hash.
34+
*
35+
* @param data The data that will be added to the hash.
36+
*
37+
* @throws {Error} If the hash fails.
38+
*
39+
* @remarks This function should be called multiple times.
40+
*/
41+
WolfSSLHmac.prototype.update = function (data) {
42+
if (this.hmac == null) {
43+
throw 'Hmac is not allocated';
44+
}
45+
var ret = wolfcrypt.wc_HmacUpdate(this.hmac, data, data.length);
46+
if (ret != 0) {
47+
throw 'Failed to update hash';
48+
}
49+
};
50+
/**
51+
* Finalize the hmac process.
52+
*
53+
* @returns The digest of the hashed data.
54+
*
55+
* @throws {Error} If the digest fails.
56+
*
57+
* @remarks This function should be called once to finalize the hmac
58+
* process.
59+
*/
60+
WolfSSLHmac.prototype.finalize = function () {
61+
if (this.hmac == null) {
62+
throw 'Hmac is not allocated';
63+
}
64+
var outBuffer = Buffer.alloc(this.digestLength);
65+
var ret = wolfcrypt.wc_HmacFinal(this.hmac, outBuffer);
66+
wolfcrypt.wc_HmacFree(this.hmac);
67+
this.hmac = null;
68+
if (ret != 0) {
69+
throw 'Failed to finalize digest';
70+
}
71+
return outBuffer;
72+
};
73+
WolfSSLHmac.prototype.free = function () {
74+
if (this.hmac != null) {
75+
wolfcrypt.wc_HmacFree(this.hmac);
76+
this.hmac = null;
77+
}
78+
else {
79+
throw 'Hmac is not allocated';
80+
}
81+
};
82+
return WolfSSLHmac;
83+
}());
84+
exports.WolfSSLHmac = WolfSSLHmac;
85+
var WolfSSLHmacStream = /** @class */ (function (_super) {
86+
__extends(WolfSSLHmacStream, _super);
87+
/**
88+
* Initializes a new instance of the WolfSSLEncryptionStream class.
89+
*
90+
* @param cipher The cipher name to use.
91+
* @param key The decryption key to use.
92+
* @param iv The initialization vector.
93+
*
94+
* @throws {Error} If cipher is not available or unknown.
95+
* @throws {Error} If the creation of the Decryption object failed.
96+
*/
97+
function WolfSSLHmacStream(type, key) {
98+
var _this = _super.call(this) || this;
99+
_this.hmac = new WolfSSLHmac(type, key);
100+
return _this;
101+
}
102+
WolfSSLHmacStream.prototype._transform = function (chunk, enc, cb) {
103+
var buffer = Buffer.isBuffer(chunk) ? chunk : new Buffer(chunk, enc);
104+
this.hmac.update(chunk);
105+
cb();
106+
};
107+
WolfSSLHmacStream.prototype._flush = function (cb) {
108+
var ret_buffer = this.hmac.finalize();
109+
if (ret_buffer.length > 0) {
110+
this.push(ret_buffer);
111+
}
112+
cb();
113+
};
114+
return WolfSSLHmacStream;
115+
}(stream.Transform));
116+
exports.WolfSSLHmacStream = WolfSSLHmacStream;

0 commit comments

Comments
 (0)