Exemple #1
0
        /// <summary>
        /// Get this is a valid header file
        /// </summary>
        ///
        /// <param name="Authority">The stream containing a KeyAuthority structure</param>
        ///
        /// <returns>Valid</returns>
        public static bool IsValid(KeyAuthority Authority)
        {
            int count = 0;

            for (int i = 0; i < Authority.OriginId.Length; i++)
            {
                if (Authority.OriginId[i] == (byte)0)
                {
                    count++;
                }
            }

            return(count < 8);
        }
Exemple #2
0
        /// <summary>
        /// A PackageKey header structure.
        /// </summary>
        ///
        /// <param name="Authority">The <see cref="KeyAuthority">KeyAuthority</see> structure containing the key authorization schema.</param>
        /// <param name="Cipher">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">CipherDescription</see> structure containing a complete description of the cipher instance.</param>
        /// <param name="SubKeyCount">The number of Key Sets contained in this key package file.</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if an invalid ExtensionKey is used</exception>
        public PackageKey(KeyAuthority Authority, CipherDescription Cipher, int SubKeyCount)
        {
            this.KeyPolicy   = Authority.KeyPolicy;
            this.Authority   = Authority;
            this.Description = Cipher;
            this.SubKeyCount = SubKeyCount;
            SubKeyPolicy     = new long[SubKeyCount];
            SubKeyID         = new byte[SubKeyCount][];

            // generate the subkey ids and set master policy
            for (int i = 0; i < SubKeyCount; i++)
            {
                SubKeyPolicy[i] = (long)Authority.KeyPolicy;
                SubKeyID[i]     = Guid.NewGuid().ToByteArray();
            }

            CreatedOn = DateTime.Now.Ticks;
        }
