Exemple #1
0
        public static bool TryImport(
            Algorithm algorithm,
            ReadOnlySpan <byte> blob,
            KeyBlobFormat format,
            KeyFlags flags,
            out Key result)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                success = algorithm.TryImportKey(blob, format, out keyHandle, out publicKeyBytes);
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            result = success ? new Key(algorithm, flags, keyHandle, publicKeyBytes) : null;
            return(success);
        }
Exemple #2
0
        public static Key Import(
            Algorithm algorithm,
            ReadOnlySpan <byte> blob,
            KeyBlobFormat format,
            KeyExportPolicies exportPolicy = KeyExportPolicies.None)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                success = algorithm.TryImportKey(blob, format, out keyHandle, out publicKeyBytes);
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            if (!success)
            {
                throw Error.Format_InvalidBlob();
            }

            return(new Key(algorithm, exportPolicy, keyHandle, publicKeyBytes));
        }
Exemple #3
0
        public static SharedSecret Import(
            ReadOnlySpan <byte> sharedSecret)
        {
            if (sharedSecret.Length > 128)
            {
                throw Error.Argument_SharedSecretLength(nameof(sharedSecret), 128.ToString());
            }

            Sodium.Initialize();

            SecureMemoryHandle sharedSecretHandle = null;
            bool success = false;

            try
            {
                SecureMemoryHandle.Import(sharedSecret, out sharedSecretHandle);
                success = true;
            }
            finally
            {
                if (!success && sharedSecretHandle != null)
                {
                    sharedSecretHandle.Dispose();
                }
            }

            return(new SharedSecret(sharedSecretHandle));
        }
        public Key DeriveKey(
            SharedSecret sharedSecret,
            ReadOnlySpan <byte> salt,
            ReadOnlySpan <byte> info,
            Algorithm algorithm,
            KeyExportPolicies exportPolicy = KeyExportPolicies.None)
        {
            if (sharedSecret == null)
            {
                throw Error.ArgumentNull_SharedSecret(nameof(sharedSecret));
            }
            if (!_supportsSalt && !salt.IsEmpty)
            {
                throw Error.Argument_SaltNotSupported(nameof(salt));
            }
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int seedSize = algorithm.GetDefaultSeedSize();

            if (seedSize > MaxOutputSize)
            {
                throw Error.NotSupported_CreateKey();
            }
            Debug.Assert(seedSize <= 64);

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                Span <byte> seed = stackalloc byte[seedSize];
                try
                {
                    DeriveBytesCore(sharedSecret.Handle, salt, info, seed);
                    algorithm.CreateKey(seed, out keyHandle, out publicKeyBytes);
                    success = true;
                }
                finally
                {
                    sodium_memzero(ref seed.DangerousGetPinnableReference(), (UIntPtr)seed.Length);
                }
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            return(new Key(algorithm, exportPolicy, keyHandle, publicKeyBytes));
        }
Exemple #5
0
        public Key DeriveKey(
            SharedSecret sharedSecret,
            ReadOnlySpan <byte> salt,
            ReadOnlySpan <byte> info,
            Algorithm algorithm,
            KeyFlags flags = KeyFlags.None)
        {
            if (sharedSecret == null)
            {
                throw Error.ArgumentNull_SharedSecret(nameof(sharedSecret));
            }
            if (!_supportsSalt && !salt.IsEmpty)
            {
                throw Error.Argument_SaltNotSupported(nameof(salt));
            }
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int keySize = algorithm.GetDefaultKeySize();

            if (keySize > MaxOutputSize)
            {
                throw Error.NotSupported_CreateKey();
            }

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                SecureMemoryHandle.Alloc(keySize, out keyHandle);
                DeriveKeyCore(sharedSecret.Handle, salt, info, keyHandle);
                algorithm.CreateKey(keyHandle, out publicKeyBytes);
                success = true;
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            return(new Key(algorithm, flags, keyHandle, publicKeyBytes));
        }
Exemple #6
0
        public Key(
            Algorithm algorithm,
            KeyExportPolicies exportPolicy = KeyExportPolicies.None)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int seedSize = algorithm.GetDefaultSeedSize();

            Debug.Assert(seedSize <= 64);

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                Span <byte> seed = stackalloc byte[seedSize];
                try
                {
                    RandomGenerator.Default.GenerateBytes(seed);
                    algorithm.CreateKey(seed, out keyHandle, out publicKeyBytes);
                    success = true;
                }
                finally
                {
                    sodium_memzero(ref seed.DangerousGetPinnableReference(), (UIntPtr)seed.Length);
                }
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            keyHandle.MakeReadOnly();

            _algorithm    = algorithm;
            _exportPolicy = exportPolicy;
            _handle       = keyHandle;
            _publicKey    = (publicKeyBytes) != null ? new PublicKey(algorithm, publicKeyBytes) : null;
        }
