Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,48 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using System;
using System.Runtime.CompilerServices;
namespace System.Security.Cryptography {
/// <summary>
/// Abstract base class for implementations of the AES algorithm
/// </summary>
#if !FEATURE_CORECLR
[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
#else // FEATURE_CORECLR
[TypeForwardedFrom("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
#endif // !FEATURE_CORECLR
public abstract class Aes : SymmetricAlgorithm {
private static KeySizes[] s_legalBlockSizes = { new KeySizes(128, 128, 0) };
private static KeySizes[] s_legalKeySizes = { new KeySizes(128, 256, 64) };
/// <summary>
/// Setup the default values for AES encryption
/// </summary>
protected Aes() {
LegalBlockSizesValue = s_legalBlockSizes;
LegalKeySizesValue = s_legalKeySizes;
BlockSizeValue = 128;
FeedbackSizeValue = 8;
KeySizeValue = 256;
ModeValue = CipherMode.CBC;
}
public static new Aes Create() {
return Create("AES");
}
public static new Aes Create(string algorithmName) {
if (algorithmName == null) {
throw new ArgumentNullException("algorithmName");
}
return CryptoConfig.CreateFromName(algorithmName) as Aes;
}
}
}

View File

@@ -0,0 +1,100 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// AsymmetricAlgorithm.cs
//
namespace System.Security.Cryptography {
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class AsymmetricAlgorithm : IDisposable {
protected int KeySizeValue;
protected KeySizes[] LegalKeySizesValue;
//
// public constructors
//
protected AsymmetricAlgorithm() {}
// AsymmetricAlgorithm implements IDisposable
public void Dispose() {
Clear();
}
public void Clear() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
return;
}
//
// public properties
//
public virtual int KeySize {
get { return KeySizeValue; }
set {
int i;
int j;
for (i=0; i<LegalKeySizesValue.Length; i++) {
if (LegalKeySizesValue[i].SkipSize == 0) {
if (LegalKeySizesValue[i].MinSize == value) { // assume MinSize = MaxSize
KeySizeValue = value;
return;
}
} else {
for (j = LegalKeySizesValue[i].MinSize; j<=LegalKeySizesValue[i].MaxSize;
j += LegalKeySizesValue[i].SkipSize) {
if (j == value) {
KeySizeValue = value;
return;
}
}
}
}
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
}
}
public virtual KeySizes[] LegalKeySizes {
get { return (KeySizes[]) LegalKeySizesValue.Clone(); }
}
public abstract String SignatureAlgorithm {
get;
}
public abstract String KeyExchangeAlgorithm {
get;
}
//
// public methods
//
static public AsymmetricAlgorithm Create() {
// Use the crypto config system to return an instance of
// the default AsymmetricAlgorithm on this machine
return Create("System.Security.Cryptography.AsymmetricAlgorithm");
}
static public AsymmetricAlgorithm Create(String algName) {
return (AsymmetricAlgorithm) CryptoConfig.CreateFromName(algName);
}
public abstract void FromXmlString(String xmlString);
public abstract String ToXmlString(bool includePrivateParameters);
}
}

View File

@@ -0,0 +1,41 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// AsymmetricKeyExchangeDeformatter.cs
//
namespace System.Security.Cryptography {
using System;
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class AsymmetricKeyExchangeDeformatter {
//
// protected constructors
//
protected AsymmetricKeyExchangeDeformatter() {
}
//
// public properties
//
public abstract String Parameters {
get;
set;
}
//
// public methods
//
abstract public void SetKey(AsymmetricAlgorithm key);
abstract public byte[] DecryptKeyExchange(byte[] rgb);
}
}

View File

@@ -0,0 +1,41 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// AsymmetricKeyExchangeFormatter.cs
//
namespace System.Security.Cryptography {
using System;
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class AsymmetricKeyExchangeFormatter {
//
// protected constructors
//
protected AsymmetricKeyExchangeFormatter() {
}
//
// public properties
//
public abstract String Parameters {
get;
}
//
// public methods
//
abstract public void SetKey(AsymmetricAlgorithm key);
abstract public byte[] CreateKeyExchange(byte[] data);
abstract public byte[] CreateKeyExchange(byte[] data, Type symAlgType);
}
}

View File

@@ -0,0 +1,43 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// AsymmetricSignatureDeformatter.cs
//
namespace System.Security.Cryptography {
using System.Security;
using System;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class AsymmetricSignatureDeformatter {
//
// protected constructors
//
protected AsymmetricSignatureDeformatter() {
}
//
// public methods
//
abstract public void SetKey(AsymmetricAlgorithm key);
abstract public void SetHashAlgorithm(String strName);
public virtual bool VerifySignature(HashAlgorithm hash, byte[] rgbSignature) {
if (hash == null) throw new ArgumentNullException("hash");
Contract.EndContractBlock();
SetHashAlgorithm(hash.ToString());
return VerifySignature(hash.Hash, rgbSignature);
}
abstract public bool VerifySignature(byte[] rgbHash, byte[] rgbSignature);
}
}

View File

@@ -0,0 +1,42 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// AsymmetricSignatureFormatter.cs
//
namespace System.Security.Cryptography {
using System;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class AsymmetricSignatureFormatter {
//
// protected constructors
//
protected AsymmetricSignatureFormatter() {
}
//
// public methods
//
abstract public void SetKey(AsymmetricAlgorithm key);
abstract public void SetHashAlgorithm(String strName);
public virtual byte[] CreateSignature(HashAlgorithm hash) {
if (hash == null) throw new ArgumentNullException("hash");
Contract.EndContractBlock();
SetHashAlgorithm(hash.ToString());
return CreateSignature(hash.Hash);
}
abstract public byte[] CreateSignature(byte[] rgbHash);
}
}

View File

@@ -0,0 +1,280 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// Base64Transform.cs
//
// This file contains two ICryptoTransforms: ToBase64Transform and FromBase64Transform
// they may be attached to a CryptoStream in either read or write mode
namespace System.Security.Cryptography {
using System;
using System.IO;
using System.Text;
using System.Diagnostics.Contracts;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum FromBase64TransformMode {
IgnoreWhiteSpaces = 0,
DoNotIgnoreWhiteSpaces = 1,
}
[System.Runtime.InteropServices.ComVisible(true)]
public class ToBase64Transform : ICryptoTransform {
// converting to Base64 takes 3 bytes input and generates 4 bytes output
public int InputBlockSize {
get { return(3); }
}
public int OutputBlockSize {
get { return(4); }
}
public bool CanTransformMultipleBlocks {
get { return(false); }
}
public virtual bool CanReuseTransform {
get { return(true); }
}
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
// Do some validation
if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
// for now, only convert 3 bytes to 4
char[] temp = new char[4];
Convert.ToBase64CharArray(inputBuffer, inputOffset, 3, temp, 0);
byte[] tempBytes = Encoding.ASCII.GetBytes(temp);
if (tempBytes.Length != 4) throw new CryptographicException(Environment.GetResourceString( "Cryptography_SSE_InvalidDataSize" ));
Buffer.BlockCopy(tempBytes, 0, outputBuffer, outputOffset, tempBytes.Length);
return(tempBytes.Length);
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
// Do some validation
if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
// Convert.ToBase64CharArray already does padding, so all we have to check is that
// the inputCount wasn't 0
// again, for now only a block at a time
if (inputCount == 0) {
return(EmptyArray<Byte>.Value);
} else {
char[] temp = new char[4];
Convert.ToBase64CharArray(inputBuffer, inputOffset, inputCount, temp, 0);
byte[] tempBytes = Encoding.ASCII.GetBytes(temp);
return(tempBytes);
}
}
// must implement IDisposable, but in this case there's nothing to do.
public void Dispose() {
Clear();
}
public void Clear() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
}
~ToBase64Transform() {
//
// A finalizer is not necessary here, however since we shipped a finalizer that called
// Dispose(false) in v2.0, we need to keep it around in case any existing code had subclassed
// this transform and expects to have a base class finalizer call its dispose method
//
Dispose(false);
}
}
[System.Runtime.InteropServices.ComVisible(true)]
public class FromBase64Transform : ICryptoTransform {
private byte[] _inputBuffer = new byte[4];
private int _inputIndex;
private FromBase64TransformMode _whitespaces;
// Constructors
public FromBase64Transform() : this(FromBase64TransformMode.IgnoreWhiteSpaces) {}
public FromBase64Transform(FromBase64TransformMode whitespaces) {
_whitespaces = whitespaces;
_inputIndex = 0;
}
// converting from Base64 generates 3 bytes output from each 4 bytes input block
public int InputBlockSize {
get { return(1); }
}
public int OutputBlockSize {
get { return(3); }
}
public bool CanTransformMultipleBlocks {
get { return(false); }
}
public virtual bool CanReuseTransform {
get { return(true); }
}
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
// Do some validation
if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (_inputBuffer == null)
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
byte[] temp = new byte[inputCount];
char[] tempChar;
int effectiveCount;
if (_whitespaces == FromBase64TransformMode.IgnoreWhiteSpaces) {
temp = DiscardWhiteSpaces(inputBuffer, inputOffset, inputCount);
effectiveCount = temp.Length;
} else {
Buffer.InternalBlockCopy(inputBuffer, inputOffset, temp, 0, inputCount);
effectiveCount = inputCount;
}
if (effectiveCount + _inputIndex < 4) {
Buffer.InternalBlockCopy(temp, 0, _inputBuffer, _inputIndex, effectiveCount);
_inputIndex += effectiveCount;
return 0;
}
// Get the number of 4 bytes blocks to transform
int numBlocks = (effectiveCount + _inputIndex) / 4;
byte[] transformBuffer = new byte[_inputIndex + effectiveCount];
Buffer.InternalBlockCopy(_inputBuffer, 0, transformBuffer, 0, _inputIndex);
Buffer.InternalBlockCopy(temp, 0, transformBuffer, _inputIndex, effectiveCount);
_inputIndex = (effectiveCount + _inputIndex) % 4;
Buffer.InternalBlockCopy(temp, effectiveCount - _inputIndex, _inputBuffer, 0, _inputIndex);
tempChar = Encoding.ASCII.GetChars(transformBuffer, 0, 4*numBlocks);
byte[] tempBytes = Convert.FromBase64CharArray(tempChar, 0, 4*numBlocks);
Buffer.BlockCopy(tempBytes, 0, outputBuffer, outputOffset, tempBytes.Length);
return(tempBytes.Length);
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
// Do some validation
if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (_inputBuffer == null)
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
byte[] temp = new byte[inputCount];
char[] tempChar;
int effectiveCount;
if (_whitespaces == FromBase64TransformMode.IgnoreWhiteSpaces) {
temp = DiscardWhiteSpaces(inputBuffer, inputOffset, inputCount);
effectiveCount = temp.Length;
} else {
Buffer.InternalBlockCopy(inputBuffer, inputOffset, temp, 0, inputCount);
effectiveCount = inputCount;
}
if (effectiveCount + _inputIndex < 4) {
Reset();
return (EmptyArray<Byte>.Value);
}
// Get the number of 4 bytes blocks to transform
int numBlocks = (effectiveCount + _inputIndex) / 4;
byte[] transformBuffer = new byte[_inputIndex + effectiveCount];
Buffer.InternalBlockCopy(_inputBuffer, 0, transformBuffer, 0, _inputIndex);
Buffer.InternalBlockCopy(temp, 0, transformBuffer, _inputIndex, effectiveCount);
_inputIndex = (effectiveCount + _inputIndex) % 4;
Buffer.InternalBlockCopy(temp, effectiveCount - _inputIndex, _inputBuffer, 0, _inputIndex);
tempChar = Encoding.ASCII.GetChars(transformBuffer, 0, 4*numBlocks);
byte[] tempBytes = Convert.FromBase64CharArray(tempChar, 0, 4*numBlocks);
// reinitialize the transform
Reset();
return(tempBytes);
}
private byte[] DiscardWhiteSpaces(byte[] inputBuffer, int inputOffset, int inputCount) {
int i, iCount = 0;
for (i=0; i<inputCount; i++)
if (Char.IsWhiteSpace((char)inputBuffer[inputOffset + i])) iCount++;
byte[] rgbOut = new byte[inputCount - iCount];
iCount = 0;
for (i=0; i<inputCount; i++)
if (!Char.IsWhiteSpace((char)inputBuffer[inputOffset + i])) {
rgbOut[iCount++] = inputBuffer[inputOffset + i];
}
return rgbOut;
}
// must implement IDisposable, which in this case means clearing the input buffer
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
// Reset the state of the transform so it can be used again
private void Reset() {
_inputIndex = 0;
}
public void Clear() {
Dispose();
}
protected virtual void Dispose(bool disposing) {
// we always want to clear the input buffer
if (disposing) {
if (_inputBuffer != null)
Array.Clear(_inputBuffer, 0, _inputBuffer.Length);
_inputBuffer = null;
_inputIndex = 0;
}
}
~FromBase64Transform() {
//
// A finalizer is not necessary here, however since we shipped a finalizer that called
// Dispose(false) in v2.0, we need to keep it around in case any existing code had subclassed
// this transform and expects to have a base class finalizer call its dispose method
//
Dispose(false);
}
}
}

