public GetFileFromDfsObserverHandlerTests(ITestOutputHelper testOutput) : base(testOutput) { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _logger = Substitute.For <ILogger>(); _fakeContext = Substitute.For <IChannelHandlerContext>(); _fileDownloadFactory = new DownloadFileTransferFactory(_logger); _logger = Substitute.For <ILogger>(); _dfs = Substitute.For <IDfs>(); }
public void Init() { new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); _memPool = new Mempool(Substitute.For <IMempoolService <PublicEntryDao> >()); _mapperProvider = new TestMapperProvider(); _mempoolItem = TransactionHelper .GetPublicTransaction().PublicEntry .ToDao <PublicEntry, PublicEntryDao>(_mapperProvider); }
public SimpleRpcClient(IUserOutput userOutput, IPasswordRegistry passwordRegistry, X509Certificate2 certificate, ILogger logger, SigningContext signingContextProvider) { _logger = logger; _certificate = certificate; var fileSystem = new FileSystem(); var consolePasswordReader = new ConsolePasswordReader(userOutput, new ConsoleUserInput()); var passwordManager = new PasswordManager(consolePasswordReader, passwordRegistry); var cryptoContext = new FfiWrapper(); var hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); var peerSettings = Substitute.For <IPeerSettings>(); peerSettings.NetworkType.Returns(signingContextProvider.NetworkType); var localKeyStore = new LocalKeyStore(passwordManager, cryptoContext, fileSystem, hashProvider, _logger); var keyRegistry = new KeyRegistry(); var keySigner = new KeySigner(localKeyStore, cryptoContext, keyRegistry); var memoryCacheOptions = new MemoryCacheOptions(); var memoryCache = new MemoryCache(memoryCacheOptions); var changeTokenProvider = new TtlChangeTokenProvider(10000); var messageCorrelationManager = new RpcMessageCorrelationManager(memoryCache, _logger, changeTokenProvider); var peerIdValidator = new PeerIdValidator(cryptoContext); var nodeRpcClientChannelFactory = new RpcClientChannelFactory(keySigner, messageCorrelationManager, peerIdValidator, peerSettings); var eventLoopGroupFactoryConfiguration = new EventLoopGroupFactoryConfiguration { TcpClientHandlerWorkerThreads = 4 }; var tcpClientEventLoopGroupFactory = new TcpClientEventLoopGroupFactory(eventLoopGroupFactoryConfiguration); var handlers = new List <IRpcResponseObserver> { new BroadcastRawTransactionResponseObserver(_logger), new GetVersionResponseObserver(_logger) }; _rpcClientFactory = new RpcClientFactory(nodeRpcClientChannelFactory, tcpClientEventLoopGroupFactory, handlers); //PeerId for RPC/TCP is currently redundant. var publicKey = keyRegistry.GetItemFromRegistry(KeyRegistryTypes.DefaultKey).GetPublicKey().Bytes; _senderPeerId = publicKey.BuildPeerIdFromPublicKey(IPAddress.Any, 1026); }
//todo add unit tests public PeerSyncManagerUnitTests() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); _peerService = Substitute.For <IPeerService>(); _peerClient = Substitute.For <IPeerClient>(); _peerRepository = new PeerRepository(new InMemoryRepository <Peer, string>()); _deltaHeightReplaySubject = new ReplaySubject <IObserverDto <ProtocolMessage> >(1); _peerService.MessageStream.Returns(_deltaHeightReplaySubject.AsObservable()); }
public GetFileFromDfsRequestObserverTests() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _fileTransferFactory = Substitute.For <IUploadFileTransferFactory>(); _dfs = Substitute.For <IDfs>(); var peerSettings = PeerIdHelper.GetPeerId("test").ToSubstitutedPeerSettings(); _observer = new GetFileFromDfsRequestObserver(_dfs, _hashProvider, peerSettings, _fileTransferFactory, Substitute.For <ILogger>()); }
public DeltaElectorTests() { _testScheduler = new TestScheduler(); _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _logger = Substitute.For <ILogger>(); _reputationManager = new ReputationManager(new PeerRepository(new InMemoryRepository <Peer, string>()), _logger, _testScheduler); _cache = Substitute.For <IMemoryCache>(); _deltaProducersProvider = Substitute.For <IDeltaProducersProvider>(); }
public void HashingAlgorithm_GetterAndSetter() { Assert.AreEqual(HashingAlgorithm.Native, pool.HashingAlgorithm); HashingAlgorithm value = HashingAlgorithm.NewCompatibleHash; pool.HashingAlgorithm = value; Assert.AreEqual(value, pool.HashingAlgorithm); Assert.AreEqual(value, pool.SockIOPool.HashingAlgorithm); }
public void GetMetadata() { var info = HashingAlgorithm.GetAlgorithmMetadata("sha3-256"); Assert.NotNull(info); Assert.Equal("sha3-256", info.Name); Assert.Equal(0x16, info.Code); Assert.Equal(256 / 8, info.DigestSize); Assert.NotNull(info.Hasher); }
public void GetMetadata_Alias() { var info = HashingAlgorithm.GetAlgorithmMetadata("id"); Assert.NotNull(info); Assert.Equal("identity", info.Name); Assert.Equal(0, info.Code); Assert.Equal(0, info.DigestSize); Assert.NotNull(info.Hasher); }
public void Init() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); _broadcastManager = Substitute.For <IBroadcastManager>(); var logger = Substitute.For <ILogger>(); _peerId = PeerIdHelper.GetPeerId("me"); _dfsService = Substitute.For <IDfsService>(); _hub = new DeltaHubWithFastRetryPolicy(_broadcastManager, _peerId.ToSubstitutedPeerSettings(), _dfsService, _hashProvider, logger); }
public void Init() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); _fileTransferFactory = Substitute.For <IUploadFileTransferFactory>(); _dfsService = Substitute.For <IDfsService>(); var peerSettings = PeerIdHelper.GetPeerId("test").ToSubstitutedPeerSettings(); _observer = new GetFileFromDfsRequestObserver(_dfsService, peerSettings, _fileTransferFactory, Substitute.For <ILogger>()); }
public void Init() { var hashingAlgorithm = HashingAlgorithm.GetAlgorithmMetadata("keccak-256"); _hashProvider = new HashProvider(hashingAlgorithm); _dfsService = Substitute.For <IDfsService>(); _logger = Substitute.For <ILogger>(); _dfsReader = new DeltaDfsReader(_dfsService, _logger); }
public DeltaDfsReaderTests() { var hashingAlgorithm = HashingAlgorithm.GetAlgorithmMetadata("blake2b-256"); _hashProvider = new HashProvider(hashingAlgorithm); _dfs = Substitute.For <IDfs>(); _logger = Substitute.For <ILogger>(); _dfsReader = new DeltaDfsReader(_dfs, _logger); }
public void Init() { Setup(TestContext.CurrentContext); _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); _logger = Substitute.For <ILogger>(); _fakeContext = Substitute.For <IChannelHandlerContext>(); _fileDownloadFactory = new DownloadFileTransferFactory(_logger); _logger = Substitute.For <ILogger>(); _dfsService = Substitute.For <IDfsService>(); }
public DeltaHubTests() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _broadcastManager = Substitute.For <IBroadcastManager>(); var logger = Substitute.For <ILogger>(); _peerId = PeerIdHelper.GetPeerId("me"); _dfs = Substitute.For <IDfs>(); _hub = new DeltaHubWithFastRetryPolicy(_broadcastManager, _peerId.ToSubstitutedPeerSettings(), _dfs, logger); }
public void Init() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); _deltaHashProvider = Substitute.For <IDeltaHashProvider>(); _fakeChannelContext = Substitute.For <IChannelHandlerContext>(); _syncState = new SyncState { IsSynchronized = true, IsRunning = true }; _logger = Substitute.For <ILogger>(); _peerRepository = Substitute.For <IPeerRepository>(); }
public BadDeltas() { var hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); var noPreviousHash = new Delta { PreviousDeltaDfsHash = new byte[0].ToByteString() }; var noMerkleRoot = DeltaHelper.GetDelta(hashProvider, merkleRoot: new byte[0]); AddRow(noMerkleRoot, typeof(InvalidDataException)); AddRow(noPreviousHash, typeof(InvalidDataException)); AddRow(null as Delta, typeof(ArgumentNullException)); }
public LedgerSynchroniserTests(ITestOutputHelper output) { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _output = output; _deltaCache = Substitute.For <IDeltaCache>(); var logger = Substitute.For <ILogger>(); _cancellationToken = new CancellationToken(); _synchroniser = new LedgerSynchroniser(_deltaCache, logger); }
public void Cli_Can_Request_Node_Info() { var hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")); var hash = hashProvider.ComputeUtf8MultiHash("hello").ToCid(); var result = Shell.ParseCommand("getdelta", "-h", hash, NodeArgumentPrefix, ServerNodeName); result.Should().BeTrue(); var request = AssertSentMessageAndGetMessageContent <GetDeltaRequest>(); MultiBase.Encode(request.DeltaDfsHash.ToByteArray(), "base32").Should().Be(hash); }
/// <summary> /// Initializes a new instance of the AS2MdnSettings class. /// </summary> /// <param name="needMdn">The value indicating whether to send or /// request a MDN.</param> /// <param name="signMdn">The value indicating whether the MDN needs to /// be signed or not.</param> /// <param name="sendMdnAsynchronously">The value indicating whether to /// send the asynchronous MDN.</param> /// <param name="signOutboundMdnIfOptional">The value indicating /// whether to sign the outbound MDN if optional.</param> /// <param name="sendInboundMdnToMessageBox">The value indicating /// whether to send inbound MDN to message box.</param> /// <param name="micHashingAlgorithm">The signing or hashing algorithm. /// Possible values include: 'NotSpecified', 'None', 'MD5', 'SHA1', /// 'SHA2256', 'SHA2384', 'SHA2512'</param> /// <param name="receiptDeliveryUrl">The receipt delivery URL.</param> /// <param name="dispositionNotificationTo">The disposition /// notification to header value.</param> /// <param name="mdnText">The MDN text.</param> public AS2MdnSettings(bool needMdn, bool signMdn, bool sendMdnAsynchronously, bool signOutboundMdnIfOptional, bool sendInboundMdnToMessageBox, HashingAlgorithm micHashingAlgorithm, string receiptDeliveryUrl = default(string), string dispositionNotificationTo = default(string), string mdnText = default(string)) { NeedMdn = needMdn; SignMdn = signMdn; SendMdnAsynchronously = sendMdnAsynchronously; ReceiptDeliveryUrl = receiptDeliveryUrl; DispositionNotificationTo = dispositionNotificationTo; SignOutboundMdnIfOptional = signOutboundMdnIfOptional; MdnText = mdnText; SendInboundMdnToMessageBox = sendInboundMdnToMessageBox; MicHashingAlgorithm = micHashingAlgorithm; CustomInit(); }
public DeltaCacheTests() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _memoryCache = Substitute.For <IMemoryCache>(); _dfsReader = Substitute.For <IDeltaDfsReader>(); _logger = Substitute.For <ILogger>(); var tokenProvider = Substitute.For <IDeltaCacheChangeTokenProvider>(); tokenProvider.GetChangeToken().Returns(Substitute.For <IChangeToken>()); _deltaCache = new DeltaCache(_hashProvider, _memoryCache, _dfsReader, tokenProvider, _logger); }
public void Catalyst_virtual_machine_can_be_initialized() { var virtualMachine = new KatVirtualMachine( Substitute.For <IStateProvider>(), Substitute.For <IStorageProvider>(), Substitute.For <IStateUpdateHashProvider>(), new CatalystSpecProvider(), new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")), new FfiWrapper(), LimboLogs.Instance); Assert.NotNull(virtualMachine); }
public CandidateDeltaObserverTests() { var hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _deltaVoter = Substitute.For <IDeltaVoter>(); _fakeChannelContext = Substitute.For <IChannelHandlerContext>(); var logger = Substitute.For <ILogger>(); _newHash = hashProvider.ComputeUtf8MultiHash("newHash").CreateCid(); _prevHash = hashProvider.ComputeUtf8MultiHash("prevHash").CreateCid(); _producerId = PeerIdHelper.GetPeerId("candidate delta producer"); _candidateDeltaObserver = new CandidateDeltaObserver(_deltaVoter, hashProvider, logger); }
/// <summary> /// Gets ASN-encoded algorithm identifier based on current configuration. /// </summary> /// <param name="alternate"> /// Specifies whether alternate signature format is used. This parameter has meaning only for /// ECDSA keys. Otherwise, the parameter is ignored. Default value is <strong>false</strong>. /// </param> /// <returns>ASN-encoded algorithm identifier.</returns> public AlgorithmIdentifier GetAlgorithmIdentifier(Boolean alternate = false) { if (SignatureAlgorithm == null) { getSignatureAlgorithm(); } Oid algId = SignatureAlgorithm; List <Byte> parameters = new List <Byte>(); switch (PublicKeyAlgorithm.Value) { case AlgorithmOids.ECC: // ECDSA if (alternate) { // specifiedECDSA algId = new Oid(AlgorithmOids.ECDSA_SPECIFIED); // only here we override algorithm OID parameters .AddRange( new AlgorithmIdentifier(HashingAlgorithm.ToOid(), Asn1Utils.EncodeNull()).RawData ); } break; case AlgorithmOids.RSA: // RSA // only RSA supports parameters. For PKCS1 padding: NULL, for PSS padding: // RSASSA-PSS-params ::= SEQUENCE { // hashAlgorithm [0] HashAlgorithm DEFAULT sha1, // maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, // saltLength [2] INTEGER DEFAULT 20, // trailerField [3] TrailerField DEFAULT trailerFieldBC // } if (PaddingScheme == SignaturePadding.PSS) { Byte[] hash = new AlgorithmIdentifier(HashingAlgorithm.ToOid(), null).RawData; parameters.AddRange(Asn1Utils.Encode(hash, 0xa0)); // mask generation function: mgf1 Byte[] mgf = new AlgorithmIdentifier(new Oid("1.2.840.113549.1.1.8"), hash).RawData; parameters.AddRange(Asn1Utils.Encode(mgf, 0xa1)); // salt parameters.AddRange(Asn1Utils.Encode(new Asn1Integer(20).RawData, 0xa2)); // general PSS parameters encode parameters = new List <Byte>(Asn1Utils.Encode(parameters.ToArray(), 48)); } else { parameters.AddRange(Asn1Utils.EncodeNull()); } break; } return(new AlgorithmIdentifier(algId, parameters.ToArray())); }
public IHashingServiceProvider GetProvider() { var hashingAlgorithmToUse = HashingAlgorithm.FromName(_configSettings.HashAlgorithm); var instance = _providers.Where(provider => hashingAlgorithmToUse == provider.HashingAlgorithm).FirstOrDefault(); if (instance == null) { throw new Exception(string.Format("Could not find implementation for the HashingAlgorithm {0}.", hashingAlgorithmToUse)); } return(instance); }
public DevDfsTests() { _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _fileSystem = Substitute.For <IFileSystem>(); var file = Substitute.For <IFile>(); _fileSystem.File.Returns(file); _fileSystem.GetCatalystDataDir() .Returns(new DirectoryInfo("correct-information")); _dfs = new DevDfs(_fileSystem, _hashProvider); _baseFolder = Path.Combine(_fileSystem.GetCatalystDataDir().FullName, Constants.DfsDataSubDir); }
public DeltaHashProviderTests(ITestOutputHelper output) : base(output) { _deltaCache = Substitute.For <IDeltaCache>(); _logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(output) .CreateLogger() .ForContext(MethodBase.GetCurrentMethod().DeclaringType); _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _deltaCache.GenesisHash.Returns( _hashProvider.ComputeMultiHash(new Delta().ToByteArray()).CreateCid()); }
public void Compute_Not_Implemented_Hash_Array() { var alg = HashingAlgorithm.Register("not-implemented", 0x0F, 32); try { var hello = Encoding.UTF8.GetBytes("Hello, world."); ExceptionAssert.Throws <NotImplementedException>(() => MultiHash.ComputeHash(hello, "not-implemented")); } finally { HashingAlgorithm.Deregister(alg); } }
/// <summary> /// Calculates the checksum of a file /// </summary> /// <param name="filePath">path to the file to be checked</param> /// <param name="hashingAlgorithm">The hashing algo to be used. Defaults to SHA256</param> /// <returns>Byte array representing the checksum of the file</returns> /// <exception cref="ArgumentException">The hashing algo supplied is not supported by the OS/Language Version</exception> public static byte[] GetChecksum(string filePath, HashingAlgorithm hashingAlgorithm = HashingAlgorithm.SHA256) { using (var hasher = System.Security.Cryptography.HashAlgorithm.Create(hashingAlgorithm.ToString())) { if (hasher == null) { throw new ArgumentException($"{hashingAlgorithm} not a valid hashing algorithm"); } using (var stream = System.IO.File.OpenRead(filePath)) { return(hasher.ComputeHash(stream)); } } }
public LedgerTests() { _testScheduler = new TestScheduler(); _fakeRepository = Substitute.For <IAccountRepository>(); _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256")); _logger = Substitute.For <ILogger>(); _mempool = Substitute.For <IMempool <MempoolDocument> >(); _deltaHashProvider = Substitute.For <IDeltaHashProvider>(); _ledgerSynchroniser = Substitute.For <ILedgerSynchroniser>(); _genesisHash = _hashProvider.ComputeUtf8MultiHash("genesis"); _ledgerSynchroniser.DeltaCache.GenesisHash.Returns(_genesisHash); _ledgerSynchroniser.DeltaCache.GenesisAddress.Returns(_genesisHash.ToBase32()); }
internal static HashAlgorithm Create(HashingAlgorithm algoType) { HashAlgorithm hashingInstance = null; switch (algoType) { case HashingAlgorithm.MD5: hashingInstance = MD5.Create(); break; case HashingAlgorithm.SHA1: hashingInstance = SHA1Managed.Create(); break; case HashingAlgorithm.SHA256: hashingInstance = SHA256Managed.Create(); break; case HashingAlgorithm.SHA512: hashingInstance = SHA512Managed.Create(); break; default: throw new Exception("Incorrect use of HashingAlgorithm factory"); } return hashingInstance; }
/// <summary> /// Computes a hash value for a Stream object at a specific start position. /// </summary> /// <param name="hash">Hashing function to use.</param> /// <param name="inputStream">Any System.IO.Stream object.</param> /// <param name="startPosition">Byte position of where the hash computation should begin.</param> /// <returns>Hash value in a string format.</returns> /// <remarks> /// The Stream object must allow reads and must allow seeking. /// </remarks> /// <seealso cref="GetHash(HashingAlgorithm, string)"/> public static string ComputeHash(HashingAlgorithm hash, Stream inputStream, long startPosition) { if (inputStream == null) throw new ArgumentNullException("inputStream"); if (!inputStream.CanRead) throw new ArgumentException("must be readable. The CanRead property must return a value of 'true'.", "inputStream"); if (!inputStream.CanSeek) throw new ArgumentException("must be seekable. The CanSeek property must return a value of 'true'.", "inputStream"); if (startPosition < 0) throw new ArgumentOutOfRangeException("startPosition", "must contain a value greater than or equal to 0"); HashAlgorithm hashAlgo = null; switch (hash) { case HashingAlgorithm.Crc32: hashAlgo = new Starksoft.Aspen.Crc32(); break; case HashingAlgorithm.Md5: hashAlgo = new MD5CryptoServiceProvider(); break; case HashingAlgorithm.Sha1: hashAlgo = new SHA1CryptoServiceProvider(); break; case HashingAlgorithm.Sha256: #if CLR_4_PLUS hashAlgo = new SHA256CryptoServiceProvider(); break; #else throw new FtpsException("Sha256 algorithm not supported on this CLR version; recompile with .NET 4.0 or higher"); #endif case HashingAlgorithm.Sha512: #if CLR_4_PLUS hashAlgo = new SHA512CryptoServiceProvider(); break; #else throw new FtpsException("Sha256 algorithm not supported on this CLR version; recompile with .NET 4.0 or higher"); #endif } if (startPosition > 0) inputStream.Position = startPosition; else inputStream.Position = 0; byte[] hashArray = hashAlgo.ComputeHash(inputStream); // convert byte array to a string StringBuilder buffer = new StringBuilder(hashArray.Length); foreach (byte hashByte in hashArray) { buffer.Append(hashByte.ToString("x2")); } return buffer.ToString(); }
/// <summary> /// Computes a hash value for a Stream object. /// </summary> /// <param name="hash">Hashing function to use.</param> /// <param name="inputStream">Any System.IO.Stream object.</param> /// <returns>Hash value in a string format.</returns> /// <remarks> /// The Stream object must allow reads and must allow seeking. /// </remarks> /// <seealso cref="GetHash(HashingAlgorithm, string)"/> public string ComputeHash(HashingAlgorithm hash, Stream inputStream) { return ComputeHash(hash, inputStream, 0); }
/// <summary> /// Computes a cryptographic hash or CRC value for a local file. /// </summary> /// <param name="hash">Hashing function to use.</param> /// <param name="localPath">Path to file to perform hashing operation on.</param> /// <returns>Hash value in a string format.</returns> /// <seealso cref="GetHash(HashingAlgorithm, string)"/> public string ComputeHash(HashingAlgorithm hash, string localPath) { if (!File.Exists(localPath)) throw new ArgumentException("file does not exist.", "localPath"); using (FileStream fileStream = File.OpenRead(localPath)) { return ComputeHash(hash, fileStream); } }
/// <summary> /// Sets the hashing algorithm option on the remote FTP server. /// </summary> /// <remarks> /// Not all FTP servers support the HASH feature. /// </remarks> /// <param name="algorithm">Hasing algorithm to use</param> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="FtpsCommandNotSupportedException"></exception> /// <exception cref="FtpsHashingException"></exception> public void SetHashOption(HashingAlgorithm algorithm) { if (algorithm == HashingAlgorithm.None) throw new ArgumentOutOfRangeException("algorithm"); if (!_feats.Contains(FtpsCmd.Hash)) throw new FtpsCommandNotSupportedException("Cannot set the HASH option on FTP server.", FtpsCmd.Hash); // get the hash argument feature from the features collection FtpsFeatureArgument fa = GetHashFeatureArgument(algorithm); string hashArgText = ConvertHashAlgoToTextArg(algorithm); // attempt to send a request to change the option for the HASH function string hashCmd = String.Format("HASH {0}", hashArgText); try { SendRequest(new FtpsRequest(_encode, FtpsCmd.Opts, hashCmd)); } catch (FtpsException ex) { throw new FtpsHashingException("Unable to set hashing option.", ex); } // refresh the features collection TryResetFeatures(); // find the Hash feature argument agains and verify the option has been set properly FtpsFeatureArgument fa2 = GetHashFeatureArgument(algorithm); if (!fa2.IsDefault) throw new FtpsHashingException("Hashing option not set to default by FTP server."); }
/// <summary> /// Gets the hash value from the FTP server for the file specified. /// Use this value to compare a local hash to determine file integrity. /// </summary> /// <param name="algorithm">Hashing function to use.</param> /// <param name="path">Path to the file on the remote FTP server.</param> /// <param name="startPosition">Byte position of where the server should begin computing the hash.</param> /// <param name="endPosition">Byte position of where the server should end computing the hash.</param> /// <returns>Hash value in a string format.</returns> /// <remarks> /// FTP file hashing is not a fully ratified RFC standard and therefore is not widely supported. There is /// a convention that some FTP server support that allows for partial file hashing. The command that allow /// partial file hashing are XCRC, XMD5, XSHA1, XSHA256, XSHA512 as well as other variations not listed. /// When computing a CRC, MD5 or SHA1 on a server that supports the commands, an optional startPosition /// and endPosition value can also be specified. These optional parameters allow for partial file hashing /// which can be used while resuming a file transfer. In that way only the additional bytes are hashed /// for accuracy and not the entire file on the FTP server. /// /// The second FTP file hashing implementation is a RFC draft specification and uses a new FTP command named HASH. /// The default hashing algorithm can be set with the OPTS HASH command specifying the supported algorithm as an argument. /// Optionally, the HASH command supports partial file hashing with another command called RANG. The RANG command /// requires a byte range to use when calculating the file hash. Partial file hashing with HASH is only supported if the /// command RANG is also a supported. The HASH command also has several additional return error codes. For example, /// an FTP server that implements the HASH command should reply with a 450 reply if the server is busy. This signals /// that the client can try again some time later. In addition, an FTP server that implements the HASH command should reply with /// a 501 reply to the OPTS HASH command if the user has requested an unknown or unsupported algorithm. /// /// The Starksoft FtpsClient will attempt to determine which hashing command features are enabled on the FTP server /// and formulate the hashing request accordingly. The default hashing command is always HASH. If HASH is not available, the /// FtpsClient will attempt to execute the appropriate alternative XCRC, XMD5, XSHA1, XSHA256 or XSHA512 command. If the /// alternate command is not supported then a FileHashingException will be thrown. /// /// For partial file hashing, if HASH is supported but RANG is not, the FtpsClient will attempted to execute the approriate XCRC, XMD5, XSHA1, /// XSHA256 or XSHA512 command instead. If the FTP server does not support the alternate hashing command then an exception will be thrown. /// /// See RFC draft-ietf-ftpext2-hash-03 for more information /// http://tools.ietf.org/html/draft-ietf-ftpext2-hash-03#section-3.2 /// </remarks> /// <seealso cref="ComputeHash(HashingAlgorithm, string)"/> public string GetHash(HashingAlgorithm algorithm, string path, long startPosition, long endPosition) { if (algorithm == HashingAlgorithm.None) throw new ArgumentOutOfRangeException("algorithm", "must contain a value other than 'Unknown'"); if (startPosition < 0) throw new ArgumentOutOfRangeException("startPosition", "must contain a value greater than or equal to 0"); if (endPosition < 0) throw new ArgumentOutOfRangeException("startPosition", "must contain a value greater than or equal to 0"); if (startPosition > endPosition) throw new ArgumentOutOfRangeException("startPosition", "must contain a value less than or equal to endPosition"); // gather information about the hashing methods supported on the FTP server string hashArgText = ConvertHashAlgoToTextArg(algorithm); FtpsCmd hashXCmd = ConvertHashXAlgoToTextCmd(algorithm); FtpsFeature hf = Features.Find(FtpsCmd.Hash); FtpsFeatureArgument hfa = null; if (hf != null) hfa = hf.Arguments.Find(hashArgText); FtpsFeature rf = Features.Find(FtpsCmd.Rang); bool partialReq = startPosition > 0 ? true : false; bool canHash = hf != null && hfa != null ? true : false; bool canHashPartial = rf != null ? true : false; if (partialReq && (!canHash || !canHashPartial) || (!partialReq && !canHash)) { try { if (partialReq) { SendRequest(new FtpsRequest(_encode, hashXCmd, path, startPosition.ToString(), endPosition.ToString())); } else { SendRequest(new FtpsRequest(_encode, ConvertHashXAlgoToTextCmd(algorithm), path)); } } catch (FtpsException x) { throw new FtpsHashingException(String.Format("Unable to partial hash file using {0} command.", hashXCmd.ToString().ToUpper()), x); } } else { try { // set the hash function if it is not already set if (!hfa.IsDefault) SetHashOption(algorithm); if (partialReq) { // send RANGe command if it is a partial hash SendRequest(new FtpsRequest(_encode, FtpsCmd.Rang, startPosition.ToString(), endPosition.ToString())); } // send the HASH command SendRequest(new FtpsRequest(_encode, FtpsCmd.Hash, path)); } catch (FtpsException ex2) { if (_response.Code == FtpsResponseCode.SyntaxErrorInParametersOrArguments) throw new FtpsHashingInvalidAlgorithmException("FTP server does not support selected hashing algorithm."); else if (_response.Code == FtpsResponseCode.RequestedFileActionNotTaken) throw new FtpsHashingServerBusyException("FTP server is busy. Please try again later."); else throw new FtpsHashingException("Unable to partial hash file using HASH command.", ex2); } } return _response.Text; }
/// <summary> /// Gets the hash value from the FTP server for the file specified. /// Use this value to compare a local hash value to determine file integrity. /// </summary> /// <param name="algorithm">Hashing function to use.</param> /// <param name="path">Path to the file ont the remote FTP server.</param> /// <returns>Hash value in a string format.</returns> /// <seealso cref="ComputeHash(HashingAlgorithm, string)"/> public string GetHash(HashingAlgorithm algorithm, string path) { return GetHash(algorithm, path, 0, 0); }
/// <summary> /// Returns appropriate SockIO object given /// string cache key and optional hashcode. /// /// Trys to get SockIO from pool. Fails over /// to additional pools in event of server failure. /// </summary> /// <param name="key">hashcode for cache key</param> /// <param name="hashCode">if not null, then the int hashcode to use</param> /// <returns>SockIO obj connected to server</returns> public SockIO GetSock(string key, object hashCode) { //string hashCodeString = "<null>"; //if(hashCode != null) // hashCodeString = hashCode.ToString(); if (string.IsNullOrEmpty(key) || !_initialized || _buckets.Count == 0) { return null; } // if only one server, return it if(_buckets.Count == 1) return GetConnection((string)_buckets[0]); int tries = 0; int hv; if(hashCode != null) { hv = (int)hashCode; } else { // NATIVE_HASH = 0 // OLD_COMPAT_HASH = 1 // NEW_COMPAT_HASH = 2 switch(_hashingAlgorithm) { case HashingAlgorithm.Native: hv = key.GetHashCode(); break; case HashingAlgorithm.OldCompatibleHash: hv = OriginalHashingAlgorithm(key); break; case HashingAlgorithm.NewCompatibleHash: hv = NewHashingAlgorithm(key); break; default: // use the native hash as a default hv = key.GetHashCode(); _hashingAlgorithm = HashingAlgorithm.Native; break; } } // keep trying different servers until we find one while(tries++ <= _buckets.Count) { // get bucket using hashcode // get one from factory int bucket = hv % _buckets.Count; if(bucket < 0) bucket += _buckets.Count; SockIO sock = GetConnection((string)_buckets[bucket]); if(sock != null) return sock; // if we do not want to failover, then bail here if(!_failover) return null; // if we failed to get a socket from this server // then we try again by adding an incrementer to the // current key and then rehashing switch(_hashingAlgorithm) { case HashingAlgorithm.Native: hv += ((string)("" + tries + key)).GetHashCode(); break; case HashingAlgorithm.OldCompatibleHash: hv += OriginalHashingAlgorithm("" + tries + key); break; case HashingAlgorithm.NewCompatibleHash: hv += NewHashingAlgorithm("" + tries + key); break; default: // use the native hash as a default hv += ((string)("" + tries + key)).GetHashCode(); _hashingAlgorithm = HashingAlgorithm.Native; break; } } return null; }
private FtpsCmd ConvertHashXAlgoToTextCmd(HashingAlgorithm hash) { switch (hash) { case HashingAlgorithm.Crc32: return FtpsCmd.Xcrc; case HashingAlgorithm.Md5: return FtpsCmd.Xmd5; case HashingAlgorithm.Sha1: return FtpsCmd.Xsha1; case HashingAlgorithm.Sha256: return FtpsCmd.Xsha256; case HashingAlgorithm.Sha512: return FtpsCmd.Xsha512; default: throw new FtpsException("unsupported hash option"); } }
private FtpsFeatureArgument GetHashFeatureArgument(HashingAlgorithm algo) { string argText = ConvertHashAlgoToTextArg(algo); FtpsFeature f = Features[FtpsCmd.Hash]; if (f == null) throw new FtpsCommandNotSupportedException("Cannot find hash feature.", FtpsCmd.Hash); FtpsFeatureArgument fa = f.Arguments[argText]; if (fa == null) throw new FtpsFeatureException(String.Format("The HASH feature argument '{0}' is not supported by the FTP server.", argText)); return fa; }
void RaiseUnknownHashingAlgorithm(HashingAlgorithm algorithm) { if (log.IsWarnEnabled) log.WarnFormat("Unknown hashing algorithm number 0x{0:x2}.", algorithm.Code); var handler = UnknownHashingAlgorithm; if (handler != null) { var args = new UnknownHashingAlgorithmEventArgs { Algorithm = algorithm }; handler(this, args); } }
/// <summary> /// Register a new IPFS hashing algorithm. /// </summary> /// <param name="name"> /// The name of the algorithm. /// </param> /// <param name="code"> /// The IPFS number assigned to the hashing algorithm. /// </param> /// <param name="digestSize"> /// The size, in bytes, of the digest value. /// </param> /// <param name="hasher"> /// A <c>Func</c> that a <see cref="HashAlgorithm"/>. If not specified, then a <c>Func</c> is created to /// return a <see cref="NotImplementedException"/>. /// </param> /// <returns> /// A new <see cref="HashingAlgorithm"/>. /// </returns> public static HashingAlgorithm Register(string name, byte code, byte digestSize, Func<HashAlgorithm> hasher = null) { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException("name"); if (Names.ContainsKey(name)) throw new ArgumentException(string.Format("The IPFS hashing algorithm '{0}' is already defined.", name)); if (Codes[code] != null) throw new ArgumentException(string.Format("The IPFS hashing algorithm code 0x{0:x2} is already defined.", code)); if (hasher == null) hasher = () => { throw new NotImplementedException(string.Format("The IPFS hashing algorithm '{0}' is not implemented.", name)); }; var a = new HashingAlgorithm { Name = name, Code = code, DigestSize = digestSize, Hasher = hasher }; Names[name] = a; Codes[code] = a; return a; }
/// <summary> /// Compares a hash of the specified plain text value to a given hash /// value. Plain text is hashed with the same salt value as the original /// hash. /// </summary> /// <param name="plainText"> /// Plain text to be verified against the specified hash. The function /// does not check whether this parameter is null. /// </param> /// <param name="hashAlgorithm"> /// Name of the hash algorithm. Allowed values are: "MD5", "SHA1", /// "SHA256", "SHA384", and "SHA512" (if any other value is specified, /// MD5 hashing algorithm will be used). This value is case-insensitive. /// </param> /// <param name="hashValue"> /// Base64-encoded hash value produced by ComputeHash function. This value /// includes the original salt appended to it. /// </param> /// <returns> /// If computed hash mathes the specified hash the function the return /// value is true; otherwise, the function returns false. /// </returns> public static bool VerifyHash(string plainText, HashingAlgorithm hashAlgorithm, string hashValue) { // Convert base64-encoded hash value into a byte array. byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue); // We must know size of hash (without salt). int hashSizeInBits, hashSizeInBytes; // Size of hash is based on the specified algorithm. switch (hashAlgorithm) { case HashingAlgorithm.SHA1: hashSizeInBits = 160; break; case HashingAlgorithm.SHA256: hashSizeInBits = 256; break; case HashingAlgorithm.SHA384: hashSizeInBits = 384; break; case HashingAlgorithm.SHA512: hashSizeInBits = 512; break; default: // Must be MD5 hashSizeInBits = 128; break; } // Convert size of hash from bits to bytes. hashSizeInBytes = hashSizeInBits / 8; // Make sure that the specified hash value is long enough. if (hashWithSaltBytes.Length < hashSizeInBytes) return false; // Allocate array to hold original salt bytes retrieved from hash. byte[] saltBytes = new byte[hashWithSaltBytes.Length - hashSizeInBytes]; // Copy salt from the end of the hash to the new array. for (int i = 0; i < saltBytes.Length; i++) saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i]; // Compute a new hash string. string expectedHashString = ComputeHash(plainText, hashAlgorithm, saltBytes); // If the computed hash matches the specified hash, // the plain text value must be correct. return (hashValue == expectedHashString); }
/// <summary> /// Generates a hash for the given plain text value and returns a /// base64-encoded result. Before the hash is computed, a random salt /// is generated and appended to the plain text. This salt is stored at /// the end of the hash value, so it can be used later for hash /// verification. /// </summary> /// <param name="plainText"> /// Plaintext value to be hashed. The function does not check whether /// this parameter is null. /// </param> /// <param name="hashAlgorithm"> /// Name of the hash algorithm. Allowed values are: "MD5", "SHA1", /// "SHA256", "SHA384", and "SHA512" (if any other value is specified /// MD5 hashing algorithm will be used). This value is case-insensitive. /// </param> /// <param name="saltBytes"> /// Salt bytes. This parameter can be null, in which case a random salt /// value will be generated. /// </param> /// <returns> /// Hash value formatted as a base64-encoded string. /// </returns> public static string ComputeHash(string plainText, HashingAlgorithm hashAlgorithm, byte[] saltBytes) { // If salt is not specified, generate it on the fly. if (saltBytes == null) { // Define min and max salt sizes. int minSaltSize = 4; int maxSaltSize = 8; // Generate a random number for the size of the salt. Random random = new Random(); int saltSize = random.Next(minSaltSize, maxSaltSize); // Allocate a byte array, which will hold the salt. saltBytes = new byte[saltSize]; // Initialize a random number generator. RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); // Fill the salt with cryptographically strong byte values. rng.GetNonZeroBytes(saltBytes); } // Convert plain text into a byte array. byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); // Allocate array, which will hold plain text and salt. byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length]; // Copy plain text bytes into resulting array. for (int i = 0; i < plainTextBytes.Length; i++) plainTextWithSaltBytes[i] = plainTextBytes[i]; // Append salt bytes to the resulting array. for (int i = 0; i < saltBytes.Length; i++) plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i]; // Because we support multiple hashing algorithms, we must define // hash object as a common (abstract) base class. We will specify the // actual hashing algorithm class later during object creation. HashAlgorithm hash; // Initialize appropriate hashing algorithm class. switch (hashAlgorithm) { case HashingAlgorithm.SHA1: hash = new SHA1Managed(); break; case HashingAlgorithm.SHA256: hash = new SHA256Managed(); break; case HashingAlgorithm.SHA384: hash = new SHA384Managed(); break; case HashingAlgorithm.SHA512: hash = new SHA512Managed(); break; default: hash = new MD5CryptoServiceProvider(); break; } // Compute hash value of our plain text with appended salt. byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes); // Create array which will hold hash and original salt bytes. byte[] hashWithSaltBytes = new byte[hashBytes.Length + saltBytes.Length]; // Copy hash bytes into resulting array. for (int i = 0; i < hashBytes.Length; i++) hashWithSaltBytes[i] = hashBytes[i]; // Append salt bytes to the result. for (int i = 0; i < saltBytes.Length; i++) hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i]; // Convert result into a base64-encoded string. string hashValue = Convert.ToBase64String(hashWithSaltBytes); // Return the result. return hashValue; }
/// <summary> /// Returns appropriate SockIO object given /// string cache key and optional hashcode. /// /// Trys to get SockIO from pool. Fails over /// to additional pools in event of server failure. /// </summary> /// <param name="key">hashcode for cache key</param> /// <param name="hashCode">if not null, then the int hashcode to use</param> /// <returns>SockIO obj connected to server</returns> public SockIO GetSock(string key, object hashCode) { string hashCodeString = "<null>"; if(hashCode != null) hashCodeString = hashCode.ToString(); //if(Log.IsDebugEnabled) //{ // Log.Debug(GetLocalizedString("cache socket pick").Replace("$$Key$$", key).Replace("$$HashCode$$", hashCodeString)); //} if (key == null || key.Length == 0) { //if(Log.IsDebugEnabled) //{ // Log.Debug(GetLocalizedString("null key")); //} return null; } if(!_initialized) { //if(Log.IsErrorEnabled) //{ // Log.Error(GetLocalizedString("get socket from uninitialized pool")); //} return null; } // if no servers return null if(_buckets.Count == 0) return null; // if only one server, return it if(_buckets.Count == 1) return GetConnection((string)_buckets[0]); int tries = 0; // generate hashcode int hv; if(hashCode != null) { hv = (int)hashCode; } else { // NATIVE_HASH = 0 // OLD_COMPAT_HASH = 1 // NEW_COMPAT_HASH = 2 switch(_hashingAlgorithm) { case HashingAlgorithm.Native: hv = key.GetHashCode(); break; case HashingAlgorithm.OldCompatibleHash: hv = OriginalHashingAlgorithm(key); break; case HashingAlgorithm.NewCompatibleHash: hv = NewHashingAlgorithm(key); break; default: // use the native hash as a default hv = key.GetHashCode(); _hashingAlgorithm = HashingAlgorithm.Native; break; } } // keep trying different servers until we find one while(tries++ <= _buckets.Count) { // get bucket using hashcode // get one from factory int bucket = hv % _buckets.Count; if(bucket < 0) bucket += _buckets.Count; SockIO sock = GetConnection((string)_buckets[bucket]); //if(Log.IsDebugEnabled) //{ // Log.Debug(GetLocalizedString("cache choose").Replace("$$Bucket$$", _buckets[bucket].ToString()).Replace("$$Key$$", key)); //} if(sock != null) return sock; // if we do not want to failover, then bail here if(!_failover) return null; // if we failed to get a socket from this server // then we try again by adding an incrementer to the // current key and then rehashing switch(_hashingAlgorithm) { case HashingAlgorithm.Native: hv += ((string)("" + tries + key)).GetHashCode(); break; case HashingAlgorithm.OldCompatibleHash: hv += OriginalHashingAlgorithm("" + tries + key); break; case HashingAlgorithm.NewCompatibleHash: hv += NewHashingAlgorithm("" + tries + key); break; default: // use the native hash as a default hv += ((string)("" + tries + key)).GetHashCode(); _hashingAlgorithm = HashingAlgorithm.Native; break; } } return null; }
private string ConvertHashAlgoToTextArg(HashingAlgorithm hash) { switch (hash) { case HashingAlgorithm.Crc32: return HASH_CRC_32; case HashingAlgorithm.Md5: return HASH_MD5; case HashingAlgorithm.Sha1: return HASH_SHA_1; case HashingAlgorithm.Sha256: return HASH_SHA_256; case HashingAlgorithm.Sha512: return HASH_SHA_512; default: throw new FtpsException("unsupported hash option"); } }
public void DKIMSign(ISigner signer, CanonicalizationType headerCanonicalization, CanonicalizationType bodyCanonicalization, HashingAlgorithm hashAlgorithm, string domain, string selector) { if (IsSigned) throw new InvalidOperationException("Message already have DKIM header."); IsSigned = true; string hashtype = hashAlgorithm == HashingAlgorithm.RSASha1 ? "sha1" : "sha256"; StringBuilder dkim = new StringBuilder(300) .Append("v=1;") // version .Append("a=").Append("rsa-").Append(hashtype).Append(";") // hash algorithm .Append("c=").Append(string.Format("{0}/{1}", headerCanonicalization, bodyCanonicalization).ToLower()).Append(";") // canonicalization types headers/body .Append("d=").Append(domain).Append(";") // domain for diim check .Append("s=").Append(selector).Append(";") // TXT record selector .Append("t=").Append(Convert.ToInt64((DateTime.Now.ToUniversalTime() - DateTime.SpecifyKind(DateTime.Parse("00:00:00 January 1, 1970"), DateTimeKind.Utc)).TotalSeconds).ToString()).Append(";") // creation time .Append("bh=").Append(GetBodyHash(bodyCanonicalization, hashtype)).Append(";"); // body hash var headers = ComputedHeaders; List<string> h = new List<string>(); foreach (string header in headers) foreach (string value in headers.GetValues(header)) h.Add(header); dkim.Append("h=").Append(string.Join(":", h)).Append(";") // headers for hashing .Append("b="); // signature data var canonialized = DKIMCanonicalizer.CanonicalizeHeader(headerCanonicalization, headers) + "dkim-signature:" + dkim.ToString(); var bytes = (HeadersEncoding ?? Encoding.UTF8).GetBytes(canonialized); lock (signer) { signer.BlockUpdate(bytes, 0, bytes.Length); bytes = signer.GenerateSignature();//computing signature signer.Reset(); } dkim.Append(Convert.ToBase64String(bytes)); Headers.Add("dkim-signature", dkim.ToString());// adding DKIM header }