Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement X509Certificate in node:crypto #16173

Merged
merged 63 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
741b768
Implement X509Certificate
Jarred-Sumner Jan 5, 2025
f6d957c
`bun run clang-format`
Jarred-Sumner Jan 5, 2025
247227e
probably fix build
Jarred-Sumner Jan 6, 2025
2ebf024
Update CryptoKey.h
Jarred-Sumner Jan 6, 2025
6a8733b
Update CryptoKey.h
Jarred-Sumner Jan 6, 2025
03227ab
Update ncrypto.cpp
Jarred-Sumner Jan 6, 2025
718b3af
Update ncrypto.h
Jarred-Sumner Jan 6, 2025
e5cd3f7
Update ncrypto.h
Jarred-Sumner Jan 6, 2025
a3ce321
Update ncrypto.cpp
Jarred-Sumner Jan 6, 2025
7f50aea
Merge branch 'main' into jarred/x509
dylan-conway Jan 14, 2025
0a8d9c5
errors
dylan-conway Jan 15, 2025
ce21fc2
x509Certificate fixes
dylan-conway Jan 15, 2025
d16cd31
stateless dh
dylan-conway Jan 15, 2025
b942e60
add tests
dylan-conway Jan 15, 2025
fd6a627
Merge branch 'main' into jarred/x509
dylan-conway Jan 15, 2025
8d8b9bf
`bun run zig-format`
dylan-conway Jan 15, 2025
158ed4c
Add missing include
Jarred-Sumner Jan 15, 2025
43d5429
we have the primes
Jarred-Sumner Jan 15, 2025
c739ff4
Fix leak
Jarred-Sumner Jan 15, 2025
30012b4
double free
dylan-conway Jan 15, 2025
8c62cf1
ref
dylan-conway Jan 15, 2025
70d9c22
add missing field
dylan-conway Jan 15, 2025
53dae55
Merge branch 'main' into jarred/x509
dylan-conway Jan 15, 2025
8f69c56
fix test
dylan-conway Jan 16, 2025
e57a5f4
fixup
dylan-conway Jan 16, 2025
f1c6a1b
fix pbkdf2 test
dylan-conway Jan 16, 2025
b26aaac
console.log
dylan-conway Jan 16, 2025
9186b1f
fix name object array
dylan-conway Jan 16, 2025
64a19d8
fix test
dylan-conway Jan 16, 2025
289ff78
fix
dylan-conway Jan 16, 2025
eb2cbd9
ECDH.convertKey
dylan-conway Jan 16, 2025
bb85c14
pass test-crypto-dh-curves.js
dylan-conway Jan 16, 2025
b77387a
&& -> and
dylan-conway Jan 16, 2025
cb53347
more
dylan-conway Jan 16, 2025
cf6aef3
fix test-crypto-verify-failure.js
dylan-conway Jan 16, 2025
7f874d4
add test-crypto-certificate.js
dylan-conway Jan 17, 2025
5674745
Certificate
dylan-conway Jan 17, 2025
9106c4d
add test-crypto-webcrypto-aes-decrypt-too-small.js
dylan-conway Jan 17, 2025
2b048fd
subtle crypto error messages
dylan-conway Jan 17, 2025
95e7f06
add test-webcrypto-digest.js
dylan-conway Jan 17, 2025
b3d8393
more error
dylan-conway Jan 17, 2025
8341612
add test-crypto-psychic-signatures.js
dylan-conway Jan 17, 2025
48c8e0b
verify false
dylan-conway Jan 17, 2025
0a0c454
oops
dylan-conway Jan 17, 2025
149b866
Merge branch 'main' into jarred/x509
dylan-conway Jan 17, 2025
e2b32cb
more function
dylan-conway Jan 17, 2025
01ea4a2
fix
dylan-conway Jan 17, 2025
0318e29
correct function name
dylan-conway Jan 17, 2025
11cb16b
fix test output
dylan-conway Jan 17, 2025
a908ac2
add test
dylan-conway Jan 17, 2025
66c55c3
add test-webcrypto-sign-verify.js
dylan-conway Jan 17, 2025
e002387
add test-webcrypto-wrap-unwrap.js
dylan-conway Jan 17, 2025
96de98d
add webcrypto derivekey and derivebits cfrg
dylan-conway Jan 17, 2025
4784273
AES errors
dylan-conway Jan 17, 2025
203550b
add test-webcrypto-encrypt-decrypt-aes.js
dylan-conway Jan 17, 2025
e51ffe6
delete
dylan-conway Jan 17, 2025
830540f
out of bounds
dylan-conway Jan 17, 2025
2ac05c5
null byte
dylan-conway Jan 17, 2025
a63077c
Merge branch 'main' into jarred/x509
dylan-conway Jan 17, 2025
cb8d6ca
oops
dylan-conway Jan 17, 2025
afa8cc1
getCipherInfo
dylan-conway Jan 17, 2025
bc83a81
clean up some lifetimes
Jarred-Sumner Jan 17, 2025
95981c9
Update NodeCrypto.cpp
Jarred-Sumner Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .clangd
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ CompileFlags:

