/// <summary> /// Calculate Server checksum (TD section 2.8.1) of the PAC message, /// place the checksum as a PacInfoBuffer whose ulType_Values is V3. /// Then calculate KDC checksum (TD section 2.8.2) of the PAC message, /// place the checksum as a PacInfoBuffer whose ulType_Values is V4. /// </summary> /// <param name="serverSignKey">The server signature key used to generate server signature.</param> /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param> /// <exception cref="ArgumentNullException">serverSignkey or kdcSignKey is null.</exception> public void Sign(byte[] serverSignKey, byte[] kdcSignKey) { // locate server and KDC signatures. PacSignatureData serverSign; PacSignatureData kdcSign; FindSignatures(out serverSign, out kdcSign); // types PAC_SIGNATURE_DATA_SignatureType_Values serversignType = serverSign.NativePacSignatureData.SignatureType; PAC_SIGNATURE_DATA_SignatureType_Values kdcSignType = kdcSign.NativePacSignatureData.SignatureType; // clear signatures. int serverLength = PacSignatureData.CalculateSignatureLength(serversignType); serverSign.NativePacSignatureData.Signature = new byte[serverLength]; int kdcLength = PacSignatureData.CalculateSignatureLength(kdcSignType); kdcSign.NativePacSignatureData.Signature = new byte[kdcLength]; // sign server byte[] serverSignResult = PacSignatureData.Sign( ToBytes(), serversignType, serverSignKey); serverSign.NativePacSignatureData.Signature = serverSignResult; // sign KDC kdcSign.NativePacSignatureData.Signature = PacSignatureData.Sign( serverSignResult, kdcSignType, kdcSignKey); }
/// <summary> /// Find Server Signature and KDC signature. /// </summary> /// <param name="serverSign">The found Server Signature.</param> /// <param name="kdcSign">The found KDC Signature.</param> private void FindSignatures(out PacSignatureData serverSign, out PacSignatureData kdcSign) { serverSign = null; kdcSign = null; foreach (PacInfoBuffer infoBuffer in pacInfoBuffers) { if (infoBuffer == null) { continue; } PAC_INFO_BUFFER_Type_Values ulType = infoBuffer.GetBufferInfoType(); if (ulType == PAC_INFO_BUFFER_Type_Values.ServerChecksum || ulType == PAC_INFO_BUFFER_Type_Values.KdcChecksum) { PacSignatureData sign = (PacSignatureData)infoBuffer; if (ulType == PAC_INFO_BUFFER_Type_Values.ServerChecksum) { serverSign = sign; } else { kdcSign = sign; } } } AssertSignsNotNull(serverSign, kdcSign); }
/// <summary> /// Assert signatures are not null. /// </summary> /// <param name="serverSign">Server signature to be asserted.</param> /// <param name="kdcSign">KDC signature to be asserted.</param> private static void AssertSignsNotNull(PacSignatureData serverSign, PacSignatureData kdcSign) { if (serverSign == null) { throw new ArgumentException("server signature is not found"); } if (kdcSign == null) { throw new ArgumentException("KDC signature is not found"); } }
/// <summary> /// Find Server Signature and KDC signature. /// </summary> /// <param name="serverSign">The found Server Signature.</param> /// <param name="kdcSign">The found KDC Signature.</param> private void FindSignatures(out PacSignatureData serverSign, out PacSignatureData kdcSign) { serverSign = null; kdcSign = null; foreach (PacInfoBuffer infoBuffer in pacInfoBuffers) { if (infoBuffer == null) continue; PAC_INFO_BUFFER_Type_Values ulType = infoBuffer.GetBufferInfoType(); if (ulType == PAC_INFO_BUFFER_Type_Values.ServerChecksum || ulType == PAC_INFO_BUFFER_Type_Values.KdcChecksum) { PacSignatureData sign = (PacSignatureData)infoBuffer; if (ulType == PAC_INFO_BUFFER_Type_Values.ServerChecksum) { serverSign = sign; } else { kdcSign = sign; } } } AssertSignsNotNull(serverSign, kdcSign); }
/// <summary> /// Verify Server checksum (TD section 2.8.1) and KDC checksum (TD section 2.8.2) /// of the PAC message. /// </summary> /// <param name="serverSignKey">The server signature key used to generate server signature.</param> /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param> /// <param name="isServerSignValid">true if server signature is valid.</param> /// <param name="isKdcSignValid">true if KDC signature is valid.</param> /// <exception cref="ArgumentNullException">serverSignkey or kdcSignKey is null.</exception> public void ValidateSign(byte[] serverSignKey, byte[] kdcSignKey, out bool isServerSignValid, out bool isKdcSignValid) { if (serverSignKey == null) { throw new ArgumentNullException("serverSignKey"); } if (kdcSignKey == null) { throw new ArgumentNullException("kdcSignKey"); } // locate server and KDC signatures. PacSignatureData serverSign; PacSignatureData kdcSign; FindSignatures(out serverSign, out kdcSign); // these validate operation will change signature values, so must backup and restore. byte[] oldServerSign = null; byte[] oldKdcSign = null; isServerSignValid = false; isKdcSignValid = false; try { // types PAC_SIGNATURE_DATA_SignatureType_Values serverSignType = serverSign.NativePacSignatureData.SignatureType; PAC_SIGNATURE_DATA_SignatureType_Values kdcSignType = kdcSign.NativePacSignatureData.SignatureType; // backup and clear signatures. int serverLength = PacSignatureData.CalculateSignatureLength(serverSignType); oldServerSign = serverSign.NativePacSignatureData.Signature; serverSign.NativePacSignatureData.Signature = new byte[serverLength]; int kdcLength = PacSignatureData.CalculateSignatureLength(kdcSignType); oldKdcSign = kdcSign.NativePacSignatureData.Signature; kdcSign.NativePacSignatureData.Signature = new byte[kdcLength]; // validate server sign byte[] serverSignResult = PacSignatureData.Sign( ToBytes(), serverSignType, serverSignKey); isServerSignValid = ArrayUtility.CompareArrays <byte>(serverSignResult, oldServerSign); // validate KDC sign byte[] kdcSignResult = PacSignatureData.Sign( serverSignResult, kdcSignType, kdcSignKey); isKdcSignValid = ArrayUtility.CompareArrays <byte>(kdcSignResult, oldKdcSign); } finally { // restore server signature if (oldServerSign != null) { serverSign.NativePacSignatureData.Signature = oldServerSign; } // restore KDC signature if (oldKdcSign != null) { kdcSign.NativePacSignatureData.Signature = oldKdcSign; } } }
internal static int CalculateSignatureLength(IEvaluationContext context) { PAC_SIGNATURE_DATA_SignatureType_Values signatureType = (PAC_SIGNATURE_DATA_SignatureType_Values)context.Variables["SignatureType"]; return(PacSignatureData.CalculateSignatureLength(signatureType)); }