View File

@@ -0,0 +1,168 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// Crypto.cs
//
namespace System.Security.Cryptography {
using Microsoft.Win32;
using System.Runtime.Serialization;
using System.Globalization;
// This enum represents cipher chaining modes: cipher block chaining (CBC),
// electronic code book (ECB), output feedback (OFB), cipher feedback (CFB),
// and ciphertext-stealing (CTS). Not all implementations will support all modes.
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum CipherMode { // Please keep in [....] with wincrypt.h
CBC = 1,
ECB = 2,
OFB = 3,
CFB = 4,
CTS = 5
}
// This enum represents the padding method to use for filling out short blocks.
// "None" means no padding (whole blocks required).
// "PKCS7" is the padding mode defined in RFC 2898, Section 6.1.1, Step 4, generalized
// to whatever block size is required.
// "Zeros" means pad with zero bytes to fill out the last block.
// "ISO 10126" is the same as PKCS5 except that it fills the bytes before the last one with
// random bytes. "ANSI X.923" fills the bytes with zeros and puts the number of padding
// bytes in the last byte.
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum PaddingMode {
None = 1,
PKCS7 = 2,
Zeros = 3,
ANSIX923 = 4,
ISO10126 = 5
}
// This structure is used for returning the set of legal key sizes and
// block sizes of the symmetric algorithms.
// Note: this class should be sealed, otherwise someone could sub-class it and the read-only
// properties we depend on can have setters. Ideally, we should have a struct here (value type)
// but we use what we have now and try to close the hole allowing someone to specify an invalid key size
#if !FEATURE_CORECLR
[System.Runtime.InteropServices.ComVisible(true)]
#endif // !FEATURE_CORECLR
public sealed class KeySizes {
private int m_minSize;
private int m_maxSize;
private int m_skipSize;
public int MinSize {
get { return m_minSize; }
}
public int MaxSize {
get { return m_maxSize; }
}
public int SkipSize {
get { return m_skipSize; }
}
public KeySizes(int minSize, int maxSize, int skipSize) {
m_minSize = minSize; m_maxSize = maxSize; m_skipSize = skipSize;
}
}
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class CryptographicException : SystemException {
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
public CryptographicException()
: base(Environment.GetResourceString("Arg_CryptographyException")) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO);
}
public CryptographicException(String message)
: base(message) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO);
}
public CryptographicException(String format, String insert)
: base(String.Format(CultureInfo.CurrentCulture, format, insert)) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO);
}
public CryptographicException(String message, Exception inner)
: base(message, inner) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO);
}
[System.Security.SecuritySafeCritical] // auto-generated
public CryptographicException(int hr)
: this(
#if FEATURE_LEGACYNETCFCRYPTO
CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 ? GetLegacyNetCFMessage(hr) :
#endif
Win32Native.GetMessage(hr)) {
if ((hr & 0x80000000) != 0x80000000)
hr = (hr & 0x0000FFFF) | unchecked((int)0x80070000);
SetErrorCode(hr);
}
#if FEATURE_SERIALIZATION
protected CryptographicException(SerializationInfo info, StreamingContext context) : base (info, context) {}
#endif // FEATURE_SERIALIZATION
// This method is only called from inside the VM.
private static void ThrowCryptographicException (int hr) {
throw new CryptographicException(hr);
}
#if FEATURE_LEGACYNETCFCRYPTO
// NetCF throws CryptographicExceptions with the text "Unknown Error (hresult here)."
private static string GetLegacyNetCFMessage(int hr) {
if ((uint)hr == 0x8000701a) { // PAL_ERROR_CRYPT_PROV_TYPE_NOT_DEF
return Environment.GetResourceString("Cryptography_LegacyNetCF_CSP_CouldNotAcquire");
}
return Environment.GetResourceString("Cryptography_LegacyNetCF_UnknownError", hr.ToString("X", CultureInfo.InvariantCulture));
}
#endif
}
[Serializable()]
[System.Runtime.InteropServices.ComVisible(true)]
public class CryptographicUnexpectedOperationException : CryptographicException {
public CryptographicUnexpectedOperationException()
: base() {
SetErrorCode(__HResults.CORSEC_E_CRYPTO_UNEX_OPER);
}
public CryptographicUnexpectedOperationException(String message)
: base(message) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO_UNEX_OPER);
}
public CryptographicUnexpectedOperationException(String format, String insert)
: base(String.Format(CultureInfo.CurrentCulture, format, insert)) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO_UNEX_OPER);
}
public CryptographicUnexpectedOperationException(String message, Exception inner)
: base(message, inner) {
SetErrorCode(__HResults.CORSEC_E_CRYPTO_UNEX_OPER);
}
#if FEATURE_SERIALIZATION
protected CryptographicUnexpectedOperationException(SerializationInfo info, StreamingContext context) : base (info, context) {}
#endif // FEATURE_SERIALIZATION
}
}

View File