Exemple #3
0
        /// <summary>
        /// Compare this object instance with another
        /// </summary>
        ///
        /// <param name="Obj">Object to compare</param>
        ///
        /// <returns>True if equal, otherwise false</returns>
        public override bool Equals(Object Obj)
        {
            if (!(Obj is KeyAuthority))
            {
                return(false);
            }

            KeyAuthority other = (KeyAuthority)Obj;

            if (!Compare.IsEqual(DomainId, other.DomainId))
            {
                return(false);
            }
            if (!Compare.IsEqual(OriginId, other.OriginId))
            {
                return(false);
            }
            if (!Compare.IsEqual(TargetId, other.TargetId))
            {
                return(false);
            }
            if (!Compare.IsEqual(PackageId, other.PackageId))
            {
                return(false);
            }
            if (!Compare.IsEqual(PackageTag, other.PackageTag))
            {
                return(false);
            }
            if (KeyPolicy != other.KeyPolicy)
            {
                return(false);
            }
            if (OptionFlag != other.OptionFlag)
            {
                return(false);
            }

            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Initialize the PackageKey structure using a Stream
        /// </summary>
        ///
        /// <param name="KeyStream">The Stream containing the PackageKey</param>
        public PackageKey(Stream KeyStream)
        {
            BinaryReader reader = new BinaryReader(KeyStream);

            KeyPolicy    = reader.ReadInt64();
            CreatedOn    = reader.ReadInt64();
            Authority    = new KeyAuthority(KeyStream);
            Description  = new CipherDescription(KeyStream);
            SubKeyCount  = reader.ReadInt32();
            SubKeyPolicy = new long[SubKeyCount];

            byte[] buffer = reader.ReadBytes(SubKeyCount * KEYPOL_SIZE);
            Buffer.BlockCopy(buffer, 0, SubKeyPolicy, 0, buffer.Length);

            buffer   = reader.ReadBytes(SubKeyCount * KEYID_SIZE);
            SubKeyID = new byte[SubKeyCount][];

            for (int i = 0; i < SubKeyCount; i++)
            {
                SubKeyID[i] = new byte[KEYID_SIZE];
                Buffer.BlockCopy(buffer, i * KEYID_SIZE, SubKeyID[i], 0, KEYID_SIZE);
            }
        }
Exemple #5
0
 /// <summary>
 /// Set the KeyAuthority structure
 /// </summary>
 ///
 /// <param name="KeyStream">The stream containing a key package</param>
 /// <param name="Authority">The CipherDescription structure</param>
 public static void SetKeyAuthority(Stream KeyStream, KeyAuthority Authority)
 {
     KeyStream.Seek(KEYAUT_SEEK, SeekOrigin.Begin);
     new BinaryWriter(KeyStream).Write(Authority.ToBytes());
 }
Exemple #6
0
        /// <summary>
        /// Initialize the PackageKey structure using a Stream
        /// </summary>
        /// 
        /// <param name="KeyStream">The Stream containing the PackageKey</param>
        public PackageKey(Stream KeyStream)
        {
            BinaryReader reader = new BinaryReader(KeyStream);

            KeyPolicy = reader.ReadInt64();
            CreatedOn = reader.ReadInt64();
            Authority = new KeyAuthority(KeyStream);
            Description = new CipherDescription(KeyStream);
            ExtensionKey = reader.ReadBytes(EXTKEY_SIZE);
            SubKeyCount = reader.ReadInt32();
            SubKeyPolicy = new long[SubKeyCount];

            byte[] buffer = reader.ReadBytes(SubKeyCount * KEYPOL_SIZE);
            Buffer.BlockCopy(buffer, 0, SubKeyPolicy, 0, buffer.Length);

            buffer = reader.ReadBytes(SubKeyCount * KEYID_SIZE);
            SubKeyID = new byte[SubKeyCount][];

            for (int i = 0; i < SubKeyCount; i++)
            {
                SubKeyID[i] = new byte[KEYID_SIZE];
                Buffer.BlockCopy(buffer, i * KEYID_SIZE, SubKeyID[i], 0, KEYID_SIZE);
            }
        }
Exemple #7
0
 /// <summary>
 /// Set the KeyAuthority structure
 /// </summary>
 /// 
 /// <param name="KeyStream">The stream containing a key package</param>
 /// <param name="Authority">The CipherDescription structure</param>
 public static void SetKeyAuthority(Stream KeyStream, KeyAuthority Authority)
 {
     KeyStream.Seek(KEYAUT_SEEK, SeekOrigin.Begin);
     new BinaryWriter(KeyStream).Write(Authority.ToBytes());
 }
Exemple #8
0
        /// <summary>
        /// A PackageKey header structure. 
        /// </summary>
        /// 
        /// <param name="Authority">The <see cref="KeyAuthority">KeyAuthority</see> structure containing the key authorization schema.</param>
        /// <param name="Cipher">The <see cref="CipherDescription">CipherDescription</see> structure containing a complete description of the cipher instance.</param>
        /// <param name="SubKeyCount">The number of Key Sets contained in this key package file.</param>
        /// <param name="ExtensionKey">An array of random bytes used to encrypt a message file extension. A null value auto generates this field.</param>
        /// 
        /// <exception cref="CryptoProcessingException">Thrown if an invalid ExtensionKey is used</exception>
        public PackageKey(KeyAuthority Authority, CipherDescription Cipher, int SubKeyCount, byte[] ExtensionKey = null)
        {
            this.KeyPolicy = Authority.KeyPolicy;
            this.Authority = Authority;
            this.Description = Cipher;
            this.SubKeyCount = SubKeyCount;
            SubKeyPolicy = new long[SubKeyCount];
            SubKeyID = new byte[SubKeyCount][];

            // generate the subkey ids and set master policy
            for (int i = 0; i < SubKeyCount; i++)
            {
                SubKeyPolicy[i] = (long)Authority.KeyPolicy;
                SubKeyID[i] = Guid.NewGuid().ToByteArray();
            }

            if (ExtensionKey != null)
            {
                if (ExtensionKey.Length != 16)
                    throw new CryptoProcessingException("PackageKey:CTor", "Extension key must be exactly 16 bytes in length!", new ArgumentOutOfRangeException());

                this.ExtensionKey = ExtensionKey;
            }
            else
            {
                using (CSPRng rand = new CSPRng())
                    this.ExtensionKey = rand.GetBytes(16);
            }

            CreatedOn = DateTime.Now.Ticks;
        }
Exemple #9
0
        /// <summary>
        /// Create a key file using a <see cref="PackageKey"/> structure; containing the cipher description and operating ids and flags.
        /// </summary>
        /// 
        /// <param name="Package">The <see cref="PackageKey">Key Header</see> containing the cipher description and operating ids and flags</param>
        /// <param name="SeedEngine">The <see cref="Prngs">Random Generator</see> used to create the stage I seed material during key generation.</param>
        /// <param name="DigestEngine">The <see cref="Digests">Digest Engine</see> used in the stage II phase of key generation.</param>
        /// 
        /// <exception cref="CryptoProcessingException">Thrown if a key file exists at the path specified, the path is read only, the CipherDescription or KeyAuthority structures are invalid, or
        /// number of SubKeys specified is either less than 1 or more than the maximum allowed (100,000)</exception>
        public void Create(PackageKey Package, Prngs SeedEngine = Prngs.CSPRng, Digests DigestEngine = Digests.SHA512)
        {
            // if you are getting exceptions.. read the docs!
            if (File.Exists(_keyPath))
                throw new CryptoProcessingException("PackageFactory:Create", "The key file exists! Can not overwrite an existing key file, choose a different path.", new FileLoadException());
            if (!DirectoryTools.IsWritable(Path.GetDirectoryName(_keyPath)))
                throw new CryptoProcessingException("PackageFactory:Create", "The selected directory is read only! Choose a different path.", new UnauthorizedAccessException());
            if (!CipherDescription.IsValid(Package.Description))
                throw new CryptoProcessingException("PackageFactory:Create", "The key package cipher settings are invalid!", new FormatException());
            if (!KeyAuthority.IsValid(Package.Authority))
                throw new CryptoProcessingException("PackageFactory:Create", "The key package key authority settings are invalid!", new FormatException());
            if (Package.SubKeyCount < 1)
                throw new CryptoProcessingException("PackageFactory:Create", "The key package must contain at least 1 key!", new ArgumentOutOfRangeException());
            if (Package.SubKeyCount > SUBKEY_MAX)
                throw new CryptoProcessingException("PackageFactory:Create", String.Format("The key package can not contain more than {0} keys!", SUBKEY_MAX), new ArgumentOutOfRangeException());

            // get the size of a subkey set
            int subKeySize = Package.Description.KeySize;

            if (Package.Description.IvSize > 0)
                subKeySize += Package.Description.IvSize;

            if (Package.Description.MacSize > 0)
                subKeySize += Package.Description.MacSize;

            if (subKeySize < 0)
                throw new CryptoProcessingException("PackageFactory:Create", "The key package cipher settings are invalid!", new Exception());

            try
            {
                // store the auth struct and policy
                _keyOwner = Package.Authority;
                this.KeyPolicy = Package.KeyPolicy;
                // get the serialized header
                byte[] header = Package.ToBytes();
                // size key buffer
                byte[] buffer = new byte[subKeySize * Package.SubKeyCount];

                // generate the keying material
                using (KeyGenerator keyGen = new KeyGenerator(SeedEngine, DigestEngine))
                    keyGen.GetBytes(buffer);

                using (BinaryWriter keyWriter = new BinaryWriter(new FileStream(_keyPath, FileMode.Create, FileAccess.Write)))
                {
                    // pre-set the size to avoid fragmentation
                    keyWriter.BaseStream.SetLength(PackageKey.GetHeaderSize(Package) + (subKeySize * Package.SubKeyCount));

                    if (IsEncrypted(Package.KeyPolicy))
                    {
                        // add policy flags, only part of key not encrypted
                        keyWriter.Write(Package.KeyPolicy);
                        // get salt, return depends on auth flag settings
                        byte[] salt = GetSalt();
                        // create a buffer for encrypted data
                        int hdrLen = header.Length - PackageKey.GetPolicyOffset();
                        byte[] data = new byte[buffer.Length + hdrLen];
                        // copy header and key material
                        Buffer.BlockCopy(header, PackageKey.GetPolicyOffset(), data, 0, hdrLen);
                        Buffer.BlockCopy(buffer, 0, data, hdrLen, buffer.Length);
                        // encrypt the key and header
                        TransformBuffer(data, salt);
                        // write to file
                        keyWriter.Write(data);
                        // don't wait for gc
                        Array.Clear(salt, 0, salt.Length);
                        Array.Clear(data, 0, data.Length);
                    }
                    else
                    {
                        // write the keypackage header
                        keyWriter.Write(header, 0, header.Length);
                        // write the keying material
                        keyWriter.Write(buffer, 0, buffer.Length);
                    }
                }
                // cleanup
                Array.Clear(header, 0, header.Length);
                Array.Clear(buffer, 0, buffer.Length);
            }
            catch
            {
                throw;
            }
        }
Exemple #10
0
        /// <summary>
        /// Initialize this class with a key file path. 
        /// <para>If the key exixts, permissions are tested, otherwise this path is used as the new key path and file name.</para>
        /// </summary>
        /// 
        /// <param name="KeyPath">The fully qualified path to the key file to be read or created</param>
        /// <param name="Authority">The local KeyAuthority credentials structure</param>
        /// 
        /// <exception cref="CryptoProcessingException">Thrown if an empty KeyPath is used</exception>
        public PackageFactory(string KeyPath, KeyAuthority Authority)
        {
            if (string.IsNullOrEmpty(KeyPath) || Path.GetExtension(KeyPath).Length < 1 || Path.GetFileNameWithoutExtension(KeyPath).Length < 1 || !Path.IsPathRooted(KeyPath))
                throw new CryptoProcessingException("PackageFactory:Ctor", "The key path must contain a valid directory and file name!", new ArgumentException());

            // store authority
            _keyOwner = Authority;
            // file path or destination
            _keyPath = KeyPath;

            if (File.Exists(_keyPath))
                AccessScope = Authenticate();
        }
Exemple #11
0
        /// <summary>
        /// Creates a temporary PackageKey on disk, extracts and compares the copy
        /// <para>Throws an Exception on failure</</para>
        /// </summary>
        public static void PackageFactoryTest()
        {
            string path = GetTempPath();
            KeyGenerator kgen = new KeyGenerator();
            // populate a KeyAuthority structure
            KeyAuthority authority = new KeyAuthority(kgen.GetBytes(16), kgen.GetBytes(16), kgen.GetBytes(16), kgen.GetBytes(32), 0);

            // cipher paramaters
            CipherDescription desc = new CipherDescription(
                SymmetricEngines.RDX, 32,
                IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.X923,
                BlockSizes.B128,
                RoundCounts.R14,
                Digests.Keccak512,
                64,
                Digests.Keccak512);

            // create the package key
            PackageKey pkey = new PackageKey(authority, desc, 10);

            // write a key file
            using (PackageFactory pf = new PackageFactory(path, authority))
                pf.Create(pkey);

            for (int i = 0; i < pkey.SubKeyCount; i++)
            {
                CipherDescription desc2;
                KeyParams kp1;
                KeyParams kp2;
                byte[] ext;
                byte[] id = pkey.SubKeyID[i];

                // get at index
                using (FileStream stream = new FileStream(path, FileMode.Open))
                    kp2 = PackageKey.AtIndex(stream, i);

                // read the package from id
                using (PackageFactory pf = new PackageFactory(path, authority))
                    pf.Extract(id, out desc2, out kp1, out ext);

                // compare key material
                if (!Compare.AreEqual(kp1.Key, kp2.Key))
                    throw new Exception();
                if (!Compare.AreEqual(kp1.IV, kp2.IV))
                    throw new Exception();
                if (!Compare.AreEqual(pkey.ExtensionKey, ext))
                    throw new Exception();
                if (!desc.Equals(desc2))
                    throw new Exception();
            }
            if (File.Exists(path))
                File.Delete(path);
        }
Exemple #12
0
        /// <summary>
        /// Get this is a valid header file
        /// </summary>
        /// 
        /// <param name="Authority">The stream containing a KeyAuthority structure</param>
        /// 
        /// <returns>Valid</returns>
        public static bool IsValid(KeyAuthority Authority)
        {
            int count = 0;
            for (int i = 0; i < Authority.OriginId.Length; i++)
            {
                if (Authority.OriginId[i] == (byte)0)
                    count++;
            }

            return count < 8;
        }