Пример #1
0
        public SignatureSubPacket[] ParsePackets(byte[] bBinaryData)
        {
            ArrayList alPackets = new ArrayList(100);

            byte[] bTmpData = new byte[bBinaryData.Length];
            Array.Copy(bBinaryData, bTmpData, bBinaryData.Length);

            long iCurrentIndex = 0;

            while (iCurrentIndex < bBinaryData.Length)
            {
                SignatureSubPacket pTmpPacket     = new SignatureSubPacket();
                SignatureSubPacket pCurrentPacket = pTmpPacket.ParsePacket(bTmpData);

                iCurrentIndex += pCurrentPacket.Length;
                alPackets.Add(pCurrentPacket);

                bTmpData = new byte[bTmpData.Length - pCurrentPacket.Length];
                Array.Copy(bBinaryData, (int)iCurrentIndex, bTmpData, 0, bBinaryData.Length - (int)iCurrentIndex);
            }

            SignatureSubPacket[] pReturnPackets = new SignatureSubPacket[alPackets.Count];
            IEnumerator          iePacketEnum   = alPackets.GetEnumerator();
            int iCount = 0;

            while (iePacketEnum.MoveNext())
            {
                pReturnPackets[iCount++] = (SignatureSubPacket)iePacketEnum.Current;
            }

            return(pReturnPackets);
        }
Пример #2
0
        public static string ClearTextSign(string strMessage, SecretKeyRing skrKeyRing)
        {
            SignaturePacket spSign = new SignaturePacket();

            strMessage = Radix64.TrimMessage(strMessage);
            QueryPassphrase qpPassphrase = new QueryPassphrase();
            qpPassphrase.ShowMyDialog(skrKeyRing);
            string strPassphrase = qpPassphrase.Passphrase;
            TransportableSecretKey tskKey = qpPassphrase.SelectedKey;
            SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign);

            Working wWorking = new Working();
            wWorking.Show();

            spSign.HashAlgorithm = HashAlgorithms.SHA1;
            spSign.Format = PacketFormats.New;

            wWorking.Progress(10);

            SignatureSubPacket sspCreator = new SignatureSubPacket();
            sspCreator.Type = SignatureSubPacketTypes.IssuerKeyID;
            sspCreator.KeyID = skpKey.PublicKey.KeyID;
            SignatureSubPacket sspCreationTime = new SignatureSubPacket();
            sspCreationTime.Type = SignatureSubPacketTypes.SignatureCreationTime;
            sspCreationTime.TimeCreated = DateTime.Now;
            spSign.HashedSubPackets = new SignatureSubPacket[2];
            spSign.HashedSubPackets[0] = sspCreator;
            spSign.HashedSubPackets[1] = sspCreationTime;

            wWorking.Progress(20);

            //spSign.KeyID = skpKey.PublicKey.KeyID;
            //spSign.TimeCreated = DateTime.Now;
            spSign.SignatureAlgorithm = skpKey.PublicKey.Algorithm;
            spSign.SignatureType = SignatureTypes.TextSignature;
            spSign.Version = SignaturePacketVersionNumbers.v4;

            wWorking.Progress(10);

            byte[] bMessage = System.Text.Encoding.UTF8.GetBytes(strMessage);
            spSign.Sign(bMessage, skpKey, strPassphrase);

            wWorking.Progress(40);
            byte[] bSignature = spSign.Generate();

            string strSignature = Radix64.Encode(bSignature, true);

            wWorking.Progress(20);

            string strFinal = Armor.WrapCleartextSignature(strMessage, strSignature);

            wWorking.Hide();

            return strFinal;
        }
Пример #3
0
 /// <summary>
 /// Creates a new signature packet. Format defaults
 /// to new packet format.
 /// </summary>
 /// <remarks>No remarks</remarks>
 public SignaturePacket()
 {
     bBody              = new byte[0];
     bHeader            = new byte[0];
     pfFormat           = PacketFormats.New;
     ctContent          = ContentTypes.Signature;
     dtTimeCreated      = DateTime.Now;
     HashedSubPackets   = new SignatureSubPacket[0];
     UnhashedSubPackets = new SignatureSubPacket[0];
     this.bIsUpdated    = true;
 }
Пример #4
0
 public void AddSubPacket(SignatureSubPacket sspSubPacket, bool bHashed)
 {
     if (bHashed)
     {
         SignatureSubPacket[] sspHashed = new SignatureSubPacket[this.HashedSubPackets.Length + 1];
         Array.Copy(this.HashedSubPackets, 0, sspHashed, 0, this.HashedSubPackets.Length);
         sspHashed[sspHashed.Length - 1] = sspSubPacket;
         this.HashedSubPackets           = sspHashed;
     }
     else
     {
         SignatureSubPacket[] sspUnhashed = new SignatureSubPacket[this.UnhashedSubPackets.Length + 1];
         Array.Copy(this.HashedSubPackets, 0, sspUnhashed, 0, this.UnhashedSubPackets.Length);
         sspUnhashed[sspUnhashed.Length - 1] = sspSubPacket;
         this.UnhashedSubPackets             = sspUnhashed;
     }
     this.bIsUpdated = true;
 }
Пример #5
0
        /// <summary>
        /// Adds a userID to the specified key
        /// </summary>
        /// <param name="userID">user id to be added</param>
        /// <param name="email">user email address</param>
        /// <param name="infos">xml encoded user infos</param>
        /// <param name="strPassphrase">passphrase of the secret key we want to add the user id to</param>
        /// <param name="KeyID">keyID of the key we want to add the userID to</param>
        /// <param name="isRevocable">is a revocable keyID</param>
        public void AddUserID(string userID, string email, string infos, string strPassphrase, ulong KeyID, bool isRevocable)
        {
            TransportablePublicKey tpkKey = this.PublicRing.Find(KeyID,false);
            TransportableSecretKey tskKey = this.SecretRing.Find(KeyID);
            if (tpkKey != null && tskKey != null) {
                CertifiedUserID cuiUID = new CertifiedUserID();
                UserIDPacket uipUID = new UserIDPacket();
                uipUID.UserID = userID.Trim() + " <" + email.Trim() + ">";
                cuiUID.UserID = uipUID;

                SecretKeyPacket skpSignatureKey = tskKey.FindKey(AsymActions.Sign);
                SignaturePacket spSelfSig = new SignaturePacket();
                if (infos != null) {
                    SignatureSubPacket sspNotation = new SignatureSubPacket();
                    sspNotation.Type = SignatureSubPacketTypes.NotationData;
                    sspNotation.NotationName = "PersonalData";
                    sspNotation.NotationValue = infos;
                    spSelfSig.AddSubPacket(sspNotation,false);
                }
                if (!isRevocable) {
                    SignatureSubPacket sspRevocable = new SignatureSubPacket();
                    sspRevocable.Type = SignatureSubPacketTypes.Revocable;
                    sspRevocable.Revocable = isRevocable;
                    spSelfSig.AddSubPacket(sspRevocable, true);
                }
                SignatureSubPacket sspPrimaryUID = new SignatureSubPacket();
                sspPrimaryUID.Type = SignatureSubPacketTypes.PrimaryUserID;
                sspPrimaryUID.Revocable = false;
                spSelfSig.AddSubPacket(sspPrimaryUID, true);

                spSelfSig.Version = SignaturePacketVersionNumbers.v4;
                spSelfSig.HashAlgorithm = HashAlgorithms.SHA1;
                spSelfSig.KeyID = skpSignatureKey.PublicKey.KeyID;
                spSelfSig.TimeCreated = DateTime.Now;
                cuiUID.Certificates = new System.Collections.ArrayList();
                cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, tpkKey.PrimaryKey);

                tpkKey.Certifications.Add(cuiUID);
                tskKey.UserIDs.Add(uipUID);
                return;
            }
            throw new Exception("Keys not found");
        }