@@ -0,0 +1,425 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// CryptoAPITransform.cs
//
namespace System.Security.Cryptography {
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
#if FEATURE_MACL && FEATURE_CRYPTO
[Serializable]
internal enum CryptoAPITransformMode {
Encrypt = 0,
Decrypt = 1
}
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class CryptoAPITransform : ICryptoTransform {
private int BlockSizeValue;
private byte[] IVValue;
private CipherMode ModeValue;
private PaddingMode PaddingValue;
private CryptoAPITransformMode encryptOrDecrypt;
private byte[] _rgbKey;
private byte[] _depadBuffer = null;
[System.Security.SecurityCritical] // auto-generated
private SafeKeyHandle _safeKeyHandle;
[System.Security.SecurityCritical] // auto-generated
private SafeProvHandle _safeProvHandle;
private CryptoAPITransform () {}
[System.Security.SecurityCritical] // auto-generated
internal CryptoAPITransform(int algid, int cArgs, int[] rgArgIds,
Object[] rgArgValues, byte[] rgbKey, PaddingMode padding,
CipherMode cipherChainingMode, int blockSize,
int feedbackSize, bool useSalt,
CryptoAPITransformMode encDecMode) {
int dwValue;
byte[] rgbValue;
BlockSizeValue = blockSize;
ModeValue = cipherChainingMode;
PaddingValue = padding;
encryptOrDecrypt = encDecMode;
// Copy the input args
int _cArgs = cArgs;
int[] _rgArgIds = new int[rgArgIds.Length];
Array.Copy(rgArgIds, _rgArgIds, rgArgIds.Length);
_rgbKey = new byte[rgbKey.Length];
Array.Copy(rgbKey, _rgbKey, rgbKey.Length);
Object[] _rgArgValues = new Object[rgArgValues.Length];
// an element of rgArgValues can only be an int or a byte[]
for (int j = 0; j < rgArgValues.Length; j++) {
if (rgArgValues[j] is byte[]) {
byte[] rgbOrig = (byte[]) rgArgValues[j];
byte[] rgbNew = new byte[rgbOrig.Length];
Array.Copy(rgbOrig, rgbNew, rgbOrig.Length);
_rgArgValues[j] = rgbNew;
continue;
}
if (rgArgValues[j] is int) {
_rgArgValues[j] = (int) rgArgValues[j];
continue;
}
if (rgArgValues[j] is CipherMode) {
_rgArgValues[j] = (int) rgArgValues[j];
continue;
}
}
_safeProvHandle = Utils.AcquireProvHandle(new CspParameters(Utils.DefaultRsaProviderType));
SafeKeyHandle safeKeyHandle = SafeKeyHandle.InvalidHandle;
// _ImportBulkKey will check for failures and throw an exception
Utils._ImportBulkKey(_safeProvHandle, algid, useSalt, _rgbKey, ref safeKeyHandle);
_safeKeyHandle = safeKeyHandle;
for (int i=0; i<cArgs; i++) {
switch (rgArgIds[i]) {
case Constants.KP_IV:
IVValue = (byte[]) _rgArgValues[i];
rgbValue = IVValue;
Utils.SetKeyParamRgb(_safeKeyHandle, _rgArgIds[i], rgbValue, rgbValue.Length);
break;
case Constants.KP_MODE:
ModeValue = (CipherMode) _rgArgValues[i];
dwValue = (Int32) _rgArgValues[i];
SetAsDWord:
Utils.SetKeyParamDw(_safeKeyHandle, _rgArgIds[i], dwValue);
break;
case Constants.KP_MODE_BITS:
dwValue = (Int32) _rgArgValues[i];
goto SetAsDWord;
case Constants.KP_EFFECTIVE_KEYLEN:
dwValue = (Int32) _rgArgValues[i];
goto SetAsDWord;
default:
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeyParameter"), "_rgArgIds[i]");
}
}
}
public void Dispose() {
Clear();
}
[System.Security.SecuritySafeCritical] // auto-generated
public void Clear() {
Dispose(true);
GC.SuppressFinalize(this);
}
[System.Security.SecurityCritical] // auto-generated
private void Dispose(bool disposing) {
if (disposing) {
// We need to always zeroize the following fields because they contain sensitive data
if (_rgbKey != null) {
Array.Clear(_rgbKey,0,_rgbKey.Length);
_rgbKey = null;
}
if (IVValue != null) {
Array.Clear(IVValue,0,IVValue.Length);
IVValue = null;
}
if (_depadBuffer != null) {
Array.Clear(_depadBuffer, 0, _depadBuffer.Length);
_depadBuffer = null;
}
if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed) {
_safeKeyHandle.Dispose();
}
if (_safeProvHandle != null && !_safeProvHandle.IsClosed) {
_safeProvHandle.Dispose();
}
}
}
//
// public properties
//
public IntPtr KeyHandle {
[System.Security.SecuritySafeCritical] // auto-generated
[SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
get { return _safeKeyHandle.DangerousGetHandle(); }
}
public int InputBlockSize {
get { return(BlockSizeValue/8); }
}
public int OutputBlockSize {
get { return(BlockSizeValue/8); }
}
public bool CanTransformMultipleBlocks {
get { return(true); }
}
public bool CanReuseTransform {
get { return(true); }
}
//
// public methods
//
// This routine resets the internal state of the CryptoAPITransform
[System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
public void Reset() {
_depadBuffer = null;
// just ensure we've called CryptEncrypt with the true flag
byte[] temp = null;
Utils._EncryptData(_safeKeyHandle, EmptyArray<Byte>.Value, 0, 0, ref temp, 0, PaddingValue, true);
}
[System.Security.SecuritySafeCritical] // auto-generated
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
// Note: special handling required if decrypting & using padding because the padding adds to the end of the last
// block, we have to buffer an entire block's worth of bytes in case what I just transformed turns out to be
// the last block Then in TransformFinalBlock we strip off the padding.
if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
if (outputBuffer == null) throw new ArgumentNullException("outputBuffer");
if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if ((inputCount <= 0) || (inputCount % InputBlockSize != 0) || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (encryptOrDecrypt == CryptoAPITransformMode.Encrypt) {
// if we're encrypting we can always push out the bytes because no padding mode
// removes bytes during encryption
return Utils._EncryptData(_safeKeyHandle, inputBuffer, inputOffset, inputCount, ref outputBuffer, outputOffset, PaddingValue, false);
} else {
if (PaddingValue == PaddingMode.Zeros || PaddingValue == PaddingMode.None) {
// like encryption, if we're using None or Zeros padding on decrypt we can write out all
// the bytes. Note that we cannot depad a block partially padded with Zeros because
// we can't tell if those zeros are plaintext or pad.
return Utils._DecryptData(_safeKeyHandle, inputBuffer, inputOffset, inputCount, ref outputBuffer, outputOffset, PaddingValue, false);
} else {
// OK, now we're in the special case. Check to see if this is the *first* block we've seen
// If so, buffer it and return null zero bytes
if (_depadBuffer == null) {
_depadBuffer = new byte[InputBlockSize];
// copy the last InputBlockSize bytes to _depadBuffer everything else gets processed and returned
int inputToProcess = inputCount - InputBlockSize;
Buffer.InternalBlockCopy(inputBuffer, inputOffset+inputToProcess, _depadBuffer, 0, InputBlockSize);
return Utils._DecryptData(_safeKeyHandle, inputBuffer, inputOffset, inputToProcess, ref outputBuffer, outputOffset, PaddingValue, false);
} else {
// we already have a depad buffer, so we need to decrypt that info first & copy it out
int r = Utils._DecryptData(_safeKeyHandle, _depadBuffer, 0, _depadBuffer.Length, ref outputBuffer, outputOffset, PaddingValue, false);
outputOffset += OutputBlockSize;
int inputToProcess = inputCount - InputBlockSize;
Buffer.InternalBlockCopy(inputBuffer, inputOffset+inputToProcess, _depadBuffer, 0, InputBlockSize);
r = Utils._DecryptData(_safeKeyHandle, inputBuffer, inputOffset, inputToProcess, ref outputBuffer, outputOffset, PaddingValue, false);
return (OutputBlockSize + r);
}
}
}
}
[System.Security.SecuritySafeCritical] // auto-generated
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0) throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if ((inputCount < 0) || (inputCount > inputBuffer.Length)) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (encryptOrDecrypt == CryptoAPITransformMode.Encrypt) {
// If we're encrypting we can always return what we compute because there's no _depadBuffer
byte[] transformedBytes = null;
Utils._EncryptData(_safeKeyHandle, inputBuffer, inputOffset, inputCount, ref transformedBytes, 0, PaddingValue, true);
Reset();
return transformedBytes;
} else {
if (inputCount%InputBlockSize != 0)
throw new CryptographicException(Environment.GetResourceString("Cryptography_SSD_InvalidDataSize"));
if (_depadBuffer == null) {
byte[] transformedBytes = null;
Utils._DecryptData(_safeKeyHandle, inputBuffer, inputOffset, inputCount, ref transformedBytes, 0, PaddingValue, true);
Reset();
return transformedBytes;
} else {
byte[] temp = new byte[_depadBuffer.Length + inputCount];
Buffer.InternalBlockCopy(_depadBuffer, 0, temp, 0, _depadBuffer.Length);
Buffer.InternalBlockCopy(inputBuffer, inputOffset, temp, _depadBuffer.Length, inputCount);
byte[] transformedBytes = null;
Utils._DecryptData(_safeKeyHandle, temp, 0, temp.Length, ref transformedBytes, 0, PaddingValue, true);
Reset();
return transformedBytes;
}
}
}
}
#endif // FEATURE_MACL && FEATURE_CRYPTO
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
[Flags]
public enum CspProviderFlags {
NoFlags = 0x0000,
UseMachineKeyStore = 0x0001,
UseDefaultKeyContainer = 0x0002,
UseNonExportableKey = 0x0004,
UseExistingKey = 0x0008,
UseArchivableKey = 0x0010,
UseUserProtectedKey = 0x0020,
NoPrompt = 0x0040,
CreateEphemeralKey = 0x0080
}
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class CspParameters
{
public int ProviderType;
public string ProviderName;
[ResourceExposure(ResourceScope.Machine)]
public string KeyContainerName;
public int KeyNumber;
private int m_flags;
public CspProviderFlags Flags {
get { return (CspProviderFlags) m_flags; }
set {
int allFlags = 0x00FF; // this should change if more values are added to CspProviderFlags
Contract.Assert((CspProviderFlags.UseMachineKeyStore |
CspProviderFlags.UseDefaultKeyContainer |
CspProviderFlags.UseNonExportableKey |
CspProviderFlags.UseExistingKey |
CspProviderFlags.UseArchivableKey |
CspProviderFlags.UseUserProtectedKey |
CspProviderFlags.NoPrompt |
CspProviderFlags.CreateEphemeralKey) == (CspProviderFlags)allFlags, "allFlags does not match all CspProviderFlags");
int flags = (int) value;
if ((flags & ~allFlags) != 0)
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)value), "value");
m_flags = flags;
}
}
#if FEATURE_MACL
private CryptoKeySecurity m_cryptoKeySecurity;
public CryptoKeySecurity CryptoKeySecurity {
get {
return m_cryptoKeySecurity;
}
set {
m_cryptoKeySecurity = value;
}
}
#endif
#if FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS
private SecureString m_keyPassword;
public SecureString KeyPassword {
get {
return m_keyPassword;
}
set {
m_keyPassword = value;
// Parent handle and PIN are mutually exclusive.
m_parentWindowHandle = IntPtr.Zero;
}
}
private IntPtr m_parentWindowHandle;
public IntPtr ParentWindowHandle {
[ResourceExposure(ResourceScope.Machine)]
get {
return m_parentWindowHandle;
}
[ResourceExposure(ResourceScope.Machine)]
set {
m_parentWindowHandle = value;
// Parent handle and PIN are mutually exclusive.
m_keyPassword = null;
}
}
#endif
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
public CspParameters () : this(Utils.DefaultRsaProviderType, null, null) {}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
public CspParameters (int dwTypeIn) : this(dwTypeIn, null, null) {}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
public CspParameters (int dwTypeIn, string strProviderNameIn) : this(dwTypeIn, strProviderNameIn, null) {}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public CspParameters (int dwTypeIn, string strProviderNameIn, string strContainerNameIn) :
this (dwTypeIn, strProviderNameIn, strContainerNameIn, CspProviderFlags.NoFlags) {}
#if FEATURE_MACL && FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public CspParameters (int providerType, string providerName, string keyContainerName,
CryptoKeySecurity cryptoKeySecurity, SecureString keyPassword)
: this (providerType, providerName, keyContainerName) {
m_cryptoKeySecurity = cryptoKeySecurity;
m_keyPassword = keyPassword;
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public CspParameters (int providerType, string providerName, string keyContainerName,
CryptoKeySecurity cryptoKeySecurity, IntPtr parentWindowHandle)
: this (providerType, providerName, keyContainerName) {
m_cryptoKeySecurity = cryptoKeySecurity;
m_parentWindowHandle = parentWindowHandle;
}
#endif // #if FEATURE_MACL && FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS
[ResourceExposure(ResourceScope.Machine)]
internal CspParameters (int providerType, string providerName, string keyContainerName, CspProviderFlags flags) {
ProviderType = providerType;
ProviderName = providerName;
KeyContainerName = keyContainerName;
KeyNumber = -1;
Flags = flags;
}
// copy constructor
internal CspParameters (CspParameters parameters) {
ProviderType = parameters.ProviderType;
ProviderName = parameters.ProviderName;
KeyContainerName = parameters.KeyContainerName;
KeyNumber = parameters.KeyNumber;
Flags = parameters.Flags;
#if FEATURE_MACL
m_cryptoKeySecurity = parameters.m_cryptoKeySecurity;
#endif // FEATURE_MACL
#if FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS
m_keyPassword = parameters.m_keyPassword;
m_parentWindowHandle = parameters.m_parentWindowHandle;
#endif // FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DeriveBytes.cs
//
namespace System.Security.Cryptography {
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class DeriveBytes
// On Orcas DeriveBytes is not disposable, so we cannot add the IDisposable implementation to the
// CoreCLR mscorlib. However, this type does need to be disposable since subtypes can and do hold onto
// native resources. Therefore, on desktop mscorlibs we add an IDisposable implementation.
#if !FEATURE_CORECLR
: IDisposable
#endif // !FEATURE_CORECLR
{
//
// public methods
//
public abstract byte[] GetBytes(int cb);
public abstract void Reset();
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
return;
}
}
}

View File

@@ -0,0 +1,141 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DES.cs
//
namespace System.Security.Cryptography {
using System;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class DES : SymmetricAlgorithm
{
private static KeySizes[] s_legalBlockSizes = {
new KeySizes(64, 64, 0)
};
private static KeySizes[] s_legalKeySizes = {
new KeySizes(64, 64, 0)
};
//
// protected constructors
//
protected DES() {
KeySizeValue = 64;
BlockSizeValue = 64;
FeedbackSizeValue = BlockSizeValue;
LegalBlockSizesValue = s_legalBlockSizes;
LegalKeySizesValue = s_legalKeySizes;
}
//
// public properties
//
public override byte[] Key {
get {
if (KeyValue == null) {
// Never hand back a weak or semi-weak key
do {
GenerateKey();
} while (IsWeakKey(KeyValue) || IsSemiWeakKey(KeyValue));
}
return (byte[]) KeyValue.Clone();
}
set {
if (value == null) throw new ArgumentNullException("value");
Contract.EndContractBlock();
if (!ValidKeySize(value.Length * 8)) { // must convert bytes to bits
throw new ArgumentException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
}
if (IsWeakKey(value)) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_Weak"),"DES");
}
if (IsSemiWeakKey(value)) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_SemiWeak"),"DES");
}
KeyValue = (byte[]) value.Clone();
KeySizeValue = value.Length * 8;
}
}
//
// public methods
//
new static public DES Create() {
return Create("System.Security.Cryptography.DES");
}
new static public DES Create(String algName) {
return (DES) CryptoConfig.CreateFromName(algName);
}
public static bool IsWeakKey(byte[] rgbKey) {
if (!IsLegalKeySize(rgbKey)) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
}
byte[] rgbOddParityKey = Utils.FixupKeyParity(rgbKey);
UInt64 key = QuadWordFromBigEndian(rgbOddParityKey);
if ((key == 0x0101010101010101) ||
(key == 0xfefefefefefefefe) ||
(key == 0x1f1f1f1f0e0e0e0e) ||
(key == 0xe0e0e0e0f1f1f1f1)) {
return(true);
}
return(false);
}
public static bool IsSemiWeakKey(byte[] rgbKey) {
if (!IsLegalKeySize(rgbKey)) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize"));
}
byte[] rgbOddParityKey = Utils.FixupKeyParity(rgbKey);
UInt64 key = QuadWordFromBigEndian(rgbOddParityKey);
if ((key == 0x01fe01fe01fe01fe) ||
(key == 0xfe01fe01fe01fe01) ||
(key == 0x1fe01fe00ef10ef1) ||
(key == 0xe01fe01ff10ef10e) ||
(key == 0x01e001e001f101f1) ||
(key == 0xe001e001f101f101) ||
(key == 0x1ffe1ffe0efe0efe) ||
(key == 0xfe1ffe1ffe0efe0e) ||
(key == 0x011f011f010e010e) ||
(key == 0x1f011f010e010e01) ||
(key == 0xe0fee0fef1fef1fe) ||
(key == 0xfee0fee0fef1fef1)) {
return(true);
}
return(false);
}
//
// private methods
//
private static bool IsLegalKeySize(byte[] rgbKey) {
if (rgbKey != null && rgbKey.Length == 8) return(true);
return(false);
}
private static UInt64 QuadWordFromBigEndian(byte[] block)
{
UInt64 x;
x = (
(((UInt64)block[0]) << 56) | (((UInt64)block[1]) << 48) |
(((UInt64)block[2]) << 40) | (((UInt64)block[3]) << 32) |
(((UInt64)block[4]) << 24) | (((UInt64)block[5]) << 16) |
(((UInt64)block[6]) << 8) | ((UInt64)block[7])
);
return(x);
}
}
}

