Skip to content

Commit 0d4f993

Browse files
author
John Bland
committed
move rng setup to bind_wc_ecc_init and add der import export functions to the bindings
previously only x963 format public keys were supported, now der public and private keys can be exported with the bindings
1 parent f314c4a commit 0d4f993

File tree

5 files changed

+208
-11
lines changed

5 files changed

+208
-11
lines changed

addon/wolfcrypt/ecc.cpp

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ Napi::Number bind_wc_ecc_init(const Napi::CallbackInfo& info)
5151
Napi::Env env = info.Env();
5252
ecc_key* ecc = (ecc_key*)( info[0].As<Napi::Uint8Array>().Data() );
5353

54-
ecc->rng = NULL;
5554
ret = wc_ecc_init( ecc );
5655

56+
ecc->rng = wc_rng_new( NULL, 0, NULL );
57+
5758
return Napi::Number::New( env, ret );
5859
}
5960

@@ -64,8 +65,6 @@ Napi::Number bind_wc_ecc_make_key(const Napi::CallbackInfo& info)
6465
int key_size = info[0].As<Napi::Number>().Int32Value();
6566
ecc_key* ecc = (ecc_key*)( info[1].As<Napi::Uint8Array>().Data() );
6667

67-
ecc->rng = wc_rng_new( NULL, 0, NULL );
68-
6968
ret = wc_ecc_make_key( ecc->rng, key_size, ecc );
7069

7170
return Napi::Number::New( env, ret );
@@ -113,6 +112,84 @@ Napi::Number bind_wc_ecc_import_x963(const Napi::CallbackInfo& info)
113112
return Napi::Number::New( env, ret );
114113
}
115114

