((size << 2) | (sign << 1) | little)
-typedef njs_int_t (*njs_buffer_encode)(njs_vm_t *vm, njs_value_t *value,
- const njs_str_t *src);
-typedef size_t (*njs_buffer_encode_length)(const njs_str_t *src,
- size_t *out_size);
-
-typedef struct {
- njs_str_t name;
- njs_buffer_encode encode;
- njs_buffer_encode decode;
- njs_buffer_encode_length decode_length;
-} njs_buffer_encoding_t;
-
-
static njs_buffer_encoding_t njs_buffer_encodings[] =
{
{
njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
uint64_t offset, uint64_t length);
static njs_int_t njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array,
- njs_value_t *value, const njs_buffer_encoding_t *encoding, uint64_t offset,
+ const njs_value_t *fill, const njs_value_t *encoding, uint64_t offset,
uint64_t end);
-static njs_int_t njs_buffer_fill_string(njs_vm_t *vm, njs_value_t *value,
+static njs_int_t njs_buffer_fill_string(njs_vm_t *vm, const njs_value_t *value,
njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
uint8_t *start, uint8_t *end);
-static njs_int_t njs_buffer_fill_typed_array(njs_vm_t *vm, njs_value_t *value,
- njs_typed_array_t *array, uint8_t *start, uint8_t *end);
-static const njs_buffer_encoding_t *njs_buffer_encoding(njs_vm_t *vm,
- njs_value_t *value);
-static njs_int_t njs_buffer_decode_string(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *dst, const njs_buffer_encoding_t *encoding);
-static void njs_buffer_decode_destroy(njs_vm_t *vm, njs_value_t *source,
+static njs_int_t njs_buffer_fill_typed_array(njs_vm_t *vm,
+ const njs_value_t *value, njs_typed_array_t *array, uint8_t *start,
+ uint8_t *end);
+static void njs_buffer_decode_destroy(njs_vm_t *vm, const njs_value_t *source,
njs_value_t *target);
}
-static njs_typed_array_t *
-njs_buffer_alloc_array(njs_vm_t *vm, size_t size, njs_bool_t zeroing)
+njs_typed_array_t *
+njs_buffer_alloc(njs_vm_t *vm, size_t size, njs_bool_t zeroing)
{
njs_value_t value;
njs_typed_array_t *array;
}
+njs_int_t
+njs_buffer_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
+ uint32_t size)
+{
+ njs_typed_array_t *buffer;
+
+ buffer = njs_buffer_alloc(vm, size, 0);
+ if (njs_slow_path(buffer == NULL)) {
+ return NJS_ERROR;
+ }
+
+ memcpy(njs_typed_array_buffer(buffer)->u.u8, start, size);
+
+ njs_set_typed_array(value, buffer);
+
+ return NJS_OK;
+}
+
+
static njs_int_t
njs_buffer_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
static njs_int_t
-njs_buffer_alloc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+njs_buffer_alloc_safe(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t safe)
{
- double size;
- njs_int_t ret;
- njs_typed_array_t *array;
- const njs_buffer_encoding_t *encoding;
+ double size;
+ njs_int_t ret;
+ njs_typed_array_t *array;
+ const njs_value_t *fill;
if (njs_slow_path(!njs_is_number(njs_arg(args, nargs, 1)))) {
njs_type_error(vm, "\"size\" argument must be of type number");
return NJS_ERROR;
}
- array = njs_buffer_alloc_array(vm, size, safe || nargs <= 2);
+ array = njs_buffer_alloc(vm, size, safe || nargs <= 2);
if (njs_slow_path(array == NULL)) {
return NJS_ERROR;
}
- if (safe && nargs > 2) {
- encoding = njs_buffer_utf8_encoding();
-
- if (nargs > 3 && njs_is_string(njs_argument(args, 2))) {
- encoding = njs_buffer_encoding(vm, njs_argument(args, 3));
- if (njs_slow_path(encoding == NULL)) {
- return NJS_ERROR;
- }
- }
+ fill = njs_arg(args, nargs, 2);
- ret = njs_buffer_fill(vm, array, njs_argument(args, 2), encoding, 0,
+ if (safe && njs_is_defined(fill)) {
+ ret = njs_buffer_fill(vm, array, fill, njs_arg(args, nargs, 3), 0,
array->byte_length);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
njs_arg(args, nargs, 3));
case NJS_STRING:
- encoding = njs_buffer_utf8_encoding();
-
- if (nargs > 2) {
- encoding = njs_buffer_encoding(vm, njs_argument(args, 2));
- if (njs_slow_path(encoding == NULL)) {
- return NJS_ERROR;
- }
+ encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, 2));
+ if (njs_slow_path(encoding == NULL)) {
+ return NJS_ERROR;
}
return njs_buffer_from_string(vm, value, encoding);
return ret;
}
- buffer = njs_buffer_alloc_array(vm, len, 0);
+ buffer = njs_buffer_alloc(vm, len, 0);
if (njs_slow_path(buffer == NULL)) {
return NJS_ERROR;
}
length = njs_typed_array_length(array);
- buffer = njs_buffer_alloc_array(vm, length, 0);
+ buffer = njs_buffer_alloc(vm, length, 0);
if (njs_slow_path(buffer == NULL)) {
return NJS_ERROR;
}
njs_string_get(&dst, &str);
- buffer = njs_buffer_alloc_array(vm, str.length, 0);
+ buffer = njs_buffer_alloc(vm, str.length, 0);
if (njs_slow_path(buffer == NULL)) {
return NJS_ERROR;
}
}
}
- buffer = njs_buffer_alloc_array(vm, len, 0);
+ buffer = njs_buffer_alloc(vm, len, 0);
if (njs_slow_path(buffer == NULL)) {
return NJS_ERROR;
}
njs_buffer_is_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- njs_set_boolean(&vm->retval,
- njs_buffer_encoding(vm, njs_arg(args, nargs, 1)) != NULL);
+ const njs_value_t *value;
+
+ value = njs_arg(args, nargs, 1);
+ njs_set_boolean(&vm->retval, njs_is_defined(value)
+ && njs_buffer_encoding(vm, value) != NULL);
return NJS_OK;
}
njs_buffer_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- uint64_t offset, end;
- njs_int_t ret;
- njs_value_t *this, *value, *value_offset, *value_end,
- *encode;
- njs_typed_array_t *array;
- const njs_buffer_encoding_t *encoding;
+ uint64_t offset, end;
+ njs_int_t ret;
+ njs_value_t *this, *value, *value_offset, *value_end,
+ *encode;
+ njs_typed_array_t *array;
this = njs_argument(args, 0);
if (njs_slow_path(nargs < 2)) {
value_offset = njs_arg(args, nargs, 2);
value_end = njs_arg(args, nargs, 3);
encode = njs_arg(args, nargs, 4);
- encoding = njs_buffer_utf8_encoding();
-
offset = 0;
end = array->byte_length;
if (njs_is_defined(value_offset)) {
if (njs_is_string(value) && njs_is_string(value_offset)) {
encode = value_offset;
- goto encoding;
+ goto fill;
}
ret = njs_value_to_index(vm, value_offset, &offset);
if (njs_is_defined(value_end)) {
if (njs_is_string(value) && njs_is_string(value_end)) {
encode = value_end;
- goto encoding;
+ goto fill;
}
ret = njs_value_to_index(vm, value_end, &end);
}
}
- if (njs_is_defined(encode)) {
- if (njs_slow_path(!njs_is_string(encode))) {
- njs_type_error(vm, "\"encoding\" argument must be of type string");
- return NJS_ERROR;
- }
-
- encoding:
-
- encoding = njs_buffer_encoding(vm, encode);
- if (njs_slow_path(encoding == NULL)) {
- return NJS_ERROR;
- }
- }
+fill:
- ret = njs_buffer_fill(vm, array, value, encoding, offset, end);
+ ret = njs_buffer_fill(vm, array, value, encode, offset, end);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
static njs_int_t
-njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array, njs_value_t *value,
- const njs_buffer_encoding_t *encoding, uint64_t offset, uint64_t end)
+njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array, const njs_value_t *fill,
+ const njs_value_t *encode, uint64_t offset, uint64_t end)
{
- double num;
- uint8_t *start, *stop;
- njs_int_t ret;
- njs_array_buffer_t *buffer;
+ double num;
+ uint8_t *start, *stop;
+ njs_int_t ret;
+ njs_array_buffer_t *buffer;
+ const njs_buffer_encoding_t *encoding;
buffer = njs_typed_array_writable(vm, array);
if (njs_slow_path(buffer == NULL)) {
start = &buffer->u.u8[array->offset + offset];
stop = &buffer->u.u8[array->offset + end];
- switch (value->type) {
+ switch (fill->type) {
case NJS_STRING:
- return njs_buffer_fill_string(vm, value, array, encoding, start, stop);
+ encoding = njs_buffer_encoding(vm, encode);
+ if (njs_slow_path(encoding == NULL)) {
+ return NJS_ERROR;
+ }
+
+ return njs_buffer_fill_string(vm, fill, array, encoding, start, stop);
case NJS_TYPED_ARRAY:
- return njs_buffer_fill_typed_array(vm, value, array, start, stop);
+ return njs_buffer_fill_typed_array(vm, fill, array, start, stop);
default:
- ret = njs_value_to_number(vm, value, &num);
+ ret = njs_value_to_number(vm, njs_value_arg(fill), &num);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
static njs_int_t
-njs_buffer_fill_string(njs_vm_t *vm, njs_value_t *value,
+njs_buffer_fill_string(njs_vm_t *vm, const njs_value_t *value,
njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
uint8_t *start, uint8_t *end)
{
static njs_int_t
-njs_buffer_fill_typed_array(njs_vm_t *vm, njs_value_t *value,
+njs_buffer_fill_typed_array(njs_vm_t *vm, const njs_value_t *value,
njs_typed_array_t *array, uint8_t *to, uint8_t *end)
{
size_t byte_length;
uint64_t start, end;
njs_int_t ret;
njs_str_t str;
- njs_value_t *this, *enc, *value_start, *value_end;
+ njs_value_t *this, *value_start, *value_end;
njs_typed_array_t *array;
const njs_buffer_encoding_t *encoding;
return NJS_ERROR;
}
- enc = njs_arg(args, nargs, 1);
value_start = njs_arg(args, nargs, 2);
value_end = njs_arg(args, nargs, 3);
end = array->byte_length;
encoding = njs_buffer_utf8_encoding();
- if (njs_is_defined(enc)) {
- encoding = njs_buffer_encoding(vm, njs_argument(args, 1));
- if (njs_slow_path(encoding == NULL)) {
- return NJS_ERROR;
- }
+ encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, 1));
+ if (njs_slow_path(encoding == NULL)) {
+ return NJS_ERROR;
}
if (njs_is_defined(value_start)) {
}
-static const njs_buffer_encoding_t *
-njs_buffer_encoding(njs_vm_t *vm, njs_value_t *value)
+const njs_buffer_encoding_t *
+njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value)
{
- njs_str_t str;
- njs_int_t ret;
+ njs_str_t name;
njs_buffer_encoding_t *encoding;
if (njs_slow_path(!njs_is_string(value))) {
- ret = njs_value_to_string(vm, value, value);
- if (njs_slow_path(ret != NJS_OK)) {
+ if (njs_is_defined(value)) {
+ njs_type_error(vm, "encoding must be a string");
return NULL;
}
+
+ return &njs_buffer_encodings[0];
}
- njs_string_get(value, &str);
+ njs_string_get(value, &name);
for (encoding = &njs_buffer_encodings[0];
encoding->name.length != 0;
encoding++)
{
- if (njs_strstr_eq(&str, &encoding->name)) {
+ if (njs_strstr_eq(&name, &encoding->name)) {
return encoding;
}
}
- njs_type_error(vm, "\"%V\" encoding is not supported", &str);
+ njs_type_error(vm, "\"%V\" encoding is not supported", &name);
return NULL;
}
-static njs_int_t
-njs_buffer_decode_string(njs_vm_t *vm, njs_value_t *value, njs_value_t *dst,
- const njs_buffer_encoding_t *encoding)
+njs_int_t
+njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value,
+ njs_value_t *dst, const njs_buffer_encoding_t *encoding)
{
njs_int_t ret;
njs_str_t str;
static void
-njs_buffer_decode_destroy(njs_vm_t *vm, njs_value_t *source,
+njs_buffer_decode_destroy(njs_vm_t *vm, const njs_value_t *source,
njs_value_t *target)
{
njs_str_t src, trg;
{
.type = NJS_PROPERTY,
.name = njs_string("alloc"),
- .value = njs_native_function2(njs_buffer_alloc, 0, 1),
+ .value = njs_native_function2(njs_buffer_alloc_safe, 0, 1),
.writable = 1,
.configurable = 1,
},
{
.type = NJS_PROPERTY,
.name = njs_string("allocUnsafe"),
- .value = njs_native_function2(njs_buffer_alloc, 1, 0),
+ .value = njs_native_function2(njs_buffer_alloc_safe, 1, 0),
.writable = 1,
.configurable = 1,
},
{
.type = NJS_PROPERTY,
.name = njs_long_string("allocUnsafeSlow"),
- .value = njs_native_function2(njs_buffer_alloc, 1, 0),
+ .value = njs_native_function2(njs_buffer_alloc_safe, 1, 0),
.writable = 1,
.configurable = 1,
},
#define _NJS_BUFFER_H_INCLUDED_
+typedef njs_int_t (*njs_buffer_encode_t)(njs_vm_t *vm, njs_value_t *value,
+ const njs_str_t *src);
+typedef size_t (*njs_buffer_encode_length_t)(const njs_str_t *src,
+ size_t *out_size);
+
+typedef struct {
+ njs_str_t name;
+ njs_buffer_encode_t encode;
+ njs_buffer_encode_t decode;
+ njs_buffer_encode_length_t decode_length;
+} njs_buffer_encoding_t;
+
+
njs_int_t njs_buffer_set(njs_vm_t *vm, njs_value_t *value, const u_char *start,
uint32_t size);
+njs_int_t njs_buffer_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
+ uint32_t size);
+njs_typed_array_t *njs_buffer_alloc(njs_vm_t *vm, size_t size,
+ njs_bool_t zeroing);
+
+const njs_buffer_encoding_t *njs_buffer_encoding(njs_vm_t *vm,
+ const njs_value_t *value);
+njs_int_t njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value,
+ njs_value_t *dst, const njs_buffer_encoding_t *encoding);
extern const njs_object_type_init_t njs_buffer_type_init;
} njs_crypto_enc_t;
+static njs_hash_alg_t *njs_crypto_algorithm(njs_vm_t *vm,
+ const njs_value_t *value);
+static njs_crypto_enc_t *njs_crypto_encoding(njs_vm_t *vm,
+ const njs_value_t *value);
+static njs_int_t njs_buffer_digest(njs_vm_t *vm, njs_value_t *value,
+ const njs_str_t *src);
+
+
static njs_hash_alg_t njs_hash_algorithms[] = {
{
};
+
static njs_crypto_enc_t njs_encodings[] = {
+ {
+ njs_str("buffer"),
+ njs_buffer_digest
+ },
+
{
njs_str("hex"),
njs_string_hex
};
-static njs_hash_alg_t *njs_crypto_alg(njs_vm_t *vm, const njs_str_t *name);
-static njs_crypto_enc_t *njs_crypto_encoding(njs_vm_t *vm,
- const njs_str_t *name);
-
-
static njs_object_value_t *
njs_crypto_object_value_alloc(njs_vm_t *vm, njs_object_type_t type)
{
njs_crypto_create_hash(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- njs_str_t alg_name;
njs_digest_t *dgst;
njs_hash_alg_t *alg;
njs_object_value_t *hash;
- if (njs_slow_path(nargs < 2 || !njs_is_string(&args[1]))) {
- njs_type_error(vm, "algorithm must be a string");
- return NJS_ERROR;
- }
-
- njs_string_get(&args[1], &alg_name);
-
- alg = njs_crypto_alg(vm, &alg_name);
+ alg = njs_crypto_algorithm(vm, njs_arg(args, nargs, 1));
if (njs_slow_path(alg == NULL)) {
return NJS_ERROR;
}
static njs_int_t
njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
- njs_index_t unused)
+ njs_index_t tag)
{
- njs_str_t data;
- njs_value_t *this;
- njs_digest_t *dgst;
-
- if (njs_slow_path(nargs < 2 || !njs_is_string(&args[1]))) {
- njs_type_error(vm, "data must be a string");
- return NJS_ERROR;
- }
+ njs_str_t data;
+ njs_int_t ret;
+ njs_hmac_t *ctx;
+ njs_value_t *this, dst;
+ njs_digest_t *dgst;
+ njs_typed_array_t *array;
+ const njs_value_t *value;
+ njs_array_buffer_t *buffer;
+ const njs_buffer_encoding_t *encoding;
this = njs_argument(args, 0);
-
- if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HASH))) {
+ if (njs_slow_path(!njs_is_object_data(this, tag))) {
njs_type_error(vm, "\"this\" is not a hash object");
return NJS_ERROR;
}
- njs_string_get(&args[1], &data);
+ value = njs_arg(args, nargs, 1);
- dgst = njs_object_data(this);
+ switch (value->type) {
+ case NJS_STRING:
+ encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, 2));
+ if (njs_slow_path(encoding == NULL)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_buffer_decode_string(vm, value, &dst, encoding);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ njs_string_get(&dst, &data);
+ break;
+
+ case NJS_TYPED_ARRAY:
+ case NJS_DATA_VIEW:
+ array = njs_typed_array(value);
+ buffer = array->buffer;
+ if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+ njs_type_error(vm, "detached buffer");
+ return NJS_ERROR;
+ }
+
+ data.start = &buffer->u.u8[array->offset];
+ data.length = array->byte_length;
+ break;
+
+ default:
+ njs_type_error(vm, "data argument \"%s\" is not a string "
+ "or Buffer-like object", njs_type_string(value->type));
- if (njs_slow_path(dgst->alg == NULL)) {
- njs_error(vm, "Digest already called");
return NJS_ERROR;
}
- dgst->alg->update(&dgst->u, data.start, data.length);
+ if (tag == NJS_DATA_TAG_CRYPTO_HASH) {
+ dgst = njs_object_data(this);
+ if (njs_slow_path(dgst->alg == NULL)) {
+ njs_error(vm, "Digest already called");
+ return NJS_ERROR;
+ }
+
+ dgst->alg->update(&dgst->u, data.start, data.length);
+
+ } else {
+ ctx = njs_object_data(this);
+ if (njs_slow_path(ctx->alg == NULL)) {
+ njs_error(vm, "Digest already called");
+ return NJS_ERROR;
+ }
+
+ ctx->alg->update(&ctx->u, data.start, data.length);
+ }
vm->retval = *this;
static njs_int_t
njs_hash_prototype_digest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
- njs_index_t unused)
+ njs_index_t tag)
{
- u_char digest[32], *p;
- njs_int_t ret;
- njs_str_t enc_name, str;
+ njs_str_t str;
+ njs_hmac_t *ctx;
njs_value_t *this;
njs_digest_t *dgst;
njs_hash_alg_t *alg;
njs_crypto_enc_t *enc;
+ u_char hash1[32], digest[32];
- if (njs_slow_path(nargs > 1 && !njs_is_string(&args[1]))) {
- njs_type_error(vm, "encoding must be a string");
+ this = njs_argument(args, 0);
+ if (njs_slow_path(!njs_is_object_data(this, tag))) {
+ njs_type_error(vm, "\"this\" is not a hash object");
return NJS_ERROR;
}
- this = njs_argument(args, 0);
-
- if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HASH))) {
- njs_type_error(vm, "\"this\" is not a hash object");
+ enc = njs_crypto_encoding(vm, njs_arg(args, nargs, 1));
+ if (njs_slow_path(enc == NULL)) {
return NJS_ERROR;
}
- enc = NULL;
+ if (tag == NJS_DATA_TAG_CRYPTO_HASH) {
+ dgst = njs_object_data(this);
+ if (njs_slow_path(dgst->alg == NULL)) {
+ goto exception;
+ }
- if (nargs > 1) {
- njs_string_get(&args[1], &enc_name);
+ alg = dgst->alg;
+ alg->final(digest, &dgst->u);
+ dgst->alg = NULL;
- enc = njs_crypto_encoding(vm, &enc_name);
- if (njs_slow_path(enc == NULL)) {
- return NJS_ERROR;
+ } else {
+ ctx = njs_object_data(this);
+ if (njs_slow_path(ctx->alg == NULL)) {
+ goto exception;
}
- }
- dgst = njs_object_data(this);
+ alg = ctx->alg;
+ alg->final(hash1, &ctx->u);
- if (njs_slow_path(dgst->alg == NULL)) {
- njs_error(vm, "Digest already called");
- return NJS_ERROR;
+ alg->init(&ctx->u);
+ alg->update(&ctx->u, ctx->opad, 64);
+ alg->update(&ctx->u, hash1, alg->size);
+ alg->final(digest, &ctx->u);
+ ctx->alg = NULL;
}
- alg = dgst->alg;
-
- alg->final(digest, &dgst->u);
-
str.start = digest;
str.length = alg->size;
- if (enc == NULL) {
- p = njs_string_alloc(vm, &vm->retval, str.length, 0);
-
- if (njs_fast_path(p != NULL)) {
- memcpy(p, str.start, str.length);
- ret = NJS_OK;
-
- } else {
- ret = NJS_ERROR;
- }
-
- } else {
- ret = enc->encode(vm, &vm->retval, &str);
- }
+ return enc->encode(vm, &vm->retval, &str);
- dgst->alg = NULL;
+exception:
- return ret;
+ njs_error(vm, "Digest already called");
+ return NJS_ERROR;
}
{
.type = NJS_PROPERTY,
.name = njs_string("update"),
- .value = njs_native_function(njs_hash_prototype_update, 0),
+ .value = njs_native_function2(njs_hash_prototype_update, 0,
+ NJS_DATA_TAG_CRYPTO_HASH),
.writable = 1,
.configurable = 1,
},
{
.type = NJS_PROPERTY,
.name = njs_string("digest"),
- .value = njs_native_function(njs_hash_prototype_digest, 0),
+ .value = njs_native_function2(njs_hash_prototype_digest, 0,
+ NJS_DATA_TAG_CRYPTO_HASH),
.writable = 1,
.configurable = 1,
},
njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- u_char digest[32], key_buf[64];
- njs_str_t alg_name, key;
+ njs_str_t key;
njs_uint_t i;
njs_hmac_t *ctx;
njs_hash_alg_t *alg;
+ njs_typed_array_t *array;
+ const njs_value_t *value;
+ njs_array_buffer_t *buffer;
njs_object_value_t *hmac;
+ u_char digest[32], key_buf[64];
- if (njs_slow_path(nargs < 2 || !njs_is_string(&args[1]))) {
- njs_type_error(vm, "algorithm must be a string");
+ alg = njs_crypto_algorithm(vm, njs_arg(args, nargs, 1));
+ if (njs_slow_path(alg == NULL)) {
return NJS_ERROR;
}
- if (njs_slow_path(nargs < 3 || !njs_is_string(&args[2]))) {
- njs_type_error(vm, "key must be a string");
- return NJS_ERROR;
- }
+ value = njs_arg(args, nargs, 2);
- njs_string_get(&args[1], &alg_name);
+ switch (value->type) {
+ case NJS_STRING:
+ njs_string_get(value, &key);
+ break;
+
+ case NJS_TYPED_ARRAY:
+ case NJS_DATA_VIEW:
+ array = njs_typed_array(value);
+ buffer = array->buffer;
+ if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+ njs_type_error(vm, "detached buffer");
+ return NJS_ERROR;
+ }
+
+ key.start = &buffer->u.u8[array->offset];
+ key.length = array->byte_length;
+ break;
+
+ default:
+ njs_type_error(vm, "key argument \"%s\" is not a string "
+ "or Buffer-like object", njs_type_string(value->type));
- alg = njs_crypto_alg(vm, &alg_name);
- if (njs_slow_path(alg == NULL)) {
return NJS_ERROR;
}
- njs_string_get(&args[2], &key);
-
ctx = njs_mp_alloc(vm->mem_pool, sizeof(njs_hmac_t));
if (njs_slow_path(ctx == NULL)) {
njs_memory_error(vm);
}
-static njs_int_t
-njs_hmac_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
- njs_index_t unused)
-{
- njs_str_t data;
- njs_hmac_t *ctx;
- njs_value_t *this;
-
- if (njs_slow_path(nargs < 2 || !njs_is_string(&args[1]))) {
- njs_type_error(vm, "data must be a string");
- return NJS_ERROR;
- }
-
- this = njs_argument(args, 0);
-
- if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HMAC))) {
- njs_type_error(vm, "\"this\" is not a hash object");
- return NJS_ERROR;
- }
-
- njs_string_get(&args[1], &data);
-
- ctx = njs_object_data(this);
-
- if (njs_slow_path(ctx->alg == NULL)) {
- njs_error(vm, "Digest already called");
- return NJS_ERROR;
- }
-
- ctx->alg->update(&ctx->u, data.start, data.length);
-
- vm->retval = *this;
-
- return NJS_OK;
-}
-
-
-static njs_int_t
-njs_hmac_prototype_digest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
- njs_index_t unused)
-{
- u_char hash1[32], digest[32], *p;
- njs_str_t enc_name, str;
- njs_int_t ret;
- njs_hmac_t *ctx;
- njs_value_t *this;
- njs_hash_alg_t *alg;
- njs_crypto_enc_t *enc;
-
- if (njs_slow_path(nargs > 1 && !njs_is_string(&args[1]))) {
- njs_type_error(vm, "encoding must be a string");
- return NJS_ERROR;
- }
-
- this = njs_argument(args, 0);
-
- if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HMAC))) {
- njs_type_error(vm, "\"this\" is not a hash object");
- return NJS_ERROR;
- }
-
- enc = NULL;
-
- if (nargs > 1) {
- njs_string_get(&args[1], &enc_name);
-
- enc = njs_crypto_encoding(vm, &enc_name);
- if (njs_slow_path(enc == NULL)) {
- return NJS_ERROR;
- }
- }
-
- ctx = njs_object_data(this);
-
- if (njs_slow_path(ctx->alg == NULL)) {
- njs_error(vm, "Digest already called");
- return NJS_ERROR;
- }
-
- alg = ctx->alg;
-
- alg->final(hash1, &ctx->u);
-
- alg->init(&ctx->u);
- alg->update(&ctx->u, ctx->opad, 64);
- alg->update(&ctx->u, hash1, alg->size);
- alg->final(digest, &ctx->u);
-
- str.start = digest;
- str.length = alg->size;
-
- if (enc == NULL) {
- p = njs_string_alloc(vm, &vm->retval, str.length, 0);
-
- if (njs_fast_path(p != NULL)) {
- memcpy(p, str.start, str.length);
- ret = NJS_OK;
-
- } else {
- ret = NJS_ERROR;
- }
-
- } else {
- ret = enc->encode(vm, &vm->retval, &str);
- }
-
- ctx->alg = NULL;
-
- return ret;
-}
-
-
static const njs_object_prop_t njs_hmac_prototype_properties[] =
{
{
{
.type = NJS_PROPERTY,
.name = njs_string("update"),
- .value = njs_native_function(njs_hmac_prototype_update, 0),
+ .value = njs_native_function2(njs_hash_prototype_update, 0,
+ NJS_DATA_TAG_CRYPTO_HMAC),
.writable = 1,
.configurable = 1,
},
{
.type = NJS_PROPERTY,
.name = njs_string("digest"),
- .value = njs_native_function(njs_hmac_prototype_digest, 0),
+ .value = njs_native_function2(njs_hash_prototype_digest, 0,
+ NJS_DATA_TAG_CRYPTO_HMAC),
.writable = 1,
.configurable = 1,
},
static njs_hash_alg_t *
-njs_crypto_alg(njs_vm_t *vm, const njs_str_t *name)
+njs_crypto_algorithm(njs_vm_t *vm, const njs_value_t *value)
{
- njs_hash_alg_t *e;
+ njs_str_t name;
+ njs_hash_alg_t *e;
+
+ if (njs_slow_path(!njs_is_string(value))) {
+ njs_type_error(vm, "algorithm must be a string");
+ return NULL;
+ }
+
+ njs_string_get(value, &name);
for (e = &njs_hash_algorithms[0]; e->name.length != 0; e++) {
- if (njs_strstr_eq(name, &e->name)) {
+ if (njs_strstr_eq(&name, &e->name)) {
return e;
}
}
- njs_type_error(vm, "not supported algorithm: \"%V\"", name);
+ njs_type_error(vm, "not supported algorithm: \"%V\"", &name);
return NULL;
}
static njs_crypto_enc_t *
-njs_crypto_encoding(njs_vm_t *vm, const njs_str_t *name)
+njs_crypto_encoding(njs_vm_t *vm, const njs_value_t *value)
{
- njs_crypto_enc_t *e;
+ njs_str_t name;
+ njs_crypto_enc_t *e;
- for (e = &njs_encodings[0]; e->name.length != 0; e++) {
- if (njs_strstr_eq(name, &e->name)) {
+ if (njs_slow_path(!njs_is_string(value))) {
+ if (njs_is_defined(value)) {
+ njs_type_error(vm, "encoding must be a string");
+ return NULL;
+ }
+
+ return &njs_encodings[0];
+ }
+
+ njs_string_get(value, &name);
+
+ for (e = &njs_encodings[1]; e->name.length != 0; e++) {
+ if (njs_strstr_eq(&name, &e->name)) {
return e;
}
}
- njs_type_error(vm, "Unknown digest encoding: \"%V\"", name);
+ njs_type_error(vm, "Unknown digest encoding: \"%V\"", &name);
return NULL;
}
+
+
+static njs_int_t
+njs_buffer_digest(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
+{
+ return njs_buffer_new(vm, value, src->start, src->length);
+}
"h.constructor.name"),
njs_str("Hash") },
- { njs_str("var h = require('crypto').createHash('md5');"
- "h.update('AB').digest('hex')"),
- njs_str("b86fc6b051f63d73de262d4c34e3a0a9") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').update('B').digest('hex')"),
- njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('AB').digest('hex')"),
- njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('AB').digest().toString('hex')"),
- njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('AB').digest('base64')"),
- njs_str("BtlFlCqiamG+GMPiK/GbvKjdK10=") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('AB').digest('base64url')"),
- njs_str("BtlFlCqiamG-GMPiK_GbvKjdK10") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('AB').digest().toString('base64')"),
- njs_str("BtlFlCqiamG+GMPiK/GbvKjdK10=") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('abc'.repeat(100)).digest('hex')"),
- njs_str("c95466320eaae6d19ee314ae4f135b12d45ced9a") },
-
- { njs_str("var h = require('crypto').createHash('sha256');"
- "h.update('A').update('B').digest('hex')"),
- njs_str("38164fbd17603d73f696b8b4d72664d735bb6a7c88577687fd2ae33fd6964153") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'md5');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hash().update('AB').digest().toString(e);"
+ " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hash().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("b86fc6b051f63d73de262d4c34e3a0a9,"
+ "uG/GsFH2PXPeJi1MNOOgqQ==,"
+ "uG_GsFH2PXPeJi1MNOOgqQ") },
+
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hash().update('4142', 'hex').digest().toString(e);"
+ " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hash().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d,"
+ "BtlFlCqiamG+GMPiK/GbvKjdK10=,"
+ "BtlFlCqiamG-GMPiK_GbvKjdK10") },
+
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
+ "['hex', 'base64', 'base64url'].every(e => {"
+ " var h = hash().digest(e);"
+ " var h2 = hash().update('').digest(e);"
+ " if (h !== h2) {throw new Error(`digest($e):$h != update('').digest($e):$h2`)};"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("var h = require('crypto').createHash('sha256');"
- "h.update('AB').digest('hex')"),
- njs_str("38164fbd17603d73f696b8b4d72664d735bb6a7c88577687fd2ae33fd6964153") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
+ "["
+ " ['AB'],"
+ " ['4142', 'hex'],"
+ " ['QUI=', 'base64'],"
+ " ['QUI', 'base64url']"
+ "].every(args => {"
+ " return hash().update(args[0], args[1]).digest('hex') === '06d945942aa26a61be18c3e22bf19bbca8dd2b5d';"
+ "})"),
+ njs_str("true") },
- { njs_str("var h = require('crypto').createHash('sha256');"
- "h.update('abc'.repeat(100)).digest('hex')"),
- njs_str("d9f5aeb06abebb3be3f38adec9a2e3b94228d52193be923eb4e24c9b56ee0930") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha256');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hash().update('AB').digest().toString(e);"
+ " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hash().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("38164fbd17603d73f696b8b4d72664d735bb6a7c88577687fd2ae33fd6964153,"
+ "OBZPvRdgPXP2lri01yZk1zW7anyIV3aH/SrjP9aWQVM=,"
+ "OBZPvRdgPXP2lri01yZk1zW7anyIV3aH_SrjP9aWQVM") },
+
+ { njs_str("var hash = require('crypto').createHash;"
+ "njs.dump(['', 'abc'.repeat(100)].map(v => {"
+ " return ['md5', 'sha1', 'sha256'].map(h => {"
+ " return hash(h).update(v).digest('hex');"
+ " })"
+ "}))"),
+ njs_str("[['d41d8cd98f00b204e9800998ecf8427e',"
+ "'da39a3ee5e6b4b0d3255bfef95601890afd80709',"
+ "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'],"
+ "['f571117acbd8153c8dc3c81b8817773a',"
+ "'c95466320eaae6d19ee314ae4f135b12d45ced9a',"
+ "'d9f5aeb06abebb3be3f38adec9a2e3b94228d52193be923eb4e24c9b56ee0930']]") },
{ njs_str("var h = require('crypto').createHash()"),
njs_str("TypeError: algorithm must be a string") },
njs_str("TypeError: not supported algorithm: \"sha512\"") },
{ njs_str("var h = require('crypto').createHash('sha1');"
- "h.update()"),
- njs_str("TypeError: data must be a string") },
+ "h.update()"),
+ njs_str("TypeError: data argument \"undefined\" is not a string or Buffer-like object") },
{ njs_str("var h = require('crypto').createHash('sha1');"
- "h.update({})"),
- njs_str("TypeError: data must be a string") },
+ "h.update({})"),
+ njs_str("TypeError: data argument \"object\" is not a string or Buffer-like object") },
{ njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').digest('latin1')"),
+ "h.update('A').digest('latin1')"),
njs_str("TypeError: Unknown digest encoding: \"latin1\"") },
+ { njs_str("require('crypto').createHash('sha1').digest() instanceof Buffer"),
+ njs_str("true") },
+
{ njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').digest('hex'); h.digest('hex')"),
+ "h.update('A').digest('hex'); h.digest('hex')"),
njs_str("Error: Digest already called") },
{ njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').digest('hex'); h.update('B')"),
+ "h.update('A').digest('hex'); h.update('B')"),
njs_str("Error: Digest already called") },
{ njs_str("typeof require('crypto').createHash('md5')"),
"[Object.prototype.toString.call(h), njs.dump(h),h]"),
njs_str("[object Hmac],Hmac {},[object Hmac]") },
- { njs_str("var h = require('crypto').createHmac('md5', '');"
- "h.digest('hex')"),
- njs_str("74e6f7298a9c2d168935f58c001bad88") },
+ { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'md5', '');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hmac().update('AB').digest().toString(e);"
+ " var h2 = hmac().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hmac().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("9e0e9e545ef63d41dfb653daecf8ebc7,"
+ "ng6eVF72PUHftlPa7Pjrxw==,"
+ "ng6eVF72PUHftlPa7Pjrxw") },
+
+ { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'sha1', '');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hmac().update('AB').digest().toString(e);"
+ " var h2 = hmac().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hmac().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("d32c0b6637cc2dfe4670f3fe48ef4434123c4810,"
+ "0ywLZjfMLf5GcPP+SO9ENBI8SBA=,"
+ "0ywLZjfMLf5GcPP-SO9ENBI8SBA") },
- { njs_str("var h = require('crypto').createHmac('sha1', '');"
- "h.digest('hex')"),
- njs_str("fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") },
+ { njs_str("var hash = require('crypto').createHmac.bind(undefined, 'sha1', '');"
+ "["
+ " ['AB'],"
+ " ['4142', 'hex'],"
+ " ['QUI=', 'base64'],"
+ " ['QUI', 'base64url']"
+ "].every(args => {"
+ " return hash().update(args[0], args[1]).digest('hex') === 'd32c0b6637cc2dfe4670f3fe48ef4434123c4810';"
+ "})"),
+ njs_str("true") },
- { njs_str("var h = require('crypto').createHmac('sha1', '');"
- "h.digest().toString('hex')"),
- njs_str("fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") },
+ { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'sha256', '');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hmac().update('AB').digest().toString(e);"
+ " var h2 = hmac().update(Buffer.from('AB')).digest(e);"
+ " var h3 = hmac().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("d53400095496267cf02e5dbd4b0bf9fbfb5f36f311ea7d9809af5487421743e3,"
+ "1TQACVSWJnzwLl29Swv5+/tfNvMR6n2YCa9Uh0IXQ+M=,"
+ "1TQACVSWJnzwLl29Swv5-_tfNvMR6n2YCa9Uh0IXQ-M") },
+
+ { njs_str("var hmac = require('crypto').createHmac;"
+ "njs.dump(['', 'abc'.repeat(100)].map(v => {"
+ " return ['md5', 'sha1', 'sha256'].map(h => {"
+ " return hmac(h, Buffer.from('secret')).update(v).digest('hex');"
+ " })"
+ "}))"),
+ njs_str("[['5c8db03f04cec0f43bcb060023914190',"
+ "'25af6174a0fcecc4d346680a72b7ce644b9a88e8',"
+ "'f9e66e179b6747ae54108f82f8ade8b3c25d76fd30afde6c395822c530196169'],"
+ "['91eb74a225cdd3bbfccc34396c6e3ac5',"
+ "'0aac71e3a813a7acc4a809cfdedb2ecba04ffc5e',"
+ "'8660d2d51d6f20f61d5aadfb6c43df7fd05fc2fc4967d8aec1846f3d9ec03987']]") },
{ njs_str("var h = require('crypto').createHmac('sha1', '');"
"var Hmac = h.constructor; "
"h.constructor.name"),
njs_str("Hmac") },
- { njs_str("var h = require('crypto').createHmac('md5', 'secret key');"
- "h.update('AB').digest('hex')"),
- njs_str("9c72728915eb26620a5caeafd0063b29") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('A').update('B').digest('hex')"),
- njs_str("adc60e03459c4bae7cf4eb6d9730003e9490b22f") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('AB').digest('hex')"),
- njs_str("adc60e03459c4bae7cf4eb6d9730003e9490b22f") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('AB').digest('base64')"),
- njs_str("rcYOA0WcS6589OttlzAAPpSQsi8=") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('AB').digest('base64url')"),
- njs_str("rcYOA0WcS6589OttlzAAPpSQsi8") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('AB').digest().toString('base64')"),
- njs_str("rcYOA0WcS6589OttlzAAPpSQsi8=") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('abc'.repeat(100)).digest('hex')"),
- njs_str("b105ad6921e4c54d3fa0a9ec3f7f0ee9bd2c659d") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'A'.repeat(40));"
- "h.update('AB').digest('hex')"),
- njs_str("0b84f78ca5275d76d4b7dafb5845ee2b6a79c4c2") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'A'.repeat(64));"
- "h.update('AB').digest('hex')"),
- njs_str("400ce530816c6b3247e2959f3982a12aaf58c0c9") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'A'.repeat(100));"
- "h.update('AB').digest('hex')"),
- njs_str("670e7cdebae6392797e000e79e51d3b6589d8fad") },
-
- { njs_str("var h = require('crypto').createHmac('sha256', '');"
- "h.digest('hex')"),
- njs_str("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad") },
-
- { njs_str("var h = require('crypto').createHmac('sha256', 'secret key');"
- "h.update('A').update('B').digest('hex')"),
- njs_str("46085184b3b45a13d838bf71a0ce03675dab30931e0f1f68fa636ea65fdb286d") },
-
- { njs_str("var h = require('crypto').createHmac('sha256', 'secret key');"
- "h.update('AB').digest('hex')"),
- njs_str("46085184b3b45a13d838bf71a0ce03675dab30931e0f1f68fa636ea65fdb286d") },
+ { njs_str("require('crypto').createHmac('sha1', '').digest() instanceof Buffer"),
+ njs_str("true") },
{ njs_str("var h = require('crypto').createHmac('sha256', 'A'.repeat(64));"
- "h.update('AB').digest('hex')"),
+ "h.update('AB').digest('hex')"),
njs_str("ee9dce43b12eb3e865614ad9c1a8d4fad4b6eac2b64647bd24cd192888d3f367") },
{ njs_str("var h = require('crypto').createHmac('sha256', 'A'.repeat(100));"
- "h.update('AB').digest('hex')"),
+ "h.update('AB').digest('hex')"),
njs_str("5647b6c429701ff512f0f18232b4507065d2376ca8899a816a0a6e721bf8ddcc") },
- { njs_str("var h = require('crypto').createHmac('md5', 'secret key');"
- "h.update('abc'.repeat(100)).digest('hex')"),
- njs_str("5dd706af43536f8c9c83e7ea55b1a5a2") },
-
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('abc'.repeat(100)).digest('hex')"),
- njs_str("b105ad6921e4c54d3fa0a9ec3f7f0ee9bd2c659d") },
-
- { njs_str("var h = require('crypto').createHmac('sha256', 'secret key');"
- "h.update('abc'.repeat(100)).digest('hex')"),
- njs_str("f6550d398ce350ee8d94a0f44f2cf6b9bc8d316ae4625fb4434f22980a276bac") },
-
{ njs_str("var h = require('crypto').createHmac()"),
njs_str("TypeError: algorithm must be a string") },
njs_str("TypeError: not supported algorithm: \"sha512\"") },
{ njs_str("var h = require('crypto').createHmac('sha1', [])"),
- njs_str("TypeError: key must be a string") },
+ njs_str("TypeError: key argument \"array\" is not a string or Buffer-like object") },
{ njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('A').digest('hex'); h.digest('hex')"),
+ "h.update('A').digest('hex'); h.digest('hex')"),
njs_str("Error: Digest already called") },
{ njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('A').digest('hex'); h.update('B')"),
+ "h.update('A').digest('hex'); h.update('B')"),
njs_str("Error: Digest already called") },
{ njs_str("typeof require('crypto').createHmac('md5', 'a')"),
{ njs_str("var h = require('crypto').createHash('sha1')" ENTER
"h.update([])" ENTER),
- njs_str("TypeError: data must be a string\n"
+ njs_str("TypeError: data argument \"array\" is not a string or Buffer-like object\n"
" at Hash.prototype.update (native)\n"
" at main (:1)\n") },
{ njs_str("require('crypto').createHmac('sha1', [])" ENTER),
- njs_str("TypeError: key must be a string\n"
+ njs_str("TypeError: key argument \"array\" is not a string or Buffer-like object\n"
" at crypto.createHmac (native)\n"
" at main (:1)\n") },
{ njs_str("var h = require('crypto').createHmac('sha1', 'secret')" ENTER
"h.update([])" ENTER),
- njs_str("TypeError: data must be a string\n"
+ njs_str("TypeError: data argument \"array\" is not a string or Buffer-like object\n"
" at Hmac.prototype.update (native)\n"
" at main (:1)\n") },