View File

@@ -0,0 +1,132 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DESCryptoServiceProvider.cs
//
namespace System.Security.Cryptography {
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class DESCryptoServiceProvider : DES {
//
// public constructors
//
[System.Security.SecuritySafeCritical] // auto-generated
public DESCryptoServiceProvider () {
if (!Utils.HasAlgorithm(Constants.CALG_DES, 0))
throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_AlgorithmNotAvailable"));
// Since the CSP only supports a CFB feedback of 8, make that the default
FeedbackSizeValue = 8;
}
//
// public methods
//
[System.Security.SecuritySafeCritical] // auto-generated
public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) {
if (IsWeakKey(rgbKey))
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_Weak"),"DES");
if (IsSemiWeakKey(rgbKey))
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_SemiWeak"),"DES");
return _NewEncryptor(rgbKey, ModeValue, rgbIV, FeedbackSizeValue, CryptoAPITransformMode.Encrypt);
}
[System.Security.SecuritySafeCritical] // auto-generated
public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) {
if (IsWeakKey(rgbKey))
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_Weak"),"DES");
if (IsSemiWeakKey(rgbKey))
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKey_SemiWeak"),"DES");
return _NewEncryptor(rgbKey, ModeValue, rgbIV, FeedbackSizeValue, CryptoAPITransformMode.Decrypt);
}
public override void GenerateKey () {
KeyValue = new byte[8];
Utils.StaticRandomNumberGenerator.GetBytes(KeyValue);
// Never hand back a weak or semi-weak key
while (DES.IsWeakKey(KeyValue) || DES.IsSemiWeakKey(KeyValue)) {
Utils.StaticRandomNumberGenerator.GetBytes(KeyValue);
}
}
public override void GenerateIV () {
IVValue = new byte[8];
Utils.StaticRandomNumberGenerator.GetBytes(IVValue);
}
//
// private methods
//
[System.Security.SecurityCritical] // auto-generated
private ICryptoTransform _NewEncryptor (byte[] rgbKey, CipherMode mode, byte[] rgbIV, int feedbackSize, CryptoAPITransformMode encryptMode) {
int cArgs = 0;
int[] rgArgIds = new int[10];
Object[] rgArgValues = new Object[10];
// Check for bad values
// 1) we don't support OFB mode in DESCryptoServiceProvider
if (mode == CipherMode.OFB)
throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_OFBNotSupported"));
// 2) we only support CFB with a feedback size of 8 bits
if ((mode == CipherMode.CFB) && (feedbackSize != 8))
throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CFBSizeNotSupported"));
// Build the key if one does not already exist
if (rgbKey == null) {
rgbKey = new byte[8];
Utils.StaticRandomNumberGenerator.GetBytes(rgbKey);
}
// Set the mode for the encryptor (defaults to CBC)
if (mode != CipherMode.CBC) {
rgArgIds[cArgs] = Constants.KP_MODE;
rgArgValues[cArgs] = mode;
cArgs += 1;
}
// If not ECB mode -- pass in an IV
if (mode != CipherMode.ECB) {
if (rgbIV == null) {
rgbIV = new byte[8];
Utils.StaticRandomNumberGenerator.GetBytes(rgbIV);
}
//
// We truncate IV's that are longer than the block size to 8 bytes : this is
// done to maintain backward compatibility with the behavior shipped in V1.x.
// The call to set the IV in CryptoAPI will ignore any bytes after the first 8
// bytes. We'll still reject IV's that are shorter than the block size though.
//
if (rgbIV.Length < 8)
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidIVSize"));
rgArgIds[cArgs] = Constants.KP_IV;
rgArgValues[cArgs] = rgbIV;
cArgs += 1;
}
// If doing OFB or CFB, then we need to set the feed back loop size
if ((mode == CipherMode.OFB) || (mode == CipherMode.CFB)) {
rgArgIds[cArgs] = Constants.KP_MODE_BITS;
rgArgValues[cArgs] = feedbackSize;
cArgs += 1;
}
// Create the encryptpr/decryptor object
return new CryptoAPITransform(Constants.CALG_DES, cArgs, rgArgIds,
rgArgValues, rgbKey, PaddingValue,
mode, BlockSizeValue, feedbackSize, false,
encryptMode);
}
}
}