115+
Napi::Number bind_wc_EccKeyDerSize(const Napi::CallbackInfo& info)
116+
{
117+
Napi::Env env = info.Env();
118+
int ret;
119+
ecc_key* ecc = (ecc_key*)( info[0].As<Napi::Uint8Array>().Data() );
120+
int pub = info[1].As<Napi::Number>().Int32Value();
121+
122+
ret = wc_EccKeyDerSize( ecc, pub );
123+
124+
return Napi::Number::New( env, ret );
125+
}
126+
127+
Napi::Number bind_wc_EccPublicKeyDerSize(const Napi::CallbackInfo& info)
128+
{
129+
Napi::Env env = info.Env();
130+
int ret;
131+
ecc_key* ecc = (ecc_key*)( info[0].As<Napi::Uint8Array>().Data() );
132+
133+
ret = wc_EccPublicKeyDerSize( ecc, 1 );
134+
135+
return Napi::Number::New( env, ret );
136+
}
137+
138+
Napi::Number bind_wc_EccPublicKeyToDer(const Napi::CallbackInfo& info)
139+
{
140+
Napi::Env env = info.Env();
141+
int ret;
142+
ecc_key* ecc = (ecc_key*)( info[0].As<Napi::Uint8Array>().Data() );
143+
uint8_t* out = (uint8_t*)( info[1].As<Napi::Uint8Array>().Data() );
144+
unsigned int out_len = info[2].As<Napi::Number>().Int32Value();
145+
146+
ret = wc_EccPublicKeyToDer( ecc, out, out_len, 1 );
147+
//ret = wc_EccPublicKeyToDer( ecc, out, out_len, 0 );
148+
149+
return Napi::Number::New( env, ret );
150+
}
151+
152+
Napi::Number bind_wc_EccPublicKeyDecode(const Napi::CallbackInfo& info)
153+
{
154+
Napi::Env env = info.Env();
155+
int ret;
156+
uint8_t* in = (uint8_t*)( info[0].As<Napi::Uint8Array>().Data() );
157+
ecc_key* ecc = (ecc_key*)( info[1].As<Napi::Uint8Array>().Data() );
158+
unsigned int in_len = info[2].As<Napi::Number>().Int32Value();
159+
unsigned int idx = 0;
160+
161+
ret = wc_EccPublicKeyDecode( in, &idx, ecc, in_len );
162+
163+
return Napi::Number::New( env, ret );
164+
}
165+
166+
Napi::Number bind_wc_EccPrivateKeyToDer(const Napi::CallbackInfo& info)
167+
{
168+
Napi::Env env = info.Env();
169+
int ret;
170+
ecc_key* ecc = (ecc_key*)( info[0].As<Napi::Uint8Array>().Data() );
171+
uint8_t* out = (uint8_t*)( info[1].As<Napi::Uint8Array>().Data() );
172+
unsigned int out_len = info[2].As<Napi::Number>().Int32Value();
173+
174+
ret = wc_EccPrivateKeyToDer( ecc, out, out_len );
175+
176+
return Napi::Number::New( env, ret );
177+
}
178+
179+
Napi::Number bind_wc_EccPrivateKeyDecode(const Napi::CallbackInfo& info)
180+
{
181+
Napi::Env env = info.Env();
182+
int ret;
183+
uint8_t* in = (uint8_t*)( info[0].As<Napi::Uint8Array>().Data() );
184+
ecc_key* ecc = (ecc_key*)( info[1].As<Napi::Uint8Array>().Data() );
185+
unsigned int in_len = info[2].As<Napi::Number>().Int32Value();
186+
unsigned int idx = 0;
187+
188+
ret = wc_EccPrivateKeyDecode( in, &idx, ecc, in_len );
189+
190+
return Napi::Number::New( env, ret );
191+
}
192+
116193
Napi::Number bind_wc_ecc_set_curve(const Napi::CallbackInfo& info)
117194
{
118195
Napi::Env env = info.Env();
@@ -160,18 +237,13 @@ Napi::Number bind_wc_ecc_sign_hash(const Napi::CallbackInfo& info)
160237
{
161238
Napi::Env env = info.Env();
162239
int ret;
163-
WC_RNG rng;
164240
uint8_t* in = (uint8_t*)( info[0].As<Napi::Uint8Array>().Data() );
165241
int in_len = info[1].As<Napi::Number>().Int32Value();
166242
uint8_t* out = (uint8_t*)( info[2].As<Napi::Uint8Array>().Data() );
167243
unsigned int out_len = info[3].As<Napi::Number>().Int32Value();
168244
ecc_key* ecc = (ecc_key*)( info[4].As<Napi::Uint8Array>().Data() );
169245

170-
ret = wc_InitRng( &rng );
171-
if (ret == 0)
172-
{
173-
ret = wc_ecc_sign_hash( in, in_len, out, &out_len, &rng, ecc );
174-
}
246+
ret = wc_ecc_sign_hash( in, in_len, out, &out_len, ecc->rng, ecc );
175247

176248
if ( ret < 0 )
177249
{

addon/wolfcrypt/h/ecc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "wolfssl/options.h"
2323
#include <wolfssl/wolfcrypt/settings.h>
2424
#include <wolfssl/wolfcrypt/ecc.h>
25+
#include <wolfssl/wolfcrypt/asn.h>
2526

2627
Napi::Number sizeof_ecc_key(const Napi::CallbackInfo& info);
2728
Napi::Number sizeof_ecc_point(const Napi::CallbackInfo& info);
@@ -31,6 +32,12 @@ Napi::Number bind_wc_ecc_make_key(const Napi::CallbackInfo& info);
3132
Napi::Number sizeof_ecc_x963(const Napi::CallbackInfo& info);
3233
Napi::Number bind_wc_ecc_export_x963(const Napi::CallbackInfo& info);
3334
Napi::Number bind_wc_ecc_import_x963(const Napi::CallbackInfo& info);
35+
Napi::Number bind_wc_EccKeyDerSize(const Napi::CallbackInfo& info);
36+
Napi::Number bind_wc_EccPublicKeyToDer(const Napi::CallbackInfo& info);
37+
Napi::Number bind_wc_EccPublicKeyDecode(const Napi::CallbackInfo& info);
38+
Napi::Number bind_wc_EccPublicKeyDerSize(const Napi::CallbackInfo& info);
39+
Napi::Number bind_wc_EccPrivateKeyToDer(const Napi::CallbackInfo& info);
40+
Napi::Number bind_wc_EccPrivateKeyDecode(const Napi::CallbackInfo& info);
3441
Napi::Number bind_wc_ecc_set_curve(const Napi::CallbackInfo& info);
3542
Napi::Number bind_wc_ecc_shared_secret(const Napi::CallbackInfo& info);
3643
Napi::Number bind_wc_ecc_sig_size(const Napi::CallbackInfo& info);

addon/wolfcrypt/main.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
106106
exports.Set(Napi::String::New(env, "sizeof_ecc_x963"), Napi::Function::New(env, sizeof_ecc_x963));
107107
exports.Set(Napi::String::New(env, "wc_ecc_export_x963"), Napi::Function::New(env, bind_wc_ecc_export_x963));
108108
exports.Set(Napi::String::New(env, "wc_ecc_import_x963"), Napi::Function::New(env, bind_wc_ecc_import_x963));
109+
exports.Set(Napi::String::New(env, "wc_EccKeyDerSize"), Napi::Function::New(env, bind_wc_EccKeyDerSize));
110+
exports.Set(Napi::String::New(env, "wc_EccPublicKeyToDer"), Napi::Function::New(env, bind_wc_EccPublicKeyToDer));
111+
exports.Set(Napi::String::New(env, "wc_EccPublicKeyDecode"), Napi::Function::New(env, bind_wc_EccPublicKeyDecode));
112+
exports.Set(Napi::String::New(env, "wc_EccPublicKeyDerSize"), Napi::Function::New(env, bind_wc_EccPublicKeyDerSize));
113+
exports.Set(Napi::String::New(env, "wc_EccPrivateKeyToDer"), Napi::Function::New(env, bind_wc_EccPrivateKeyToDer));
114+
exports.Set(Napi::String::New(env, "wc_EccPrivateKeyDecode"), Napi::Function::New(env, bind_wc_EccPrivateKeyDecode));
109115
exports.Set(Napi::String::New(env, "wc_ecc_set_curve"), Napi::Function::New(env, bind_wc_ecc_set_curve));
110116
exports.Set(Napi::String::New(env, "wc_ecc_shared_secret"), Napi::Function::New(env, bind_wc_ecc_shared_secret));
111117
exports.Set(Napi::String::New(env, "wc_ecc_sig_size"), Napi::Function::New(env, bind_wc_ecc_sig_size));

interfaces/ecc.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,84 @@ class WolfSSLEcc
9191
}
9292
}
9393

94+
PublicKeyToDer()
95+
{
96+
if ( this.ecc == null )
97+
{
98+
throw 'Ecc not allocated'
99+
}
100+
101+
let derBuf = Buffer.alloc( wolfcrypt.wc_EccPublicKeyDerSize( this.ecc ) )
102+
103+
let ret = wolfcrypt.wc_EccPublicKeyToDer( this.ecc, derBuf, derBuf.length )
104+
105+
if ( ret <= 0 )
106+
{
107+
throw `Failed to wc_EccPublicKeyToDer ${ ret }`
108+
}
109+
110+
return derBuf
111+
}
112+
113+
PublicKeyDecode( derBuf )
114+
{
115+
if ( this.ecc == null )
116+
{
117+
throw 'Ecc not allocated'
118+
}
119+
120+
if ( !Buffer.isBuffer( derBuf ) )
121+
{
122+
throw 'Public key der must be a Buffer'
123+
}
124+
125+
let ret = wolfcrypt.wc_EccPublicKeyDecode( derBuf, this.ecc, derBuf.length )
126+
127+
if ( ret != 0 )
128+
{
129+
throw `Failed to wc_EccPublicKeyDecode ${ ret }`
130+
}
131+
}
132+
133+
PrivateKeyToDer()
134+
{
135+
if ( this.ecc == null )
136+
{
137+
throw 'Ecc not allocated'
138+
}
139+
140+
let derBuf = Buffer.alloc( wolfcrypt.wc_EccKeyDerSize( this.ecc, 0 ) )
141+
142+
let ret = wolfcrypt.wc_EccPrivateKeyToDer( this.ecc, derBuf, derBuf.length )
143+
144+
if ( ret <= 0 )
145+
{
146+
throw `Failed to wc_EccPrivateKeyToDer ${ ret }`
147+
}
148+
149+
return derBuf
150+
}
151+
152+
PrivateKeyDecode( derBuf )
153+
{
154+
if ( this.ecc == null )
155+
{
156+
throw 'Ecc not allocated'
157+
}
158+
159+
if ( !Buffer.isBuffer( derBuf ) )
160+
{
161+
throw 'Private key der must be a Buffer'
162+
}
163+
164+
let ret = wolfcrypt.wc_EccPrivateKeyDecode( derBuf, this.ecc, derBuf.length )
165+
166+
if ( ret != 0 )
167+
{
168+
throw `Failed to wc_EccPrivateKeyDecode ${ ret }`
169+
}
170+
}
171+
94172
set_curve( keySize, curveId )
95173
{
96174
if ( this.ecc == null )

tests/ecc.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ const ecc_tests =
104104
ecc0.free()
105105
},
106106

107-
// Validate Industries
108-
importExport: function()
107+
importExportx963: function()
109108
{
110109
let ecc0 = new WolfSSLEcc()
111110
let ecc1 = new WolfSSLEcc()
@@ -130,6 +129,41 @@ const ecc_tests =
130129
ecc0.free()
131130
ecc1.free()
132131
},
132+
133+
importExportDer: function()
134+
{
135+
let ecc0 = new WolfSSLEcc()
136+
let ecc1 = new WolfSSLEcc()
137+
let ecc2 = new WolfSSLEcc()
138+
139+
ecc0.make_key( 32 )
140+
141+
const sigBefore = ecc0.sign_hash( message )
142+
143+
let privKeyDer = ecc0.PrivateKeyToDer()
144+
let pubKeyDer = ecc0.PublicKeyToDer()
145+
146+
ecc0.free()
147+
148+
ecc0 = new WolfSSLEcc()
149+
150+
ecc1.PrivateKeyDecode( privKeyDer )
151+
ecc2.PublicKeyDecode( pubKeyDer )
152+
153+
const sigAfter = ecc1.sign_hash( message )
154+
155+
if ( ecc2.verify_hash( sigBefore, message ) == true && ecc2.verify_hash( sigAfter, message ) )
156+
{
157+
console.log( 'PASS ecc importExport' )
158+
}
159+
else
160+
{
161+
console.log( 'FAIL ecc importExport public' )
162+
}
163+
164+
ecc1.free()
165+
ecc2.free()
166+
}
133167
}
134168

135169
module.exports = ecc_tests

0 commit comments

Comments
 (0)