// // XML Export // // See code:System.Security.Cryptography.ECDsaCng#ECCXMLFormat and // code:System.Security.Cryptography.Rfc4050KeyFormatter#RFC4050ECKeyFormat for information about // elliptic curve XML formats. // public override string ToXmlString(bool includePrivateParameters) { throw new NotImplementedException(SR.GetString(SR.Cryptography_ECXmlSerializationFormatRequired)); }
public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey) { Contract.Ensures(Contract.Result <byte[]>() != null); Contract.Assert(m_kdf >= ECDiffieHellmanKeyDerivationFunction.Hash && m_kdf <= ECDiffieHellmanKeyDerivationFunction.Tls); if (otherPartyPublicKey == null) { throw new ArgumentNullException("otherPartyPublicKey"); } if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "otherPartyPublicKey"); } if (otherPartyPublicKey.KeySize != KeySize) { throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHKeySizeMismatch), "otherPartyPublicKey"); } NCryptNative.SecretAgreementFlags flags = UseSecretAgreementAsHmacKey ? NCryptNative.SecretAgreementFlags.UseSecretAsHmacKey : NCryptNative.SecretAgreementFlags.None; // We require access to the handles for generating key material. This is safe since we will never // expose these handles to user code new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // This looks horribly wrong - but accessing the handle property actually returns a duplicate handle, which // we need to dispose of - otherwise, we're stuck keepign the resource alive until the GC runs. This explicitly // is not disposing of the handle underlying the key dispite what the syntax looks like. using (SafeNCryptKeyHandle localKey = Key.Handle) using (SafeNCryptKeyHandle otherKey = otherPartyPublicKey.Handle) { CodeAccessPermission.RevertAssert(); // // Generating key material is a two phase process. // 1. Generate the secret agreement // 2. Pass the secret agreement through a KDF to get key material // using (SafeNCryptSecretHandle secretAgreement = NCryptNative.DeriveSecretAgreement(localKey, otherKey)) { if (KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hash) { byte[] secretAppend = SecretAppend == null ? null : SecretAppend.Clone() as byte[]; byte[] secretPrepend = SecretPrepend == null ? null : SecretPrepend.Clone() as byte[]; return(NCryptNative.DeriveKeyMaterialHash(secretAgreement, HashAlgorithm.Algorithm, secretPrepend, secretAppend, flags)); } else if (KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hmac) { byte[] hmacKey = HmacKey == null ? null : HmacKey.Clone() as byte[]; byte[] secretAppend = SecretAppend == null ? null : SecretAppend.Clone() as byte[]; byte[] secretPrepend = SecretPrepend == null ? null : SecretPrepend.Clone() as byte[]; return(NCryptNative.DeriveKeyMaterialHmac(secretAgreement, HashAlgorithm.Algorithm, hmacKey, secretPrepend, secretAppend, flags)); } else { Debug.Assert(KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Tls, "Unknown KDF"); byte[] label = Label == null ? null : Label.Clone() as byte[]; byte[] seed = Seed == null ? null : Seed.Clone() as byte[]; if (label == null || seed == null) { throw new InvalidOperationException(SR.GetString(SR.Cryptography_TlsRequiresLabelAndSeed)); } return(NCryptNative.DeriveKeyMaterialTls(secretAgreement, label, seed, flags)); } } } }
// // XML Import // // See code:System.Security.Cryptography.ECDsaCng#ECCXMLFormat and // code:System.Security.Cryptography.Rfc4050KeyFormatter#RFC4050ECKeyFormat for information about // elliptic curve XML formats. // public override void FromXmlString(string xmlString) { throw new NotImplementedException(SR.GetString(SR.Cryptography_ECXmlSerializationFormatRequired)); }
/// <summary> /// Validate the current curve. /// </summary> /// <exception cref="CryptographicException"> /// if the curve parameters are not valid for the current CurveType. /// </exception> public void Validate() { if (IsNamed) { if (HasAnyExplicitParameters()) { throw new CryptographicException(SR.Cryptography_InvalidECNamedCurve); } if (Oid == null || (string.IsNullOrEmpty(Oid.FriendlyName) && string.IsNullOrEmpty(Oid.Value))) { throw new CryptographicException(SR.Cryptography_InvalidCurveOid); } } else if (IsExplicit) { bool hasErrors = false; if (A == null || B == null || B.Length != A.Length || G.X == null || G.X.Length != A.Length || G.Y == null || G.Y.Length != A.Length || Order == null || Order.Length == 0 || Cofactor == null || Cofactor.Length == 0) { hasErrors = true; } if (IsPrime) { if (!hasErrors) { if (Prime == null || Prime.Length != A.Length) { hasErrors = true; } } if (hasErrors) { throw new CryptographicException(SR.Cryptography_InvalidECPrimeCurve); } } else if (IsCharacteristic2) { if (!hasErrors) { if (Polynomial == null || Polynomial.Length == 0) { hasErrors = true; } } if (hasErrors) { throw new CryptographicException(SR.Cryptography_InvalidECCharacteristic2Curve); } } } else { // Implicit; if there are any values, throw Debug.Assert(CurveType == ECCurveType.Implicit); if (HasAnyExplicitParameters() || Oid != null) { throw new CryptographicException(SR.Format(SR.Cryptography_CurveNotSupported, CurveType.ToString())); } } }