Пример #6
0
        /// <summary>
        /// Signs a key 
        /// </summary>
        /// <param name="tspKey">key to be signed</param>
        /// <param name="cuidTobeSigned">user id to be signed</param>
        /// <param name="skpKeySigner">signer private key</param>
        /// <param name="strPassphrase">signer passphrase</param>
        /// <param name="exportable">exportable signature</param>
        /// <param name="expirationTime">expiration time (new DateTime(0) == never)</param>
        /// <param name="isRevocable"></param>
        public void SignKey(TransportablePublicKey tspKey, CertifiedUserID cuidTobeSigned, TransportableSecretKey skpKeySigner, string strPassphrase, bool exportable, DateTime expirationTime, bool isRevocable)
        {
            SignaturePacket spSig = new SignaturePacket();
            spSig.Version = SignaturePacketVersionNumbers.v4;
            spSig.HashAlgorithm = HashAlgorithms.SHA1;
            spSig.KeyID = skpKeySigner.PrimaryKey.PublicKey.KeyID;
            spSig.TimeCreated = DateTime.Now;
            SignatureSubPacket sspExportableSignature = new SignatureSubPacket();
            sspExportableSignature.Type = SignatureSubPacketTypes.ExportableSignature;
            sspExportableSignature.ExportableSignature = exportable;
            spSig.AddSubPacket(sspExportableSignature, false);
            if (!isRevocable) {
                SignatureSubPacket sspRevocable = new SignatureSubPacket();
                sspRevocable.Type = SignatureSubPacketTypes.Revocable;
                sspRevocable.Revocable = isRevocable;
                spSig.AddSubPacket(sspRevocable, true);
            }
            if (expirationTime.Ticks != 0) {
                SignatureSubPacket sspExpiration = new SignatureSubPacket();
                sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime;
                sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970,1,2)).Ticks - tspKey.PrimaryKey.TimeCreated.Ticks);
                spSig.AddSubPacket(sspExpiration, true);
            }

            cuidTobeSigned.Sign(spSig, skpKeySigner.PrimaryKey, strPassphrase, tspKey.PrimaryKey);
        }
Пример #7
0
 /// <summary>
 /// Sets the trust level and amount for a specified userID in a key
 /// </summary>
 /// <param name="userIdKeyId">KeyID of the key containing the userID which this set the trust of</param>
 /// <param name="userID">UserID whose trust has to be set</param>
 /// <param name="KeyID">Signer (Truster) keyID</param>
 /// <param name="strPassphrase">passphrase of the signer</param>
 /// <param name="trustLevel">trust level</param>
 /// <param name="trustAmount">trust amount</param>
 public void setUserIDTrust(ulong userIdKeyId, CertifiedUserID userID, ulong KeyID, string strPassphrase, int trustLevel, int trustAmount)
 {
     TransportablePublicKey tpkKey = this.PublicRing.Find(userIdKeyId,false);
     TransportableSecretKey tskKey = this.SecretRing.Find(KeyID);
     bool updated = false;
     if (tpkKey!=null && tskKey!=null) {
         ArrayList cert = new ArrayList(userID.Certificates);
         for (int k = 0; k < cert.Count; k++) {
             updated = false;
             SignaturePacket sp = (SignaturePacket)cert[k];
             if ((sp.SignatureType == SignatureTypes.UserIDSignature ||
                 sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification ||
                 sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification ||
                 sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification) && sp.KeyID == KeyID)
             {
                 foreach (SignatureSubPacket ssp in sp.HashedSubPackets) {
                     if(ssp.Type == SignatureSubPacketTypes.TrustSignature) {
                         ssp.TrustLevel = (byte)(trustLevel & 0xFF);
                         ssp.TrustAmount = (byte)(trustAmount & 0xFF);
                         updated = true;
                     }
                 }
                 if (!updated) {
                     foreach (SignatureSubPacket ssp in sp.UnhashedSubPackets) {
                         if (ssp.Type == SignatureSubPacketTypes.TrustSignature) {
                             ssp.TrustLevel = (byte)(trustLevel & 0xFF);
                             ssp.TrustAmount = (byte)(trustAmount & 0xFF);
                             updated = true;
                         }
                     }
                 }
                 if(updated)	{
                     userID.Certificates.Remove(sp);
                     userID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey);
                     updated = true;
                 } else {
                     SignatureSubPacket sspTrust = new SignatureSubPacket();
                     sspTrust.Type = SignatureSubPacketTypes.TrustSignature;
                     sspTrust.TrustAmount = (byte)(trustAmount & 0xFF);
                     sspTrust.TrustLevel = (byte)(trustLevel & 0xFF);
                     sp.AddSubPacket(sspTrust, false);
                     userID.Certificates.Remove(sp);
                     userID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey);
                     updated = true;
                 }
             }
         }
     }
     if (!updated)
         throw new Exception("User id not certified by this Key. You cannot set Trust.");
 }
Пример #8
0
 /// <summary>
 /// Creates a new signature packet. Format defaults
 /// to new packet format.
 /// </summary>
 /// <remarks>No remarks</remarks>
 public SignaturePacket()
 {
     bBody = new byte[0];
     bHeader = new byte[0];
     pfFormat = PacketFormats.New;
     ctContent = ContentTypes.Signature;
     dtTimeCreated = DateTime.Now;
     HashedSubPackets = new SignatureSubPacket[0];
     UnhashedSubPackets = new SignatureSubPacket[0];
     this.bIsUpdated = true;
 }
Пример #9
0
        /// <summary>
        /// Signes the data given as parameter with the given secret key.
        /// The given password has to fit the given key.
        /// </summary>
        /// <remarks>
        /// <para>The function calculates a message digest over the given signature
        /// data and signes the digest with the given key.</para>
        /// <para>The results of the signature operation are directly stored
        /// in the Signature property of this class.</para>
        /// </remarks>
        /// <param name="bSignedData">The data that is to be signed.</param>
        /// <param name="skpKey">The key that is to sign the data</param>
        /// <param name="strPassphrase">The passphrase that is neccessary to
        /// decrypt the given key.</param>
        public void Sign(byte[] bSignedData, SecretKeyPacket skpKey, string strPassphrase)
        {
            System.Security.Cryptography.HashAlgorithm haSigner;
            AsymmetricCipher acSigner;

            this.SignatureAlgorithm = skpKey.PublicKey.Algorithm;

            switch (this.HashAlgorithm)
            {
            case HashAlgorithms.MD5:
                haSigner = System.Security.Cryptography.MD5.Create();
                break;

            case HashAlgorithms.SHA1:
                haSigner = 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:
                acSigner = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA();
                break;

            case AsymAlgorithms.RSA_Encrypt_Sign:
            case AsymAlgorithms.RSA_Sign_Only:
                acSigner = 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
            {
                // Add Issuer KeyID Subpacket if it's not there.
                try {
                    ulong lTestForKeyID = this.KeyID;
                } catch (Exception) {
                    SignatureSubPacket sspIssuerKeyID = new SignatureSubPacket();
                    sspIssuerKeyID.Type  = SignatureSubPacketTypes.IssuerKeyID;
                    sspIssuerKeyID.KeyID = this.lKeyID;
                    this.AddSubPacket(sspIssuerKeyID, true);
                }

                // Add TimeCreated Subpacket if it's not there.
                try {
                    this.FindSignatureCreationTime();
                } catch (Exception) {
                    SignatureSubPacket sspCreationTime = new SignatureSubPacket();
                    sspCreationTime.Type        = SignatureSubPacketTypes.SignatureCreationTime;
                    sspCreationTime.TimeCreated = DateTime.Now;
                    this.AddSubPacket(sspCreationTime, true);
                }

                //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
                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  = haSigner.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  = (skpKey.PublicKey.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);
            }

            sSignedHash16Bit = (ushort)((bHash[0] << 8) + bHash[1]);
            biSignature      = acSigner.Sign(biHash, skpKey, strPassphrase);
            this.bIsUpdated  = true;
        }
Пример #10
0
        /// <summary>
        /// Revokes a key certified userID
        /// </summary>
        /// <param name="KeyID">key containing the certified user id</param>
        /// <param name="cuidTobeSigned">certified user id to be revoked</param>
        /// <param name="skpKeySigner">revoker secret key</param>
        /// <param name="strPassphrase">revoker passphrase</param>
        /// <param name="exportable">exportable revocation</param>
        public void RevokeKeyCertificate(ulong KeyID, CertifiedUserID cuidTobeSigned, TransportableSecretKey skpKeySigner, string strPassphrase, bool exportable)
        {
            TransportablePublicKey tspKey = this.PublicRing.Find(KeyID,false);
            if(tspKey == null)
                throw new Exception("Public Key not found");
            bool found = false;
            CertifiedUserID toBeVerified = null;
            foreach(CertifiedUserID cui in tspKey.Certifications) {
                if(cui==cuidTobeSigned) {
                    found=true;
                    toBeVerified = cui;
                    break;
                }
            }
            if (!found)
                throw new Exception("UserId not found among Key certificates");

            found = false;
            foreach(SignaturePacket sign in toBeVerified.Certificates) {
                if(sign.KeyID == skpKeySigner.PrimaryKey.PublicKey.KeyID && sign.isRevocable())
                    found = true;
            }
            if (!found)
                throw new Exception("UserId not certified by this private key or not revocable");

            SignaturePacket spSig = new SignaturePacket();
            spSig.Version = SignaturePacketVersionNumbers.v4;
            spSig.HashAlgorithm = HashAlgorithms.SHA1;
            spSig.KeyID = skpKeySigner.PrimaryKey.PublicKey.KeyID;
            spSig.TimeCreated = DateTime.Now;
            SignatureSubPacket sspExportableSignature = new SignatureSubPacket();
            sspExportableSignature.Type = SignatureSubPacketTypes.ExportableSignature;
            sspExportableSignature.ExportableSignature = exportable;
            spSig.AddSubPacket(sspExportableSignature, false);
            cuidTobeSigned.Revoke(spSig, skpKeySigner.PrimaryKey, strPassphrase, tspKey.PrimaryKey);
        }
Пример #11
0
        /// <summary>
        /// Generate a key pair
        /// </summary>
        /// <param name="iKeySize">Encription key size</param>
        /// <param name="strPassphrase">passhrase for the key pair</param>
        /// <param name="userID">primary user id</param>
        /// <param name="email">user email</param>
        /// <param name="notation">xml encoded user info</param>
        /// <param name="expirationTime">expiration date of the primary key (new DateTime(0) == never)</param>
        /// <param name="keyType">1: RSA/DSA   0:Elgamal/DSA(DEFAULT)</param>
        /// <param name="isRevocableKey">revocable?</param>
        /// <param name="isRevocableSubkey">revocable subkey?</param>
        public void GenerateKey(int iKeySize, string strPassphrase, string userID, string email, string notation, DateTime expirationTime, int keyType, bool isRevocableKey, bool isRevocableSubkey)
        {
            if(iKeySize % 1024 != 0)
                throw new Exception("Keysize must be a 1024 multiple");

            System.Security.Cryptography.RandomNumberGenerator rngRand;

            // let's first create the encryption key
            BigInteger[][] biEncryptionKey;
            if (keyType == 1) {
                // it's a RSA/DSA key
                biEncryptionKey = GenerateRSAEncryptionKey(iKeySize);
            } else {
                // it's an elgamal/DSA key DEFAULF
                biEncryptionKey = GenerateElGamalEncryptionKey(iKeySize);
            }

            // now the signature key
            BigInteger[][] biSignatureKey = GenerateDSASignatureKey();

            PublicKeyPacket pkpSignatureKey = new PublicKeyPacket(false);
            pkpSignatureKey.Algorithm = AsymAlgorithms.DSA;
            pkpSignatureKey.KeyMaterial = biSignatureKey[0];
            pkpSignatureKey.TimeCreated = DateTime.Now;
            pkpSignatureKey.Version = PublicKeyPacketVersionNumbers.v4;

            SecretKeyPacket skpSignatureKey = new SecretKeyPacket(false);
            skpSignatureKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
            skpSignatureKey.PublicKey = pkpSignatureKey;
            skpSignatureKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
            rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpSignatureKey.InitialVector);
            skpSignatureKey.EncryptKeyMaterial(biSignatureKey[1], strPassphrase);
            skpSignatureKey.PublicKey = pkpSignatureKey;

            PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
            if (keyType == 0) {
                // it's an elgamal/DSA key
                pkpEncryptionKey.Algorithm = AsymAlgorithms.ElGamal_Encrypt_Only;
            } else if (keyType == 1) {
                // it's a RSA/DSA key
                pkpEncryptionKey.Algorithm = AsymAlgorithms.RSA_Encrypt_Only;
            }
            pkpEncryptionKey.KeyMaterial = biEncryptionKey[0];
            pkpEncryptionKey.TimeCreated = DateTime.Now;
            pkpEncryptionKey.Version = PublicKeyPacketVersionNumbers.v4;

            SecretKeyPacket skpEncryptionKey = new SecretKeyPacket(true);
            skpEncryptionKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
            skpEncryptionKey.PublicKey = pkpEncryptionKey;
            skpEncryptionKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
            rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();
            rngRand.GetBytes(skpEncryptionKey.InitialVector);
            skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
            skpEncryptionKey.PublicKey = pkpEncryptionKey;

            CertifiedUserID cuiUID = new CertifiedUserID();
            UserIDPacket uipUID = new UserIDPacket();
            uipUID.UserID = userID.Trim() + " <" + email.Trim() + ">";
            cuiUID.UserID = uipUID;
            SignaturePacket spSelfSig = new SignaturePacket();
            if (notation != null) {
                SignatureSubPacket sspNotation = new SignatureSubPacket();
                sspNotation.Type = SignatureSubPacketTypes.NotationData;
                sspNotation.NotationName = "PersonalData";
                sspNotation.NotationValue = notation;
                spSelfSig.AddSubPacket(sspNotation,false);
            }
            if (expirationTime.Ticks != 0) {
                SignatureSubPacket sspExpiration = new SignatureSubPacket();
                sspExpiration.Type = SignatureSubPacketTypes.KeyExpirationTime;
                sspExpiration.KeyExpirationTime = new DateTime(expirationTime.Ticks + (new DateTime(1970,1,2)).Ticks - pkpEncryptionKey.TimeCreated.Ticks);
                spSelfSig.AddSubPacket(sspExpiration, true);
            }
            if (!isRevocableKey) {
                SignatureSubPacket sspRevocable = new SignatureSubPacket();
                sspRevocable.Type = SignatureSubPacketTypes.Revocable;
                sspRevocable.Revocable = isRevocableKey;
                spSelfSig.AddSubPacket(sspRevocable, true);
            }
            SignatureSubPacket sspPrimaryUID = new SignatureSubPacket();
            sspPrimaryUID.Type = SignatureSubPacketTypes.PrimaryUserID;
            sspPrimaryUID.Revocable = true;
            spSelfSig.AddSubPacket(sspPrimaryUID, true);

            spSelfSig.Version = SignaturePacketVersionNumbers.v4;
            spSelfSig.HashAlgorithm = HashAlgorithms.SHA1;
            spSelfSig.KeyID = pkpSignatureKey.KeyID;
            spSelfSig.TimeCreated = DateTime.Now;
            SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket();
            sspPrimaryUserID.Type = SignatureSubPacketTypes.PrimaryUserID;
            sspPrimaryUserID.PrimaryUserID = true;
            spSelfSig.AddSubPacket(sspPrimaryUserID, true);
            SignatureSubPacket sspPreferedSymAlgos = new SignatureSubPacket();
            sspPreferedSymAlgos.Type = SignatureSubPacketTypes.PreferedSymmetricAlgorithms;
            sspPreferedSymAlgos.PreferedSymAlgos = new SymAlgorithms[] {SymAlgorithms.AES256, SymAlgorithms.AES192, SymAlgorithms.AES256, SymAlgorithms.CAST5, SymAlgorithms.Triple_DES};
            spSelfSig.AddSubPacket(sspPreferedSymAlgos, true);
            SignatureSubPacket sspPreferedHashAlgos = new SignatureSubPacket();
            sspPreferedHashAlgos.Type = SignatureSubPacketTypes.PreferedHashAlgorithms;
            sspPreferedHashAlgos.PreferedHashAlgos = new HashAlgorithms[] {HashAlgorithms.SHA1};
            spSelfSig.AddSubPacket(sspPreferedHashAlgos, true);

            cuiUID.Certificates = new System.Collections.ArrayList();
            cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, pkpSignatureKey);

            CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
            cpsEncryptionKey.Subkey = pkpEncryptionKey;
            cpsEncryptionKey.SignKeyBindingSignature(pkpSignatureKey, skpSignatureKey, strPassphrase, expirationTime, isRevocableSubkey);

            TransportablePublicKey tpkPublicKey = new TransportablePublicKey();
            tpkPublicKey.PrimaryKey = pkpSignatureKey;
            tpkPublicKey.SubKeys.Add(cpsEncryptionKey);
            tpkPublicKey.Certifications.Add(cuiUID);

            this.PublicRing.AddPublicKey(tpkPublicKey);

            TransportableSecretKey tskSecretKey = new TransportableSecretKey();
            tskSecretKey.PrimaryKey = skpSignatureKey;
            tskSecretKey.SubKeys.Add(skpEncryptionKey);
            tskSecretKey.UserIDs.Add(uipUID);

            this.SecretRing.AddSecretKey(tskSecretKey);
        }
Пример #12
0
        public void SignKey(ulong lSignedKeyID, ulong lSigningKeyID, string strUserID, int nIntroducerDepth, bool bIsExportable, int nType, string strPassphrase)
        {
            TransportableSecretKey tskKey = skrKeyRing.Find(lSigningKeyID);
            SecretKeyPacket skpSignatureKey = tskKey.FindKey(AsymActions.Sign);

            TransportablePublicKey tpkKey = pkrKeyRing.Find(lSignedKeyID, false);

            SignaturePacket spCertificate = new SignaturePacket();
            spCertificate.SignatureType = (SignatureTypes)nType;
            spCertificate.Version = SignaturePacketVersionNumbers.v4;
            spCertificate.HashAlgorithm = HashAlgorithms.SHA1;
            spCertificate.KeyID = skpSignatureKey.PublicKey.KeyID;
            spCertificate.TimeCreated = DateTime.Now;

            CertifiedUserID cuiID = null;
            IEnumerator ieUserIDs = tpkKey.Certifications.GetEnumerator();
            while (ieUserIDs.MoveNext()) {
                if (!(ieUserIDs.Current is CertifiedUserID))
                    continue;

                CertifiedUserID cuiThisID = (CertifiedUserID)ieUserIDs.Current;
                if (cuiThisID.ToString() == strUserID) {
                    cuiID = cuiThisID;
                }
            }
            if (cuiID == null)
                throw new Exception("UserID could not be found!");

            if (bIsExportable == false) {
                SignatureSubPacket sspNotExportable = new SignatureSubPacket();
                sspNotExportable.Type = SignatureSubPacketTypes.ExportableSignature;
                sspNotExportable.ExportableSignature = false;
                spCertificate.AddSubPacket(sspNotExportable, true);
            }

            if (nIntroducerDepth > 0) {
                SignatureSubPacket sspTrust = new SignatureSubPacket();
                sspTrust.Type = SignatureSubPacketTypes.TrustSignature;
                sspTrust.TrustLevel = (byte)nIntroducerDepth;
                sspTrust.TrustAmount = 120;
                spCertificate.AddSubPacket(sspTrust, true);
            }

            cuiID.Sign(spCertificate, skpSignatureKey, strPassphrase, tpkKey.PrimaryKey);
            tpkKey.Certifications.Remove(cuiID);
            tpkKey.Certifications.Add(cuiID);

            pkrKeyRing.Delete(lSignedKeyID);
            pkrKeyRing.AddPublicKey(tpkKey);
            pkrKeyRing.Save();
        }
Пример #13
0
        public void GenerateKey(string strName, string strEmail, string strKeyType, int iKeySize, long lExpiration, string strPassphrase)
        {
            if (strKeyType == "ElGamal/DSA") {
                System.Security.Cryptography.RandomNumberGenerator rngRand = System.Security.Cryptography.RandomNumberGenerator.Create();

                // let's first create the encryption key
                BigInteger[][] biEncryptionKey = GenerateEncryptionKey(iKeySize);

                // now the signature key
                BigInteger[][] biSignatureKey = GenerateSignatureKey();

                PublicKeyPacket pkpSignatureKey = new PublicKeyPacket(false);
                pkpSignatureKey.Algorithm = AsymAlgorithms.DSA;
                pkpSignatureKey.KeyMaterial = biSignatureKey[0];
                pkpSignatureKey.TimeCreated = DateTime.Now;
                pkpSignatureKey.Version = PublicKeyPacketVersionNumbers.v4;

                SecretKeyPacket skpSignatureKey = new SecretKeyPacket(false);
                skpSignatureKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
                skpSignatureKey.PublicKey = pkpSignatureKey;
                skpSignatureKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
                rngRand.GetBytes(skpSignatureKey.InitialVector);
                skpSignatureKey.EncryptKeyMaterial(biSignatureKey[1], strPassphrase);
                skpSignatureKey.PublicKey = pkpSignatureKey;

                PublicKeyPacket pkpEncryptionKey = new PublicKeyPacket(true);
                pkpEncryptionKey.Algorithm = AsymAlgorithms.ElGamal_Encrypt_Only;
                pkpEncryptionKey.KeyMaterial = biEncryptionKey[0];
                pkpEncryptionKey.TimeCreated = DateTime.Now;
                pkpEncryptionKey.Version = PublicKeyPacketVersionNumbers.v4;

                SecretKeyPacket skpEncryptionKey = new SecretKeyPacket(true);
                skpEncryptionKey.SymmetricalAlgorithm = SymAlgorithms.AES256;
                skpEncryptionKey.PublicKey = pkpEncryptionKey;
                skpEncryptionKey.InitialVector = new byte[CipherHelper.CipherBlockSize(SymAlgorithms.AES256)];
                rngRand.GetBytes(skpEncryptionKey.InitialVector);
                skpEncryptionKey.EncryptKeyMaterial(biEncryptionKey[1], strPassphrase);
                skpEncryptionKey.PublicKey = pkpEncryptionKey;

                CertifiedUserID cuiUID = new CertifiedUserID();
                UserIDPacket uipUID = new UserIDPacket();
                uipUID.UserID = strName.Trim() + " <" + strEmail.Trim() + ">";
                cuiUID.UserID = uipUID;
                SignaturePacket spSelfSig = new SignaturePacket();
                spSelfSig.Version = SignaturePacketVersionNumbers.v4;
                spSelfSig.HashAlgorithm = HashAlgorithms.SHA1;
                spSelfSig.KeyID = pkpSignatureKey.KeyID;
                spSelfSig.TimeCreated = DateTime.Now;
                SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket();
                sspPrimaryUserID.Type = SignatureSubPacketTypes.PrimaryUserID;
                sspPrimaryUserID.PrimaryUserID = true;
                spSelfSig.AddSubPacket(sspPrimaryUserID, true);
                SignatureSubPacket sspPreferedSymAlgos = new SignatureSubPacket();
                sspPreferedSymAlgos.Type = SignatureSubPacketTypes.PreferedSymmetricAlgorithms;
                sspPreferedSymAlgos.PreferedSymAlgos = new SymAlgorithms[] {SymAlgorithms.AES256, SymAlgorithms.AES192, SymAlgorithms.AES256, SymAlgorithms.CAST5, SymAlgorithms.Triple_DES};
                spSelfSig.AddSubPacket(sspPreferedSymAlgos, true);
                SignatureSubPacket sspPreferedHashAlgos = new SignatureSubPacket();
                sspPreferedHashAlgos.Type = SignatureSubPacketTypes.PreferedHashAlgorithms;
                sspPreferedHashAlgos.PreferedHashAlgos = new HashAlgorithms[] {HashAlgorithms.SHA1};
                spSelfSig.AddSubPacket(sspPreferedHashAlgos, true);
                if (lExpiration != 0) {
                    SignatureSubPacket sspExpiration = new SignatureSubPacket();
                    sspExpiration.Type = SignatureSubPacketTypes.SignatureExpirationTime;
                    sspExpiration.SignatureExpirationTime = new DateTime(lExpiration);
                    spSelfSig.AddSubPacket(sspExpiration, true);
                }
                cuiUID.Certificates = new System.Collections.ArrayList();
                cuiUID.Sign(spSelfSig, skpSignatureKey, strPassphrase, pkpSignatureKey);

                CertifiedPublicSubkey cpsEncryptionKey = new CertifiedPublicSubkey();
                cpsEncryptionKey.Subkey = pkpEncryptionKey;
                cpsEncryptionKey.SignKeyBindingSignature(pkpSignatureKey, skpSignatureKey, strPassphrase, new DateTime(lExpiration), true);

                TransportablePublicKey tpkPublicKey = new TransportablePublicKey();
                tpkPublicKey.PrimaryKey = pkpSignatureKey;
                tpkPublicKey.SubKeys.Add(cpsEncryptionKey);
                tpkPublicKey.Certifications.Add(cuiUID);

                TransportableSecretKey tskSecretKey = new TransportableSecretKey();
                tskSecretKey.PrimaryKey = skpSignatureKey;
                tskSecretKey.SubKeys.Add(skpEncryptionKey);
                tskSecretKey.UserIDs.Add(uipUID);

                this.pkrKeyRing.AddPublicKey(tpkPublicKey);
                this.skrKeyRing.AddSecretKey(tskSecretKey);
                pkrKeyRing.Save();
                skrKeyRing.Save();

            // it's an RSA key
            } else if (strKeyType == "RSA") {

            }
        }
Пример #14
0
        public SignatureSubPacket[] ParsePackets(byte[] bBinaryData)
        {
            ArrayList alPackets	= new ArrayList(100);
            byte[] bTmpData = new byte[bBinaryData.Length];
            Array.Copy(bBinaryData, bTmpData, bBinaryData.Length);

            long iCurrentIndex = 0;

            while (iCurrentIndex < bBinaryData.Length) {
                SignatureSubPacket pTmpPacket = new SignatureSubPacket();
                SignatureSubPacket pCurrentPacket = pTmpPacket.ParsePacket(bTmpData);

                iCurrentIndex += pCurrentPacket.Length;
                alPackets.Add(pCurrentPacket);

                bTmpData = new byte[bTmpData.Length - pCurrentPacket.Length];
                Array.Copy(bBinaryData, (int)iCurrentIndex, bTmpData, 0, bBinaryData.Length - (int)iCurrentIndex);
            }

            SignatureSubPacket[] pReturnPackets = new SignatureSubPacket[alPackets.Count];
            IEnumerator iePacketEnum = alPackets.GetEnumerator();
            int iCount = 0;
            while (iePacketEnum.MoveNext()) {
                pReturnPackets[iCount++] = (SignatureSubPacket)iePacketEnum.Current;
            }

            return pReturnPackets;
        }
Пример #15
0
        /// <summary>
        /// Parses the packet given as byte array into the current
        /// class and returns this with the populated parameters.
        /// </summary>
        /// <param name="bData">A byte array containing an OpenPGP
        /// representation of the packet.</param>
        /// <returns>Returns an SignaturePacket that containes
        /// the parsed properties.</returns>
        /// <remarks>No remarks</remarks>
        public override Packet ParsePacket(byte[] bData)
        {
            Version = (SignaturePacketVersionNumbers)bData[0];

            if (Version == SignaturePacketVersionNumbers.v3)
            {
                SignatureType = (SignatureTypes)bData[2];

                long iTime = (long)bData[3] << 24;
                iTime      ^= (long)bData[4] << 16;
                iTime      ^= (long)bData[5] << 8;
                iTime      ^= (long)bData[6];
                TimeCreated = new DateTime(iTime * 10000000 + new DateTime(1970, 1, 1).Ticks);

                lKeyID  = (ulong)bData[7] << 56;
                lKeyID ^= (ulong)bData[8] << 48;
                lKeyID ^= (ulong)bData[9] << 40;
                lKeyID ^= (ulong)bData[10] << 32;
                lKeyID ^= (ulong)bData[11] << 24;
                lKeyID ^= (ulong)bData[12] << 16;
                lKeyID ^= (ulong)bData[13] << 8;
                lKeyID ^= (ulong)bData[14];

                SignatureAlgorithm = (AsymAlgorithms)bData[15];
                HashAlgorithm      = (HashAlgorithms)bData[16];
                HashedSubPackets   = new SignatureSubPacket[0];
                UnhashedSubPackets = new SignatureSubPacket[0];

                sSignedHash16Bit  = (ushort)(bData[17] << 8);
                sSignedHash16Bit ^= (ushort)(bData[18]);

                byte[] bMPIs = new byte[bData.Length - 19];
                Array.Copy(bData, 19, bMPIs, 0, bMPIs.Length);

                Signature = BigInteger.ParseMPIs(bMPIs);
            }
            else if (Version == SignaturePacketVersionNumbers.v4)
            {
                SignatureType      = (SignatureTypes)bData[1];
                SignatureAlgorithm = (AsymAlgorithms)bData[2];
                HashAlgorithm      = (HashAlgorithms)bData[3];

                int iHashedSubPacketLength = (bData[4] << 8) ^ (bData[5]);

                byte[] bHashedSubPackets = new byte[iHashedSubPacketLength];
                Array.Copy(bData, 6, bHashedSubPackets, 0, iHashedSubPacketLength);

                SignatureSubPacket sspSubPacketParser = new SignatureSubPacket();
                sspHashedSubPackets = sspSubPacketParser.ParsePackets(bHashedSubPackets);
                for (int i = 0; i < sspHashedSubPackets.Length; i++)
                {
                    if (sspHashedSubPackets[i].Type == SignatureSubPacketTypes.IssuerKeyID)
                    {
                        this.KeyID = sspHashedSubPackets[i].KeyID;
                    }
                    else if (sspHashedSubPackets[i].Type == SignatureSubPacketTypes.SignatureCreationTime)
                    {
                        this.TimeCreated = sspHashedSubPackets[i].TimeCreated;
                    }
                }

                int iIndex = iHashedSubPacketLength + 6;

                bHashedPart = new byte[iIndex];
                Array.Copy(bData, 0, bHashedPart, 0, iIndex);

                int iUnhashedSubPacketLength = (bData[iIndex++] << 8)
                                               ^ bData[iIndex++];

                byte[] bUnhashedSubPackets = new byte[iUnhashedSubPacketLength];
                Array.Copy(bData, iIndex, bUnhashedSubPackets, 0, iUnhashedSubPacketLength);

                sspSubPacketParser    = new SignatureSubPacket();
                sspUnhashedSubPackets = sspSubPacketParser.ParsePackets(bUnhashedSubPackets);
                for (int i = 0; i < sspUnhashedSubPackets.Length; i++)
                {
                    if (sspUnhashedSubPackets[i].Type == SignatureSubPacketTypes.IssuerKeyID)
                    {
                        this.KeyID = sspUnhashedSubPackets[i].KeyID;
                    }
                    else if (sspUnhashedSubPackets[i].Type == SignatureSubPacketTypes.SignatureCreationTime)
                    {
                        this.TimeCreated = sspUnhashedSubPackets[i].TimeCreated;
                    }
                }

                iIndex           += iUnhashedSubPacketLength;
                sSignedHash16Bit  = (ushort)(bData[iIndex++] << 8);
                sSignedHash16Bit ^= (ushort)(bData[iIndex++]);

                byte[] bMPIs = new byte[bData.Length - iIndex];
                Array.Copy(bData, iIndex, bMPIs, 0, bMPIs.Length);

                Signature = BigInteger.ParseMPIs(bMPIs);
            }

            this.bIsUpdated = false;
            return(this);
        }
Пример #16
0
 /// <summary>
 /// Changes the primary user id of a public key
 /// </summary>
 /// <param name="newPUID">the certified user id to se as primary</param>
 /// <param name="KeyID">the keyID to execute the operation for</param>
 /// <param name="strPassphrase"></param>
 public void changePrimaryUserID(CertifiedUserID newPUID, ulong KeyID, string strPassphrase)
 {
     TransportablePublicKey tpkKey = this.PublicRing.Find(KeyID,false);
     TransportableSecretKey tskKey = this.SecretRing.Find(KeyID);
     if (tpkKey!=null && tskKey!=null) {
         CertifiedUserID oldPUID = tpkKey.PrimaryUserIDCert;
         if (oldPUID!=newPUID) {
             bool updated = false;
             for (int k = 0; k < oldPUID.Certificates.Count; k++) {
                 SignaturePacket sp = (SignaturePacket)oldPUID.Certificates[k];
                 if(sp.SignatureType == SignatureTypes.UserIDSignature ||
                     sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification ||
                     sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification ||
                     sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification)
                 {
                     foreach (SignatureSubPacket ssp in sp.HashedSubPackets) {
                         if(ssp.Type == SignatureSubPacketTypes.PrimaryUserID) {
                             ssp.PrimaryUserID = false;
                             updated = true;
                         }
                     }
                     if (!updated) {
                         foreach(SignatureSubPacket ssp in sp.UnhashedSubPackets) {
                             if(ssp.Type == SignatureSubPacketTypes.PrimaryUserID) {
                                 ssp.PrimaryUserID = false;
                                 updated = true;
                             }
                         }
                     }
                     if (updated)	{
                         oldPUID.Certificates.Remove(sp);
                         oldPUID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey);
                         break;
                     }
                 }
             }
             updated = false;
             for (int k = 0; k < oldPUID.Certificates.Count; k++) {
                 SignaturePacket sp = (SignaturePacket)newPUID.Certificates[k];
                 if (sp.SignatureType == SignatureTypes.UserIDSignature ||
                     sp.SignatureType == SignatureTypes.UserIDSignature_CasualVerification ||
                     sp.SignatureType == SignatureTypes.UserIDSignature_NoVerification ||
                     sp.SignatureType == SignatureTypes.UserIDSignature_PositivVerification)
                 {
                     foreach(SignatureSubPacket ssp in sp.HashedSubPackets) {
                         if(ssp.Type == SignatureSubPacketTypes.PrimaryUserID) {
                             ssp.PrimaryUserID = true;
                             updated = true;
                         }
                     }
                     if (!updated) {
                         foreach (SignatureSubPacket ssp in sp.UnhashedSubPackets) {
                             if (ssp.Type == SignatureSubPacketTypes.PrimaryUserID) {
                                 ssp.PrimaryUserID = true;
                                 updated = true;
                             }
                         }
                     }
                     if (updated) {
                         newPUID.Certificates.Remove(sp);
                         newPUID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey);
                         break;
                     }
                     if (!updated) {
                         SignatureSubPacket sspPrimaryUserID = new SignatureSubPacket();
                         sspPrimaryUserID.Type = SignatureSubPacketTypes.PrimaryUserID;
                         sspPrimaryUserID.PrimaryUserID = true;
                         sp.AddSubPacket(sspPrimaryUserID,true);
                         newPUID.Certificates.Remove(sp);
                         newPUID.Sign(sp, tskKey.PrimaryKey, strPassphrase, tpkKey.PrimaryKey);
                         break;
                     }
                 }
             }
         }
     }
 }
Пример #17
0
        /// <summary>
        /// Text signing
        /// </summary>
        /// <param name="strMessage">text to be signed</param>
        /// <param name="tskKey">secret key for signing purpose</param>
        /// <param name="strPassphrase">passphrase for the secret key</param>
        /// <returns>the signed text</returns>
        public string ClearTextSign(string strMessage, TransportableSecretKey tskKey, string strPassphrase, bool embedMessage)
        {
            SignaturePacket spSign = new SignaturePacket();

            strMessage = Radix64.TrimMessage(strMessage);

            SecretKeyPacket skpKey = tskKey.FindKey(AsymActions.Sign);

            spSign.HashAlgorithm = HashAlgorithms.SHA1;
            spSign.Format = PacketFormats.New;

            SignatureSubPacket sspCreator = new SignatureSubPacket();
            sspCreator.Type = SignatureSubPacketTypes.IssuerKeyID;
            sspCreator.KeyID = skpKey.PublicKey.KeyID;
            SignatureSubPacket sspCreationTime = new SignatureSubPacket();
            sspCreationTime.Type = SignatureSubPacketTypes.SignatureCreationTime;
            sspCreationTime.TimeCreated = DateTime.Now;
            spSign.HashedSubPackets = new SignatureSubPacket[2];
            spSign.HashedSubPackets[0] = sspCreator;
            spSign.HashedSubPackets[1] = sspCreationTime;

            //spSign.KeyID = skpKey.PublicKey.KeyID;
            //spSign.TimeCreated = DateTime.Now;
            spSign.SignatureAlgorithm = skpKey.PublicKey.Algorithm;
            spSign.SignatureType = SignatureTypes.TextSignature;
            spSign.Version = SignaturePacketVersionNumbers.v4;

            byte[] bMessage = System.Text.Encoding.UTF8.GetBytes(strMessage);
            spSign.Sign(bMessage, skpKey, strPassphrase);

            byte[] bSignature = spSign.Generate();

            string strSignature = Radix64.Encode(bSignature, true);

            string strFinal;

            if(embedMessage)
                strFinal = Armor.WrapCleartextSignature(strMessage, strSignature);
            else
                strFinal = Armor.WrapCleartextSignature(strSignature);

            return strFinal;
        }