Diagnostics:
UnusedIncludes: None

HeaderInsertion:
IncludeBlocks: Preserve # Do not auto-include headers.
3 changes: 3 additions & 0 deletions packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ declare module "bun" {
import type { Encoding as CryptoEncoding } from "crypto";
import type { CipherNameAndProtocol, EphemeralKeyInfo, PeerCertificate } from "tls";
import type { Stats } from "node:fs";
import type { X509Certificate } from "node:crypto";
interface Env {
NODE_ENV?: string;
/**
Expand Down Expand Up @@ -5372,6 +5373,7 @@ declare module "bun" {
* socket has been destroyed, `null` will be returned.
*/
getCertificate(): PeerCertificate | object | null;
getX509Certificate(): X509Certificate | undefined;

/**
* Returns an object containing information on the negotiated cipher suite.
Expand Down Expand Up @@ -5410,6 +5412,7 @@ declare module "bun" {
* @return A certificate object.
*/
getPeerCertificate(): PeerCertificate;
getPeerX509Certificate(): X509Certificate;

/**
* See [SSL\_get\_shared\_sigalgs](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_shared_sigalgs.html) for more information.
Expand Down
58 changes: 40 additions & 18 deletions src/bun.js/api/BunObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,7 @@ pub const Crypto = struct {
sha512,
@"sha512-224",
@"sha512-256",

@"sha3-224",
@"sha3-256",
@"sha3-384",
Expand All @@ -1139,6 +1140,7 @@ pub const Crypto = struct {
.blake2b512 => BoringSSL.EVP_blake2b512(),
.md4 => BoringSSL.EVP_md4(),
.md5 => BoringSSL.EVP_md5(),
.ripemd160 => BoringSSL.EVP_ripemd160(),
.sha1 => BoringSSL.EVP_sha1(),
.sha224 => BoringSSL.EVP_sha224(),
.sha256 => BoringSSL.EVP_sha256(),
Expand Down Expand Up @@ -1359,28 +1361,37 @@ pub const Crypto = struct {
return globalThis.throwNotEnoughArguments("pbkdf2", 5, arguments.len);
}

if (!arguments[3].isAnyInt()) {
return globalThis.throwInvalidArgumentTypeValue("keylen", "integer", arguments[3]);
if (!arguments[3].isNumber()) {
return globalThis.throwInvalidArgumentTypeValue("keylen", "number", arguments[3]);
}

const length = arguments[3].coerce(i64, globalThis);
const keylen_num = arguments[3].asNumber();

if (std.math.isInf(keylen_num) or std.math.isNan(keylen_num)) {
return globalThis.throwRangeError(keylen_num, .{
.field_name = "keylen",
.msg = "an integer",
});
}

if (!globalThis.hasException() and (length < 0 or length > std.math.maxInt(i32))) {
return globalThis.throwInvalidArguments("keylen must be > 0 and < {d}", .{std.math.maxInt(i32)});
if (keylen_num < 0 or keylen_num > std.math.maxInt(i32)) {
return globalThis.throwRangeError(keylen_num, .{ .field_name = "keylen", .min = 0, .max = std.math.maxInt(i32) });
}

const keylen: i32 = @intFromFloat(keylen_num);

if (globalThis.hasException()) {
return error.JSError;
}

if (!arguments[2].isAnyInt()) {
return globalThis.throwInvalidArgumentTypeValue("iteration count", "integer", arguments[2]);
return globalThis.throwInvalidArgumentTypeValue("iterations", "number", arguments[2]);
}

const iteration_count = arguments[2].coerce(i64, globalThis);

if (!globalThis.hasException() and (iteration_count < 1 or iteration_count > std.math.maxInt(u32))) {
return globalThis.throwInvalidArguments("iteration count must be >= 1 and <= maxInt", .{});
if (!globalThis.hasException() and (iteration_count < 1 or iteration_count > std.math.maxInt(i32))) {
return globalThis.throwRangeError(iteration_count, .{ .field_name = "iterations", .min = 1, .max = std.math.maxInt(i32) + 1 });
}

if (globalThis.hasException()) {
Expand All @@ -1389,23 +1400,28 @@ pub const Crypto = struct {

const algorithm = brk: {
if (!arguments[4].isString()) {
return globalThis.throwInvalidArgumentTypeValue("algorithm", "string", arguments[4]);
return globalThis.throwInvalidArgumentTypeValue("digest", "string", arguments[4]);
}

break :brk EVP.Algorithm.map.fromJSCaseInsensitive(globalThis, arguments[4]) orelse {
if (!globalThis.hasException()) {
const slice = arguments[4].toSlice(globalThis, bun.default_allocator);
defer slice.deinit();
const name = slice.slice();
return globalThis.ERR_CRYPTO_INVALID_DIGEST("Unsupported algorithm \"{s}\"", .{name}).throw();
invalid: {
switch (EVP.Algorithm.map.fromJSCaseInsensitive(globalThis, arguments[4]) orelse break :invalid) {
.shake128, .shake256, .@"sha3-224", .@"sha3-256", .@"sha3-384", .@"sha3-512" => break :invalid,
else => |alg| break :brk alg,
}
return error.JSError;
};
}

if (!globalThis.hasException()) {
const slice = arguments[4].toSlice(globalThis, bun.default_allocator);
defer slice.deinit();
const name = slice.slice();
return globalThis.ERR_CRYPTO_INVALID_DIGEST("Invalid digest: {s}", .{name}).throw();
}
return error.JSError;
};

var out = PBKDF2{
.iteration_count = @intCast(iteration_count),
.length = @truncate(length),
.length = keylen,
.algorithm = algorithm,
};
defer {
Expand Down Expand Up @@ -1436,6 +1452,12 @@ pub const Crypto = struct {
return globalThis.throwInvalidArguments("password is too long", .{});
}

if (is_async) {
if (!arguments[5].isFunction()) {
return globalThis.throwInvalidArgumentTypeValue("callback", "function", arguments[5]);
}
}

return out;
}
};
Expand Down
33 changes: 33 additions & 0 deletions src/bun.js/api/bun/socket.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3218,6 +3218,39 @@ fn NewSocket(comptime ssl: bool) type {
return JSValue.jsUndefined();
}

pub fn getPeerX509Certificate(
this: *This,
globalObject: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) bun.JSError!JSValue {
if (comptime ssl == false) {
return JSValue.jsUndefined();
}
const ssl_ptr = this.socket.ssl() orelse return JSValue.jsUndefined();
const cert = BoringSSL.SSL_get_peer_certificate(ssl_ptr);
if (cert) |x509| {
return X509.toJSObject(x509, globalObject);
}
return JSValue.jsUndefined();
}

pub fn getX509Certificate(
this: *This,
globalObject: *JSC.JSGlobalObject,
_: *JSC.CallFrame,
) bun.JSError!JSValue {
if (comptime ssl == false) {
return JSValue.jsUndefined();
}

const ssl_ptr = this.socket.ssl() orelse return JSValue.jsUndefined();
const cert = BoringSSL.SSL_get_certificate(ssl_ptr);
if (cert) |x509| {
return X509.toJSObject(x509.ref(), globalObject);
}
return JSValue.jsUndefined();
}

pub fn getServername(
this: *This,
globalObject: *JSC.JSGlobalObject,
Expand Down
Loading
Loading