зеркало из https://github.com/microsoft/msquic.git
new API for async certificate validation (#3318)
* new API for async certificate validation * Fix func pointer assignment * generate dotnet
This commit is contained in:
Родитель
da33894d0c
Коммит
97616f7601
|
@ -0,0 +1,40 @@
|
|||
ConnectionCertificateValidationComplete function
|
||||
======
|
||||
|
||||
Uses the QUIC (client) handle to complete resumption ticket validation. This must be called after client app handles certificate validation and then return QUIC_STATUS_PENDING.
|
||||
|
||||
# Syntax
|
||||
|
||||
```C
|
||||
typedef
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
(QUIC_API * QUIC_CONNECTION_COMP_CERT_FN)(
|
||||
_In_ _Pre_defensive_ HQUIC Connection,
|
||||
_In_ BOOLEAN Result
|
||||
);
|
||||
```
|
||||
|
||||
# Parameters
|
||||
|
||||
`Connection`
|
||||
|
||||
The valid handle to an open connection object.
|
||||
|
||||
`Result`
|
||||
|
||||
Ticket validation result.
|
||||
|
||||
# Return Value
|
||||
|
||||
The function returns a [QUIC_STATUS](QUIC_STATUS.md). The app may use `QUIC_FAILED` or `QUIC_SUCCEEDED` to determine if the function failed or succeeded.
|
||||
|
||||
# Remarks
|
||||
|
||||
- Available from v2.2
|
||||
|
||||
# See Also
|
||||
|
||||
[ConnectionOpen](ConnectionStart.md)<br>
|
||||
[ConnectionClose](ConnectionClose.md)<br>
|
||||
[ConnectionShutdown](ConnectionShutdown.md)<br>
|
|
@ -1721,3 +1721,77 @@ Error:
|
|||
|
||||
return Status;
|
||||
}
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
QUIC_API
|
||||
MsQuicConnectionCertificateValidationComplete(
|
||||
_In_ _Pre_defensive_ HQUIC Handle,
|
||||
_In_ BOOLEAN Result
|
||||
)
|
||||
{
|
||||
QUIC_STATUS Status;
|
||||
QUIC_CONNECTION* Connection;
|
||||
QUIC_OPERATION* Oper;
|
||||
|
||||
QuicTraceEvent(
|
||||
ApiEnter,
|
||||
"[ api] Enter %u (%p).",
|
||||
QUIC_TRACE_API_CONNECTION_COMPLETE_CERTIFICATE_VALIDATION,
|
||||
Handle);
|
||||
|
||||
if (IS_CONN_HANDLE(Handle)) {
|
||||
#pragma prefast(suppress: __WARNING_25024, "Pointer cast already validated.")
|
||||
Connection = (QUIC_CONNECTION*)Handle;
|
||||
} else if (IS_STREAM_HANDLE(Handle)) {
|
||||
#pragma prefast(suppress: __WARNING_25024, "Pointer cast already validated.")
|
||||
QUIC_STREAM* Stream = (QUIC_STREAM*)Handle;
|
||||
CXPLAT_TEL_ASSERT(!Stream->Flags.HandleClosed);
|
||||
CXPLAT_TEL_ASSERT(!Stream->Flags.Freed);
|
||||
Connection = Stream->Connection;
|
||||
} else {
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
QUIC_CONN_VERIFY(Connection, !Connection->State.Freed);
|
||||
|
||||
if (QuicConnIsServer(Connection)) {
|
||||
Status = QUIC_STATUS_INVALID_PARAMETER;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (Connection->Crypto.TlsState.HandshakeComplete) {
|
||||
Status = QUIC_STATUS_INVALID_STATE;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Oper = QuicOperationAlloc(Connection->Worker, QUIC_OPER_TYPE_API_CALL);
|
||||
if (Oper == NULL) {
|
||||
Status = QUIC_STATUS_OUT_OF_MEMORY;
|
||||
QuicTraceEvent(
|
||||
AllocFailure,
|
||||
"Allocation of '%s' failed. (%llu bytes)",
|
||||
"CONN_COMPLETE_CERTIFICATE_VALIDATION operation",
|
||||
0);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Oper->API_CALL.Context->Type = QUIC_API_TYPE_CONN_COMPLETE_CERTIFICATE_VALIDATION;
|
||||
Oper->API_CALL.Context->CONN_COMPLETE_CERTIFICATE_VALIDATION.Result = Result;
|
||||
|
||||
//
|
||||
// Queue the operation but don't wait for the completion.
|
||||
//
|
||||
QuicConnQueueOper(Connection, Oper);
|
||||
Status = QUIC_STATUS_PENDING;
|
||||
|
||||
Error:
|
||||
|
||||
QuicTraceEvent(
|
||||
ApiExitStatus,
|
||||
"[ api] Exit %u",
|
||||
Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -269,3 +269,11 @@ MsQuicConnectionResumptionTicketValidationComplete(
|
|||
_In_ _Pre_defensive_ HQUIC Handle,
|
||||
_In_ BOOLEAN Result
|
||||
);
|
||||
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
QUIC_API
|
||||
MsQuicConnectionCertificateValidationComplete(
|
||||
_In_ _Pre_defensive_ HQUIC Handle,
|
||||
_In_ BOOLEAN Result
|
||||
);
|
||||
|
|
|
@ -7313,6 +7313,13 @@ QuicConnProcessApiOperation(
|
|||
ApiCtx->CONN_COMPLETE_RESUMPTION_TICKET_VALIDATION.Result);
|
||||
break;
|
||||
|
||||
case QUIC_API_TYPE_CONN_COMPLETE_CERTIFICATE_VALIDATION:
|
||||
CXPLAT_DBG_ASSERT(QuicConnIsClient(Connection));
|
||||
QuicCryptoCustomCertValidationComplete(
|
||||
&Connection->Crypto,
|
||||
ApiCtx->CONN_COMPLETE_CERTIFICATE_VALIDATION.Result);
|
||||
break;
|
||||
|
||||
case QUIC_API_TYPE_STRM_CLOSE:
|
||||
QuicStreamClose(ApiCtx->STRM_CLOSE.Stream);
|
||||
break;
|
||||
|
|
|
@ -1669,6 +1669,7 @@ MsQuicOpenVersion(
|
|||
Api->ConnectionSetConfiguration = MsQuicConnectionSetConfiguration;
|
||||
Api->ConnectionSendResumptionTicket = MsQuicConnectionSendResumptionTicket;
|
||||
Api->ConnectionResumptionTicketValidationComplete = MsQuicConnectionResumptionTicketValidationComplete;
|
||||
Api->ConnectionCertificateValidationComplete = MsQuicConnectionCertificateValidationComplete;
|
||||
|
||||
Api->StreamOpen = MsQuicStreamOpen;
|
||||
Api->StreamClose = MsQuicStreamClose;
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef enum QUIC_API_TYPE {
|
|||
|
||||
QUIC_API_TYPE_DATAGRAM_SEND,
|
||||
QUIC_API_TYPE_CONN_COMPLETE_RESUMPTION_TICKET_VALIDATION,
|
||||
QUIC_API_TYPE_CONN_COMPLETE_CERTIFICATE_VALIDATION,
|
||||
|
||||
} QUIC_API_TYPE;
|
||||
|
||||
|
@ -119,6 +120,10 @@ typedef struct QUIC_API_CONTEXT {
|
|||
BOOLEAN Result;
|
||||
} CONN_COMPLETE_RESUMPTION_TICKET_VALIDATION;
|
||||
|
||||
struct {
|
||||
BOOLEAN Result;
|
||||
} CONN_COMPLETE_CERTIFICATE_VALIDATION;
|
||||
|
||||
struct {
|
||||
QUIC_STREAM_OPEN_FLAGS Flags;
|
||||
QUIC_STREAM_CALLBACK_HANDLER Handler;
|
||||
|
|
|
@ -2755,6 +2755,9 @@ namespace Microsoft.Quic
|
|||
|
||||
[NativeTypeName("QUIC_CONNECTION_COMP_RESUMPTION_FN")]
|
||||
internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, byte, int> ConnectionResumptionTicketValidationComplete;
|
||||
|
||||
[NativeTypeName("QUIC_CONNECTION_COMP_CERT_FN")]
|
||||
internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, byte, int> ConnectionCertificateValidationComplete;
|
||||
}
|
||||
|
||||
internal static unsafe partial class MsQuic
|
||||
|
|
|
@ -1279,6 +1279,19 @@ QUIC_STATUS
|
|||
_In_ BOOLEAN Result
|
||||
);
|
||||
|
||||
//
|
||||
// Uses the QUIC (client) handle to complete certificate validation.
|
||||
// This must be called after client app handles certificate validation
|
||||
// and then return QUIC_STATUS_PENDING.
|
||||
//
|
||||
typedef
|
||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
QUIC_STATUS
|
||||
(QUIC_API * QUIC_CONNECTION_COMP_CERT_FN)(
|
||||
_In_ _Pre_defensive_ HQUIC Connection,
|
||||
_In_ BOOLEAN Result
|
||||
);
|
||||
|
||||
//
|
||||
// Streams
|
||||
//
|
||||
|
@ -1507,6 +1520,7 @@ typedef struct QUIC_API_TABLE {
|
|||
QUIC_DATAGRAM_SEND_FN DatagramSend;
|
||||
|
||||
QUIC_CONNECTION_COMP_RESUMPTION_FN ConnectionResumptionTicketValidationComplete; // Available from v2.2
|
||||
QUIC_CONNECTION_COMP_CERT_FN ConnectionCertificateValidationComplete; // Available from v2.2
|
||||
|
||||
} QUIC_API_TABLE;
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ typedef enum QUIC_TRACE_API_TYPE {
|
|||
QUIC_TRACE_API_CONNECTION_SET_CONFIGURATION,
|
||||
QUIC_TRACE_API_CONNECTION_SEND_RESUMPTION_TICKET,
|
||||
QUIC_TRACE_API_CONNECTION_COMPLETE_RESUMPTION_TICKET_VALIDATION,
|
||||
QUIC_TRACE_API_CONNECTION_COMPLETE_CERTIFICATE_VALIDATION,
|
||||
QUIC_TRACE_API_STREAM_OPEN,
|
||||
QUIC_TRACE_API_STREAM_CLOSE,
|
||||
QUIC_TRACE_API_STREAM_START,
|
||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -1082,6 +1082,10 @@ struct ApiTable {
|
|||
connection: Handle,
|
||||
result: BOOLEAN,
|
||||
) -> u32,
|
||||
certificate_validation_complete: extern "C" fn(
|
||||
connection: Handle,
|
||||
result: BOOLEAN,
|
||||
) -> u32,
|
||||
}
|
||||
|
||||
#[link(name = "msquic")]
|
||||
|
@ -1538,6 +1542,21 @@ impl Connection {
|
|||
panic!("ticket validation completion failure 0x{:x}", status);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn certificate_validation_complete(
|
||||
&self,
|
||||
result: BOOLEAN,
|
||||
) {
|
||||
let status = unsafe {
|
||||
((*self.table).certificate_validation_complete)(
|
||||
self.handle,
|
||||
result,
|
||||
)
|
||||
};
|
||||
if Status::failed(status) {
|
||||
panic!("ticket validation completion failure 0x{:x}", status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Connection {
|
||||
|
|
|
@ -993,6 +993,7 @@ typedef enum QUIC_API_TYPE {
|
|||
|
||||
QUIC_API_TYPE_DATAGRAM_SEND,
|
||||
QUIC_API_TYPE_CONN_COMPLETE_RESUMPTION_TICKET_VALIDATION,
|
||||
QUIC_API_TYPE_CONN_COMPLETE_CERTIFICATE_VALIDATION,
|
||||
|
||||
} QUIC_API_TYPE;
|
||||
|
||||
|
@ -1036,6 +1037,8 @@ struct ApiCall : Struct {
|
|||
return "API_TYPE_DATAGRAM_SEND";
|
||||
case QUIC_API_TYPE_CONN_COMPLETE_RESUMPTION_TICKET_VALIDATION:
|
||||
return "API_TYPE_CONN_COMPLETE_RESUMPTION_TICKET_VALIDATION";
|
||||
case QUIC_API_TYPE_CONN_COMPLETE_CERTIFICATE_VALIDATION:
|
||||
return "API_TYPE_CONN_COMPLETE_CERTIFICATE_VALIDATION";
|
||||
default:
|
||||
return "INVALID API";
|
||||
}
|
||||
|
|
|
@ -751,11 +751,9 @@ TestConnection::SetCustomValidationResult(
|
|||
{
|
||||
BOOLEAN Result = AcceptCert ? TRUE : FALSE;
|
||||
return
|
||||
MsQuic->SetParam(
|
||||
MsQuic->ConnectionCertificateValidationComplete(
|
||||
QuicConnection,
|
||||
QUIC_PARAM_CONN_PEER_CERTIFICATE_VALID,
|
||||
sizeof(Result),
|
||||
&Result);
|
||||
Result);
|
||||
}
|
||||
|
||||
QUIC_STATUS
|
||||
|
|
|
@ -258,6 +258,7 @@ typedef enum {
|
|||
SpinQuicAPICallGetParamStream,
|
||||
SpinQuicAPICallDatagramSend,
|
||||
SpinQuicAPICallCompleteTicketValidation,
|
||||
SpinQuicAPICallCompleteCertificateValidation,
|
||||
SpinQuicAPICallStreamReceiveSetEnabled,
|
||||
SpinQuicAPICallStreamReceiveComplete,
|
||||
SpinQuicAPICallCount // Always the last element
|
||||
|
@ -881,6 +882,12 @@ void Spin(Gbs& Gb, LockableVector<HQUIC>& Connections, std::vector<HQUIC>* Liste
|
|||
MsQuic.ConnectionResumptionTicketValidationComplete(Connection, GetRandom(2) == 0);
|
||||
break;
|
||||
}
|
||||
case SpinQuicAPICallCompleteCertificateValidation: {
|
||||
auto Connection = Connections.TryGetRandom();
|
||||
BAIL_ON_NULL_CONNECTION(Connection);
|
||||
MsQuic.ConnectionCertificateValidationComplete(Connection, GetRandom(2) == 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче