6.2 Appendix A.2: Kerberos.IDL

The full syntax of the Kerberos message types IDL is as follows:

 import "ms-dtyp.idl";
  
 #include "ms-rdpear_remoteguardcallids.h"
  
 // Various types used by the Input/Output structs futher down below
 typedef LONG64 KEY_AGREEMENT_HANDLE;
  
 typedef LONG KERBERR, *PKERBERR; // [RFC4120], section 7.5.9
  
 static const KEY_AGREEMENT_HANDLE KEY_AGREEMENT_HANDLE_INVALID = -1;
  
 typedef struct _KERB_ASN1_DATA {
     ULONG Pdu;
     ULONG32 Length;
     [size_is(Length)] PUCHAR Asn1Buffer;
 } KERB_ASN1_DATA;
  
 typedef struct _KERB_RPC_OCTET_STRING {
     ULONG length;
     [size_is(length)] PUCHAR value;
 } KERB_RPC_OCTET_STRING;
  
 typedef struct _KERB_RPC_INTERNAL_NAME {
     SHORT NameType;
     USHORT NameCount;
     [size_is(NameCount)] RPC_UNICODE_STRING* Names;
 } KERB_RPC_INTERNAL_NAME;
  
 typedef struct _KERB_RPC_PA_DATA
 {
     INT32 preauth_data_type;
     KERB_RPC_OCTET_STRING preauth_data;
 } KERB_RPC_PA_DATA;
  
 typedef struct _KERB_RPC_CRYPTO_API_BLOB
 {
     DWORD cbData;
     [size_is(cbData)] PBYTE pbData;
 } KERB_RPC_CRYPTO_API_BLOB;
 
 typedef struct _SECPKG_SUPPLEMENTAL_CRED {
     RPC_UNICODE_STRING PackageName;
     ULONG CredentialSize;
     [size_is(CredentialSize)] PUCHAR Credentials;
 } SECPKG_SUPPLEMENTAL_CRED, *PSECPKG_SUPPLEMENTAL_CRED;
  
 typedef struct _SECPKG_SUPPLEMENTAL_CRED_ARRAY {
     ULONG CredentialCount;
     [size_is(CredentialCount)] SECPKG_SUPPLEMENTAL_CRED Credentials[*];
 } SECPKG_SUPPLEMENTAL_CRED_ARRAY, *PSECPKG_SUPPLEMENTAL_CRED_ARRAY;
  
 typedef struct _KERB_RPC_ENCRYPTION_KEY {
     void* reserved1;
     long reserved2;
     KERB_RPC_OCTET_STRING reserved3;
 } KERB_RPC_ENCRYPTION_KEY, *PKERB_RPC_ENCRYPTION_KEY;
  
 // Objects of this type encapsulate input parameters for a remote Kerberos
 // credential isolation server. Optional values, which may be null, are indicated
 // with a trailing “optional” comment.
 typedef struct _KerbCredIsoRemoteInput
 {
     // CallId determines the call being sent over the wire.
     RemoteGuardCallId CallId;
  
     // Input paramters are held in a union so that each call can be sent
     // over the wire in the same type of KerbCredIsoRemoteInput structure.
     [switch_type(RemoteGuardCallId), switch_is(CallId)] union
     {
         [case(RemoteCallKerbNegotiateVersion)] struct
         {
             ULONG MaxSupportedVersion;
         } NegotiateVersion;
  
         // Create an AS_REQ message authenticator.
         [case(RemoteCallKerbBuildAsReqAuthenticator)] struct
         {
             KERB_RPC_ENCRYPTION_KEY* EncryptionKey;
             KERB_RPC_ENCRYPTION_KEY* ArmorKey; // optional
             PLARGE_INTEGER TimeSkew;
         } BuildAsReqAuthenticator;
  
         // Verify that the given service ticket is valid within the given skew.
         // The encrypted part of the reply data is decrypted for the caller.
         [case(RemoteCallKerbVerifyServiceTicket)] struct
         {
             KERB_ASN1_DATA* PackedTicket;
             KERB_RPC_ENCRYPTION_KEY* ServiceKey;
             PLARGE_INTEGER TimeSkew; // optional
         } VerifyServiceTicket;
  
         // Create an authenticator for an KRB_AP_REQ message.
         [case(RemoteCallKerbCreateApReqAuthenticator)] struct
         {
             KERB_RPC_ENCRYPTION_KEY* EncryptionKey;
             ULONG SequenceNumber;
             KERB_RPC_INTERNAL_NAME* ClientName;
             PRPC_UNICODE_STRING ClientRealm;
             PLARGE_INTEGER SkewTime;
             KERB_RPC_ENCRYPTION_KEY* SubKey; // optional
             KERB_ASN1_DATA* AuthData; // optional
             KERB_ASN1_DATA* GssChecksum; // optional
             ULONG KeyUsage;
         } CreateApReqAuthenticator;
  
         // Decrypt the encrypted part of an AP_REP.
         [case(RemoteCallKerbDecryptApReply)] struct
         {
             KERB_ASN1_DATA* EncryptedReply;
             KERB_RPC_ENCRYPTION_KEY* Key;
         } DecryptApReply;
  
         // Decrypt the encrypted part of a KRB_KDC_REP from the KDC. The type
         // of reply is indicated by the PDU – either encrypted AS_REPLY PDU or 
         // encrypted TGS_REPLY PDU. Key usage allows the caller to specify either the
         // TGS or AS REP key derivation types. This is done to allow back-compatibility
         // with a previous server release which returned the wrong PDU for an AS_REP. 
         [case(RemoteCallKerbUnpackKdcReplyBody)] struct
         {
             KERB_ASN1_DATA* EncryptedData;
             KERB_RPC_ENCRYPTION_KEY* Key;
             KERB_RPC_ENCRYPTION_KEY* StrengthenKey;
             ULONG Pdu;
             ULONG KeyUsage;
         } UnpackKdcReplyBody;
  
         // Calculate the MAC for a KRB_TGS_REQ. In RFC 4120 it is referred
         // to as a "Checksum" and thus the terminology is maintained.
         [case(RemoteCallKerbComputeTgsChecksum)] struct
         {
             KERB_ASN1_DATA* RequestBody;
             KERB_RPC_ENCRYPTION_KEY* Key;
             ULONG ChecksumType;
         } ComputeTgsChecksum;
  
         // Encrypt the given authorization data which is to be included 
         // within the request body of a message to be sent to the KDC.
         [case(RemoteCallKerbBuildEncryptedAuthData)] struct
         {
             ULONG KeyUsage;
             KERB_RPC_ENCRYPTION_KEY* Key;
             KERB_ASN1_DATA* PlainAuthData;
         } BuildEncryptedAuthData;
  
         // Pack up and encrypt a KRB_AP_REP message using the given session key.
         [case(RemoteCallKerbPackApReply)] struct
         {
             KERB_ASN1_DATA* Reply;
             KERB_ASN1_DATA* ReplyBody;
             KERB_RPC_ENCRYPTION_KEY* SessionKey;
         } PackApReply;
  
         // Create a MAC for S4U pre-authentication data to be include in a KRB_TGS_REQ
         // when requesting an S4U service ticket for another principal.
         [case(RemoteCallKerbHashS4UPreauth)] struct
         {
             KERB_ASN1_DATA* S4UPreauth;
             KERB_RPC_ENCRYPTION_KEY* Key;
             LONG ChecksumType;
         } HashS4UPreauth;
  
         // Create a MAC for S4U pre-authentication data that is for
         // certificate-based users. This pa-data is added to KRB_TGS_REQ 
         // when requesting anS4U service ticket.
         [case(RemoteCallKerbSignS4UPreauthData)] struct
         {
             KERB_RPC_ENCRYPTION_KEY* Key;
             BOOL IsRequest;
             KERB_ASN1_DATA* UserId;
             PLONG ChecksumType;
         } SignS4UPreauthData;
  
         // Calculate a MAC from the given data and compare it to the given expected
         // value. Used to detect mismatches which may indicate tampering with 
         // the PAC which is sent by the KDC to the client inside a KRB_KDC_REP.
         [case(RemoteCallKerbVerifyChecksum)] struct
         {
             KERB_RPC_ENCRYPTION_KEY* Key;
             ULONG ChecksumType;
             ULONG ExpectedChecksumSize;
             [size_is(ExpectedChecksumSize)] const UCHAR* ExpectedChecksum;
             ULONG DataToCheckSize;
             [size_is(DataToCheckSize)] const UCHAR* DataToCheck;
         } VerifyChecksum;
 
         // Decrypt the supplemental credentials which are contained
         // with the PAC sent back by the KDC in a KRB_KDC_REP.
         [case(RemoteCallKerbDecryptPacCredentials)] struct
         {
             KERB_RPC_ENCRYPTION_KEY* Key;
             ULONG Version;
             ULONG EncryptionType;
             ULONG DataSize;
             [size_is(DataSize)] UCHAR* Data;
         } DecryptPacCredentials;
  
         // Create a new ECDH key agreement handle with the given ECC key bit length
         [case(RemoteCallKerbCreateECDHKeyAgreement)] struct
         {
             ULONG KeyBitLen;
         } CreateECDHKeyAgreement;
  
         [case(RemoteCallKerbCreateDHKeyAgreement)] struct
         {
             // This [case(RemoteCallKerb)] struct has no input parameters, but for 
             // simplicity and consistency with the other parameters, let's define
             // this as a [case(RemoteCallKerb)] struct with a single ignored value.
             UCHAR Ignored;
         } CreateDHKeyAgreement;
  
         // Destroy a key agreement handle which was previously constructed
         // with either CreateECDHKeyAgreement or CreateDHKeyAgreement.
         [case(RemoteCallKerbDestroyKeyAgreement)] struct
         {
             KEY_AGREEMENT_HANDLE KeyAgreementHandle;
         } DestroyKeyAgreement;
  
         // Generate a nonce for use with the given key agreement. This nonce is part 
         // of the Diffie-Hellman agreement that is part of Kerberos PKINIT (RFC 4556)
         [case(RemoteCallKerbKeyAgreementGenerateNonce)] struct
         {
             KEY_AGREEMENT_HANDLE KeyAgreementHandle;
         } KeyAgreementGenerateNonce;
  
         // Finish a Kerberos PKINIT (RFC 4556) key agreement.
         [case(RemoteCallKerbFinalizeKeyAgreement)] struct
         {
             KEY_AGREEMENT_HANDLE* KeyAgreementHandle;
             ULONG KerbEType;
             ULONG RemoteNonceLen;
             [size_is(RemoteNonceLen)] PBYTE RemoteNonce;
             ULONG X509PublicKeyLen;
             [size_is(X509PublicKeyLen)] PBYTE X509PublicKey;
         } FinalizeKeyAgreement;
     };
 } KerbCredIsoRemoteInput, *PKerbCredIsoRemoteInput;
  
 // Objects of this type contain the output which corresponds to one of the 
 // inputs from the above KerbCredIsoRemoteInput structure. Please see the
 // input type in the above union for an explanation of the call.
 typedef struct _KerbCredIsoRemoteOutput
 {
     RemoteGuardCallId CallId;
     NTSTATUS Status;
     [switch_type(RemoteGuardCallId), switch_is(CallId)] union
     {
         [case(RemoteCallKerbNegotiateVersion)] struct
         {
             ULONG VersionToUse;
         } NegotiateVersion;
  
         [case(RemoteCallKerbBuildAsReqAuthenticator)] struct
         {
             LONG PreauthDataType;
             KERB_RPC_OCTET_STRING PreauthData;
         } BuildAsReqAuthenticator;
  
         [case(RemoteCallKerbVerifyServiceTicket)] struct
         {
             KERB_ASN1_DATA DecryptedTicket;
             LONG KerbProtocolError;
         } VerifyServiceTicket;
  
         [case(RemoteCallKerbCreateApReqAuthenticator)] struct
         {
             LARGE_INTEGER AuthenticatorTime;
             KERB_ASN1_DATA Authenticator;
             LONG KerbProtocolError;
         } CreateApReqAuthenticator;
  
         [case(RemoteCallKerbDecryptApReply)] struct
         {
             KERB_ASN1_DATA ApReply;
         } DecryptApReply;
  
         [case(RemoteCallKerbUnpackKdcReplyBody)] struct
         {
             LONG KerbProtocolError;
             KERB_ASN1_DATA ReplyBody;
         } UnpackKdcReplyBody;
  
         [case(RemoteCallKerbComputeTgsChecksum)] struct
         {
             KERB_ASN1_DATA Checksum;
         } ComputeTgsChecksum;
  
         [case(RemoteCallKerbBuildEncryptedAuthData)] struct
         {
             KERB_ASN1_DATA EncryptedAuthData;
         } BuildEncryptedAuthData;
  
         [case(RemoteCallKerbPackApReply)] struct
         {
             ULONG PackedReplySize;
             [size_is(PackedReplySize)] PUCHAR PackedReply;
         } PackApReply;
  
         [case(RemoteCallKerbHashS4UPreauth)] struct
         {
             PULONG ChecksumSize;
             [size_is(, *ChecksumSize)] PUCHAR* ChecksumValue;
         } HashS4UPreauth;
  
         [case(RemoteCallKerbSignS4UPreauthData)] struct
         {
             PLONG ChecksumType;
             PULONG ChecksumSize;
             [size_is(, *ChecksumSize)] PUCHAR* ChecksumValue;
         } SignS4UPreauthData;
  
         [case(RemoteCallKerbVerifyChecksum)] struct
         {
             BOOL IsValid;
         } VerifyChecksum;
 
         [case(RemoteCallKerbDecryptPacCredentials)] struct
         {
             PSECPKG_SUPPLEMENTAL_CRED_ARRAY Credentials;
         } DecryptPacCredentials;
  
         [case(RemoteCallKerbCreateECDHKeyAgreement)] struct
         {
             KEY_AGREEMENT_HANDLE* KeyAgreementHandle;
             KERBERR* KerbErr;
             PULONG EncodedPubKeyLen;
             [size_is(, *EncodedPubKeyLen)] PBYTE* EncodedPubKey;
         } CreateECDHKeyAgreement;
  
         [case(RemoteCallKerbCreateDHKeyAgreement)] struct
         {
             KERB_RPC_CRYPTO_API_BLOB* ModulusP;
             KERB_RPC_CRYPTO_API_BLOB* GeneratorG;
             KERB_RPC_CRYPTO_API_BLOB* FactorQ;
             KEY_AGREEMENT_HANDLE* KeyAgreementHandle;
             KERBERR* KerbErr;
             PULONG LittleEndianPublicKeyLen;
             [size_is(, *LittleEndianPublicKeyLen)] PBYTE* LittleEndianPublicKey;
         } CreateDHKeyAgreement;
  
         [case(RemoteCallKerbDestroyKeyAgreement)] struct
         {
             // This [case(RemoteCallKerb)] struct has no output, but for 
             // simplicity and consistency define as a 
             // [case(RemoteCallKerb)] struct with a single ignored value.
             UCHAR Ignored;
         } DestroyKeyAgreement;
  
         [case(RemoteCallKerbKeyAgreementGenerateNonce)] struct
         {
             PULONG NonceLen;
             [size_is(, *NonceLen)] PBYTE* Nonce;
         } KeyAgreementGenerateNonce;
  
         [case(RemoteCallKerbFinalizeKeyAgreement)] struct
         {
             KERB_RPC_ENCRYPTION_KEY* SharedKey;
         } FinalizeKeyAgreement;
     };
 } KerbCredIsoRemoteOutput, *PKerbCredIsoRemoteOutput;