/// <summary> /// Creates a new SignaturePacket with the parameters /// in pSource /// </summary> /// <param name="pSource">Packet from which the /// parameters are derived</param> /// <remarks>No remarks</remarks> public SignaturePacket(Packet pSource) { lLength = pSource.Length; bBody = pSource.Body; ctContent = pSource.Content; pfFormat = pSource.Format; bHeader = pSource.Header; bSignatureData = new byte[0]; ssSignatureStatus = SignatureStatusTypes.Not_Verified; this.bIsUpdated = false; }
/// <summary> /// Verifies the data given as parameter with the given public key. /// </summary> /// <remarks> /// <para>The function calculates a message digest over the given signature /// data and verifies the digest with the digest stored in the /// signature packet.</para> /// <para>The results of the verify operation are directly stored /// in the SignatureStatus property of this class.</para> /// </remarks> /// <param name="bSignedData">The data that is to be verified.</param> /// <param name="pkpKey">The key that is to verify the signature</param> public void Verify(byte[] bSignedData, PublicKeyPacket pkpKey) { System.Security.Cryptography.HashAlgorithm haVerifyer; AsymmetricCipher acVerifyer; switch (this.HashAlgorithm) { case HashAlgorithms.MD5: haVerifyer = System.Security.Cryptography.MD5.Create(); break; case HashAlgorithms.SHA1: haVerifyer = System.Security.Cryptography.SHA1.Create(); break; default: throw(new System.Exception("Currently only MD5 and SHA1 are implemented as hash algorithms!")); } switch (this.SignatureAlgorithm) { case AsymAlgorithms.DSA: acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA(); break; case AsymAlgorithms.RSA_Encrypt_Sign: case AsymAlgorithms.RSA_Sign_Only: acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.RSA(); break; default: throw(new System.Exception("Currently only DSA and RSA are implemented as signature algorithms!")); } byte[] bSignature = new byte[0]; int iCounter = 0; if (this.Version <= SignaturePacketVersionNumbers.v3) { bSignature = new byte[5]; bSignature[iCounter++] = (byte)this.SignatureType; long lTime = (dtTimeCreated.Ticks - new DateTime(1970, 1, 1).Ticks)/10000000; bSignature[iCounter++] = (byte)((lTime >> 24) & 0xFF); bSignature[iCounter++] = (byte)((lTime >> 16) & 0xFF); bSignature[iCounter++] = (byte)((lTime >> 8) & 0xFF); bSignature[iCounter++] = (byte)(lTime & 0xFF); } else { //Hashed Subpackets Length int lHashedSubPacketLength = 0; for (int i=0; i<this.HashedSubPackets.Length; i++) { lHashedSubPacketLength += this.HashedSubPackets[i].Generate().Length; } bSignature = new byte[lHashedSubPacketLength + 12]; bSignature[iCounter++] = 4; // Version bSignature[iCounter++] = (byte)this.SignatureType; bSignature[iCounter++] = (byte)this.SignatureAlgorithm; bSignature[iCounter++] = (byte)this.HashAlgorithm; //Hashed Subpackets bSignature[iCounter++] = (byte)((lHashedSubPacketLength >> 8) & 0xFF); bSignature[iCounter++] = (byte)(lHashedSubPacketLength & 0xFF); for (int i=0; i<this.HashedSubPackets.Length; i++) { byte[] bSubPacket = this.HashedSubPackets[i].Generate(); Array.Copy(bSubPacket, 0, bSignature, iCounter, bSubPacket.Length); iCounter += bSubPacket.Length; } //Final Trailer of 6 bytes bSignature[iCounter++] = 0x04; bSignature[iCounter++] = 0xFF; bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 24) & 0xFF); bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 16) & 0xFF); bSignature[iCounter++] = (byte)(((lHashedSubPacketLength+6) >> 8) & 0xFF); bSignature[iCounter++] = (byte)((lHashedSubPacketLength+6) & 0xFF); } byte[] bData = new byte[bSignedData.Length + bSignature.Length]; Array.Copy(bSignedData, bData, bSignedData.Length); Array.Copy(bSignature, 0, bData, bSignedData.Length, bSignature.Length); byte[] bHash = haVerifyer.ComputeHash(bData); BigInteger biHash = new BigInteger(bHash); //PKCS1 Encode the hash if (this.SignatureAlgorithm != AsymAlgorithms.DSA) { // We encode the MD in this way: // 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) // PAD consists of FF bytes. byte[] bASN = new byte[0]; switch (this.HashAlgorithm) { case HashAlgorithms.MD5: bASN = new byte[] {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; break; case HashAlgorithms.SHA1: bASN = new byte[] {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; break; } int iFrameSize = (pkpKey.KeyMaterial[0].bitCount() + 7) / 8; byte[] bFrame = new byte[iFrameSize]; int iASNCounter = 0; bFrame[iASNCounter++] = 0; bFrame[iASNCounter++] = 1; int iFFLength = iFrameSize - bHash.Length - bASN.Length - 3; for (int i=0; i<iFFLength; i++) { bFrame[iASNCounter++] = 0xFF; } bFrame[iASNCounter++] = 0; Array.Copy(bASN, 0, bFrame, iASNCounter, bASN.Length); iASNCounter += bASN.Length; Array.Copy(bHash, 0, bFrame, iASNCounter, bHash.Length); biHash = new BigInteger(bFrame); } if (acVerifyer.Verify(this.Signature, biHash, pkpKey)) { ssSignatureStatus = SignatureStatusTypes.Valid; } else { ssSignatureStatus = SignatureStatusTypes.Invalid; } }
/// <summary> /// Verifies the data given as parameter with the given public key. /// </summary> /// <remarks> /// <para>The function calculates a message digest over the given signature /// data and verifies the digest with the digest stored in the /// signature packet.</para> /// <para>The results of the verify operation are directly stored /// in the SignatureStatus property of this class.</para> /// </remarks> /// <param name="bSignedData">The data that is to be verified.</param> /// <param name="pkpKey">The key that is to verify the signature</param> public void Verify(byte[] bSignedData, PublicKeyPacket pkpKey) { System.Security.Cryptography.HashAlgorithm haVerifyer; AsymmetricCipher acVerifyer; switch (this.HashAlgorithm) { case HashAlgorithms.MD5: haVerifyer = System.Security.Cryptography.MD5.Create(); break; case HashAlgorithms.SHA1: haVerifyer = System.Security.Cryptography.SHA1.Create(); break; default: throw(new System.Exception("Currently only MD5 and SHA1 are implemented as hash algorithms!")); } switch (this.SignatureAlgorithm) { case AsymAlgorithms.DSA: acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA(); break; case AsymAlgorithms.RSA_Encrypt_Sign: case AsymAlgorithms.RSA_Sign_Only: acVerifyer = new SharpPrivacy.SharpPrivacyLib.Cipher.RSA(); break; default: throw(new System.Exception("Currently only DSA and RSA are implemented as signature algorithms!")); } byte[] bSignature = new byte[0]; int iCounter = 0; if (this.Version <= SignaturePacketVersionNumbers.v3) { bSignature = new byte[5]; bSignature[iCounter++] = (byte)this.SignatureType; long lTime = (dtTimeCreated.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000; bSignature[iCounter++] = (byte)((lTime >> 24) & 0xFF); bSignature[iCounter++] = (byte)((lTime >> 16) & 0xFF); bSignature[iCounter++] = (byte)((lTime >> 8) & 0xFF); bSignature[iCounter++] = (byte)(lTime & 0xFF); } else { //Hashed Subpackets Length int lHashedSubPacketLength = 0; for (int i = 0; i < this.HashedSubPackets.Length; i++) { lHashedSubPacketLength += this.HashedSubPackets[i].Generate().Length; } bSignature = new byte[lHashedSubPacketLength + 12]; bSignature[iCounter++] = 4; // Version bSignature[iCounter++] = (byte)this.SignatureType; bSignature[iCounter++] = (byte)this.SignatureAlgorithm; bSignature[iCounter++] = (byte)this.HashAlgorithm; //Hashed Subpackets bSignature[iCounter++] = (byte)((lHashedSubPacketLength >> 8) & 0xFF); bSignature[iCounter++] = (byte)(lHashedSubPacketLength & 0xFF); for (int i = 0; i < this.HashedSubPackets.Length; i++) { byte[] bSubPacket = this.HashedSubPackets[i].Generate(); Array.Copy(bSubPacket, 0, bSignature, iCounter, bSubPacket.Length); iCounter += bSubPacket.Length; } //Final Trailer of 6 bytes bSignature[iCounter++] = 0x04; bSignature[iCounter++] = 0xFF; bSignature[iCounter++] = (byte)(((lHashedSubPacketLength + 6) >> 24) & 0xFF); bSignature[iCounter++] = (byte)(((lHashedSubPacketLength + 6) >> 16) & 0xFF); bSignature[iCounter++] = (byte)(((lHashedSubPacketLength + 6) >> 8) & 0xFF); bSignature[iCounter++] = (byte)((lHashedSubPacketLength + 6) & 0xFF); } byte[] bData = new byte[bSignedData.Length + bSignature.Length]; Array.Copy(bSignedData, bData, bSignedData.Length); Array.Copy(bSignature, 0, bData, bSignedData.Length, bSignature.Length); byte[] bHash = haVerifyer.ComputeHash(bData); BigInteger biHash = new BigInteger(bHash); //PKCS1 Encode the hash if (this.SignatureAlgorithm != AsymAlgorithms.DSA) { // We encode the MD in this way: // 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) // PAD consists of FF bytes. byte[] bASN = new byte[0]; switch (this.HashAlgorithm) { case HashAlgorithms.MD5: bASN = new byte[] { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; break; case HashAlgorithms.SHA1: bASN = new byte[] { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 }; break; } int iFrameSize = (pkpKey.KeyMaterial[0].bitCount() + 7) / 8; byte[] bFrame = new byte[iFrameSize]; int iASNCounter = 0; bFrame[iASNCounter++] = 0; bFrame[iASNCounter++] = 1; int iFFLength = iFrameSize - bHash.Length - bASN.Length - 3; for (int i = 0; i < iFFLength; i++) { bFrame[iASNCounter++] = 0xFF; } bFrame[iASNCounter++] = 0; Array.Copy(bASN, 0, bFrame, iASNCounter, bASN.Length); iASNCounter += bASN.Length; Array.Copy(bHash, 0, bFrame, iASNCounter, bHash.Length); biHash = new BigInteger(bFrame); } if (acVerifyer.Verify(this.Signature, biHash, pkpKey)) { ssSignatureStatus = SignatureStatusTypes.Valid; } else { ssSignatureStatus = SignatureStatusTypes.Invalid; } }