View File

@@ -0,0 +1,187 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DSA.cs
//
namespace System.Security.Cryptography {
using System.Text;
using System.Runtime.Serialization;
using System.Security.Util;
using System.Globalization;
using System.Diagnostics.Contracts;
// DSAParameters is serializable so that one could pass the public parameters
// across a remote call, but we explicitly make the private key X non-serializable
// so you cannot accidently send it along with the public parameters.
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public struct DSAParameters {
public byte[] P;
public byte[] Q;
public byte[] G;
public byte[] Y;
public byte[] J;
[NonSerialized] public byte[] X;
public byte[] Seed;
public int Counter;
}
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class DSA : AsymmetricAlgorithm
{
//
// Extending this class allows us to know that you are really implementing
// an DSA key. This is required for anybody providing a new DSA key value
// implemention.
//
// The class provides no methods, fields or anything else. Its only purpose is
// as a heirarchy member for identification of the algorithm.
//
protected DSA() { }
//
// public methods
//
new static public DSA Create() {
return Create("System.Security.Cryptography.DSA");
}
new static public DSA Create(String algName) {
return (DSA) CryptoConfig.CreateFromName(algName);
}
abstract public byte[] CreateSignature(byte[] rgbHash);
abstract public bool VerifySignature(byte[] rgbHash, byte[] rgbSignature);
// We can provide a default implementation of FromXmlString because we require
// every DSA implementation to implement ImportParameters
// All we have to do here is parse the XML.
public override void FromXmlString(String xmlString) {
if (xmlString == null) throw new ArgumentNullException("xmlString");
Contract.EndContractBlock();
DSAParameters dsaParams = new DSAParameters();
Parser p = new Parser(xmlString);
SecurityElement topElement = p.GetTopElement();
// P is always present
String pString = topElement.SearchForTextOfLocalName("P");
if (pString == null) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","P"));
}
dsaParams.P = Convert.FromBase64String(Utils.DiscardWhiteSpaces(pString));
// Q is always present
String qString = topElement.SearchForTextOfLocalName("Q");
if (qString == null) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","Q"));
}
dsaParams.Q = Convert.FromBase64String(Utils.DiscardWhiteSpaces(qString));
// G is always present
String gString = topElement.SearchForTextOfLocalName("G");
if (gString == null) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","G"));
}
dsaParams.G = Convert.FromBase64String(Utils.DiscardWhiteSpaces(gString));
// Y is always present
String yString = topElement.SearchForTextOfLocalName("Y");
if (yString == null) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","Y"));
}
dsaParams.Y = Convert.FromBase64String(Utils.DiscardWhiteSpaces(yString));
// J is optional
String jString = topElement.SearchForTextOfLocalName("J");
if (jString != null) dsaParams.J = Convert.FromBase64String(Utils.DiscardWhiteSpaces(jString));
// X is optional -- private key if present
String xString = topElement.SearchForTextOfLocalName("X");
if (xString != null) dsaParams.X = Convert.FromBase64String(Utils.DiscardWhiteSpaces(xString));
// Seed and PgenCounter are optional as a unit -- both present or both absent
String seedString = topElement.SearchForTextOfLocalName("Seed");
String pgenCounterString = topElement.SearchForTextOfLocalName("PgenCounter");
if ((seedString != null) && (pgenCounterString != null)) {
dsaParams.Seed = Convert.FromBase64String(Utils.DiscardWhiteSpaces(seedString));
dsaParams.Counter = Utils.ConvertByteArrayToInt(Convert.FromBase64String(Utils.DiscardWhiteSpaces(pgenCounterString)));
} else if ((seedString != null) || (pgenCounterString != null)) {
if (seedString == null) {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","Seed"));
} else {
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidFromXmlString","DSA","PgenCounter"));
}
}
ImportParameters(dsaParams);
}
// We can provide a default implementation of ToXmlString because we require
// every DSA implementation to implement ImportParameters
// If includePrivateParameters is false, this is just an XMLDSIG DSAKeyValue
// clause. If includePrivateParameters is true, then we extend DSAKeyValue with
// the other (private) elements.
public override String ToXmlString(bool includePrivateParameters) {
// From the XMLDSIG spec, RFC 3075, Section 6.4.1, a DSAKeyValue looks like this:
/*
<element name="DSAKeyValue">
<complexType>
<sequence>
<sequence>
<element name="P" type="ds:CryptoBinary"/>
<element name="Q" type="ds:CryptoBinary"/>
<element name="G" type="ds:CryptoBinary"/>
<element name="Y" type="ds:CryptoBinary"/>
<element name="J" type="ds:CryptoBinary" minOccurs="0"/>
</sequence>
<sequence minOccurs="0">
<element name="Seed" type="ds:CryptoBinary"/>
<element name="PgenCounter" type="ds:CryptoBinary"/>
</sequence>
</sequence>
</complexType>
</element>
*/
// we extend appropriately for private component X
DSAParameters dsaParams = this.ExportParameters(includePrivateParameters);
StringBuilder sb = new StringBuilder();
sb.Append("<DSAKeyValue>");
// Add P, Q, G and Y
sb.Append("<P>"+Convert.ToBase64String(dsaParams.P)+"</P>");
sb.Append("<Q>"+Convert.ToBase64String(dsaParams.Q)+"</Q>");
sb.Append("<G>"+Convert.ToBase64String(dsaParams.G)+"</G>");
sb.Append("<Y>"+Convert.ToBase64String(dsaParams.Y)+"</Y>");
// Add optional components if present
if (dsaParams.J != null) {
sb.Append("<J>"+Convert.ToBase64String(dsaParams.J)+"</J>");
}
if ((dsaParams.Seed != null)) { // note we assume counter is correct if Seed is present
sb.Append("<Seed>"+Convert.ToBase64String(dsaParams.Seed)+"</Seed>");
sb.Append("<PgenCounter>"+Convert.ToBase64String(Utils.ConvertIntToByteArray(dsaParams.Counter))+"</PgenCounter>");
}
if (includePrivateParameters) {
// Add the private component
sb.Append("<X>"+Convert.ToBase64String(dsaParams.X)+"</X>");
}
sb.Append("</DSAKeyValue>");
return(sb.ToString());
}
abstract public DSAParameters ExportParameters(bool includePrivateParameters);
abstract public void ImportParameters(DSAParameters parameters);
}
}

