pull/13324/merge
Louis Schmieder 2022-04-14 22:10:26 +08:00 committed by GitHub
commit 5b4ae88925
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 154 additions and 0 deletions

View File

@ -80,6 +80,7 @@ const (
'vlib/net/http/http_test.v',
'vlib/net/http/status_test.v',
'vlib/net/websocket/ws_test.v',
'vlib/net/openssl/rsa_test.v',
'vlib/sqlite/sqlite_test.v',
'vlib/sqlite/sqlite_orm_test.v',
'vlib/orm/orm_test.v',
@ -118,6 +119,7 @@ const (
'vlib/net/unix/unix_test.v',
'vlib/net/unix/use_net_and_net_unix_together_test.v',
'vlib/net/websocket/websocket_test.v',
'vlib/net/openssl/rsa_test.v',
'vlib/vweb/tests/vweb_test.v',
'vlib/vweb/request_test.v',
'vlib/net/http/request_test.v',

View File

@ -0,0 +1,75 @@
module rsa
import net.openssl
pub struct RSAInstance {
pair &C.RSA
pub:
public_key []byte
private_key []byte
}
pub fn gen_key_pair(len int, exp int) ?RSAInstance {
assert openssl.is_used == 1
rsa := C.RSA_new()
bn := C.BN_new()
C.BN_set_word(bn, exp)
if C.RAND_status() != 1 {
return error('Not seeded')
}
res := C.RSA_generate_key_ex(rsa, len, bn, voidptr(0))
C.BN_free(bn)
if res != 1 {
err := []byte{len: 256}
C.ERR_error_string(C.ERR_get_error(), err.data)
return error(err.bytestr())
}
private := C.BIO_new(C.BIO_s_mem())
public := C.BIO_new(C.BIO_s_mem())
C.PEM_write_bio_RSAPrivateKey(private, rsa, voidptr(0), voidptr(0), 0, voidptr(0),
voidptr(0))
C.PEM_write_bio_RSAPublicKey(public, rsa)
private_len := C.BIO_pending(private)
public_len := C.BIO_pending(public)
private_key := []byte{len: private_len}
public_key := []byte{len: public_len}
C.BIO_read(private, private_key.data, private_len)
C.BIO_read(public, public_key.data, public_len)
return RSAInstance{
pair: rsa
public_key: public_key
private_key: private_key
}
}
pub fn (rsa RSAInstance) encrypt(msg []byte) ?([]byte, int) {
res := []byte{len: C.RSA_size(rsa.pair)}
len := C.RSA_public_encrypt(msg.len, msg.data, res.data, rsa.pair, C.RSA_PKCS1_OAEP_PADDING)
if len == -1 {
err := []byte{len: 256}
C.ERR_error_string(C.ERR_get_error(), err.data)
return error(err.bytestr())
}
return res, len
}
pub fn (rsa RSAInstance) decrypt(len int, data []byte) ?[]byte {
res := []byte{len: len}
l := C.RSA_private_decrypt(len, data.data, res.data, rsa.pair, C.RSA_PKCS1_OAEP_PADDING)
if l == -1 {
err := []byte{len: 256}
C.ERR_error_string(C.ERR_get_error(), err.data)
return error(err.bytestr())
}
return res[0..l]
}

View File

@ -0,0 +1 @@
module rsa

View File

@ -29,6 +29,8 @@ $if $pkgconfig('openssl') {
//
#include <openssl/rand.h> # Please install OpenSSL development headers
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
[typedef]
@ -47,6 +49,19 @@ pub struct SSL_METHOD {
pub struct OPENSSL_INIT_SETTINGS {
}
[typedef]
struct C.RSA {
engine voidptr
n &C.BIGNUM
e &C.BIGNUM
d &C.BIGNUM
p &C.BIGNUM
q &C.BIGNUM
}
[typedef]
struct C.BIGNUM {}
fn C.BIO_new_ssl_connect(ctx &C.SSL_CTX) &C.BIO
fn C.BIO_set_conn_hostname(b &C.BIO, name &char) int
@ -66,6 +81,12 @@ fn C.BIO_read(b &C.BIO, buf voidptr, len int) int
fn C.BIO_free_all(a &C.BIO)
fn C.BIO_new(voidptr) &C.BIO
fn C.BIO_s_mem()
fn C.BIO_pending(&C.BIO) int
fn C.SSL_CTX_new(method &C.SSL_METHOD) &C.SSL_CTX
fn C.SSL_CTX_set_options(ctx &C.SSL_CTX, options int)
@ -120,6 +141,31 @@ fn C.TLSv1_2_method() voidptr
fn C.OPENSSL_init_ssl(opts u64, settings &OPENSSL_INIT_SETTINGS) int
// RSA
fn C.RSA_generate_key_ex(&C.RSA, int, &C.BIGNUM, voidptr) int
fn C.RSA_generate_key(int, u64, voidptr, voidptr) &C.RSA
fn C.RSA_new() &C.RSA
fn C.RSA_size(&C.RSA) int
fn C.RSA_public_encrypt(int, voidptr, voidptr, &C.RSA, int) int
fn C.RSA_private_decrypt(int, voidptr, voidptr, &C.RSA, int) int
fn C.BN_new() &C.BIGNUM
fn C.BN_free(&C.BIGNUM)
fn C.BN_set_word(&C.BIGNUM, int)
fn C.ENGINE_set_default(voidptr, u32)
fn C.RAND_seed(voidptr, int)
fn C.RAND_status() int
fn C.ERR_get_error() u64
fn C.ERR_error_string(u64, charptr) charptr
fn C.PEM_write_bio_RSAPrivateKey(&C.BIO, &C.RSA, voidptr, voidptr, int, voidptr, voidptr)
fn C.PEM_write_bio_RSAPublicKey(&C.BIO, &C.RSA)
fn init() {
$if ssl_pre_1_1_version ? {
// OPENSSL_VERSION_NUMBER < 0x10100000L

View File

@ -0,0 +1,30 @@
import crypto.rsa
/*
This test has to be moved here, because in the rsa there is an strange error.
OpenSSL should be a correct place aswell.
*/
fn test_rsa() {
instance := rsa.gen_key_pair(1024, 3) or {
eprintln(err)
assert false
return
}
message := 'abc123456'
encrypted, len := instance.encrypt(message.bytes()) or {
eprintln(err)
assert false
return
}
decrypted := instance.decrypt(len, encrypted) or {
eprintln(err)
assert false
return
}
assert message == decrypted.bytestr()
}