Пример #18
0
 public void AddSubPacket(SignatureSubPacket sspSubPacket, bool bHashed)
 {
     if (bHashed) {
         SignatureSubPacket[] sspHashed = new SignatureSubPacket[this.HashedSubPackets.Length + 1];
         Array.Copy(this.HashedSubPackets, 0, sspHashed, 0, this.HashedSubPackets.Length);
         sspHashed[sspHashed.Length - 1] = sspSubPacket;
         this.HashedSubPackets = sspHashed;
     } else {
         SignatureSubPacket[] sspUnhashed = new SignatureSubPacket[this.UnhashedSubPackets.Length + 1];
         Array.Copy(this.HashedSubPackets, 0, sspUnhashed, 0, this.UnhashedSubPackets.Length);
         sspUnhashed[sspUnhashed.Length - 1] = sspSubPacket;
         this.UnhashedSubPackets = sspUnhashed;
     }
     this.bIsUpdated = true;
 }
Пример #19
0
        /// <summary>
        /// Revoke a key
        /// </summary>
        /// <param name="KeyID">key to be revoked</param>
        /// <param name="skpKeySigner">revoker secret key</param>
        /// <param name="strPassphrase">revoker passphrase</param>
        /// <param name="exportable">exportable revocation</param>
        public void RevokeKey(ulong KeyID, TransportableSecretKey skpKeySigner, string strPassphrase, bool exportable)
        {
            TransportablePublicKey tspKey = this.PublicRing.Find(KeyID,false);
            if (tspKey == null)
                throw new Exception("Public Key not found");
            if (this.PublicRing.isRevoked(KeyID))
                throw new Exception("Public Key alreadyRevoked");
            if (tspKey.PrimaryKey.KeyID !=	KeyID)
                throw new Exception("This is not a Primary key... use Revoke Subkey method instead");

            foreach (SignaturePacket sign in tspKey.PrimaryUserIDCert.Certificates) {
                if (!sign.isRevocable())
                    return;
            }

            bool isRevokerKey = false;
            if (KeyID == skpKeySigner.PrimaryKey.PublicKey.KeyID) {
                isRevokerKey = true;
            } else {
                foreach (SignaturePacket spPacket in tspKey.RevocationKeys) {
                    foreach (BigInteger revoker in spPacket.FindRevokerKeys()) {
                        if (revoker.ToString() == skpKeySigner.PrimaryKey.PublicKey.Fingerprint.ToString()) {
                            isRevokerKey = true;
                        }
                    }
                }
            }
            if (!isRevokerKey)
                throw new Exception("You cannot revoke this key");

            SignaturePacket spSig = new SignaturePacket();
            spSig.Version = SignaturePacketVersionNumbers.v4;
            spSig.HashAlgorithm = HashAlgorithms.SHA1;
            spSig.KeyID = skpKeySigner.PrimaryKey.PublicKey.KeyID;
            spSig.TimeCreated = DateTime.Now;
            SignatureSubPacket sspExportableSignature = new SignatureSubPacket();
            sspExportableSignature.Type = SignatureSubPacketTypes.ExportableSignature;
            sspExportableSignature.ExportableSignature = exportable;
            spSig.AddSubPacket(sspExportableSignature, false);

            PublicKeyPacket pkpKey = tspKey.PrimaryKey;
            byte[] key = new byte[tspKey.PrimaryKey.Length];
            tspKey.PrimaryKey.Header.CopyTo(key,0);
            tspKey.PrimaryKey.Body.CopyTo(key,tspKey.PrimaryKey.Header.Length);

            spSig.SignatureType = SignatureTypes.KeyRevocationSignature;
            spSig.Sign(key, skpKeySigner.PrimaryKey, strPassphrase);
            tspKey.RevocationSignatures.Add(spSig);
        }
Пример #20
0
        /// <summary>
        /// Parses the packet given as byte array into the current
        /// class and returns this with the populated parameters.
        /// </summary>
        /// <param name="bData">A byte array containing an OpenPGP
        /// representation of the packet.</param>
        /// <returns>Returns an SignaturePacket that containes
        /// the parsed properties.</returns>
        /// <remarks>No remarks</remarks>
        public override Packet ParsePacket(byte[] bData)
        {
            Version = (SignaturePacketVersionNumbers)bData[0];

            if (Version == SignaturePacketVersionNumbers.v3) {
                SignatureType = (SignatureTypes)bData[2];

                long iTime = (long)bData[3] << 24;
                iTime ^= (long)bData[4] << 16;
                iTime ^= (long)bData[5] << 8;
                iTime ^= (long)bData[6];
                TimeCreated = new DateTime(iTime*10000000 + new DateTime(1970, 1, 1).Ticks);

                lKeyID = (ulong)bData[7] << 56;
                lKeyID ^= (ulong)bData[8] << 48;
                lKeyID ^= (ulong)bData[9] << 40;
                lKeyID ^= (ulong)bData[10] << 32;
                lKeyID ^= (ulong)bData[11] << 24;
                lKeyID ^= (ulong)bData[12] << 16;
                lKeyID ^= (ulong)bData[13] << 8;
                lKeyID ^= (ulong)bData[14];

                SignatureAlgorithm = (AsymAlgorithms)bData[15];
                HashAlgorithm = (HashAlgorithms)bData[16];
                HashedSubPackets = new SignatureSubPacket[0];
                UnhashedSubPackets = new SignatureSubPacket[0];

                sSignedHash16Bit = (ushort)(bData[17] << 8);
                sSignedHash16Bit ^= (ushort)(bData[18]);

                byte[] bMPIs = new byte[bData.Length - 19];
                Array.Copy(bData, 19, bMPIs, 0, bMPIs.Length);

                Signature = BigInteger.ParseMPIs(bMPIs);
            } else if (Version == SignaturePacketVersionNumbers.v4) {
                SignatureType = (SignatureTypes)bData[1];
                SignatureAlgorithm = (AsymAlgorithms)bData[2];
                HashAlgorithm = (HashAlgorithms)bData[3];

                int iHashedSubPacketLength = (bData[4] << 8) ^ (bData[5]);

                byte[] bHashedSubPackets = new byte[iHashedSubPacketLength];
                Array.Copy(bData, 6, bHashedSubPackets, 0, iHashedSubPacketLength);

                SignatureSubPacket sspSubPacketParser = new SignatureSubPacket();
                sspHashedSubPackets = sspSubPacketParser.ParsePackets(bHashedSubPackets);
                for (int i=0; i<sspHashedSubPackets.Length; i++) {
                    if (sspHashedSubPackets[i].Type == SignatureSubPacketTypes.IssuerKeyID) {
                        this.KeyID = sspHashedSubPackets[i].KeyID;
                    } else if (sspHashedSubPackets[i].Type == SignatureSubPacketTypes.SignatureCreationTime) {
                        this.TimeCreated = sspHashedSubPackets[i].TimeCreated;
                    }
                }

                int iIndex = iHashedSubPacketLength + 6;

                bHashedPart = new byte[iIndex];
                Array.Copy(bData, 0, bHashedPart, 0, iIndex);

                int iUnhashedSubPacketLength = (bData[iIndex++] << 8)
                            ^ bData[iIndex++];

                byte[] bUnhashedSubPackets = new byte[iUnhashedSubPacketLength];
                Array.Copy(bData, iIndex, bUnhashedSubPackets, 0, iUnhashedSubPacketLength);

                sspSubPacketParser = new SignatureSubPacket();
                sspUnhashedSubPackets = sspSubPacketParser.ParsePackets(bUnhashedSubPackets);
                for (int i=0; i<sspUnhashedSubPackets.Length; i++) {
                    if (sspUnhashedSubPackets[i].Type == SignatureSubPacketTypes.IssuerKeyID) {
                        this.KeyID = sspUnhashedSubPackets[i].KeyID;
                    } else if (sspUnhashedSubPackets[i].Type == SignatureSubPacketTypes.SignatureCreationTime) {
                        this.TimeCreated = sspUnhashedSubPackets[i].TimeCreated;
                    }
                }

                iIndex += iUnhashedSubPacketLength;
                sSignedHash16Bit = (ushort)(bData[iIndex++] << 8);
                sSignedHash16Bit ^= (ushort)(bData[iIndex++]);

                byte[] bMPIs = new byte[bData.Length - iIndex];
                Array.Copy(bData, iIndex, bMPIs, 0, bMPIs.Length);

                Signature = BigInteger.ParseMPIs(bMPIs);
            }

            this.bIsUpdated = false;
            return this;
        }