View File

@@ -0,0 +1,368 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DSACryptoServiceProvider.cs
//
// CSP-based implementation of DSA
//
namespace System.Security.Cryptography {
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Globalization;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
// Object layout of the DSAParameters structure
internal class DSACspObject {
internal byte[] P;
internal byte[] Q;
internal byte[] G;
internal byte[] Y;
internal byte[] J;
internal byte[] X;
internal byte[] Seed;
internal int Counter;
}
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class DSACryptoServiceProvider : DSA, ICspAsymmetricAlgorithm {
private int _dwKeySize;
private CspParameters _parameters;
private bool _randomKeyContainer;
[System.Security.SecurityCritical] // auto-generated
private SafeProvHandle _safeProvHandle;
[System.Security.SecurityCritical] // auto-generated
private SafeKeyHandle _safeKeyHandle;
private SHA1CryptoServiceProvider _sha1;
private static volatile CspProviderFlags s_UseMachineKeyStore = 0;
//
// public constructors
//
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
public DSACryptoServiceProvider()
: this(0, new CspParameters(Constants.PROV_DSS_DH, null, null, s_UseMachineKeyStore)) {
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
public DSACryptoServiceProvider(int dwKeySize)
: this(dwKeySize, new CspParameters(Constants.PROV_DSS_DH, null, null, s_UseMachineKeyStore)) {
}
public DSACryptoServiceProvider(CspParameters parameters)
: this(0, parameters) {
}
[System.Security.SecuritySafeCritical] // auto-generated
public DSACryptoServiceProvider(int dwKeySize, CspParameters parameters) {
if (dwKeySize < 0)
throw new ArgumentOutOfRangeException("dwKeySize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
_parameters = Utils.SaveCspParameters(CspAlgorithmType.Dss, parameters, s_UseMachineKeyStore, ref _randomKeyContainer);
LegalKeySizesValue = new KeySizes[] { new KeySizes(512, 1024, 64) }; // per the DSS spec
_dwKeySize = dwKeySize;
_sha1 = new SHA1CryptoServiceProvider();
// If this is not a random container we generate, create it eagerly
// in the constructor so we can report any errors now.
if (!_randomKeyContainer || Environment.GetCompatibilityFlag(CompatibilityFlag.EagerlyGenerateRandomAsymmKeys))
GetKeyPair();
}
//
// private methods
//
[System.Security.SecurityCritical] // auto-generated
private void GetKeyPair () {
if (_safeKeyHandle == null) {
lock (this) {
if (_safeKeyHandle == null)
Utils.GetKeyPairHelper(CspAlgorithmType.Dss, _parameters, _randomKeyContainer, _dwKeySize, ref _safeProvHandle, ref _safeKeyHandle);
}
}
}
[System.Security.SecuritySafeCritical] // overrides public transparent member
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
_safeKeyHandle.Dispose();
if (_safeProvHandle != null && !_safeProvHandle.IsClosed)
_safeProvHandle.Dispose();
}
//
// public properties
//
[System.Runtime.InteropServices.ComVisible(false)]
public bool PublicOnly {
[System.Security.SecuritySafeCritical] // auto-generated
get {
GetKeyPair();
byte[] publicKey = (byte[]) Utils._GetKeyParameter(_safeKeyHandle, Constants.CLR_PUBLICKEYONLY);
return (publicKey[0] == 1);
}
}
[System.Runtime.InteropServices.ComVisible(false)]
public CspKeyContainerInfo CspKeyContainerInfo {
[System.Security.SecuritySafeCritical] // auto-generated
get {
GetKeyPair();
return new CspKeyContainerInfo(_parameters, _randomKeyContainer);
}
}
public override int KeySize {
[System.Security.SecuritySafeCritical] // auto-generated
get {
GetKeyPair();
byte[] keySize = (byte[]) Utils._GetKeyParameter(_safeKeyHandle, Constants.CLR_KEYLEN);
_dwKeySize = (keySize[0] | (keySize[1] << 8) | (keySize[2] << 16) | (keySize[3] << 24));
return _dwKeySize;
}
}
public override string KeyExchangeAlgorithm {
get { return null; }
}
public override string SignatureAlgorithm {
get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }
}
public static bool UseMachineKeyStore {
get { return (s_UseMachineKeyStore == CspProviderFlags.UseMachineKeyStore); }
set { s_UseMachineKeyStore = (value ? CspProviderFlags.UseMachineKeyStore : 0); }
}
public bool PersistKeyInCsp {
[System.Security.SecuritySafeCritical] // auto-generated
get {
if (_safeProvHandle == null) {
lock (this) {
if (_safeProvHandle == null)
_safeProvHandle = Utils.CreateProvHandle(_parameters, _randomKeyContainer);
}
}
return Utils.GetPersistKeyInCsp(_safeProvHandle);
}
[System.Security.SecuritySafeCritical] // auto-generated
set {
bool oldPersistKeyInCsp = this.PersistKeyInCsp;
if (value == oldPersistKeyInCsp)
return;
KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
if (!value) {
KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Delete);
kp.AccessEntries.Add(entry);
} else {
KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Create);
kp.AccessEntries.Add(entry);
}
kp.Demand();
Utils.SetPersistKeyInCsp(_safeProvHandle, value);
}
}
//
// public methods
//
[System.Security.SecuritySafeCritical] // auto-generated
public override DSAParameters ExportParameters (bool includePrivateParameters) {
GetKeyPair();
if (includePrivateParameters) {
KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Export);
kp.AccessEntries.Add(entry);
kp.Demand();
}
DSACspObject dsaCspObject = new DSACspObject();
int blobType = includePrivateParameters ? Constants.PRIVATEKEYBLOB : Constants.PUBLICKEYBLOB;
// _ExportKey will check for failures and throw an exception
Utils._ExportKey(_safeKeyHandle, blobType, dsaCspObject);
return DSAObjectToStruct(dsaCspObject);
}
[System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
public byte[] ExportCspBlob (bool includePrivateParameters) {
GetKeyPair();
return Utils.ExportCspBlobHelper(includePrivateParameters, _parameters, _safeKeyHandle);
}
[System.Security.SecuritySafeCritical] // auto-generated
public override void ImportParameters(DSAParameters parameters) {
DSACspObject dsaCspObject = DSAStructToObject(parameters);
// Free the current key handle
if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
_safeKeyHandle.Dispose();
_safeKeyHandle = SafeKeyHandle.InvalidHandle;
if (IsPublic(parameters)) {
// Use our CRYPT_VERIFYCONTEXT handle, CRYPT_EXPORTABLE is not applicable to public only keys, so pass false
Utils._ImportKey(Utils.StaticDssProvHandle, Constants.CALG_DSS_SIGN, (CspProviderFlags) 0, dsaCspObject, ref _safeKeyHandle);
} else {
KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Import);
kp.AccessEntries.Add(entry);
kp.Demand();
if (_safeProvHandle == null)
_safeProvHandle = Utils.CreateProvHandle(_parameters, _randomKeyContainer);
// Now, import the key into the CSP; _ImportKey will check for failures.
Utils._ImportKey(_safeProvHandle, Constants.CALG_DSS_SIGN, _parameters.Flags, dsaCspObject, ref _safeKeyHandle);
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
public void ImportCspBlob (byte[] keyBlob) {
Utils.ImportCspBlobHelper(CspAlgorithmType.Dss, keyBlob, IsPublic(keyBlob), ref _parameters, _randomKeyContainer, ref _safeProvHandle, ref _safeKeyHandle);
}
public byte[] SignData(Stream inputStream) {
byte[] hashVal = _sha1.ComputeHash(inputStream);
return SignHash(hashVal, null);
}
public byte[] SignData(byte[] buffer) {
byte[] hashVal = _sha1.ComputeHash(buffer);
return SignHash(hashVal, null);
}
public byte[] SignData(byte[] buffer, int offset, int count) {
byte[] hashVal = _sha1.ComputeHash(buffer, offset, count);
return SignHash(hashVal, null);
}
public bool VerifyData(byte[] rgbData, byte[] rgbSignature) {
byte[] hashVal = _sha1.ComputeHash(rgbData);
return VerifyHash(hashVal, null, rgbSignature);
}
override public byte[] CreateSignature(byte[] rgbHash) {
return SignHash(rgbHash, null);
}
override public bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) {
return VerifyHash(rgbHash, null, rgbSignature);
}
[System.Security.SecuritySafeCritical] // auto-generated
public byte[] SignHash(byte[] rgbHash, string str) {
if (rgbHash == null)
throw new ArgumentNullException("rgbHash");
Contract.EndContractBlock();
if (PublicOnly)
throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_NoPrivateKey"));
int calgHash = X509Utils.NameOrOidToAlgId(str, OidGroup.HashAlgorithm);
if (rgbHash.Length != _sha1.HashSize / 8)
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidHashSize", "SHA1", _sha1.HashSize / 8));
GetKeyPair();
if (!CspKeyContainerInfo.RandomlyGenerated) {
KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(_parameters, KeyContainerPermissionFlags.Sign);
kp.AccessEntries.Add(entry);
kp.Demand();
}
return Utils.SignValue(_safeKeyHandle, _parameters.KeyNumber, Constants.CALG_DSS_SIGN, calgHash, rgbHash);
}
[System.Security.SecuritySafeCritical] // auto-generated
public bool VerifyHash(byte[] rgbHash, string str, byte[] rgbSignature) {
if (rgbHash == null)
throw new ArgumentNullException("rgbHash");
if (rgbSignature == null)
throw new ArgumentNullException("rgbSignature");
Contract.EndContractBlock();
int calgHash = X509Utils.NameOrOidToAlgId(str, OidGroup.HashAlgorithm);
if (rgbHash.Length != _sha1.HashSize / 8)
throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidHashSize", "SHA1", _sha1.HashSize / 8));
GetKeyPair();
return Utils.VerifySign(_safeKeyHandle, Constants.CALG_DSS_SIGN, calgHash, rgbHash, rgbSignature);
}
//
// private static methods
//
private static DSAParameters DSAObjectToStruct (DSACspObject dsaCspObject) {
DSAParameters dsaParams = new DSAParameters();
dsaParams.P = dsaCspObject.P;
dsaParams.Q = dsaCspObject.Q;
dsaParams.G = dsaCspObject.G;
dsaParams.Y = dsaCspObject.Y;
dsaParams.J = dsaCspObject.J;
dsaParams.X = dsaCspObject.X;
dsaParams.Seed = dsaCspObject.Seed;
dsaParams.Counter = dsaCspObject.Counter;
return dsaParams;
}
private static DSACspObject DSAStructToObject (DSAParameters dsaParams) {
DSACspObject dsaCspObject = new DSACspObject();
dsaCspObject.P = dsaParams.P;
dsaCspObject.Q = dsaParams.Q;
dsaCspObject.G = dsaParams.G;
dsaCspObject.Y = dsaParams.Y;
dsaCspObject.J = dsaParams.J;
dsaCspObject.X = dsaParams.X;
dsaCspObject.Seed = dsaParams.Seed;
dsaCspObject.Counter = dsaParams.Counter;
return dsaCspObject;
}
private static bool IsPublic (DSAParameters dsaParams) {
return (dsaParams.X == null);
}
// find whether a DSS key blob is public.
private static bool IsPublic (byte[] keyBlob) {
if (keyBlob == null)
throw new ArgumentNullException("keyBlob");
Contract.EndContractBlock();
// The CAPI DSS public key representation consists of the following sequence:
// - BLOBHEADER
// - DSSPUBKEY
// - rgbP[cbKey]
// - rgbQ[20]
// - rgbG[cbKey]
// - rgbY[cbKey]
// - DSSSEED
// The first should be PUBLICKEYBLOB and magic should be DSS_MAGIC "DSS1" or DSS_PUB_MAGIC_VER3 "DSS3"
if (keyBlob[0] != Constants.PUBLICKEYBLOB)
return false;
if ((keyBlob[11] != 0x31 && keyBlob[11] != 0x33) || keyBlob[10] != 0x53 || keyBlob[9] != 0x53 || keyBlob[8] != 0x44)
return false;
return true;
}
}
}

