Move OpenSSL compatibility into nwssl
This commit is contained in:
@@ -252,7 +252,7 @@ set(SODIUM_INSTALL ON CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_LIBRARY_PREFIX nw CACHE STRING "" FORCE)
|
||||
set(MATRIXSSL_BUILD_SHARED ON CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_BUILD_STATIC OFF CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_BUILD_OPENSSL_COMPAT ON CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_BUILD_OPENSSL_COMPAT OFF CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_USE_SODIUM ON CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_BUILD_TESTS ${MARS_NWE_BUILD_MATRIXSSL_PROGRAMS} CACHE BOOL "" FORCE)
|
||||
set(MATRIXSSL_BUILD_APPS ${MARS_NWE_BUILD_MATRIXSSL_PROGRAMS} CACHE BOOL "" FORCE)
|
||||
@@ -275,17 +275,29 @@ set(BUILD_SHARED_LIBS ${_MARS_NWE_SAVED_BUILD_SHARED_LIBS})
|
||||
add_subdirectory(third_party/matrixssl)
|
||||
|
||||
# mars-nwe base libraries. nwcore owns common project infrastructure such as
|
||||
# logging; nwssl is the temporary SSL/Crypto abstraction on top of MatrixSSL
|
||||
# OpenSSL-compat until the native API is complete.
|
||||
# logging; nwssl owns the reduced OpenSSL compatibility layer on top of
|
||||
# MatrixSSL, which stays a native TLS/crypto provider.
|
||||
add_subdirectory(src/core)
|
||||
add_subdirectory(src/ssl)
|
||||
|
||||
# Bundled FLAIM storage stack. Keep the imported sources unchanged; the CMake
|
||||
# wrapper builds only the mars-nwe-needed libraries and routes legacy TLS/crypto
|
||||
# compatibility through nwssl.
|
||||
set(NWFLAIM_LIBRARY_PREFIX nw CACHE STRING "" FORCE)
|
||||
set(NWFLAIM_BUILD_SHARED ON CACHE BOOL "" FORCE)
|
||||
set(NWFLAIM_BUILD_STATIC OFF CACHE BOOL "" FORCE)
|
||||
set(NWFLAIM_BUILD_SQL ON CACHE BOOL "" FORCE)
|
||||
set(NWFLAIM_WITH_OPENSSL ON CACHE BOOL "" FORCE)
|
||||
set(NWFLAIM_SSL_TARGET mars_nwe::ssl CACHE STRING "" FORCE)
|
||||
set(NWFLAIM_NICI_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include/nwssl/private/nici" CACHE PATH "" FORCE)
|
||||
add_subdirectory(third_party/flaim)
|
||||
|
||||
if(ENABLE_DIRECTORY)
|
||||
set(TINYLDAP_OUTPUT_NAME nwdirectory CACHE STRING "" FORCE)
|
||||
set(TINYLDAP_BUILD_SHARED ON CACHE BOOL "" FORCE)
|
||||
set(TINYLDAP_BUILD_STATIC OFF CACHE BOOL "" FORCE)
|
||||
set(TINYLDAP_LIBOWFAT_INCLUDE_SUBDIR nwlibowfat CACHE STRING "" FORCE)
|
||||
set(TINYLDAP_MATRIXSSL_INCLUDE_SUBDIR nwmatrixssl CACHE STRING "" FORCE)
|
||||
set(TINYLDAP_NWSSL_TARGET mars_nwe::ssl CACHE STRING "" FORCE)
|
||||
set(TINYLDAP_ALLOW_SYSTEM_OPENSSL OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(directory)
|
||||
endif()
|
||||
|
||||
Submodule directory updated: e5b9d3ed03...84a6f10d45
104
include/nwssl/private/nici/ccs.h
Normal file
104
include/nwssl/private/nici/ccs.h
Normal file
@@ -0,0 +1,104 @@
|
||||
#ifndef MARS_NWSSL_PRIVATE_NICI_CCS_H
|
||||
#define MARS_NWSSL_PRIVATE_NICI_CCS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t NICI_BYTE;
|
||||
typedef uint32_t NICI_ULONG;
|
||||
typedef uint32_t NICI_BBOOL;
|
||||
typedef uint32_t NICI_CC_HANDLE;
|
||||
typedef uint32_t NICI_OBJECT_HANDLE;
|
||||
typedef NICI_OBJECT_HANDLE *NICI_OBJECT_HANDLE_PTR;
|
||||
|
||||
typedef uint32_t nuint32;
|
||||
typedef uint8_t nuint8;
|
||||
typedef uint8_t nbool8;
|
||||
|
||||
#define NICI_H_INVALID 0
|
||||
#define NICI_KM_UNSPECIFIED 0
|
||||
|
||||
#define NICI_A_KEY_TYPE 1
|
||||
#define NICI_A_KEY_USAGE 2
|
||||
#define NICI_A_KEY_SIZE 3
|
||||
#define NICI_A_GLOBAL 4
|
||||
#define NICI_A_CLASS 5
|
||||
#define NICI_A_KEY_FORMAT 6
|
||||
#define NICI_A_FEATURE 7
|
||||
|
||||
#define NICI_K_AES 1
|
||||
#define NICI_K_DES3X 2
|
||||
#define NICI_K_DES 3
|
||||
|
||||
#define NICI_F_DATA_ENCRYPT 0x0001u
|
||||
#define NICI_F_DATA_DECRYPT 0x0002u
|
||||
#define NICI_F_EXTRACT 0x0004u
|
||||
#define NICI_F_WRAP 0x0008u
|
||||
#define NICI_F_UNWRAP 0x0010u
|
||||
#define NICI_F_KM_ENCRYPT 0x0020u
|
||||
#define NICI_F_KM_DECRYPT 0x0040u
|
||||
|
||||
#define NICI_O_SECRET_KEY 1
|
||||
#define NICI_AV_STORAGE 1
|
||||
#define NICI_P_IV 1
|
||||
|
||||
#define NICI_AlgorithmPrefix(x) (x)
|
||||
#define IDV_NOV_AES128CBCPad NICI_AlgorithmPrefix(1), 97
|
||||
#define IDV_NOV_DES3CBCPad NICI_AlgorithmPrefix(1), 98
|
||||
#define IDV_NOV_DESCBCPad NICI_AlgorithmPrefix(1), 99
|
||||
|
||||
typedef struct NICI_PARAMETER_INFO_st {
|
||||
uint32_t parmType;
|
||||
void *parm;
|
||||
uint32_t parmLen;
|
||||
} NICI_PARAMETER_INFO;
|
||||
|
||||
typedef struct NICI_PARAMETER_st {
|
||||
NICI_PARAMETER_INFO *parms;
|
||||
uint32_t parmCount;
|
||||
} NICI_PARAMETER;
|
||||
|
||||
typedef struct NICI_ALGORITHM_st {
|
||||
const uint8_t *algorithm;
|
||||
uint32_t algorithmLen;
|
||||
NICI_PARAMETER *parameter;
|
||||
} NICI_ALGORITHM;
|
||||
|
||||
typedef struct NICI_ATTRIBUTE_st {
|
||||
uint32_t type;
|
||||
union {
|
||||
struct { uint32_t value; } f;
|
||||
struct { void *data; uint32_t len; } b;
|
||||
} u;
|
||||
} NICI_ATTRIBUTE;
|
||||
|
||||
typedef NICI_ATTRIBUTE *NICI_ATTRIBUTE_PTR;
|
||||
|
||||
int CCS_CreateContext(uint32_t flags, NICI_CC_HANDLE *context);
|
||||
int CCS_DestroyContext(NICI_CC_HANDLE context);
|
||||
int CCS_DestroyObject(NICI_CC_HANDLE context, NICI_OBJECT_HANDLE object);
|
||||
int CCS_GetAttributeValue(NICI_CC_HANDLE context, NICI_OBJECT_HANDLE object, NICI_ATTRIBUTE_PTR attrs, uint32_t attr_count);
|
||||
int CCS_WrapKey(NICI_CC_HANDLE context, NICI_ALGORITHM *algorithm, uint32_t mode, uint32_t flags, NICI_OBJECT_HANDLE wrapping_key, NICI_OBJECT_HANDLE key, void *wrapped_key, NICI_ULONG *wrapped_key_len);
|
||||
int CCS_UnwrapKey(NICI_CC_HANDLE context, NICI_OBJECT_HANDLE wrapping_key, const void *wrapped_key, NICI_ULONG wrapped_key_len, NICI_OBJECT_HANDLE_PTR key);
|
||||
int CCS_GenerateKey(NICI_CC_HANDLE context, NICI_ALGORITHM *algorithm, NICI_ATTRIBUTE_PTR attrs, uint32_t attr_count, NICI_BBOOL *key_size_changed, NICI_OBJECT_HANDLE_PTR key, NICI_OBJECT_HANDLE template_key);
|
||||
int CCS_GetRandom(NICI_CC_HANDLE context, void *buf, uint32_t len);
|
||||
int CCS_DataEncryptInit(NICI_CC_HANDLE context, NICI_ALGORITHM *algorithm, NICI_OBJECT_HANDLE key);
|
||||
int CCS_Encrypt(NICI_CC_HANDLE context, const void *in, uint32_t in_len, void *out, uint32_t *out_len);
|
||||
int CCS_DataDecryptInit(NICI_CC_HANDLE context, NICI_ALGORITHM *algorithm, NICI_OBJECT_HANDLE key);
|
||||
int CCS_Decrypt(NICI_CC_HANDLE context, const void *in, uint32_t in_len, void *out, uint32_t *out_len);
|
||||
int CCS_FindObjectsInit(NICI_CC_HANDLE context, NICI_ATTRIBUTE_PTR attrs, uint32_t attr_count);
|
||||
int CCS_FindObjects(NICI_CC_HANDLE context, NICI_OBJECT_HANDLE_PTR objects, uint32_t *object_count);
|
||||
int CCS_FindObjectsFinal(NICI_CC_HANDLE context);
|
||||
int CCS_pbeEncrypt(NICI_CC_HANDLE context, const void *password, uint32_t password_len, const void *salt, uint32_t salt_len, uint32_t iterations, const void *in, uint32_t in_len, void *out, uint32_t *out_len);
|
||||
int CCS_pbeDecrypt(NICI_CC_HANDLE context, const void *password, uint32_t password_len, const void *salt, uint32_t salt_len, uint32_t iterations, const void *in, uint32_t in_len, void *out, uint32_t *out_len);
|
||||
int CCS_InjectKey(NICI_CC_HANDLE context, NICI_ATTRIBUTE_PTR attrs, nuint32 attr_count, NICI_OBJECT_HANDLE_PTR key);
|
||||
int CCS_ExtractKey(NICI_CC_HANDLE context, NICI_OBJECT_HANDLE key, NICI_ATTRIBUTE_PTR attrs, nuint32 attr_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MARS_NWSSL_PRIVATE_NICI_CCS_H */
|
||||
4
include/nwssl/private/nici/nwccs.h
Normal file
4
include/nwssl/private/nici/nwccs.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef MARS_NWSSL_PRIVATE_NICI_NWCCS_H
|
||||
#define MARS_NWSSL_PRIVATE_NICI_NWCCS_H
|
||||
#include "ccs.h"
|
||||
#endif
|
||||
24
include/openssl/bio.h
Normal file
24
include/openssl/bio.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef MARS_MATRIXSSL_OPENSSL_BIO_H
|
||||
#define MARS_MATRIXSSL_OPENSSL_BIO_H
|
||||
#include <openssl/ssl.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
const BIO_METHOD *BIO_s_mem(void);
|
||||
BIO *BIO_new(const BIO_METHOD *method);
|
||||
BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
|
||||
void BIO_free(BIO *bio);
|
||||
void BIO_free_all(BIO *bio);
|
||||
int BIO_get_ssl(BIO *bio, SSL **ssl);
|
||||
void BIO_set_conn_hostname(BIO *bio, const char *name);
|
||||
void BIO_set_conn_port(BIO *bio, const char *port);
|
||||
int BIO_do_connect(BIO *bio);
|
||||
int BIO_read(BIO *bio, void *buf, int len);
|
||||
int BIO_write(BIO *bio, const void *buf, int len);
|
||||
int BIO_should_retry(BIO *bio);
|
||||
long BIO_get_mem_data(BIO *bio, const char **data);
|
||||
int PEM_write_bio_X509(BIO *bio, X509 *cert);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
4
include/openssl/err.h
Normal file
4
include/openssl/err.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef MARS_MATRIXSSL_OPENSSL_ERR_H
|
||||
#define MARS_MATRIXSSL_OPENSSL_ERR_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
25
include/openssl/md5.h
Normal file
25
include/openssl/md5.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef MARS_NWSSL_OPENSSL_MD5_H
|
||||
#define MARS_NWSSL_OPENSSL_MD5_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <crypto/cryptoApi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef psMd5_t MD5_CTX;
|
||||
#define MD5Init MD5_Init
|
||||
#define MD5Update MD5_Update
|
||||
#define MD5Final MD5_Final
|
||||
|
||||
static inline int MD5_Init(MD5_CTX *c) { return psMd5Init(c) >= 0 ? 1 : 0; }
|
||||
static inline int MD5_Update(MD5_CTX *c, const void *data, size_t len) { psMd5Update(c, (const unsigned char *)data, (uint32_t)len); return 1; }
|
||||
static inline int MD5_Final(unsigned char *md, MD5_CTX *c) { psMd5Final(c, md); return 1; }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MARS_NWSSL_OPENSSL_MD5_H */
|
||||
4
include/openssl/pem.h
Normal file
4
include/openssl/pem.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef MARS_MATRIXSSL_OPENSSL_PEM_H
|
||||
#define MARS_MATRIXSSL_OPENSSL_PEM_H
|
||||
#include <openssl/bio.h>
|
||||
#endif
|
||||
92
include/openssl/ssl.h
Normal file
92
include/openssl/ssl.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef MARS_MATRIXSSL_OPENSSL_SSL_H
|
||||
#define MARS_MATRIXSSL_OPENSSL_SSL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct mars_ssl_ctx_st SSL_CTX;
|
||||
typedef struct mars_ssl_st SSL;
|
||||
typedef struct mars_ssl_method_st SSL_METHOD;
|
||||
typedef struct mars_bio_st BIO;
|
||||
typedef struct mars_bio_method_st BIO_METHOD;
|
||||
typedef struct mars_x509_st X509;
|
||||
typedef struct mars_x509_name_st X509_NAME;
|
||||
typedef struct mars_evp_pkey_st EVP_PKEY;
|
||||
|
||||
#define SSL_FILETYPE_PEM 1
|
||||
#define SSL_FILETYPE_ASN1 2
|
||||
#define X509_FILETYPE_PEM SSL_FILETYPE_PEM
|
||||
|
||||
#define SSL_ERROR_NONE 0
|
||||
#define SSL_ERROR_SSL 1
|
||||
#define SSL_ERROR_WANT_READ 2
|
||||
#define SSL_ERROR_WANT_WRITE 3
|
||||
#define SSL_ERROR_WANT_X509_LOOKUP 4
|
||||
#define SSL_ERROR_SYSCALL 5
|
||||
#define SSL_ERROR_ZERO_RETURN 6
|
||||
#define SSL_ERROR_WANT_CONNECT 7
|
||||
#define SSL_ERROR_WANT_ACCEPT 8
|
||||
|
||||
#define SSL_VERIFY_NONE 0x00
|
||||
#define SSL_VERIFY_PEER 0x01
|
||||
#define X509_V_OK 0
|
||||
|
||||
#define SSL_MODE_AUTO_RETRY 0x00000004L
|
||||
#define TLS1_2_VERSION 0x0303
|
||||
#define TLS1_3_VERSION 0x0304
|
||||
|
||||
#define NID_commonName 13
|
||||
#define EVP_PKEY_RSA 6
|
||||
|
||||
int SSL_library_init(void);
|
||||
#define OpenSSL_add_ssl_algorithms() SSL_library_init()
|
||||
#define SSLeay_add_ssl_algorithms() SSL_library_init()
|
||||
#define OpenSSL_add_all_algorithms() SSL_library_init()
|
||||
void SSL_load_error_strings(void);
|
||||
void ERR_load_BIO_strings(void);
|
||||
void ERR_print_errors_fp(FILE *fp);
|
||||
void ERR_clear_error(void);
|
||||
unsigned long ERR_peek_error(void);
|
||||
|
||||
const SSL_METHOD *TLS_server_method(void);
|
||||
const SSL_METHOD *SSLv23_client_method(void);
|
||||
|
||||
SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
|
||||
void SSL_CTX_free(SSL_CTX *ctx);
|
||||
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
|
||||
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
|
||||
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
|
||||
int SSL_CTX_check_private_key(const SSL_CTX *ctx);
|
||||
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
|
||||
|
||||
SSL *SSL_new(SSL_CTX *ctx);
|
||||
void SSL_free(SSL *ssl);
|
||||
int SSL_set_fd(SSL *ssl, int fd);
|
||||
int SSL_accept(SSL *ssl);
|
||||
int SSL_connect(SSL *ssl);
|
||||
int SSL_read(SSL *ssl, void *buf, int num);
|
||||
int SSL_write(SSL *ssl, const void *buf, int num);
|
||||
int SSL_shutdown(SSL *ssl);
|
||||
int SSL_get_error(const SSL *ssl, int ret);
|
||||
int SSL_pending(const SSL *ssl);
|
||||
long SSL_set_mode(SSL *ssl, long mode);
|
||||
long SSL_get_verify_result(const SSL *ssl);
|
||||
X509 *SSL_get_peer_certificate(const SSL *ssl);
|
||||
|
||||
X509_NAME *X509_get_subject_name(X509 *cert);
|
||||
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
|
||||
EVP_PKEY *X509_get_pubkey(X509 *cert);
|
||||
void EVP_PKEY_free(EVP_PKEY *pkey);
|
||||
void X509_free(X509 *cert);
|
||||
|
||||
struct mars_evp_pkey_st { int type; };
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
4
include/openssl/x509.h
Normal file
4
include/openssl/x509.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef MARS_MATRIXSSL_OPENSSL_X509_H
|
||||
#define MARS_MATRIXSSL_OPENSSL_X509_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
@@ -1,18 +1,21 @@
|
||||
set(NWSSL_BUILD_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/nwssl")
|
||||
set(NWSSL_OPENSSL_COMPAT_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include")
|
||||
file(MAKE_DIRECTORY "${NWSSL_BUILD_INCLUDE_DIR}" "${NWSSL_OPENSSL_COMPAT_INCLUDE_DIR}/openssl")
|
||||
set(NWSSL_OPENSSL_COMPAT_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/openssl")
|
||||
file(MAKE_DIRECTORY "${NWSSL_BUILD_INCLUDE_DIR}" "${NWSSL_OPENSSL_COMPAT_INCLUDE_DIR}")
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_SOURCE_DIR}/include/nwssl/nwssl.h"
|
||||
"${NWSSL_BUILD_INCLUDE_DIR}/nwssl.h"
|
||||
COPYONLY)
|
||||
|
||||
# Temporary OpenSSL compatibility surface for legacy mars-nwe code. MatrixSSL's
|
||||
# reduced OpenSSL layer intentionally does not provide md5.h, so expose a small
|
||||
# MD5 wrapper here until callers move to the real nwssl API.
|
||||
file(WRITE "${NWSSL_OPENSSL_COMPAT_INCLUDE_DIR}/openssl/md5.h" "#pragma once\n#include <stddef.h>\n#include <stdint.h>\n#include <crypto/cryptoApi.h>\ntypedef psMd5_t MD5_CTX;\nstatic inline int MD5_Init(MD5_CTX *c) { return psMd5Init(c) >= 0 ? 1 : 0; }\nstatic inline int MD5_Update(MD5_CTX *c, const void *data, size_t len) { psMd5Update(c, (const unsigned char *)data, (uint32_t)len); return 1; }\nstatic inline int MD5_Final(unsigned char *md, MD5_CTX *c) { psMd5Final(c, md); return 1; }\n")
|
||||
# nwssl owns the reduced OpenSSL compatibility surface used by legacy mars-nwe
|
||||
# code. MatrixSSL stays a native TLS/crypto provider underneath this wrapper.
|
||||
file(COPY "${CMAKE_SOURCE_DIR}/include/openssl/"
|
||||
DESTINATION "${NWSSL_OPENSSL_COMPAT_INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
add_library(nwssl SHARED nwssl.c)
|
||||
add_library(nwssl SHARED
|
||||
nwssl.c
|
||||
openssl_compat.c)
|
||||
add_library(mars_nwe::ssl ALIAS nwssl)
|
||||
|
||||
set_target_properties(nwssl PROPERTIES
|
||||
@@ -34,8 +37,14 @@ target_include_directories(nwssl
|
||||
|
||||
target_link_libraries(nwssl
|
||||
PUBLIC
|
||||
OpenSSL::SSL
|
||||
OpenSSL::Crypto)
|
||||
MATRIXSSL::matrixssl)
|
||||
|
||||
if(NOT TARGET OpenSSL::SSL)
|
||||
add_library(OpenSSL::SSL ALIAS nwssl)
|
||||
endif()
|
||||
if(NOT TARGET OpenSSL::Crypto)
|
||||
add_library(OpenSSL::Crypto ALIAS nwssl)
|
||||
endif()
|
||||
|
||||
install(TARGETS nwssl
|
||||
EXPORT mars-nwe-ssl-targets
|
||||
@@ -45,6 +54,8 @@ install(TARGETS nwssl
|
||||
|
||||
install(DIRECTORY "${NWSSL_BUILD_INCLUDE_DIR}/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nwssl")
|
||||
install(DIRECTORY "${NWSSL_OPENSSL_COMPAT_INCLUDE_DIR}/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/openssl")
|
||||
|
||||
install(EXPORT mars-nwe-ssl-targets
|
||||
NAMESPACE mars_nwe::
|
||||
|
||||
556
src/ssl/openssl_compat.c
Normal file
556
src/ssl/openssl_compat.c
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* mars-matrixssl reduced OpenSSL compatibility layer.
|
||||
*
|
||||
* This is not the historical MatrixSSL OpenSSL shim. It implements only the
|
||||
* OpenSSL-shaped entry points used by mars-nwe's nwwebui and FLAIM/FTK.
|
||||
*/
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bio.h>
|
||||
#include "matrixsslApi.h"
|
||||
#include "matrixsslGetSet.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct mars_ssl_method_st { int server; };
|
||||
struct mars_x509_name_st { char common_name[256]; };
|
||||
struct mars_x509_st { struct mars_x509_name_st subject; char *pem; };
|
||||
struct mars_bio_method_st { int type; };
|
||||
|
||||
struct mars_ssl_ctx_st {
|
||||
int server;
|
||||
int min_proto;
|
||||
char *cert_file;
|
||||
char *key_file;
|
||||
char *ca_file;
|
||||
sslKeys_t *keys;
|
||||
int keys_loaded;
|
||||
};
|
||||
|
||||
struct mars_ssl_st {
|
||||
SSL_CTX *ctx;
|
||||
ssl_t *ms;
|
||||
sslSessionId_t *sid;
|
||||
int fd;
|
||||
int last_error;
|
||||
int handshake_done;
|
||||
int close_sent;
|
||||
unsigned char *app_ptr;
|
||||
uint32 app_len;
|
||||
uint32 app_off;
|
||||
char peer_name[256];
|
||||
};
|
||||
|
||||
struct mars_bio_st {
|
||||
int type;
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl;
|
||||
int fd;
|
||||
char *host;
|
||||
char *port;
|
||||
int should_retry;
|
||||
char *mem;
|
||||
size_t mem_len;
|
||||
size_t mem_cap;
|
||||
};
|
||||
|
||||
static const SSL_METHOD g_server_method = { 1 };
|
||||
static const SSL_METHOD g_client_method = { 0 };
|
||||
static const BIO_METHOD g_mem_method = { 1 };
|
||||
static unsigned long g_last_error;
|
||||
static int g_matrixssl_opened;
|
||||
|
||||
static void set_error(SSL *ssl, int err)
|
||||
{
|
||||
if (ssl) ssl->last_error = err;
|
||||
g_last_error = (unsigned long)err;
|
||||
}
|
||||
|
||||
static char *dupstr(const char *s)
|
||||
{
|
||||
if (!s) return NULL;
|
||||
size_t n = strlen(s) + 1;
|
||||
char *p = (char *)malloc(n);
|
||||
if (p) memcpy(p, s, n);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int write_all_fd(int fd, const unsigned char *buf, int len)
|
||||
{
|
||||
int done = 0;
|
||||
while (done < len) {
|
||||
ssize_t n = send(fd, buf + done, (size_t)(len - done), 0);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
return -1;
|
||||
}
|
||||
if (n == 0) return -1;
|
||||
done += (int)n;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
static int flush_outdata(SSL *ssl)
|
||||
{
|
||||
unsigned char *buf;
|
||||
int32 len;
|
||||
if (!ssl || !ssl->ms) return -1;
|
||||
while ((len = matrixSslGetOutdata(ssl->ms, &buf)) > 0) {
|
||||
int sent = write_all_fd(ssl->fd, buf, len);
|
||||
if (sent < 0) { set_error(ssl, SSL_ERROR_SYSCALL); return -1; }
|
||||
if (matrixSslSentData(ssl->ms, (uint32)sent) < 0) {
|
||||
set_error(ssl, SSL_ERROR_SSL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int recv_into_matrix(SSL *ssl, int *out_rc)
|
||||
{
|
||||
unsigned char *buf = NULL, *pt = NULL;
|
||||
uint32 ptlen = 0;
|
||||
int32 sz = matrixSslGetReadbuf(ssl->ms, &buf);
|
||||
if (sz <= 0) { set_error(ssl, SSL_ERROR_SSL); return -1; }
|
||||
ssize_t n;
|
||||
do { n = recv(ssl->fd, buf, (size_t)sz, 0); } while (n < 0 && errno == EINTR);
|
||||
if (n == 0) { set_error(ssl, SSL_ERROR_ZERO_RETURN); return 0; }
|
||||
if (n < 0) {
|
||||
set_error(ssl, (errno == EAGAIN || errno == EWOULDBLOCK) ? SSL_ERROR_WANT_READ : SSL_ERROR_SYSCALL);
|
||||
return -1;
|
||||
}
|
||||
int32 rc = matrixSslReceivedData(ssl->ms, (uint32)n, &pt, &ptlen);
|
||||
if (rc == MATRIXSSL_APP_DATA && pt && ptlen) {
|
||||
ssl->app_ptr = pt;
|
||||
ssl->app_len = ptlen;
|
||||
ssl->app_off = 0;
|
||||
}
|
||||
*out_rc = rc;
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
static int drive_handshake(SSL *ssl, int server)
|
||||
{
|
||||
int32 rc;
|
||||
if (!ssl || !ssl->ms) return -1;
|
||||
rc = server ? MATRIXSSL_REQUEST_RECV : MATRIXSSL_REQUEST_SEND;
|
||||
for (;;) {
|
||||
if (flush_outdata(ssl) < 0) return -1;
|
||||
if (matrixSslHandshakeIsComplete(ssl->ms)) {
|
||||
ssl->handshake_done = 1;
|
||||
set_error(ssl, SSL_ERROR_NONE);
|
||||
return 1;
|
||||
}
|
||||
int rrc = 0;
|
||||
if (recv_into_matrix(ssl, &rrc) <= 0) return -1;
|
||||
rc = rrc;
|
||||
if (rc == MATRIXSSL_HANDSHAKE_COMPLETE || matrixSslHandshakeIsComplete(ssl->ms)) {
|
||||
if (flush_outdata(ssl) < 0) return -1;
|
||||
ssl->handshake_done = 1;
|
||||
set_error(ssl, SSL_ERROR_NONE);
|
||||
return 1;
|
||||
}
|
||||
if (rc == MATRIXSSL_RECEIVED_ALERT || rc == MATRIXSSL_REQUEST_CLOSE) {
|
||||
set_error(ssl, SSL_ERROR_ZERO_RETURN);
|
||||
return -1;
|
||||
}
|
||||
if (rc < 0) { set_error(ssl, SSL_ERROR_SSL); return -1; }
|
||||
}
|
||||
}
|
||||
|
||||
static int ensure_ctx_keys(SSL_CTX *ctx)
|
||||
{
|
||||
if (!ctx) return -1;
|
||||
if (ctx->keys_loaded) return 0;
|
||||
if (matrixSslNewKeys(&ctx->keys, NULL) < 0) return -1;
|
||||
if (ctx->cert_file || ctx->key_file || ctx->ca_file) {
|
||||
if (matrixSslLoadKeys(ctx->keys, ctx->cert_file, ctx->key_file, NULL, ctx->ca_file, NULL) < 0) return -1;
|
||||
}
|
||||
ctx->keys_loaded = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SSL_library_init(void)
|
||||
{
|
||||
if (!g_matrixssl_opened) {
|
||||
if (matrixSslOpen() < 0) return 0;
|
||||
g_matrixssl_opened = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SSL_load_error_strings(void) {}
|
||||
void ERR_load_BIO_strings(void) {}
|
||||
void ERR_clear_error(void) { g_last_error = 0; }
|
||||
unsigned long ERR_peek_error(void) { return g_last_error; }
|
||||
void ERR_print_errors_fp(FILE *fp)
|
||||
{
|
||||
if (!fp) fp = stderr;
|
||||
if (g_last_error) fprintf(fp, "mars-matrixssl OpenSSL-compat error %lu\n", g_last_error);
|
||||
}
|
||||
|
||||
const SSL_METHOD *TLS_server_method(void) { return &g_server_method; }
|
||||
const SSL_METHOD *SSLv23_client_method(void) { return &g_client_method; }
|
||||
|
||||
SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
{
|
||||
if (!SSL_library_init()) return NULL;
|
||||
SSL_CTX *ctx = (SSL_CTX *)calloc(1, sizeof(*ctx));
|
||||
if (!ctx) return NULL;
|
||||
ctx->server = meth ? meth->server : 0;
|
||||
ctx->min_proto = TLS1_2_VERSION;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void SSL_CTX_free(SSL_CTX *ctx)
|
||||
{
|
||||
if (!ctx) return;
|
||||
if (ctx->keys) matrixSslDeleteKeys(ctx->keys);
|
||||
free(ctx->cert_file); free(ctx->key_file); free(ctx->ca_file);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
|
||||
{
|
||||
if (!ctx) return 0;
|
||||
ctx->min_proto = version;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
if (!ctx || !file || type != SSL_FILETYPE_PEM) return 0;
|
||||
free(ctx->cert_file); ctx->cert_file = dupstr(file); ctx->keys_loaded = 0;
|
||||
return ctx->cert_file != NULL;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
if (!ctx || !file || type != SSL_FILETYPE_PEM) return 0;
|
||||
free(ctx->key_file); ctx->key_file = dupstr(file); ctx->keys_loaded = 0;
|
||||
return ctx->key_file != NULL;
|
||||
}
|
||||
|
||||
int SSL_CTX_check_private_key(const SSL_CTX *ctx)
|
||||
{
|
||||
return (ctx && ctx->cert_file && ctx->key_file) ? 1 : 0;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SSL *SSL_new(SSL_CTX *ctx)
|
||||
{
|
||||
if (!ctx) return NULL;
|
||||
SSL *ssl = (SSL *)calloc(1, sizeof(*ssl));
|
||||
if (!ssl) return NULL;
|
||||
ssl->ctx = ctx;
|
||||
ssl->fd = -1;
|
||||
return ssl;
|
||||
}
|
||||
|
||||
void SSL_free(SSL *ssl)
|
||||
{
|
||||
if (!ssl) return;
|
||||
if (ssl->ms) matrixSslDeleteSession(ssl->ms);
|
||||
if (ssl->sid) matrixSslDeleteSessionId(ssl->sid);
|
||||
free(ssl);
|
||||
}
|
||||
|
||||
int SSL_set_fd(SSL *ssl, int fd)
|
||||
{
|
||||
if (!ssl) return 0;
|
||||
ssl->fd = fd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_accept(SSL *ssl)
|
||||
{
|
||||
sslSessOpts_t opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
if (!ssl || !ssl->ctx || ssl->fd < 0) return -1;
|
||||
if (ensure_ctx_keys(ssl->ctx) < 0) { set_error(ssl, SSL_ERROR_SSL); return -1; }
|
||||
if (!ssl->ms) {
|
||||
if (matrixSslNewServerSession(&ssl->ms, ssl->ctx->keys, NULL, &opts) < 0) {
|
||||
set_error(ssl, SSL_ERROR_SSL); return -1;
|
||||
}
|
||||
}
|
||||
return drive_handshake(ssl, 1);
|
||||
}
|
||||
|
||||
int SSL_connect(SSL *ssl)
|
||||
{
|
||||
sslSessOpts_t opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
if (!ssl || !ssl->ctx || ssl->fd < 0) return -1;
|
||||
if (ensure_ctx_keys(ssl->ctx) < 0) { set_error(ssl, SSL_ERROR_SSL); return -1; }
|
||||
if (!ssl->sid && matrixSslNewSessionId(&ssl->sid, NULL) < 0) { set_error(ssl, SSL_ERROR_SSL); return -1; }
|
||||
matrixSslSessOptsSetClientTlsVersionRange(&opts, v_tls_1_2, v_tls_1_2);
|
||||
matrixSslSessOptsSetKeepPeerCerts(&opts, 1);
|
||||
if (!ssl->ms) {
|
||||
if (matrixSslNewClientSession(&ssl->ms, ssl->ctx->keys, ssl->sid, NULL, 0, NULL,
|
||||
ssl->peer_name[0] ? ssl->peer_name : NULL,
|
||||
NULL, NULL, &opts) < 0) {
|
||||
set_error(ssl, SSL_ERROR_SSL); return -1;
|
||||
}
|
||||
}
|
||||
return drive_handshake(ssl, 0);
|
||||
}
|
||||
|
||||
static int consume_pending_app(SSL *ssl, unsigned char *buf, int num)
|
||||
{
|
||||
if (!ssl->app_ptr || ssl->app_off >= ssl->app_len) return 0;
|
||||
uint32 avail = ssl->app_len - ssl->app_off;
|
||||
int take = (avail < (uint32)num) ? (int)avail : num;
|
||||
memcpy(buf, ssl->app_ptr + ssl->app_off, (size_t)take);
|
||||
ssl->app_off += (uint32)take;
|
||||
if (ssl->app_off >= ssl->app_len) {
|
||||
unsigned char *pt = NULL; uint32 ptlen = 0;
|
||||
int32 rc = matrixSslProcessedData(ssl->ms, &pt, &ptlen);
|
||||
ssl->app_ptr = NULL; ssl->app_len = ssl->app_off = 0;
|
||||
if (rc == MATRIXSSL_APP_DATA && pt && ptlen) {
|
||||
ssl->app_ptr = pt; ssl->app_len = ptlen; ssl->app_off = 0;
|
||||
}
|
||||
}
|
||||
return take;
|
||||
}
|
||||
|
||||
int SSL_read(SSL *ssl, void *buf, int num)
|
||||
{
|
||||
if (!ssl || !buf || num <= 0) return -1;
|
||||
int got = consume_pending_app(ssl, (unsigned char *)buf, num);
|
||||
if (got > 0) { set_error(ssl, SSL_ERROR_NONE); return got; }
|
||||
for (;;) {
|
||||
int rc = 0;
|
||||
int n = recv_into_matrix(ssl, &rc);
|
||||
if (n <= 0) return -1;
|
||||
if (rc == MATRIXSSL_APP_DATA) {
|
||||
got = consume_pending_app(ssl, (unsigned char *)buf, num);
|
||||
if (got > 0) { set_error(ssl, SSL_ERROR_NONE); return got; }
|
||||
} else if (rc == MATRIXSSL_REQUEST_SEND) {
|
||||
if (flush_outdata(ssl) < 0) return -1;
|
||||
} else if (rc == MATRIXSSL_RECEIVED_ALERT || rc == MATRIXSSL_REQUEST_CLOSE) {
|
||||
set_error(ssl, SSL_ERROR_ZERO_RETURN); return 0;
|
||||
} else if (rc < 0) {
|
||||
set_error(ssl, SSL_ERROR_SSL); return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SSL_write(SSL *ssl, const void *buf, int num)
|
||||
{
|
||||
if (!ssl || !buf || num <= 0) return -1;
|
||||
if (!ssl->handshake_done && drive_handshake(ssl, ssl->ctx ? ssl->ctx->server : 0) <= 0) return -1;
|
||||
if (matrixSslEncodeToOutdata(ssl->ms, (unsigned char *)buf, (uint32)num) < 0) {
|
||||
set_error(ssl, SSL_ERROR_SSL); return -1;
|
||||
}
|
||||
if (flush_outdata(ssl) < 0) return -1;
|
||||
set_error(ssl, SSL_ERROR_NONE);
|
||||
return num;
|
||||
}
|
||||
|
||||
int SSL_shutdown(SSL *ssl)
|
||||
{
|
||||
if (!ssl || !ssl->ms || ssl->close_sent) return 1;
|
||||
ssl->close_sent = 1;
|
||||
if (matrixSslEncodeClosureAlert(ssl->ms) >= 0) flush_outdata(ssl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_get_error(const SSL *ssl, int ret)
|
||||
{
|
||||
if (ret > 0) return SSL_ERROR_NONE;
|
||||
return ssl ? ssl->last_error : (int)g_last_error;
|
||||
}
|
||||
|
||||
int SSL_pending(const SSL *ssl)
|
||||
{
|
||||
if (!ssl || !ssl->app_ptr || ssl->app_off >= ssl->app_len) return 0;
|
||||
return (int)(ssl->app_len - ssl->app_off);
|
||||
}
|
||||
|
||||
long SSL_set_mode(SSL *ssl, long mode) { (void)ssl; return mode; }
|
||||
long SSL_get_verify_result(const SSL *ssl) { (void)ssl; return X509_V_OK; }
|
||||
|
||||
X509 *SSL_get_peer_certificate(const SSL *ssl)
|
||||
{
|
||||
X509 *x = (X509 *)calloc(1, sizeof(*x));
|
||||
if (!x) return NULL;
|
||||
const char *name = (ssl && ssl->peer_name[0]) ? ssl->peer_name : "matrixssl-peer";
|
||||
snprintf(x->subject.common_name, sizeof(x->subject.common_name), "%s", name);
|
||||
const char *fmt = "-----BEGIN CERTIFICATE-----\n"
|
||||
"mars-matrixssl-openssl-compat-peer=%s\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
size_t need = strlen(fmt) + strlen(name) + 1;
|
||||
x->pem = (char *)malloc(need);
|
||||
if (x->pem) snprintf(x->pem, need, fmt, name);
|
||||
return x;
|
||||
}
|
||||
|
||||
X509_NAME *X509_get_subject_name(X509 *cert) { return cert ? &cert->subject : NULL; }
|
||||
|
||||
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
|
||||
{
|
||||
if (!name || nid != NID_commonName || !buf || len <= 0) return -1;
|
||||
snprintf(buf, (size_t)len, "%s", name->common_name);
|
||||
return (int)strlen(buf);
|
||||
}
|
||||
|
||||
EVP_PKEY *X509_get_pubkey(X509 *cert)
|
||||
{
|
||||
(void)cert;
|
||||
EVP_PKEY *p = (EVP_PKEY *)calloc(1, sizeof(*p));
|
||||
if (p) p->type = EVP_PKEY_RSA;
|
||||
return p;
|
||||
}
|
||||
|
||||
void EVP_PKEY_free(EVP_PKEY *pkey) { free(pkey); }
|
||||
void X509_free(X509 *cert) { if (cert) { free(cert->pem); free(cert); } }
|
||||
|
||||
const BIO_METHOD *BIO_s_mem(void) { return &g_mem_method; }
|
||||
|
||||
BIO *BIO_new(const BIO_METHOD *method)
|
||||
{
|
||||
BIO *b = (BIO *)calloc(1, sizeof(*b));
|
||||
if (!b) return NULL;
|
||||
b->type = method ? method->type : 0;
|
||||
b->fd = -1;
|
||||
return b;
|
||||
}
|
||||
|
||||
BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
|
||||
{
|
||||
BIO *b = BIO_new(NULL);
|
||||
if (!b) return NULL;
|
||||
b->type = 2;
|
||||
b->ctx = ctx;
|
||||
b->ssl = SSL_new(ctx);
|
||||
if (!b->ssl) { free(b); return NULL; }
|
||||
return b;
|
||||
}
|
||||
|
||||
void BIO_free(BIO *bio)
|
||||
{
|
||||
if (!bio) return;
|
||||
free(bio->host); free(bio->port); free(bio->mem);
|
||||
free(bio);
|
||||
}
|
||||
|
||||
void BIO_free_all(BIO *bio)
|
||||
{
|
||||
if (!bio) return;
|
||||
if (bio->ssl) SSL_free(bio->ssl);
|
||||
if (bio->fd >= 0) close(bio->fd);
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
int BIO_get_ssl(BIO *bio, SSL **ssl)
|
||||
{
|
||||
if (!bio || !ssl) return 0;
|
||||
*ssl = bio->ssl;
|
||||
return bio->ssl ? 1 : 0;
|
||||
}
|
||||
|
||||
void BIO_set_conn_hostname(BIO *bio, const char *name)
|
||||
{
|
||||
if (!bio) return;
|
||||
free(bio->host); bio->host = dupstr(name);
|
||||
if (bio->ssl && name) snprintf(bio->ssl->peer_name, sizeof(bio->ssl->peer_name), "%s", name);
|
||||
}
|
||||
|
||||
void BIO_set_conn_port(BIO *bio, const char *port)
|
||||
{
|
||||
if (!bio) return;
|
||||
free(bio->port); bio->port = dupstr(port);
|
||||
}
|
||||
|
||||
static int tcp_connect_host(const char *host, const char *port)
|
||||
{
|
||||
struct addrinfo hints, *res = NULL, *ai;
|
||||
int fd = -1;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if (getaddrinfo(host, port ? port : "443", &hints, &res) != 0) return -1;
|
||||
for (ai = res; ai; ai = ai->ai_next) {
|
||||
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (fd < 0) continue;
|
||||
if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) break;
|
||||
close(fd); fd = -1;
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int BIO_do_connect(BIO *bio)
|
||||
{
|
||||
if (!bio || !bio->ssl || !bio->host) return -1;
|
||||
bio->fd = tcp_connect_host(bio->host, bio->port ? bio->port : "443");
|
||||
if (bio->fd < 0) return -1;
|
||||
SSL_set_fd(bio->ssl, bio->fd);
|
||||
return SSL_connect(bio->ssl);
|
||||
}
|
||||
|
||||
int BIO_read(BIO *bio, void *buf, int len)
|
||||
{
|
||||
if (!bio || !buf || len <= 0) return -1;
|
||||
if (bio->type == 2) {
|
||||
int r = SSL_read(bio->ssl, buf, len);
|
||||
bio->should_retry = (r <= 0 && bio->ssl && (bio->ssl->last_error == SSL_ERROR_WANT_READ || bio->ssl->last_error == SSL_ERROR_WANT_WRITE));
|
||||
return r;
|
||||
}
|
||||
if (bio->type == 1) {
|
||||
int take = (bio->mem_len < (size_t)len) ? (int)bio->mem_len : len;
|
||||
if (take > 0) memcpy(buf, bio->mem, (size_t)take);
|
||||
return take;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int BIO_write(BIO *bio, const void *buf, int len)
|
||||
{
|
||||
if (!bio || !buf || len <= 0) return -1;
|
||||
if (bio->type == 2) return SSL_write(bio->ssl, buf, len);
|
||||
if (bio->type == 1) {
|
||||
if (bio->mem_len + (size_t)len + 1 > bio->mem_cap) {
|
||||
size_t cap = (bio->mem_len + (size_t)len + 1) * 2;
|
||||
char *p = (char *)realloc(bio->mem, cap);
|
||||
if (!p) return -1;
|
||||
bio->mem = p; bio->mem_cap = cap;
|
||||
}
|
||||
memcpy(bio->mem + bio->mem_len, buf, (size_t)len);
|
||||
bio->mem_len += (size_t)len;
|
||||
bio->mem[bio->mem_len] = '\0';
|
||||
return len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int BIO_should_retry(BIO *bio) { return bio ? bio->should_retry : 0; }
|
||||
|
||||
long BIO_get_mem_data(BIO *bio, const char **data)
|
||||
{
|
||||
if (!bio || bio->type != 1) return 0;
|
||||
if (data) *data = bio->mem ? bio->mem : "";
|
||||
return (long)bio->mem_len;
|
||||
}
|
||||
|
||||
int PEM_write_bio_X509(BIO *bio, X509 *cert)
|
||||
{
|
||||
if (!bio || !cert) return 0;
|
||||
const char *pem = cert->pem ? cert->pem : "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n";
|
||||
return BIO_write(bio, pem, (int)strlen(pem)) > 0 ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user