Пример #21
0
        /// <summary>
        /// Revoke a subkey
        /// </summary>
        /// <param name="KeyID">subkey ID</param>
        /// <param name="skpKeySigner">revoker secret key</param>
        /// <param name="strPassphrase">revoker passphrase</param>
        /// <param name="exportable">exportable revocation</param>
        public void RevokeSubKey(ulong KeyID, TransportableSecretKey skpKeySigner, string strPassphrase, bool exportable)
        {
            TransportablePublicKey tspKey = this.PublicRing.Find(KeyID,false);
            if(tspKey == null)
                throw new Exception("Public Key not found");
            if(tspKey.PrimaryKey.KeyID == KeyID)
                throw new Exception("This is a primary key... use RevokeKey method instead.");

            CertifiedPublicSubkey cps = null;
            foreach(CertifiedPublicSubkey cpsi in tspKey.SubKeys) {
                if(cpsi.Subkey.KeyID == KeyID)
                    cps = cpsi;
            }

            bool allowed = false;
            ulong issuer = skpKeySigner.PrimaryKey.PublicKey.KeyID;
            if(issuer == tspKey.PrimaryKey.KeyID) {
                allowed = true;
            } else {
                foreach (SignaturePacket spPacket in tspKey.RevocationKeys) {
                    foreach (BigInteger revoker in spPacket.FindRevokerKeys()) {
                        if (revoker.ToString() == skpKeySigner.PrimaryKey.PublicKey.Fingerprint.ToString()) {
                            allowed = true;
                        }
                    }
                }
            }

            if (allowed && cps.KeyBindingSignature.isRevocable()) {
                if (this.PublicRing.isRevoked(KeyID))
                    throw new Exception("Public SubKey alreadyRevoked");

                SignaturePacket spSig = new SignaturePacket();
                spSig.Version = SignaturePacketVersionNumbers.v4;
                spSig.HashAlgorithm = HashAlgorithms.SHA1;
                spSig.KeyID = skpKeySigner.PrimaryKey.PublicKey.KeyID;
                spSig.TimeCreated = DateTime.Now;
                SignatureSubPacket sspExportableSignature = new SignatureSubPacket();
                sspExportableSignature.Type = SignatureSubPacketTypes.ExportableSignature;
                sspExportableSignature.ExportableSignature = exportable;
                spSig.AddSubPacket(sspExportableSignature, false);

                byte[] subkey = new byte[cps.Subkey.Length];
                cps.Subkey.Header.CopyTo(subkey,0);
                cps.Subkey.Body.CopyTo(subkey,cps.Subkey.Header.Length);
                subkey[0]=0x99;

                byte[] mainkey = new byte[tspKey.PrimaryKey.Length];
                tspKey.PrimaryKey.Header.CopyTo(mainkey,0);
                tspKey.PrimaryKey.Body.CopyTo(mainkey,tspKey.PrimaryKey.Header.Length);

                byte[] key = new byte[subkey.Length+mainkey.Length];
                mainkey.CopyTo(key,0);
                subkey.CopyTo(key,mainkey.Length);

                spSig.SignatureType = SignatureTypes.SubkeyRevocationSignature;
                spSig.Sign(key, skpKeySigner.PrimaryKey, strPassphrase);
                cps.RevocationSignature=spSig;
            } else
                throw new Exception("Not allowed to revoke this subkey");
        }
Пример #22
0
        /// <summary>
        /// Signes the data given as parameter with the given secret key.
        /// The given password has to fit the given key.
        /// </summary>
        /// <remarks>
        /// <para>The function calculates a message digest over the given signature
        /// data and signes the digest with the given key.</para>
        /// <para>The results of the signature operation are directly stored
        /// in the Signature property of this class.</para>
        /// </remarks>
        /// <param name="bSignedData">The data that is to be signed.</param>
        /// <param name="skpKey">The key that is to sign the data</param>
        /// <param name="strPassphrase">The passphrase that is neccessary to
        /// decrypt the given key.</param>
        public void Sign(byte[] bSignedData, SecretKeyPacket skpKey, string strPassphrase)
        {
            System.Security.Cryptography.HashAlgorithm haSigner;
            AsymmetricCipher acSigner;

            this.SignatureAlgorithm = skpKey.PublicKey.Algorithm;

            switch (this.HashAlgorithm) {
                case HashAlgorithms.MD5:
                    haSigner = System.Security.Cryptography.MD5.Create();
                    break;
                case HashAlgorithms.SHA1:
                    haSigner = 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:
                    acSigner = new SharpPrivacy.SharpPrivacyLib.Cipher.DSA();
                    break;
                case AsymAlgorithms.RSA_Encrypt_Sign:
                case AsymAlgorithms.RSA_Sign_Only:
                    acSigner = 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 {

                // Add Issuer KeyID Subpacket if it's not there.
                try {
                    ulong lTestForKeyID = this.KeyID;
                } catch (Exception) {
                    SignatureSubPacket sspIssuerKeyID = new SignatureSubPacket();
                    sspIssuerKeyID.Type = SignatureSubPacketTypes.IssuerKeyID;
                    sspIssuerKeyID.KeyID = this.lKeyID;
                    this.AddSubPacket(sspIssuerKeyID, true);
                }

                // Add TimeCreated Subpacket if it's not there.
                try {
                    this.FindSignatureCreationTime();
                } catch (Exception) {
                    SignatureSubPacket sspCreationTime = new SignatureSubPacket();
                    sspCreationTime.Type = SignatureSubPacketTypes.SignatureCreationTime;
                    sspCreationTime.TimeCreated = DateTime.Now;
                    this.AddSubPacket(sspCreationTime, true);
                }

                //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
                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 = haSigner.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 = (skpKey.PublicKey.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);
            }

            sSignedHash16Bit = (ushort)((bHash[0] << 8) + bHash[1]);
            biSignature = acSigner.Sign(biHash, skpKey, strPassphrase);
            this.bIsUpdated = true;
        }