View File

@@ -0,0 +1,68 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DSASignatureDeformatter.cs
//
using System;
using System.Diagnostics.Contracts;
using System.Security.Cryptography.X509Certificates;
namespace System.Security.Cryptography {
[System.Runtime.InteropServices.ComVisible(true)]
public class DSASignatureDeformatter : AsymmetricSignatureDeformatter {
DSA _dsaKey; // DSA Key value to do decrypt operation
string _oid;
//
// public constructors
//
public DSASignatureDeformatter() {
// The hash algorithm is always SHA1
_oid = CryptoConfig.MapNameToOID("SHA1", OidGroup.HashAlgorithm);
}
public DSASignatureDeformatter(AsymmetricAlgorithm key) : this() {
if (key == null)
throw new ArgumentNullException("key");
Contract.EndContractBlock();
_dsaKey = (DSA) key;
}
//
// public methods
//
public override void SetKey(AsymmetricAlgorithm key) {
if (key == null)
throw new ArgumentNullException("key");
Contract.EndContractBlock();
_dsaKey = (DSA) key;
}
public override void SetHashAlgorithm(string strName) {
if (CryptoConfig.MapNameToOID(strName, OidGroup.HashAlgorithm) != _oid)
throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_InvalidOperation"));
}
public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) {
if (rgbHash == null)
throw new ArgumentNullException("rgbHash");
if (rgbSignature == null)
throw new ArgumentNullException("rgbSignature");
Contract.EndContractBlock();
if (_dsaKey == null)
throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_MissingKey"));
return _dsaKey.VerifySignature(rgbHash, rgbSignature);
}
}
}

View File

@@ -0,0 +1,68 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// DSASignatureFormatter.cs
//
using System;
using System.Diagnostics.Contracts;
using System.Security.Cryptography.X509Certificates;
namespace System.Security.Cryptography {
[System.Runtime.InteropServices.ComVisible(true)]
public class DSASignatureFormatter : AsymmetricSignatureFormatter {
DSA _dsaKey;
String _oid;
//
// public constructors
//
public DSASignatureFormatter() {
// The hash algorithm is always SHA1
_oid = CryptoConfig.MapNameToOID("SHA1", OidGroup.HashAlgorithm);
}
public DSASignatureFormatter(AsymmetricAlgorithm key) : this() {
if (key == null)
throw new ArgumentNullException("key");
Contract.EndContractBlock();
_dsaKey = (DSA) key;
}
//
// public methods
//
public override void SetKey(AsymmetricAlgorithm key) {
if (key == null)
throw new ArgumentNullException("key");
Contract.EndContractBlock();
_dsaKey = (DSA) key;
}
public override void SetHashAlgorithm(String strName) {
if (CryptoConfig.MapNameToOID(strName, OidGroup.HashAlgorithm) != _oid)
throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_InvalidOperation"));
}
public override byte[] CreateSignature(byte[] rgbHash) {
if (rgbHash == null)
throw new ArgumentNullException("rgbHash");
Contract.EndContractBlock();
if (_oid == null)
throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_MissingOID"));
if (_dsaKey == null)
throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_MissingKey"));
return _dsaKey.CreateSignature(rgbHash);
}
}
}

View File