Exemple #7
0
        public Key(
            Algorithm algorithm,
            KeyFlags flags = KeyFlags.None)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int seedSize = algorithm.GetDefaultSeedSize();

            SecureMemoryHandle keyHandle = null;

            byte[]      publicKeyBytes = null;
            bool        success        = false;
            Span <byte> seed;

            try
            {
                unsafe
                {
                    Debug.Assert(seedSize <= 64);
                    byte *pointer = stackalloc byte[seedSize];
                    seed = new Span <byte>(pointer, seedSize);
                }

                SecureRandom.GenerateBytesCore(seed);
                algorithm.CreateKey(seed, out keyHandle, out publicKeyBytes);
                success = true;
            }
            finally
            {
                sodium_memzero(ref seed.DangerousGetPinnableReference(), (UIntPtr)seed.Length);
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            keyHandle.MakeReadOnly();

            _algorithm = algorithm;
            _flags     = flags;
            _handle    = keyHandle;
            _publicKey = (publicKeyBytes) != null ? new PublicKey(algorithm, publicKeyBytes) : null;
        }
        public SharedSecret Agree(
            Key key,
            PublicKey otherPartyPublicKey)
        {
            if (key == null)
            {
                throw Error.ArgumentNull_Key(nameof(key));
            }
            if (key.Algorithm != this)
            {
                throw Error.Argument_KeyWrongAlgorithm(nameof(key), key.Algorithm.GetType().FullName, GetType().FullName);
            }
            if (otherPartyPublicKey == null)
            {
                throw Error.ArgumentNull_Key(nameof(otherPartyPublicKey));
            }
            if (otherPartyPublicKey.Algorithm != this)
            {
                throw Error.Argument_KeyWrongAlgorithm(nameof(otherPartyPublicKey), key.Algorithm.GetType().FullName, GetType().FullName);
            }

            SecureMemoryHandle sharedSecretHandle = null;
            bool success = false;

            try
            {
                success = TryAgreeCore(key.Handle, otherPartyPublicKey.Bytes, out sharedSecretHandle);
            }
            finally
            {
                if (!success && sharedSecretHandle != null)
                {
                    sharedSecretHandle.Dispose();
                }
            }

            if (!success)
            {
                throw Error.Cryptographic_KeyAgreementFailed();
            }

            return(new SharedSecret(sharedSecretHandle));
        }
Exemple #9
0
        public Key GenerateKey(
            Algorithm algorithm,
            KeyExportPolicies exportPolicy = KeyExportPolicies.None)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int seedSize = algorithm.GetDefaultSeedSize();

            Debug.Assert(seedSize <= 64);

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                Span <byte> seed = stackalloc byte[seedSize];
                try
                {
                    GenerateBytesCore(seed);
                    algorithm.CreateKey(seed, out keyHandle, out publicKeyBytes);
                    success = true;
                }
                finally
                {
                    sodium_memzero(ref MemoryMarshal.GetReference(seed), (UIntPtr)seed.Length);
                }
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            return(new Key(algorithm, exportPolicy, keyHandle, publicKeyBytes));
        }
Exemple #10
0
        public Key(
            Algorithm algorithm,
            KeyFlags flags = KeyFlags.None)
        {
            if (algorithm == null)
            {
                throw Error.ArgumentNull_Algorithm(nameof(algorithm));
            }

            int keySize = algorithm.GetDefaultKeySize();

            SecureMemoryHandle keyHandle = null;

            byte[] publicKeyBytes = null;
            bool   success        = false;

            try
            {
                SecureMemoryHandle.Alloc(keySize, out keyHandle);
                SecureRandom.GenerateKeyCore(keyHandle);
                algorithm.CreateKey(keyHandle, out publicKeyBytes);
                success = true;
            }
            finally
            {
                if (!success && keyHandle != null)
                {
                    keyHandle.Dispose();
                }
            }

            keyHandle.MakeReadOnly();

            _algorithm = algorithm;
            _flags     = flags;
            _handle    = keyHandle;
            _publicKey = (publicKeyBytes) != null ? new PublicKey(algorithm, publicKeyBytes) : null;
        }
Exemple #11
0
 public void Dispose()
 {
     _handle.Dispose();
 }