/// <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> /// 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; } } }