@@ -0,0 +1,225 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// HashAlgorithm.cs
//
namespace System.Security.Cryptography {
using System.IO;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class HashAlgorithm : IDisposable, ICryptoTransform {
protected int HashSizeValue;
protected internal byte[] HashValue;
protected int State = 0;
private bool m_bDisposed = false;
protected HashAlgorithm() {}
//
// public properties
//
public virtual int HashSize {
get { return HashSizeValue; }
}
public virtual byte[] Hash {
get {
if (m_bDisposed)
throw new ObjectDisposedException(null);
if (State != 0)
throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_HashNotYetFinalized"));
return (byte[]) HashValue.Clone();
}
}
//
// public methods
//
static public HashAlgorithm Create() {
return Create("System.Security.Cryptography.HashAlgorithm");
}
static public HashAlgorithm Create(String hashName) {
return (HashAlgorithm) CryptoConfig.CreateFromName(hashName);
}
public byte[] ComputeHash(Stream inputStream) {
if (m_bDisposed)
throw new ObjectDisposedException(null);
// Default the buffer size to 4K.
byte[] buffer = new byte[4096];
int bytesRead;
do {
bytesRead = inputStream.Read(buffer, 0, 4096);
if (bytesRead > 0) {
HashCore(buffer, 0, bytesRead);
}
} while (bytesRead > 0);
HashValue = HashFinal();
byte[] Tmp = (byte[]) HashValue.Clone();
Initialize();
return(Tmp);
}
public byte[] ComputeHash(byte[] buffer) {
if (m_bDisposed)
throw new ObjectDisposedException(null);
// Do some validation
if (buffer == null) throw new ArgumentNullException("buffer");
HashCore(buffer, 0, buffer.Length);
HashValue = HashFinal();
byte[] Tmp = (byte[]) HashValue.Clone();
Initialize();
return(Tmp);
}
public byte[] ComputeHash(byte[] buffer, int offset, int count) {
// Do some validation
if (buffer == null)
throw new ArgumentNullException("buffer");
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0 || (count > buffer.Length))
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((buffer.Length - count) < offset)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (m_bDisposed)
throw new ObjectDisposedException(null);
HashCore(buffer, offset, count);
HashValue = HashFinal();
byte[] Tmp = (byte[]) HashValue.Clone();
Initialize();
return(Tmp);
}
// ICryptoTransform methods
// we assume any HashAlgorithm can take input a byte at a time
public virtual int InputBlockSize {
get { return(1); }
}
public virtual int OutputBlockSize {
get { return(1); }
}
public virtual bool CanTransformMultipleBlocks {
get { return(true); }
}
public virtual bool CanReuseTransform {
get { return(true); }
}
// We implement TransformBlock and TransformFinalBlock here
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
// Do some validation, we let BlockCopy do the destination array validation
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0)
throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (inputCount < 0 || (inputCount > inputBuffer.Length))
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (m_bDisposed)
throw new ObjectDisposedException(null);
// Change the State value
State = 1;
HashCore(inputBuffer, inputOffset, inputCount);
if ((outputBuffer != null) && ((inputBuffer != outputBuffer) || (inputOffset != outputOffset)))
Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
return inputCount;
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
// Do some validation
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0)
throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (inputCount < 0 || (inputCount > inputBuffer.Length))
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
if ((inputBuffer.Length - inputCount) < inputOffset)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
if (m_bDisposed)
throw new ObjectDisposedException(null);
HashCore(inputBuffer, inputOffset, inputCount);
HashValue = HashFinal();
byte[] outputBytes;
if (inputCount != 0)
{
outputBytes = new byte[inputCount];
Buffer.InternalBlockCopy(inputBuffer, inputOffset, outputBytes, 0, inputCount);
}
else
{
outputBytes = EmptyArray<Byte>.Value;
}
// reset the State value
State = 0;
return outputBytes;
}
// IDisposable methods
// To keep mscorlib compatibility with Orcas, CoreCLR's HashAlgorithm has an explicit IDisposable
// implementation. Post-Orcas the desktop has an implicit IDispoable implementation.
#if FEATURE_CORECLR
void IDisposable.Dispose()
#else
public void Dispose()
#endif // FEATURE_CORECLR
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Clear() {
(this as IDisposable).Dispose();
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (HashValue != null)
Array.Clear(HashValue, 0, HashValue.Length);
HashValue = null;
m_bDisposed = true;
}
}
//
// abstract public methods
//
public abstract void Initialize();
protected abstract void HashCore(byte[] array, int ibStart, int cbSize);
protected abstract byte[] HashFinal();
}
}

View File

@@ -0,0 +1,208 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
//
//
// HMAC.cs
//
//
// For test vectors, see RFC2104, e.g. http://www.faqs.org/rfcs/rfc2104.html
//
using System.Diagnostics.Contracts;
namespace System.Security.Cryptography {
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class HMAC : KeyedHashAlgorithm {
//
// protected members
//
// an HMAC uses a hash function where data is hashed by iterating a basic compression
// function on blocks of data. BlockSizeValue is the byte size of such a block
private int blockSizeValue = 64;
protected int BlockSizeValue {
get {
return blockSizeValue;
}
set {
blockSizeValue = value;
}
}
internal string m_hashName;
internal HashAlgorithm m_hash1;
internal HashAlgorithm m_hash2;
//
// private members
//
// m_inner = PaddedKey ^ {0x36,...,0x36}
// m_outer = PaddedKey ^ {0x5C,...,0x5C}
private byte[] m_inner;
private byte[] m_outer;
private bool m_hashing = false;
private void UpdateIOPadBuffers () {
if (m_inner == null)
m_inner = new byte[BlockSizeValue];
if (m_outer == null)
m_outer = new byte[BlockSizeValue];
int i;
for (i=0; i < BlockSizeValue; i++) {
m_inner[i] = 0x36;
m_outer[i] = 0x5C;
}
for (i=0; i < KeyValue.Length; i++) {
m_inner[i] ^= KeyValue[i];
m_outer[i] ^= KeyValue[i];
}
}
internal void InitializeKey (byte[] key) {
// When we change the key value, we'll need to update the initial values of the inner and outter
// computation buffers. In the case of correct HMAC vs Whidbey HMAC, these buffers could get
// generated to a different size than when we started.
m_inner = null;
m_outer = null;
if (key.Length > BlockSizeValue) {
KeyValue = m_hash1.ComputeHash(key);
// No need to call Initialize, ComputeHash will do it for us
} else {
KeyValue = (byte[]) key.Clone();
}
UpdateIOPadBuffers();
}
//
// public properties
//
public override byte[] Key {
get { return (byte[]) KeyValue.Clone(); }
set {
if (m_hashing)
throw new CryptographicException(Environment.GetResourceString("Cryptography_HashKeySet"));
InitializeKey(value);
}
}
public string HashName {
get { return m_hashName; }
#if FEATURE_CRYPTO
set {
if (m_hashing)
throw new CryptographicException(Environment.GetResourceString("Cryptography_HashNameSet"));
m_hashName = value;
// create the hash algorithms
m_hash1 = HashAlgorithm.Create(m_hashName);
m_hash2 = HashAlgorithm.Create(m_hashName);
}
#endif // FEATURE_CRYPTO
}
//
// public methods
//
new static public HMAC Create () {
return Create("System.Security.Cryptography.HMAC");
}
new static public HMAC Create (string algorithmName) {
return (HMAC) CryptoConfig.CreateFromName(algorithmName);
}
public override void Initialize () {
m_hash1.Initialize();
m_hash2.Initialize();
m_hashing = false;
}
protected override void HashCore (byte[] rgb, int ib, int cb) {
if (m_hashing == false) {
m_hash1.TransformBlock(m_inner, 0, m_inner.Length, m_inner, 0);
m_hashing = true;
}
m_hash1.TransformBlock(rgb, ib, cb, rgb, ib);
}
protected override byte[] HashFinal () {
if (m_hashing == false) {
m_hash1.TransformBlock(m_inner, 0, m_inner.Length, m_inner, 0);
m_hashing = true;
}
// finalize the original hash
m_hash1.TransformFinalBlock(EmptyArray<Byte>.Value, 0, 0);
byte[] hashValue1 = m_hash1.HashValue;
// write the outer array
m_hash2.TransformBlock(m_outer, 0, m_outer.Length, m_outer, 0);
// write the inner hash and finalize the hash
m_hash2.TransformBlock(hashValue1, 0, hashValue1.Length, hashValue1, 0);
m_hashing = false;
m_hash2.TransformFinalBlock(EmptyArray<Byte>.Value, 0, 0);
return m_hash2.HashValue;
}
//
// IDisposable methods
//
protected override void Dispose (bool disposing) {
if (disposing) {
if (m_hash1 != null)
((IDisposable)m_hash1).Dispose();
if (m_hash2 != null)
((IDisposable)m_hash2).Dispose();
if (m_inner != null)
Array.Clear(m_inner, 0, m_inner.Length);
if (m_outer != null)
Array.Clear(m_outer, 0, m_outer.Length);
}
// call the base class's Dispose
base.Dispose(disposing);
}
#if FEATURE_CRYPTO
/// <summary>
/// Get a hash algorithm instance falling back to a second algorithm in FIPS mode. For instance,
/// use SHA256Managed by default but fall back to SHA256CryptoServiceProvider which is FIPS
/// certified if FIPS is enabled.
/// </summary>
/// <returns></returns>
internal static HashAlgorithm GetHashAlgorithmWithFipsFallback(Func<HashAlgorithm> createStandardHashAlgorithmCallback,
Func<HashAlgorithm> createFipsHashAlgorithmCallback) {
Contract.Requires(createStandardHashAlgorithmCallback != null);
Contract.Requires(createFipsHashAlgorithmCallback != null);
// Use the standard algorithm implementation by default - in FIPS mode try to fall back to the
// FIPS implementation.
if (CryptoConfig.AllowOnlyFipsAlgorithms) {
try {
return createFipsHashAlgorithmCallback();
}
catch (PlatformNotSupportedException e) {
// We need to wrap the PlatformNotSupportedException into an InvalidOperationException to
// remain compatible with the error that would be triggered in previous runtimes.
throw new InvalidOperationException(e.Message, e);
}
}
else {
return createStandardHashAlgorithmCallback();
}
}
#endif // FEATURE_CRYPTO
}
}

Some files were not shown because too many files have changed in this diff Show More