mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Added initial support for the ssl service.
This commit is contained in:
parent
8e245a0ba8
commit
60e4ee04b0
@ -91,6 +91,7 @@ extern "C" {
|
|||||||
#include "switch/services/ts.h"
|
#include "switch/services/ts.h"
|
||||||
#include "switch/services/pm.h"
|
#include "switch/services/pm.h"
|
||||||
#include "switch/services/set.h"
|
#include "switch/services/set.h"
|
||||||
|
#include "switch/services/ssl.h"
|
||||||
#include "switch/services/lr.h"
|
#include "switch/services/lr.h"
|
||||||
#include "switch/services/spl.h"
|
#include "switch/services/spl.h"
|
||||||
#include "switch/services/ncm.h"
|
#include "switch/services/ncm.h"
|
||||||
|
407
nx/include/switch/services/ssl.h
Normal file
407
nx/include/switch/services/ssl.h
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
/**
|
||||||
|
* @file fs.h
|
||||||
|
* @brief SSL service IPC wrapper.
|
||||||
|
* @author yellows8
|
||||||
|
* @copyright libnx Authors
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include "../types.h"
|
||||||
|
#include "../sf/service.h"
|
||||||
|
|
||||||
|
/// CaCertificateId
|
||||||
|
typedef enum {
|
||||||
|
SslCaCertificateId_All = -1, ///< All
|
||||||
|
|
||||||
|
SslCaCertificateId_NintendoCAG3 = 1, ///< NintendoCAG3
|
||||||
|
SslCaCertificateId_NintendoClass2CAG3 = 2, ///< NintendoClass2CAG3
|
||||||
|
|
||||||
|
SslCaCertificateId_AmazonRootCA1 = 1000, ///< AmazonRootCA1
|
||||||
|
SslCaCertificateId_StarfieldServicesRootCertificateAuthorityG2 = 1001, ///< StarfieldServicesRootCertificateAuthorityG2
|
||||||
|
SslCaCertificateId_AddTrustExternalCARoot = 1002, ///< AddTrustExternalCARoot
|
||||||
|
SslCaCertificateId_COMODOCertificationAuthority = 1003, ///< COMODOCertificationAuthority
|
||||||
|
SslCaCertificateId_UTNDATACorpSGC = 1004, ///< UTNDATACorpSGC
|
||||||
|
SslCaCertificateId_UTNUSERFirstHardware = 1005, ///< UTNUSERFirstHardware
|
||||||
|
SslCaCertificateId_BaltimoreCyberTrustRoot = 1006, ///< BaltimoreCyberTrustRoot
|
||||||
|
SslCaCertificateId_CybertrustGlobalRoot = 1007, ///< CybertrustGlobalRoot
|
||||||
|
SslCaCertificateId_VerizonGlobalRootCA = 1008, ///< VerizonGlobalRootCA
|
||||||
|
SslCaCertificateId_DigiCertAssuredIDRootCA = 1009, ///< DigiCertAssuredIDRootCA
|
||||||
|
SslCaCertificateId_DigiCertAssuredIDRootG2 = 1010, ///< DigiCertAssuredIDRootG2
|
||||||
|
SslCaCertificateId_DigiCertGlobalRootCA = 1011, ///< DigiCertGlobalRootCA
|
||||||
|
SslCaCertificateId_DigiCertGlobalRootG2 = 1012, ///< DigiCertGlobalRootG2
|
||||||
|
SslCaCertificateId_DigiCertHighAssuranceEVRootCA = 1013, ///< DigiCertHighAssuranceEVRootCA
|
||||||
|
SslCaCertificateId_EntrustnetCertificationAuthority2048 = 1014, ///< EntrustnetCertificationAuthority2048
|
||||||
|
SslCaCertificateId_EntrustRootCertificationAuthority = 1015, ///< EntrustRootCertificationAuthority
|
||||||
|
SslCaCertificateId_EntrustRootCertificationAuthorityG2 = 1016, ///< EntrustRootCertificationAuthorityG2
|
||||||
|
SslCaCertificateId_GeoTrustGlobalCA2 = 1017, ///< GeoTrustGlobalCA2
|
||||||
|
SslCaCertificateId_GeoTrustGlobalCA = 1018, ///< GeoTrustGlobalCA
|
||||||
|
SslCaCertificateId_GeoTrustPrimaryCertificationAuthorityG3 = 1019, ///< GeoTrustPrimaryCertificationAuthorityG3
|
||||||
|
SslCaCertificateId_GeoTrustPrimaryCertificationAuthority = 1020, ///< GeoTrustPrimaryCertificationAuthority
|
||||||
|
SslCaCertificateId_GlobalSignRootCA = 1021, ///< GlobalSignRootCA
|
||||||
|
SslCaCertificateId_GlobalSignRootCAR2 = 1022, ///< GlobalSignRootCAR2
|
||||||
|
SslCaCertificateId_GlobalSignRootCAR3 = 1023, ///< GlobalSignRootCAR3
|
||||||
|
SslCaCertificateId_GoDaddyClass2CertificationAuthority = 1024, ///< GoDaddyClass2CertificationAuthority
|
||||||
|
SslCaCertificateId_GoDaddyRootCertificateAuthorityG2 = 1025, ///< GoDaddyRootCertificateAuthorityG2
|
||||||
|
SslCaCertificateId_StarfieldClass2CertificationAuthority = 1026, ///< StarfieldClass2CertificationAuthority
|
||||||
|
SslCaCertificateId_StarfieldRootCertificateAuthorityG2 = 1027, ///< StarfieldRootCertificateAuthorityG2
|
||||||
|
SslCaCertificateId_thawtePrimaryRootCAG3 = 1028, ///< thawtePrimaryRootCAG3
|
||||||
|
SslCaCertificateId_thawtePrimaryRootCA = 1029, ///< thawtePrimaryRootCA
|
||||||
|
SslCaCertificateId_VeriSignClass3PublicPrimaryCertificationAuthorityG3 = 1030, ///< VeriSignClass3PublicPrimaryCertificationAuthorityG3
|
||||||
|
SslCaCertificateId_VeriSignClass3PublicPrimaryCertificationAuthorityG5 = 1031, ///< VeriSignClass3PublicPrimaryCertificationAuthorityG5
|
||||||
|
SslCaCertificateId_VeriSignUniversalRootCertificationAuthority = 1032, ///< VeriSignUniversalRootCertificationAuthority
|
||||||
|
SslCaCertificateId_DSTRootCAX3 = 1033, ///< DSTRootCAX3
|
||||||
|
} SslCaCertificateId;
|
||||||
|
|
||||||
|
/// TrustedCertStatus
|
||||||
|
typedef enum {
|
||||||
|
SslTrustedCertStatus_Invalid = -1, ///< Invalid
|
||||||
|
SslTrustedCertStatus_Removed = 0, ///< Removed
|
||||||
|
SslTrustedCertStatus_EnabledTrusted = 1, ///< EnabledTrusted
|
||||||
|
SslTrustedCertStatus_EnabledNotTrusted = 2, ///< EnabledNotTrusted
|
||||||
|
SslTrustedCertStatus_Revoked = 3, ///< Revoked
|
||||||
|
} SslTrustedCertStatus;
|
||||||
|
|
||||||
|
/// FlushSessionCacheOptionType
|
||||||
|
typedef enum {
|
||||||
|
SslFlushSessionCacheOptionType_SingleHost = 0, ///< SingleHost. Uses the input string.
|
||||||
|
SslFlushSessionCacheOptionType_AllHosts = 1, ///< AllHosts. Doesn't use the input string.
|
||||||
|
} SslFlushSessionCacheOptionType;
|
||||||
|
|
||||||
|
/// DebugOptionType
|
||||||
|
typedef enum {
|
||||||
|
SslDebugOptionType_AllowDisableVerifyOption = 0, ///< AllowDisableVerifyOption
|
||||||
|
} SslDebugOptionType;
|
||||||
|
|
||||||
|
/// SslVersion
|
||||||
|
typedef enum {
|
||||||
|
SslVersion_Auto = 0x1, ///< Auto
|
||||||
|
SslVersion_TlsV10 = 0x8, ///< TlsV10
|
||||||
|
SslVersion_TlsV11 = 0x10, ///< TlsV11
|
||||||
|
SslVersion_TlsV12 = 0x20, ///< TlsV12
|
||||||
|
} SslVersion;
|
||||||
|
|
||||||
|
/// CertificateFormat
|
||||||
|
typedef enum {
|
||||||
|
SslCertificateFormat_Pem = 1, ///< Pem
|
||||||
|
SslCertificateFormat_Der = 2, ///< Der
|
||||||
|
} SslCertificateFormat;
|
||||||
|
|
||||||
|
/// InternalPki
|
||||||
|
typedef enum {
|
||||||
|
SslInternalPki_DeviceClientCertDefault = 1, ///< DeviceClientCertDefault
|
||||||
|
} SslInternalPki;
|
||||||
|
|
||||||
|
/// ContextOption
|
||||||
|
typedef enum {
|
||||||
|
SslContextOption_CrlImportDateCheckEnable = 1, ///< CrlImportDateCheckEnable
|
||||||
|
} SslContextOption;
|
||||||
|
|
||||||
|
/// VerifyOption
|
||||||
|
typedef enum {
|
||||||
|
SslVerifyOption_PeerCa = BIT(0), ///< PeerCa
|
||||||
|
SslVerifyOption_HostName = BIT(1), ///< HostName
|
||||||
|
SslVerifyOption_DateCheck = BIT(2), ///< DateCheck
|
||||||
|
SslVerifyOption_EvCertPartial = BIT(3), ///< EvCertPartial
|
||||||
|
SslVerifyOption_EvPolicyOid = BIT(4), ///< [6.0.0+] EvPolicyOid
|
||||||
|
SslVerifyOption_EvCertFingerprint = BIT(5), ///< [6.0.0+] EvCertFingerprint
|
||||||
|
} SslVerifyOption;
|
||||||
|
|
||||||
|
/// IoMode
|
||||||
|
typedef enum {
|
||||||
|
SslIoMode_Blocking = 1, ///< Blocking
|
||||||
|
SslIoMode_NonBlocking = 2, ///< NonBlocking
|
||||||
|
} SslIoMode;
|
||||||
|
|
||||||
|
/// PollEvent
|
||||||
|
typedef enum {
|
||||||
|
SslPollEvent_Read = BIT(0), ///< Read
|
||||||
|
SslPollEvent_Write = BIT(1), ///< Write
|
||||||
|
SslPollEvent_Except = BIT(2), ///< Except
|
||||||
|
} SslPollEvent;
|
||||||
|
|
||||||
|
/// SessionCacheMode
|
||||||
|
typedef enum {
|
||||||
|
SslSessionCacheMode_None = 0, ///< None
|
||||||
|
SslSessionCacheMode_SessionId = 1, ///< SessionId
|
||||||
|
SslSessionCacheMode_SessionTicket = 2, ///< SessionTicket
|
||||||
|
} SslSessionCacheMode;
|
||||||
|
|
||||||
|
/// RenegotiationMode
|
||||||
|
typedef enum {
|
||||||
|
SslRenegotiationMode_None = 0, ///< None
|
||||||
|
SslRenegotiationMode_Secure = 1, ///< Secure
|
||||||
|
} SslRenegotiationMode;
|
||||||
|
|
||||||
|
/// OptionType
|
||||||
|
typedef enum {
|
||||||
|
SslOptionType_DoNotCloseSocket = 0, ///< DoNotCloseSocket
|
||||||
|
SslOptionType_GetServerCertChain = 1, ///< [3.0.0+] GetServerCertChain
|
||||||
|
SslOptionType_SkipDefaultVerify = 2, ///< [5.0.0+] SkipDefaultVerify
|
||||||
|
SslOptionType_EnableAlpn = 3, ///< [9.0.0+] EnableAlpn
|
||||||
|
} SslOptionType;
|
||||||
|
|
||||||
|
/// AlpnProtoState
|
||||||
|
typedef enum {
|
||||||
|
SslAlpnProtoState_NoSupport = 0, ///< NoSupport
|
||||||
|
SslAlpnProtoState_Negotiated = 1, ///< Negotiated
|
||||||
|
SslAlpnProtoState_NoOverlap = 2, ///< NoOverlap
|
||||||
|
SslAlpnProtoState_Selected = 3, ///< Selected
|
||||||
|
SslAlpnProtoState_EarlyValue = 4, ///< EarlyValue
|
||||||
|
} SslAlpnProtoState;
|
||||||
|
|
||||||
|
/// SslContext
|
||||||
|
typedef struct {
|
||||||
|
Service s; ///< ISslContext
|
||||||
|
} SslContext;
|
||||||
|
|
||||||
|
/// SslConnection
|
||||||
|
typedef struct {
|
||||||
|
Service s; ///< ISslConnection
|
||||||
|
int sockfd; ///< sockfd returned by the SetSocketDescriptor cmd.
|
||||||
|
} SslConnection;
|
||||||
|
|
||||||
|
/// BuiltInCertificateInfo
|
||||||
|
typedef struct {
|
||||||
|
u32 cert_id; ///< CaCertificateId
|
||||||
|
u32 status; ///< \ref SslTrustedCertStatus
|
||||||
|
u64 cert_size; ///< CertificateSize
|
||||||
|
u8 *cert_data; ///< CertificateData (converted from an offset to a ptr), in DER format.
|
||||||
|
} SslBuiltInCertificateInfo;
|
||||||
|
|
||||||
|
/// Initialize ssl. A default value of 0x3 can be used for num_sessions. This must be 0x1-0x4.
|
||||||
|
Result sslInitialize(u32 num_sessions);
|
||||||
|
|
||||||
|
/// Exit ssl.
|
||||||
|
void sslExit(void);
|
||||||
|
|
||||||
|
/// Gets the Service object for the actual ssl service session.
|
||||||
|
Service* sslGetServiceSession(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CreateContext
|
||||||
|
* @param[out] c \ref SslContext
|
||||||
|
* @param[in] ssl_version \ref SslVersion
|
||||||
|
*/
|
||||||
|
Result sslCreateContext(SslContext *c, SslVersion ssl_version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetContextCount
|
||||||
|
* @note Not used by official sw.
|
||||||
|
* @param[out] out Output value.
|
||||||
|
*/
|
||||||
|
Result sslGetContextCount(u32 *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetCertificates
|
||||||
|
* @param[in] buffer Output buffer. The start of this buffer is an array of \ref SslBuiltInCertificateInfo, with the specified count. The cert data (SslBuiltInCertificateInfo::data) is located after this array.
|
||||||
|
* @param[in] size Output buffer size, this should be the size from \ref sslGetCertificateBufSize.
|
||||||
|
* @param[in] ca_cert_ids Input array of \ref SslCaCertificateId.
|
||||||
|
* @param[in] count Size of the ca_cert_ids array in entries.
|
||||||
|
*/
|
||||||
|
Result sslGetCertificates(void* buffer, u32 size, u32 *ca_cert_ids, u32 count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetCertificateBufSize
|
||||||
|
* @param[in] ca_cert_ids Input array of \ref SslCaCertificateId.
|
||||||
|
* @param[in] count Size of the ca_cert_ids array in entries.
|
||||||
|
* @param[out] out Output size.
|
||||||
|
*/
|
||||||
|
Result sslGetCertificateBufSize(u32 *ca_cert_ids, u32 count, u32 *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FlushSessionCache
|
||||||
|
* @note Only available on [5.0.0+].
|
||||||
|
* @param[in] str Input string. Must be NULL with ::SslFlushSessionCacheOptionType_AllHosts.
|
||||||
|
* @param[in] str_bufsize String buffer size, excluding NUL-terminator. Hence, this should be actual_bufsize-1. This must be 0 with ::SslFlushSessionCacheOptionType_AllHosts.
|
||||||
|
* @param[in] type \ref SslFlushSessionCacheOptionType
|
||||||
|
* @param[out] out Output value.
|
||||||
|
*/
|
||||||
|
Result sslFlushSessionCache(const char *str, size_t str_bufsize, SslFlushSessionCacheOptionType type, u32 *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetDebugOption
|
||||||
|
* @note Only available on [6.0.0+].
|
||||||
|
* @note The official impl of this doesn't actually use the cmd.
|
||||||
|
* @param[in] buffer Input buffer, must not be NULL. The u8 from here is copied to state.
|
||||||
|
* @param[in] size Buffer size, must not be 0.
|
||||||
|
* @param[in] type \ref SslDebugOptionType
|
||||||
|
*/
|
||||||
|
Result sslSetDebugOption(const void* buffer, size_t size, SslDebugOptionType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetDebugOption
|
||||||
|
* @note Only available on [6.0.0+].
|
||||||
|
* @param[out] buffer Output buffer, must not be NULL. An u8 is written here loaded from state.
|
||||||
|
* @param[in] size Buffer size, must not be 0.
|
||||||
|
* @param[in] type \ref SslDebugOptionType
|
||||||
|
*/
|
||||||
|
Result sslGetDebugOption(void* buffer, size_t size, SslDebugOptionType type);
|
||||||
|
|
||||||
|
///@name ISslContext
|
||||||
|
///@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes a Context object.
|
||||||
|
* @param c \ref SslContext
|
||||||
|
*/
|
||||||
|
void sslContextClose(SslContext *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetOption
|
||||||
|
* @note Prior to 4.x this is stubbed.
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] option \ref SslContextOption
|
||||||
|
* @param[in] value Value to set. With ::SslContextOption_CrlImportDateCheckEnable, this must be 0 or 1.
|
||||||
|
*/
|
||||||
|
Result sslContextSetOption(SslContext *c, SslContextOption option, s32 value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetOption
|
||||||
|
* @note Prior to 4.x this is stubbed.
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] option \ref SslContextOption
|
||||||
|
* @param[out] out Output value.
|
||||||
|
*/
|
||||||
|
Result sslContextGetOption(SslContext *c, SslContextOption option, s32 *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CreateConnection
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[out] conn Output \ref SslConnection.
|
||||||
|
*/
|
||||||
|
Result sslContextCreateConnection(SslContext *c, SslConnection *conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetConnectionCount
|
||||||
|
* @note Not used by official sw.
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[out] out Output value.
|
||||||
|
*/
|
||||||
|
Result sslContextGetConnectionCount(SslContext *c, u32 *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ImportServerPki
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] buffer Input buffer, must not be NULL.
|
||||||
|
* @param[in] size Input buffer size.
|
||||||
|
* @param[in] format \ref SslCertificateFormat
|
||||||
|
* @param[out] id Output Id.
|
||||||
|
*/
|
||||||
|
Result sslContextImportServerPki(SslContext *c, const void* buffer, u32 size, SslCertificateFormat format, u64 *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ImportClientPki
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] buf0 First input buffer, must not be NULL.
|
||||||
|
* @param[in] size0 First input buffer size.
|
||||||
|
* @param[in] buf1 Second input buffer, this can only be NULL if size1 is 0.
|
||||||
|
* @param[in] size1 Second input buffer size, this can only be 0 if buf1 is NULL.
|
||||||
|
* @param[out] id Output Id.
|
||||||
|
*/
|
||||||
|
Result sslContextImportClientPki(SslContext *c, const void* buf0, u32 size0, const void* buf1, u32 size1, u64 *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove the specified *Pki, or on [3.0.0+] Crl.
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] id Id
|
||||||
|
*/
|
||||||
|
Result sslContextRemovePki(SslContext *c, u64 id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RegisterInternalPki
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] internal_pki \ref SslInternalPki
|
||||||
|
* @param[out] id Output Id.
|
||||||
|
*/
|
||||||
|
Result sslContextRegisterInternalPki(SslContext *c, SslInternalPki internal_pki, u64 *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AddPolicyOid
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] str Input string.
|
||||||
|
* @param[in] str_bufsize String buffer size, excluding NUL-terminator. Hence, this should be actual_bufsize-1. This must not be >0xff.
|
||||||
|
*/
|
||||||
|
Result sslContextAddPolicyOid(SslContext *c, const char* str, u32 str_bufsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ImportCrl
|
||||||
|
* @note Only available on [3.0.0+].
|
||||||
|
* @param c \ref SslContext
|
||||||
|
* @param[in] buffer Input buffer, must not be NULL.
|
||||||
|
* @param[in] size Input buffer size.
|
||||||
|
* @param[out] id Output Id.
|
||||||
|
*/
|
||||||
|
Result sslContextImportCrl(SslContext *c, const void* buffer, u32 size, u64 *id);
|
||||||
|
|
||||||
|
///@}
|
||||||
|
|
||||||
|
///@name ISslConnection
|
||||||
|
///@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes a Connection object.
|
||||||
|
* @note This will use close() with the sockfd previously set by \ref sslConnectionSetSocketDescriptor if needed, hence sockets must have been initialized prior to using this.
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
*/
|
||||||
|
void sslConnectionClose(SslConnection *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetSocketDescriptor
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[in] sockfd sockfd
|
||||||
|
*/
|
||||||
|
Result sslConnectionSetSocketDescriptor(SslConnection *c, int sockfd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetHostName
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[in] str Input string.
|
||||||
|
* @param[in] str_bufsize String buffer size. This must not be >0xff.
|
||||||
|
*/
|
||||||
|
Result sslConnectionSetHostName(SslConnection *c, const char* str, u32 str_bufsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetVerifyOption
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[in] verify_option Input bitmask of \ref SslVerifyOption.
|
||||||
|
*/
|
||||||
|
Result sslConnectionSetVerifyOption(SslConnection *c, u32 verify_option);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetIoMode
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[in] mode \ref SslIoMode
|
||||||
|
*/
|
||||||
|
Result sslConnectionSetIoMode(SslConnection *c, SslIoMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetSocketDescriptor
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[out] sockfd Output sockfd.
|
||||||
|
*/
|
||||||
|
Result sslConnectionGetSocketDescriptor(SslConnection *c, int *sockfd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GetHostName
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[out] str Output string buffer.
|
||||||
|
* @param[in] str_bufsize String buffer size, must be large enough for the entire output string.
|
||||||
|
* @param[out] out Output string length.
|
||||||
|
*/
|
||||||
|
Result sslConnectionGetHostName(SslConnection *c, char* str, u32 str_bufsize, u32 *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetSessionCacheMode
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[in] mode \ref SslSessionCacheMode
|
||||||
|
*/
|
||||||
|
Result sslConnectionSetSessionCacheMode(SslConnection *c, SslSessionCacheMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SetRenegotiationMode
|
||||||
|
* @param c \ref SslConnection
|
||||||
|
* @param[in] mode \ref SslRenegotiationMode
|
||||||
|
*/
|
||||||
|
Result sslConnectionSetRenegotiationMode(SslConnection *c, SslRenegotiationMode mode);
|
||||||
|
|
||||||
|
///@}
|
||||||
|
|
496
nx/source/services/ssl.c
Normal file
496
nx/source/services/ssl.c
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "service_guard.h"
|
||||||
|
#include "sf/sessionmgr.h"
|
||||||
|
#include "runtime/hosversion.h"
|
||||||
|
#include "services/ssl.h"
|
||||||
|
|
||||||
|
static Service g_sslSrv;
|
||||||
|
static SessionMgr g_sslSessionMgr;
|
||||||
|
|
||||||
|
static Result _sslSetInterfaceVersion(u32 version);
|
||||||
|
|
||||||
|
NX_INLINE bool _sslObjectIsChild(Service* s)
|
||||||
|
{
|
||||||
|
return s->session == g_sslSrv.session;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _sslObjectClose(Service* s) {
|
||||||
|
if (!_sslObjectIsChild(s)) {
|
||||||
|
serviceClose(s);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int slot = sessionmgrAttachClient(&g_sslSessionMgr);
|
||||||
|
uint32_t object_id = serviceGetObjectId(s);
|
||||||
|
serviceAssumeDomain(s);
|
||||||
|
cmifMakeCloseRequest(armGetTls(), object_id);
|
||||||
|
svcSendSyncRequest(sessionmgrGetClientSession(&g_sslSessionMgr, slot));
|
||||||
|
sessionmgrDetachClient(&g_sslSessionMgr, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NX_INLINE Result _sslObjectDispatchImpl(
|
||||||
|
Service* s, u32 request_id,
|
||||||
|
const void* in_data, u32 in_data_size,
|
||||||
|
void* out_data, u32 out_data_size,
|
||||||
|
SfDispatchParams disp
|
||||||
|
) {
|
||||||
|
int slot = -1;
|
||||||
|
if (_sslObjectIsChild(s)) {
|
||||||
|
slot = sessionmgrAttachClient(&g_sslSessionMgr);
|
||||||
|
if (slot < 0) __builtin_unreachable();
|
||||||
|
disp.target_session = sessionmgrGetClientSession(&g_sslSessionMgr, slot);
|
||||||
|
serviceAssumeDomain(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc = serviceDispatchImpl(s, request_id, in_data, in_data_size, out_data, out_data_size, disp);
|
||||||
|
|
||||||
|
if (slot >= 0) {
|
||||||
|
sessionmgrDetachClient(&g_sslSessionMgr, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _sslObjectDispatch(_s,_rid,...) \
|
||||||
|
_sslObjectDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define _sslObjectDispatchIn(_s,_rid,_in,...) \
|
||||||
|
_sslObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define _sslObjectDispatchOut(_s,_rid,_out,...) \
|
||||||
|
_sslObjectDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define _sslObjectDispatchInOut(_s,_rid,_in,_out,...) \
|
||||||
|
_sslObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
NX_GENERATE_SERVICE_GUARD_PARAMS(ssl, (u32 num_sessions), (num_sessions));
|
||||||
|
|
||||||
|
Result _sslInitialize(u32 num_sessions) {
|
||||||
|
if (num_sessions > 4)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
Result rc = smGetService(&g_sslSrv, "ssl");
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
rc = serviceConvertToDomain(&g_sslSrv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hosversionAtLeast(3,0,0)) {
|
||||||
|
u32 version = 0x1;
|
||||||
|
|
||||||
|
if (hosversionAtLeast(5,0,0))
|
||||||
|
version = 0x2;
|
||||||
|
if (hosversionAtLeast(6,0,0))
|
||||||
|
version = 0x3;
|
||||||
|
|
||||||
|
rc = _sslSetInterfaceVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = sessionmgrCreate(&g_sslSessionMgr, g_sslSrv.session, num_sessions);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sslCleanup(void) {
|
||||||
|
// Close extra sessions
|
||||||
|
sessionmgrClose(&g_sslSessionMgr);
|
||||||
|
|
||||||
|
// We can't assume g_sslSrv is a domain here because serviceConvertToDomain might have failed
|
||||||
|
serviceClose(&g_sslSrv);
|
||||||
|
}
|
||||||
|
|
||||||
|
Service* sslGetServiceSession(void) {
|
||||||
|
return &g_sslSrv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _sslCmdInU32NoOut(Service* srv, u32 inval, u32 cmd_id) {
|
||||||
|
return _sslObjectDispatchIn(srv, cmd_id, inval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _sslCmdNoInOutU32(Service* srv, u32 *out, u32 cmd_id) {
|
||||||
|
return _sslObjectDispatchOut(srv, cmd_id, *out);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslCreateContext(SslContext *c, SslVersion ssl_version) {
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
u32 ssl_version;
|
||||||
|
u32 pad;
|
||||||
|
u64 pid_placeholder;
|
||||||
|
} in = { ssl_version, 0, 0 };
|
||||||
|
|
||||||
|
return _sslObjectDispatchIn(&g_sslSrv, 0, in,
|
||||||
|
.in_send_pid = true,
|
||||||
|
.out_num_objects = 1,
|
||||||
|
.out_objects = &c->s,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslGetContextCount(u32 *out) {
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdNoInOutU32(&g_sslSrv, out, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _sslGetCertificates(void* buffer, u32 size, u32 *ca_cert_ids, u32 count, u32 *out) {
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (hosversionBefore(3,0,0)) {
|
||||||
|
Result rc = _sslObjectDispatch(&g_sslSrv, 2,
|
||||||
|
.buffer_attrs = {
|
||||||
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
|
||||||
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
|
||||||
|
},
|
||||||
|
.buffers = {
|
||||||
|
{ buffer, size },
|
||||||
|
{ ca_cert_ids, count*sizeof(*ca_cert_ids) },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (R_SUCCEEDED(rc) && out) *out = count;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _sslObjectDispatchOut(&g_sslSrv, 2, *out,
|
||||||
|
.buffer_attrs = {
|
||||||
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_Out,
|
||||||
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
|
||||||
|
},
|
||||||
|
.buffers = {
|
||||||
|
{ buffer, size },
|
||||||
|
{ ca_cert_ids, count*sizeof(*ca_cert_ids) },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslGetCertificates(void* buffer, u32 size, u32 *ca_cert_ids, u32 count) {
|
||||||
|
if (buffer==NULL || !size || ca_cert_ids==NULL || !count)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
u32 out_count=0;
|
||||||
|
Result rc = _sslGetCertificates(buffer, size, ca_cert_ids, count, &out_count);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
SslBuiltInCertificateInfo *certs = (SslBuiltInCertificateInfo*)buffer;
|
||||||
|
for (u32 i=0; i<out_count; i++) {
|
||||||
|
// sdknso doesn't check this.
|
||||||
|
if ((uintptr_t)certs[i].cert_data >= (uintptr_t)size || certs[i].cert_size >= size || (uintptr_t)certs[i].cert_data + (uintptr_t)certs[i].cert_size > (uintptr_t)size)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen);
|
||||||
|
|
||||||
|
certs[i].cert_data+= (uintptr_t)buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslGetCertificateBufSize(u32 *ca_cert_ids, u32 count, u32 *out) {
|
||||||
|
if (ca_cert_ids==NULL || !count)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslObjectDispatchOut(&g_sslSrv, 3, *out,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { ca_cert_ids, count*sizeof(*ca_cert_ids) } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _sslSetInterfaceVersion(u32 version) { // [3.0.0+]
|
||||||
|
serviceAssumeDomain(&g_sslSrv);
|
||||||
|
return serviceDispatchIn(&g_sslSrv, 5, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result _sslFlushSessionCache(const char *str, size_t str_size, u32 type, u32 *out) {
|
||||||
|
if (hosversionBefore(5,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslObjectDispatchInOut(&g_sslSrv, 6, type, *out,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { str, str_size } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslFlushSessionCache(const char *str, size_t str_bufsize, SslFlushSessionCacheOptionType type, u32 *out) {
|
||||||
|
size_t str_size=0;
|
||||||
|
if (out) *out = 0;
|
||||||
|
|
||||||
|
if (type == SslFlushSessionCacheOptionType_SingleHost) {
|
||||||
|
if (str==NULL)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
str_size = strnlen(str, str_bufsize);
|
||||||
|
|
||||||
|
if (!str_size)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
str_size++;
|
||||||
|
}
|
||||||
|
else if (type == SslFlushSessionCacheOptionType_AllHosts) {
|
||||||
|
if (str || str_bufsize)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _sslFlushSessionCache(str, str_size, type, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslSetDebugOption(const void* buffer, size_t size, SslDebugOptionType type) {
|
||||||
|
if (hosversionBefore(6,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (buffer==NULL)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
u32 tmp=type;
|
||||||
|
return _sslObjectDispatchIn(&g_sslSrv, 7, tmp,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { buffer, size } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslGetDebugOption(void* buffer, size_t size, SslDebugOptionType type) {
|
||||||
|
if (hosversionBefore(6,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
if (!serviceIsActive(&g_sslSrv))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
u32 tmp=type;
|
||||||
|
return _sslObjectDispatchIn(&g_sslSrv, 8, tmp,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||||
|
.buffers = { { buffer, size } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISslContext
|
||||||
|
|
||||||
|
void sslContextClose(SslContext *c) {
|
||||||
|
_sslObjectClose(&c->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextSetOption(SslContext *c, SslContextOption option, s32 value) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
u32 option;
|
||||||
|
s32 value;
|
||||||
|
} in = { option, value };
|
||||||
|
|
||||||
|
return _sslObjectDispatchIn(&c->s, 0, in);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextGetOption(SslContext *c, SslContextOption option, s32 *out) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
u32 tmp=option;
|
||||||
|
return _sslObjectDispatchInOut(&c->s, 1, tmp, *out);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextCreateConnection(SslContext *c, SslConnection *conn) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
memset(conn, 0, sizeof(*conn));
|
||||||
|
conn->sockfd = -1;
|
||||||
|
|
||||||
|
return _sslObjectDispatch(&c->s, 2,
|
||||||
|
.out_num_objects = 1,
|
||||||
|
.out_objects = &conn->s,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextGetConnectionCount(SslContext *c, u32 *out) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdNoInOutU32(&c->s, out, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextImportServerPki(SslContext *c, const void* buffer, u32 size, SslCertificateFormat format, u64 *id) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (buffer==NULL)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
u32 tmp = format;
|
||||||
|
return _sslObjectDispatchInOut(&c->s, 4, tmp, *id,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { buffer, size } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextImportClientPki(SslContext *c, const void* buf0, u32 size0, const void* buf1, u32 size1, u64 *id) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (buf0==NULL || (buf1==NULL && size1) || (buf1!=NULL && !size1))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
return _sslObjectDispatchOut(&c->s, 5, *id,
|
||||||
|
.buffer_attrs = {
|
||||||
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
|
||||||
|
SfBufferAttr_HipcMapAlias | SfBufferAttr_In,
|
||||||
|
},
|
||||||
|
.buffers = {
|
||||||
|
{ buf0, size0 },
|
||||||
|
{ buf1, size1 },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextRemovePki(SslContext *c, u64 id) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
Result rc=0;
|
||||||
|
u32 cnt = hosversionBefore(3,0,0) ? 2 : 3;
|
||||||
|
|
||||||
|
for (u32 i=0; i<cnt; i++) {
|
||||||
|
u32 cmd_id=0;
|
||||||
|
if (i==0)
|
||||||
|
cmd_id = 6; // RemoveServerPki
|
||||||
|
else if (i==1)
|
||||||
|
cmd_id = 7; // RemoveClientPki
|
||||||
|
else if (i==2)
|
||||||
|
cmd_id = 11; // RemoveCrl
|
||||||
|
|
||||||
|
rc = _sslObjectDispatchIn(&c->s, cmd_id, id);
|
||||||
|
|
||||||
|
if (i<2 && R_VALUE(rc) != MAKERESULT(123, 214)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextRegisterInternalPki(SslContext *c, SslInternalPki internal_pki, u64 *id) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
u32 tmp = internal_pki;
|
||||||
|
return _sslObjectDispatchInOut(&c->s, 8, tmp, *id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextAddPolicyOid(SslContext *c, const char* str, u32 str_bufsize) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (str==NULL || str_bufsize > 0xff)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
return _sslObjectDispatch(&c->s, 9,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { str, str_bufsize } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslContextImportCrl(SslContext *c, const void* buffer, u32 size, u64 *id) {
|
||||||
|
if (hosversionBefore(3,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (buffer==NULL)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
return _sslObjectDispatchOut(&c->s, 10, *id,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { buffer, size } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISslConnection
|
||||||
|
|
||||||
|
void sslConnectionClose(SslConnection *c) {
|
||||||
|
if (c->sockfd >= 0) close(c->sockfd);
|
||||||
|
_sslObjectClose(&c->s);
|
||||||
|
|
||||||
|
memset(c, 0, sizeof(*c));
|
||||||
|
c->sockfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionSetSocketDescriptor(SslConnection *c, int sockfd) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslObjectDispatchInOut(&c->s, 0, sockfd, c->sockfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionSetHostName(SslConnection *c, const char* str, u32 str_bufsize) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (str==NULL)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
return _sslObjectDispatch(&c->s, 1,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||||
|
.buffers = { { str, str_bufsize } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionSetVerifyOption(SslConnection *c, u32 verify_option) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdInU32NoOut(&c->s, verify_option, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionSetIoMode(SslConnection *c, SslIoMode mode) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdInU32NoOut(&c->s, mode, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionGetSocketDescriptor(SslConnection *c, int *sockfd) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdNoInOutU32(&c->s, (u32*)sockfd, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionGetHostName(SslConnection *c, char* str, u32 str_bufsize, u32 *out) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
if (str==NULL)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
|
return _sslObjectDispatchOut(&c->s, 5, *out,
|
||||||
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||||
|
.buffers = { { str, str_bufsize } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionSetSessionCacheMode(SslConnection *c, SslSessionCacheMode mode) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdInU32NoOut(&c->s, mode, 17);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result sslConnectionSetRenegotiationMode(SslConnection *c, SslRenegotiationMode mode) {
|
||||||
|
if (!serviceIsActive(&c->s))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
|
return _sslCmdInU32NoOut(&c->s, mode, 20);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user