From 94391c50ea761ed6685af3ecc797ef61c9153c05 Mon Sep 17 00:00:00 2001 From: dustinkerstein Date: Tue, 18 Sep 2018 10:32:34 -0400 Subject: [PATCH] Initial commit --- Assets/Best HTTP (Pro).meta | 7 + Assets/Best HTTP (Pro)/BestHTTP.meta | 7 + .../BestHTTP/Authentication.meta | 7 + .../BestHTTP/Authentication/Credentials.cs | 63 + .../Authentication/Credentials.cs.meta | 10 + .../BestHTTP/Authentication/Digest.cs | 280 ++ .../BestHTTP/Authentication/Digest.cs.meta | 10 + .../BestHTTP/Authentication/DigestStore.cs | 73 + .../Authentication/DigestStore.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/Caching.meta | 7 + .../BestHTTP/Caching/HTTPCacheFileInfo.cs | 403 ++ .../Caching/HTTPCacheFileInfo.cs.meta | 10 + .../BestHTTP/Caching/HTTPCacheFileLock.cs | 44 + .../Caching/HTTPCacheFileLock.cs.meta | 10 + .../Caching/HTTPCacheMaintananceParams.cs | 27 + .../HTTPCacheMaintananceParams.cs.meta | 10 + .../BestHTTP/Caching/HTTPCacheService.cs | 727 ++++ .../BestHTTP/Caching/HTTPCacheService.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/Connections.meta | 7 + .../BestHTTP/Connections/ConnectionBase.cs | 220 + .../Connections/ConnectionBase.cs.meta | 10 + .../BestHTTP/Connections/FileConnection.cs | 311 ++ .../Connections/FileConnection.cs.meta | 10 + .../BestHTTP/Connections/WebGLConnection.cs | 395 ++ .../Connections/WebGLConnection.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/Cookies.meta | 7 + .../BestHTTP/Cookies/Cookie.cs | 358 ++ .../BestHTTP/Cookies/Cookie.cs.meta | 10 + .../BestHTTP/Cookies/CookieJar.cs | 491 +++ .../BestHTTP/Cookies/CookieJar.cs.meta | 10 + .../BestHTTP/Decompression.meta | 7 + .../BestHTTP/Decompression/CRC32.cs | 473 +++ .../BestHTTP/Decompression/CRC32.cs.meta | 10 + .../BestHTTP/Decompression/Deflate.cs | 1881 +++++++++ .../BestHTTP/Decompression/Deflate.cs.meta | 10 + .../BestHTTP/Decompression/DeflateStream.cs | 804 ++++ .../Decompression/DeflateStream.cs.meta | 10 + .../BestHTTP/Decompression/GZipStream.cs | 1023 +++++ .../BestHTTP/Decompression/GZipStream.cs.meta | 10 + .../BestHTTP/Decompression/InfTree.cs | 436 ++ .../BestHTTP/Decompression/InfTree.cs.meta | 10 + .../BestHTTP/Decompression/Inflate.cs | 1796 ++++++++ .../BestHTTP/Decompression/Inflate.cs.meta | 10 + .../BestHTTP/Decompression/ZTree.cs | 423 ++ .../BestHTTP/Decompression/ZTree.cs.meta | 10 + .../BestHTTP/Decompression/Zlib.cs | 546 +++ .../BestHTTP/Decompression/Zlib.cs.meta | 10 + .../BestHTTP/Decompression/ZlibBaseStream.cs | 643 +++ .../Decompression/ZlibBaseStream.cs.meta | 10 + .../BestHTTP/Decompression/ZlibCodec.cs | 712 ++++ .../BestHTTP/Decompression/ZlibCodec.cs.meta | 10 + .../BestHTTP/Decompression/ZlibConstants.cs | 128 + .../Decompression/ZlibConstants.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/Extensions.meta | 7 + .../BestHTTP/Extensions/CircularBuffer.cs | 55 + .../Extensions/CircularBuffer.cs.meta | 13 + .../BestHTTP/Extensions/Extensions.cs | 449 ++ .../BestHTTP/Extensions/Extensions.cs.meta | 10 + .../BestHTTP/Extensions/Future.cs | 398 ++ .../BestHTTP/Extensions/Future.cs.meta | 13 + .../BestHTTP/Extensions/HeaderParser.cs | 40 + .../BestHTTP/Extensions/HeaderParser.cs.meta | 10 + .../BestHTTP/Extensions/HeaderValue.cs | 114 + .../BestHTTP/Extensions/HeaderValue.cs.meta | 10 + .../BestHTTP/Extensions/HeartbeatManager.cs | 70 + .../Extensions/HeartbeatManager.cs.meta | 10 + .../BestHTTP/Extensions/KeyValuePairList.cs | 27 + .../Extensions/KeyValuePairList.cs.meta | 10 + .../Extensions/WWWAuthenticateHeaderParser.cs | 50 + .../WWWAuthenticateHeaderParser.cs.meta | 10 + .../Extensions/WriteOnlyBufferedStream.cs | 70 + .../WriteOnlyBufferedStream.cs.meta | 12 + Assets/Best HTTP (Pro)/BestHTTP/Forms.meta | 7 + .../BestHTTP/Forms/HTTPFieldData.cs | 60 + .../BestHTTP/Forms/HTTPFieldData.cs.meta | 10 + .../BestHTTP/Forms/HTTPFormBase.cs | 141 + .../BestHTTP/Forms/HTTPFormBase.cs.meta | 10 + .../BestHTTP/Forms/HTTPFormUsage.cs | 37 + .../BestHTTP/Forms/HTTPFormUsage.cs.meta | 10 + .../BestHTTP/Forms/Implementations.meta | 7 + .../Implementations/HTTPMultiPartForm.cs | 79 + .../Implementations/HTTPMultiPartForm.cs.meta | 10 + .../Implementations/HTTPUrlEncodedForm.cs | 69 + .../HTTPUrlEncodedForm.cs.meta | 10 + .../Forms/Implementations/RawJSonForm.cs | 36 + .../Forms/Implementations/RawJSonForm.cs.meta | 12 + .../Forms/Implementations/UnityForm.cs | 58 + .../Forms/Implementations/UnityForm.cs.meta | 10 + .../BestHTTP/HTTPConnection.cs | 889 ++++ .../BestHTTP/HTTPConnection.cs.meta | 10 + .../BestHTTP/HTTPConnectionStates.cs | 59 + .../BestHTTP/HTTPConnectionStates.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/HTTPManager.cs | 802 ++++ .../BestHTTP/HTTPManager.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/HTTPMethods.cs | 76 + .../BestHTTP/HTTPMethods.cs.meta | 10 + .../BestHTTP/HTTPProtocolFactory.cs | 80 + .../BestHTTP/HTTPProtocolFactory.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs | 62 + .../BestHTTP/HTTPProxy.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs | 57 + .../BestHTTP/HTTPRange.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/HTTPRequest.cs | 1434 +++++++ .../BestHTTP/HTTPRequest.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/HTTPResponse.cs | 1161 ++++++ .../BestHTTP/HTTPResponse.cs.meta | 10 + .../BestHTTP/HTTPUpdateDelegator.cs | 257 ++ .../BestHTTP/HTTPUpdateDelegator.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/JSON.meta | 7 + Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs | 487 +++ .../BestHTTP/JSON/JSON.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/Logger.meta | 7 + .../BestHTTP/Logger/DefaultLogger.cs | 128 + .../BestHTTP/Logger/DefaultLogger.cs.meta | 10 + .../BestHTTP/Logger/ILogger.cs | 62 + .../BestHTTP/Logger/ILogger.cs.meta | 10 + .../BestHTTP/PlatformSupport.meta | 7 + .../BestHTTP/PlatformSupport/Collections.meta | 7 + .../Collections/ObjectModel.meta | 7 + .../ObjectModel/ObservableDictionary.cs | 263 ++ .../ObjectModel/ObservableDictionary.cs.meta | 10 + .../Collections/Specialized.meta | 7 + .../NotifyCollectionChangedEventArgs.cs | 467 +++ .../NotifyCollectionChangedEventArgs.cs.meta | 10 + .../PlatformSupport/Cryptography.meta | 7 + .../Cryptography/MD5CryptoServiceProvider.cs | 510 +++ .../MD5CryptoServiceProvider.cs.meta | 10 + .../BestHTTP/PlatformSupport/IO.meta | 7 + .../BestHTTP/PlatformSupport/IO/Directory.cs | 270 ++ .../PlatformSupport/IO/Directory.cs.meta | 10 + .../BestHTTP/PlatformSupport/IO/File.cs | 491 +++ .../BestHTTP/PlatformSupport/IO/File.cs.meta | 10 + .../BestHTTP/PlatformSupport/IO/FileEnums.cs | 69 + .../PlatformSupport/IO/FileEnums.cs.meta | 10 + .../BestHTTP/PlatformSupport/IO/FileHelper.cs | 140 + .../PlatformSupport/IO/FileHelper.cs.meta | 10 + .../BestHTTP/PlatformSupport/IO/FileStream.cs | 338 ++ .../PlatformSupport/IO/FileStream.cs.meta | 10 + .../BestHTTP/PlatformSupport/IO/Infos.cs | 217 + .../BestHTTP/PlatformSupport/IO/Infos.cs.meta | 10 + .../BestHTTP/PlatformSupport/TcpClient.meta | 7 + .../PlatformSupport/TcpClient/TcpClient.cs | 630 +++ .../TcpClient/TcpClient.cs.meta | 10 + .../PlatformSupport/TcpClient/WinRT.meta | 7 + .../TcpClient/WinRT/DataReaderWriterStream.cs | 148 + .../WinRT/DataReaderWriterStream.cs.meta | 10 + .../TcpClient/WinRT/TcpClient.cs | 133 + .../TcpClient/WinRT/TcpClient.cs.meta | 10 + .../BestHTTP/SecureProtocol.meta | 7 + .../BestHTTP/SecureProtocol/License.txt | 7 + .../BestHTTP/SecureProtocol/License.txt.meta | 8 + .../SecureProtocol/ReflectionHelpers.cs | 112 + .../SecureProtocol/ReflectionHelpers.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1.meta | 7 + .../SecureProtocol/asn1/ASN1Generator.cs | 30 + .../SecureProtocol/asn1/ASN1Generator.cs.meta | 10 + .../asn1/ASN1OctetStringParser.cs | 13 + .../asn1/ASN1OctetStringParser.cs.meta | 10 + .../SecureProtocol/asn1/ASN1SequenceParser.cs | 11 + .../asn1/ASN1SequenceParser.cs.meta | 10 + .../SecureProtocol/asn1/ASN1SetParser.cs | 11 + .../SecureProtocol/asn1/ASN1SetParser.cs.meta | 10 + .../SecureProtocol/asn1/ASN1StreamParser.cs | 237 ++ .../asn1/ASN1StreamParser.cs.meta | 10 + .../asn1/ASN1TaggedObjectParser.cs | 13 + .../asn1/ASN1TaggedObjectParser.cs.meta | 10 + .../SecureProtocol/asn1/Asn1Encodable.cs | 81 + .../SecureProtocol/asn1/Asn1Encodable.cs.meta | 10 + .../asn1/Asn1EncodableVector.cs | 96 + .../asn1/Asn1EncodableVector.cs.meta | 10 + .../SecureProtocol/asn1/Asn1Exception.cs | 33 + .../SecureProtocol/asn1/Asn1Exception.cs.meta | 10 + .../SecureProtocol/asn1/Asn1InputStream.cs | 374 ++ .../asn1/Asn1InputStream.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/Asn1Null.cs | 21 + .../SecureProtocol/asn1/Asn1Null.cs.meta | 10 + .../SecureProtocol/asn1/Asn1Object.cs | 71 + .../SecureProtocol/asn1/Asn1Object.cs.meta | 10 + .../SecureProtocol/asn1/Asn1OctetString.cs | 122 + .../asn1/Asn1OctetString.cs.meta | 10 + .../SecureProtocol/asn1/Asn1OutputStream.cs | 38 + .../asn1/Asn1OutputStream.cs.meta | 10 + .../asn1/Asn1ParsingException.cs | 32 + .../asn1/Asn1ParsingException.cs.meta | 10 + .../SecureProtocol/asn1/Asn1Sequence.cs | 271 ++ .../SecureProtocol/asn1/Asn1Sequence.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/Asn1Set.cs | 375 ++ .../SecureProtocol/asn1/Asn1Set.cs.meta | 10 + .../SecureProtocol/asn1/Asn1TaggedObject.cs | 191 + .../asn1/Asn1TaggedObject.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/Asn1Tags.cs | 39 + .../SecureProtocol/asn1/Asn1Tags.cs.meta | 10 + .../SecureProtocol/asn1/BERBitString.cs | 46 + .../SecureProtocol/asn1/BERBitString.cs.meta | 10 + .../SecureProtocol/asn1/BERGenerator.cs | 105 + .../SecureProtocol/asn1/BERGenerator.cs.meta | 10 + .../asn1/BEROctetStringParser.cs | 39 + .../asn1/BEROctetStringParser.cs.meta | 10 + .../asn1/BERSequenceGenerator.cs | 27 + .../asn1/BERSequenceGenerator.cs.meta | 10 + .../SecureProtocol/asn1/BERSequenceParser.cs | 27 + .../asn1/BERSequenceParser.cs.meta | 10 + .../SecureProtocol/asn1/BERSetGenerator.cs | 27 + .../asn1/BERSetGenerator.cs.meta | 10 + .../SecureProtocol/asn1/BERSetParser.cs | 27 + .../SecureProtocol/asn1/BERSetParser.cs.meta | 10 + .../asn1/BERTaggedObjectParser.cs | 74 + .../asn1/BERTaggedObjectParser.cs.meta | 10 + .../asn1/BerApplicationSpecific.cs | 18 + .../asn1/BerApplicationSpecific.cs.meta | 10 + .../asn1/BerApplicationSpecificParser.cs | 32 + .../asn1/BerApplicationSpecificParser.cs.meta | 10 + .../SecureProtocol/asn1/BerOctetString.cs | 138 + .../asn1/BerOctetString.cs.meta | 10 + .../SecureProtocol/asn1/BerOutputStream.cs | 39 + .../asn1/BerOutputStream.cs.meta | 10 + .../SecureProtocol/asn1/BerSequence.cs | 72 + .../SecureProtocol/asn1/BerSequence.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/BerSet.cs | 73 + .../SecureProtocol/asn1/BerSet.cs.meta | 10 + .../SecureProtocol/asn1/BerTaggedObject.cs | 111 + .../asn1/BerTaggedObject.cs.meta | 10 + .../asn1/ConstructedOctetStream.cs | 105 + .../asn1/ConstructedOctetStream.cs.meta | 10 + .../SecureProtocol/asn1/DERExternal.cs | 205 + .../SecureProtocol/asn1/DERExternal.cs.meta | 10 + .../SecureProtocol/asn1/DERExternalParser.cs | 29 + .../asn1/DERExternalParser.cs.meta | 10 + .../SecureProtocol/asn1/DERGenerator.cs | 110 + .../SecureProtocol/asn1/DERGenerator.cs.meta | 10 + .../asn1/DEROctetStringParser.cs | 39 + .../asn1/DEROctetStringParser.cs.meta | 10 + .../SecureProtocol/asn1/DERSequenceParser.cs | 27 + .../asn1/DERSequenceParser.cs.meta | 10 + .../SecureProtocol/asn1/DERSetGenerator.cs | 43 + .../asn1/DERSetGenerator.cs.meta | 10 + .../SecureProtocol/asn1/DERSetParser.cs | 27 + .../SecureProtocol/asn1/DERSetParser.cs.meta | 10 + .../asn1/DefiniteLengthInputStream.cs | 103 + .../asn1/DefiniteLengthInputStream.cs.meta | 10 + .../asn1/DerApplicationSpecific.cs | 240 ++ .../asn1/DerApplicationSpecific.cs.meta | 10 + .../SecureProtocol/asn1/DerBMPString.cs | 120 + .../SecureProtocol/asn1/DerBMPString.cs.meta | 10 + .../SecureProtocol/asn1/DerBitString.cs | 279 ++ .../SecureProtocol/asn1/DerBitString.cs.meta | 10 + .../SecureProtocol/asn1/DerBoolean.cs | 127 + .../SecureProtocol/asn1/DerBoolean.cs.meta | 10 + .../SecureProtocol/asn1/DerEnumerated.cs | 127 + .../SecureProtocol/asn1/DerEnumerated.cs.meta | 10 + .../SecureProtocol/asn1/DerGeneralString.cs | 84 + .../asn1/DerGeneralString.cs.meta | 10 + .../SecureProtocol/asn1/DerGeneralizedTime.cs | 323 ++ .../asn1/DerGeneralizedTime.cs.meta | 10 + .../SecureProtocol/asn1/DerGraphicString.cs | 106 + .../asn1/DerGraphicString.cs.meta | 10 + .../SecureProtocol/asn1/DerIA5String.cs | 148 + .../SecureProtocol/asn1/DerIA5String.cs.meta | 10 + .../SecureProtocol/asn1/DerInteger.cs | 120 + .../SecureProtocol/asn1/DerInteger.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/DerNull.cs | 44 + .../SecureProtocol/asn1/DerNull.cs.meta | 10 + .../SecureProtocol/asn1/DerNumericString.cs | 141 + .../asn1/DerNumericString.cs.meta | 10 + .../asn1/DerObjectIdentifier.cs | 350 ++ .../asn1/DerObjectIdentifier.cs.meta | 10 + .../SecureProtocol/asn1/DerOctetString.cs | 37 + .../asn1/DerOctetString.cs.meta | 10 + .../SecureProtocol/asn1/DerOutputStream.cs | 174 + .../asn1/DerOutputStream.cs.meta | 10 + .../SecureProtocol/asn1/DerPrintableString.cs | 166 + .../asn1/DerPrintableString.cs.meta | 10 + .../SecureProtocol/asn1/DerSequence.cs | 90 + .../SecureProtocol/asn1/DerSequence.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/DerSet.cs | 113 + .../SecureProtocol/asn1/DerSet.cs.meta | 10 + .../SecureProtocol/asn1/DerStringBase.cs | 25 + .../SecureProtocol/asn1/DerStringBase.cs.meta | 10 + .../SecureProtocol/asn1/DerT61String.cs | 105 + .../SecureProtocol/asn1/DerT61String.cs.meta | 10 + .../SecureProtocol/asn1/DerTaggedObject.cs | 75 + .../asn1/DerTaggedObject.cs.meta | 10 + .../SecureProtocol/asn1/DerUTCTime.cs | 270 ++ .../SecureProtocol/asn1/DerUTCTime.cs.meta | 10 + .../SecureProtocol/asn1/DerUTF8String.cs | 101 + .../SecureProtocol/asn1/DerUTF8String.cs.meta | 10 + .../SecureProtocol/asn1/DerUniversalString.cs | 110 + .../asn1/DerUniversalString.cs.meta | 10 + .../SecureProtocol/asn1/DerVideotexString.cs | 106 + .../asn1/DerVideotexString.cs.meta | 10 + .../SecureProtocol/asn1/DerVisibleString.cs | 114 + .../asn1/DerVisibleString.cs.meta | 10 + .../asn1/IAsn1ApplicationSpecificParser.cs | 13 + .../IAsn1ApplicationSpecificParser.cs.meta | 10 + .../SecureProtocol/asn1/IAsn1Choice.cs | 20 + .../SecureProtocol/asn1/IAsn1Choice.cs.meta | 10 + .../SecureProtocol/asn1/IAsn1Convertible.cs | 10 + .../asn1/IAsn1Convertible.cs.meta | 10 + .../SecureProtocol/asn1/IAsn1String.cs | 13 + .../SecureProtocol/asn1/IAsn1String.cs.meta | 10 + .../asn1/IndefiniteLengthInputStream.cs | 173 + .../asn1/IndefiniteLengthInputStream.cs.meta | 10 + .../asn1/LazyASN1InputStream.cs | 36 + .../asn1/LazyASN1InputStream.cs.meta | 10 + .../SecureProtocol/asn1/LazyDERSequence.cs | 83 + .../asn1/LazyDERSequence.cs.meta | 10 + .../SecureProtocol/asn1/LazyDERSet.cs | 83 + .../SecureProtocol/asn1/LazyDERSet.cs.meta | 10 + .../SecureProtocol/asn1/LimitedInputStream.cs | 38 + .../asn1/LimitedInputStream.cs.meta | 10 + .../SecureProtocol/asn1/OidTokenizer.cs | 48 + .../SecureProtocol/asn1/OidTokenizer.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/anssi.meta | 7 + .../asn1/anssi/ANSSINamedCurves.cs | 126 + .../asn1/anssi/ANSSINamedCurves.cs.meta | 10 + .../asn1/anssi/ANSSIObjectIdentifiers.cs | 16 + .../asn1/anssi/ANSSIObjectIdentifiers.cs.meta | 10 + .../SecureProtocol/asn1/cryptopro.meta | 7 + .../cryptopro/CryptoProObjectIdentifiers.cs | 54 + .../CryptoProObjectIdentifiers.cs.meta | 10 + .../asn1/cryptopro/ECGOST3410NamedCurves.cs | 187 + .../cryptopro/ECGOST3410NamedCurves.cs.meta | 10 + .../asn1/cryptopro/GOST3410NamedParameters.cs | 126 + .../cryptopro/GOST3410NamedParameters.cs.meta | 10 + .../cryptopro/GOST3410ParamSetParameters.cs | 90 + .../GOST3410ParamSetParameters.cs.meta | 10 + .../GOST3410PublicKeyAlgParameters.cs | 102 + .../GOST3410PublicKeyAlgParameters.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/iana.meta | 7 + .../asn1/iana/IANAObjectIdentifiers.cs | 21 + .../asn1/iana/IANAObjectIdentifiers.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/misc.meta | 7 + .../asn1/misc/MiscObjectIdentifiers.cs | 82 + .../asn1/misc/MiscObjectIdentifiers.cs.meta | 10 + .../asn1/misc/NetscapeCertType.cs | 57 + .../asn1/misc/NetscapeCertType.cs.meta | 10 + .../asn1/misc/NetscapeRevocationURL.cs | 21 + .../asn1/misc/NetscapeRevocationURL.cs.meta | 10 + .../asn1/misc/VerisignCzagExtension.cs | 21 + .../asn1/misc/VerisignCzagExtension.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/nist.meta | 7 + .../asn1/nist/NISTNamedCurves.cs | 105 + .../asn1/nist/NISTNamedCurves.cs.meta | 10 + .../asn1/nist/NISTObjectIdentifiers.cs | 74 + .../asn1/nist/NISTObjectIdentifiers.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/ocsp.meta | 7 + .../SecureProtocol/asn1/ocsp/OCSPResponse.cs | 93 + .../asn1/ocsp/OCSPResponse.cs.meta | 10 + .../asn1/ocsp/OCSPResponseStatus.cs | 44 + .../asn1/ocsp/OCSPResponseStatus.cs.meta | 10 + .../SecureProtocol/asn1/ocsp/ResponderID.cs | 110 + .../asn1/ocsp/ResponderID.cs.meta | 10 + .../SecureProtocol/asn1/ocsp/ResponseBytes.cs | 85 + .../asn1/ocsp/ResponseBytes.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/oiw.meta | 7 + .../asn1/oiw/ElGamalParameter.cs | 50 + .../asn1/oiw/ElGamalParameter.cs.meta | 10 + .../asn1/oiw/OIWObjectIdentifiers.cs | 32 + .../asn1/oiw/OIWObjectIdentifiers.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/pkcs.meta | 7 + .../SecureProtocol/asn1/pkcs/ContentInfo.cs | 77 + .../asn1/pkcs/ContentInfo.cs.meta | 10 + .../SecureProtocol/asn1/pkcs/DHParameter.cs | 75 + .../asn1/pkcs/DHParameter.cs.meta | 10 + .../asn1/pkcs/PKCSObjectIdentifiers.cs | 276 ++ .../asn1/pkcs/PKCSObjectIdentifiers.cs.meta | 10 + .../asn1/pkcs/RSASSAPSSparams.cs | 169 + .../asn1/pkcs/RSASSAPSSparams.cs.meta | 10 + .../SecureProtocol/asn1/pkcs/SignedData.cs | 160 + .../asn1/pkcs/SignedData.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/sec.meta | 7 + .../SecureProtocol/asn1/sec/SECNamedCurves.cs | 1187 ++++++ .../asn1/sec/SECNamedCurves.cs.meta | 10 + .../asn1/sec/SECObjectIdentifiers.cs | 54 + .../asn1/sec/SECObjectIdentifiers.cs.meta | 10 + .../SecureProtocol/asn1/teletrust.meta | 7 + .../asn1/teletrust/TeleTrusTNamedCurves.cs | 473 +++ .../teletrust/TeleTrusTNamedCurves.cs.meta | 10 + .../teletrust/TeleTrusTObjectIdentifiers.cs | 48 + .../TeleTrusTObjectIdentifiers.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/util.meta | 7 + .../SecureProtocol/asn1/util/Asn1Dump.cs | 384 ++ .../SecureProtocol/asn1/util/Asn1Dump.cs.meta | 10 + .../SecureProtocol/asn1/util/FilterStream.cs | 84 + .../asn1/util/FilterStream.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/x509.meta | 7 + .../asn1/x509/AlgorithmIdentifier.cs | 99 + .../asn1/x509/AlgorithmIdentifier.cs.meta | 10 + .../asn1/x509/BasicConstraints.cs | 136 + .../asn1/x509/BasicConstraints.cs.meta | 10 + .../SecureProtocol/asn1/x509/CRLDistPoint.cs | 96 + .../asn1/x509/CRLDistPoint.cs.meta | 10 + .../SecureProtocol/asn1/x509/CRLNumber.cs | 33 + .../asn1/x509/CRLNumber.cs.meta | 10 + .../SecureProtocol/asn1/x509/CRLReason.cs | 64 + .../asn1/x509/CRLReason.cs.meta | 10 + .../asn1/x509/CertificateList.cs | 116 + .../asn1/x509/CertificateList.cs.meta | 10 + .../SecureProtocol/asn1/x509/DSAParameter.cs | 81 + .../asn1/x509/DSAParameter.cs.meta | 10 + .../SecureProtocol/asn1/x509/DigestInfo.cs | 81 + .../asn1/x509/DigestInfo.cs.meta | 10 + .../asn1/x509/DistributionPoint.cs | 164 + .../asn1/x509/DistributionPoint.cs.meta | 10 + .../asn1/x509/DistributionPointName.cs | 133 + .../asn1/x509/DistributionPointName.cs.meta | 10 + .../SecureProtocol/asn1/x509/GeneralName.cs | 422 ++ .../asn1/x509/GeneralName.cs.meta | 10 + .../SecureProtocol/asn1/x509/GeneralNames.cs | 98 + .../asn1/x509/GeneralNames.cs.meta | 10 + .../asn1/x509/IssuingDistributionPoint.cs | 250 ++ .../x509/IssuingDistributionPoint.cs.meta | 10 + .../SecureProtocol/asn1/x509/KeyUsage.cs | 81 + .../SecureProtocol/asn1/x509/KeyUsage.cs.meta | 10 + .../asn1/x509/RSAPublicKeyStructure.cs | 96 + .../asn1/x509/RSAPublicKeyStructure.cs.meta | 10 + .../SecureProtocol/asn1/x509/ReasonFlags.cs | 48 + .../asn1/x509/ReasonFlags.cs.meta | 10 + .../asn1/x509/SubjectPublicKeyInfo.cs | 105 + .../asn1/x509/SubjectPublicKeyInfo.cs.meta | 10 + .../SecureProtocol/asn1/x509/TBSCertList.cs | 278 ++ .../asn1/x509/TBSCertList.cs.meta | 10 + .../asn1/x509/TBSCertificateStructure.cs | 188 + .../asn1/x509/TBSCertificateStructure.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/x509/Time.cs | 125 + .../SecureProtocol/asn1/x509/Time.cs.meta | 10 + .../asn1/x509/X509CertificateStructure.cs | 135 + .../x509/X509CertificateStructure.cs.meta | 10 + .../asn1/x509/X509DefaultEntryConverter.cs | 66 + .../x509/X509DefaultEntryConverter.cs.meta | 10 + .../SecureProtocol/asn1/x509/X509Extension.cs | 82 + .../asn1/x509/X509Extension.cs.meta | 10 + .../asn1/x509/X509Extensions.cs | 455 +++ .../asn1/x509/X509Extensions.cs.meta | 10 + .../SecureProtocol/asn1/x509/X509Name.cs | 1080 +++++ .../SecureProtocol/asn1/x509/X509Name.cs.meta | 10 + .../asn1/x509/X509NameEntryConverter.cs | 92 + .../asn1/x509/X509NameEntryConverter.cs.meta | 10 + .../asn1/x509/X509NameTokenizer.cs | 107 + .../asn1/x509/X509NameTokenizer.cs.meta | 10 + .../asn1/x509/X509ObjectIdentifiers.cs | 62 + .../asn1/x509/X509ObjectIdentifiers.cs.meta | 10 + .../BestHTTP/SecureProtocol/asn1/x9.meta | 7 + .../asn1/x9/DHDomainParameters.cs | 121 + .../asn1/x9/DHDomainParameters.cs.meta | 10 + .../SecureProtocol/asn1/x9/DHPublicKey.cs | 49 + .../asn1/x9/DHPublicKey.cs.meta | 10 + .../asn1/x9/DHValidationParms.cs | 67 + .../asn1/x9/DHValidationParms.cs.meta | 10 + .../asn1/x9/ECNamedCurveTable.cs | 160 + .../asn1/x9/ECNamedCurveTable.cs.meta | 10 + .../SecureProtocol/asn1/x9/X962NamedCurves.cs | 754 ++++ .../asn1/x9/X962NamedCurves.cs.meta | 10 + .../SecureProtocol/asn1/x9/X962Parameters.cs | 91 + .../asn1/x9/X962Parameters.cs.meta | 10 + .../SecureProtocol/asn1/x9/X9Curve.cs | 149 + .../SecureProtocol/asn1/x9/X9Curve.cs.meta | 10 + .../SecureProtocol/asn1/x9/X9ECParameters.cs | 236 ++ .../asn1/x9/X9ECParameters.cs.meta | 10 + .../asn1/x9/X9ECParametersHolder.cs | 28 + .../asn1/x9/X9ECParametersHolder.cs.meta | 10 + .../SecureProtocol/asn1/x9/X9ECPoint.cs | 83 + .../SecureProtocol/asn1/x9/X9ECPoint.cs.meta | 10 + .../SecureProtocol/asn1/x9/X9FieldElement.cs | 72 + .../asn1/x9/X9FieldElement.cs.meta | 10 + .../SecureProtocol/asn1/x9/X9FieldID.cs | 135 + .../SecureProtocol/asn1/x9/X9FieldID.cs.meta | 10 + .../asn1/x9/X9IntegerConverter.cs | 43 + .../asn1/x9/X9IntegerConverter.cs.meta | 10 + .../asn1/x9/X9ObjectIdentifiers.cs | 140 + .../asn1/x9/X9ObjectIdentifiers.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto.meta | 7 + .../crypto/AsymmetricCipherKeyPair.cs | 56 + .../crypto/AsymmetricCipherKeyPair.cs.meta | 10 + .../crypto/AsymmetricKeyParameter.cs | 51 + .../crypto/AsymmetricKeyParameter.cs.meta | 10 + .../crypto/BufferedAeadBlockCipher.cs | 251 ++ .../crypto/BufferedAeadBlockCipher.cs.meta | 10 + .../crypto/BufferedAsymmetricBlockCipher.cs | 156 + .../BufferedAsymmetricBlockCipher.cs.meta | 10 + .../crypto/BufferedBlockCipher.cs | 371 ++ .../crypto/BufferedBlockCipher.cs.meta | 10 + .../crypto/BufferedCipherBase.cs | 117 + .../crypto/BufferedCipherBase.cs.meta | 10 + .../crypto/BufferedIesCipher.cs | 117 + .../crypto/BufferedIesCipher.cs.meta | 10 + .../crypto/BufferedStreamCipher.cs | 135 + .../crypto/BufferedStreamCipher.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/Check.cs | 29 + .../SecureProtocol/crypto/Check.cs.meta | 10 + .../crypto/CipherKeyGenerator.cs | 87 + .../crypto/CipherKeyGenerator.cs.meta | 10 + .../SecureProtocol/crypto/CryptoException.cs | 32 + .../crypto/CryptoException.cs.meta | 10 + .../crypto/DataLengthException.cs | 46 + .../crypto/DataLengthException.cs.meta | 10 + .../crypto/IAsymmetricBlockCipher.cs | 34 + .../crypto/IAsymmetricBlockCipher.cs.meta | 10 + .../IAsymmetricCipherKeyPairGenerator.cs | 28 + .../IAsymmetricCipherKeyPairGenerator.cs.meta | 10 + .../SecureProtocol/crypto/IBasicAgreement.cs | 33 + .../crypto/IBasicAgreement.cs.meta | 10 + .../SecureProtocol/crypto/IBlockCipher.cs | 40 + .../crypto/IBlockCipher.cs.meta | 10 + .../SecureProtocol/crypto/IBlockResult.cs | 27 + .../crypto/IBlockResult.cs.meta | 10 + .../SecureProtocol/crypto/IBufferedCipher.cs | 48 + .../crypto/IBufferedCipher.cs.meta | 10 + .../crypto/ICipherParameters.cs | 15 + .../crypto/ICipherParameters.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/IDSA.cs | 44 + .../SecureProtocol/crypto/IDSA.cs.meta | 10 + .../crypto/IDerivationFunction.cs | 28 + .../crypto/IDerivationFunction.cs.meta | 10 + .../crypto/IDerivationParameters.cs | 15 + .../crypto/IDerivationParameters.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/IDigest.cs | 65 + .../SecureProtocol/crypto/IDigest.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/IMac.cs | 73 + .../SecureProtocol/crypto/IMac.cs.meta | 10 + .../crypto/ISignatureFactory.cs | 24 + .../crypto/ISignatureFactory.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/ISigner.cs | 54 + .../SecureProtocol/crypto/ISigner.cs.meta | 10 + .../crypto/ISignerWithRecovery.cs | 41 + .../crypto/ISignerWithRecovery.cs.meta | 10 + .../crypto/IStreamCalculator.cs | 26 + .../crypto/IStreamCalculator.cs.meta | 10 + .../SecureProtocol/crypto/IStreamCipher.cs | 49 + .../crypto/IStreamCipher.cs.meta | 10 + .../SecureProtocol/crypto/IVerifier.cs | 28 + .../SecureProtocol/crypto/IVerifier.cs.meta | 10 + .../SecureProtocol/crypto/IVerifierFactory.cs | 24 + .../crypto/IVerifierFactory.cs.meta | 10 + .../crypto/IVerifierFactoryProvider.cs | 20 + .../crypto/IVerifierFactoryProvider.cs.meta | 10 + .../SecureProtocol/crypto/IWrapper.cs | 22 + .../SecureProtocol/crypto/IWrapper.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/IXof.cs | 33 + .../SecureProtocol/crypto/IXof.cs.meta | 10 + .../crypto/InvalidCipherTextException.cs | 44 + .../crypto/InvalidCipherTextException.cs.meta | 10 + .../crypto/KeyGenerationParameters.cs | 59 + .../crypto/KeyGenerationParameters.cs.meta | 10 + .../crypto/MaxBytesExceededException.cs | 36 + .../crypto/MaxBytesExceededException.cs.meta | 10 + .../crypto/OutputLengthException.cs | 32 + .../crypto/OutputLengthException.cs.meta | 10 + .../crypto/PbeParametersGenerator.cs | 206 + .../crypto/PbeParametersGenerator.cs.meta | 10 + .../SecureProtocol/crypto/agreement.meta | 7 + .../crypto/agreement/DHBasicAgreement.cs | 68 + .../crypto/agreement/DHBasicAgreement.cs.meta | 10 + .../crypto/agreement/ECDHBasicAgreement.cs | 64 + .../agreement/ECDHBasicAgreement.cs.meta | 10 + .../SecureProtocol/crypto/digests.meta | 7 + .../crypto/digests/GOST3411Digest.cs | 360 ++ .../crypto/digests/GOST3411Digest.cs.meta | 10 + .../crypto/digests/GeneralDigest.cs | 137 + .../crypto/digests/GeneralDigest.cs.meta | 10 + .../crypto/digests/KeccakDigest.cs | 538 +++ .../crypto/digests/KeccakDigest.cs.meta | 10 + .../crypto/digests/LongDigest.cs | 359 ++ .../crypto/digests/LongDigest.cs.meta | 10 + .../crypto/digests/MD2Digest.cs | 273 ++ .../crypto/digests/MD2Digest.cs.meta | 10 + .../crypto/digests/MD4Digest.cs | 296 ++ .../crypto/digests/MD4Digest.cs.meta | 10 + .../crypto/digests/MD5Digest.cs | 317 ++ .../crypto/digests/MD5Digest.cs.meta | 10 + .../crypto/digests/NullDigest.cs | 53 + .../crypto/digests/NullDigest.cs.meta | 10 + .../crypto/digests/RipeMD128Digest.cs | 488 +++ .../crypto/digests/RipeMD128Digest.cs.meta | 10 + .../crypto/digests/RipeMD160Digest.cs | 449 ++ .../crypto/digests/RipeMD160Digest.cs.meta | 10 + .../crypto/digests/RipeMD256Digest.cs | 434 ++ .../crypto/digests/RipeMD256Digest.cs.meta | 10 + .../crypto/digests/RipeMD320Digest.cs | 463 +++ .../crypto/digests/RipeMD320Digest.cs.meta | 10 + .../crypto/digests/SHA3Digest.cs | 90 + .../crypto/digests/SHA3Digest.cs.meta | 10 + .../crypto/digests/Sha1Digest.cs | 288 ++ .../crypto/digests/Sha1Digest.cs.meta | 10 + .../crypto/digests/Sha224Digest.cs | 293 ++ .../crypto/digests/Sha224Digest.cs.meta | 10 + .../crypto/digests/Sha256Digest.cs | 334 ++ .../crypto/digests/Sha256Digest.cs.meta | 10 + .../crypto/digests/Sha384Digest.cs | 105 + .../crypto/digests/Sha384Digest.cs.meta | 10 + .../crypto/digests/Sha512Digest.cs | 108 + .../crypto/digests/Sha512Digest.cs.meta | 10 + .../crypto/digests/Sha512tDigest.cs | 204 + .../crypto/digests/Sha512tDigest.cs.meta | 10 + .../crypto/digests/ShakeDigest.cs | 123 + .../crypto/digests/ShakeDigest.cs.meta | 10 + .../crypto/digests/TigerDigest.cs | 887 ++++ .../crypto/digests/TigerDigest.cs.meta | 10 + .../crypto/digests/WhirlpoolDigest.cs | 417 ++ .../crypto/digests/WhirlpoolDigest.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/ec.meta | 7 + .../crypto/ec/CustomNamedCurves.cs | 892 ++++ .../crypto/ec/CustomNamedCurves.cs.meta | 10 + .../SecureProtocol/crypto/encodings.meta | 7 + .../crypto/encodings/ISO9796d1Encoding.cs | 277 ++ .../encodings/ISO9796d1Encoding.cs.meta | 10 + .../crypto/encodings/OaepEncoding.cs | 353 ++ .../crypto/encodings/OaepEncoding.cs.meta | 10 + .../crypto/encodings/Pkcs1Encoding.cs | 386 ++ .../crypto/encodings/Pkcs1Encoding.cs.meta | 10 + .../SecureProtocol/crypto/engines.meta | 7 + .../crypto/engines/AesEngine.cs | 611 +++ .../crypto/engines/AesEngine.cs.meta | 10 + .../crypto/engines/AesFastEngine.cs | 1186 ++++++ .../crypto/engines/AesFastEngine.cs.meta | 10 + .../crypto/engines/AesWrapEngine.cs | 20 + .../crypto/engines/AesWrapEngine.cs.meta | 10 + .../crypto/engines/BlowfishEngine.cs | 557 +++ .../crypto/engines/BlowfishEngine.cs.meta | 10 + .../crypto/engines/CamelliaEngine.cs | 672 +++ .../crypto/engines/CamelliaEngine.cs.meta | 10 + .../crypto/engines/CamelliaWrapEngine.cs | 20 + .../crypto/engines/CamelliaWrapEngine.cs.meta | 10 + .../crypto/engines/Cast5Engine.cs | 806 ++++ .../crypto/engines/Cast5Engine.cs.meta | 10 + .../crypto/engines/Cast6Engine.cs | 283 ++ .../crypto/engines/Cast6Engine.cs.meta | 10 + .../crypto/engines/ChaCha7539Engine.cs | 66 + .../crypto/engines/ChaCha7539Engine.cs.meta | 10 + .../crypto/engines/ChaChaEngine.cs | 161 + .../crypto/engines/ChaChaEngine.cs.meta | 10 + .../crypto/engines/DesEdeEngine.cs | 104 + .../crypto/engines/DesEdeEngine.cs.meta | 10 + .../crypto/engines/DesEdeWrapEngine.cs | 326 ++ .../crypto/engines/DesEdeWrapEngine.cs.meta | 10 + .../crypto/engines/DesEngine.cs | 479 +++ .../crypto/engines/DesEngine.cs.meta | 10 + .../crypto/engines/ElGamalEngine.cs | 182 + .../crypto/engines/ElGamalEngine.cs.meta | 10 + .../crypto/engines/GOST28147Engine.cs | 372 ++ .../crypto/engines/GOST28147Engine.cs.meta | 10 + .../crypto/engines/HC128Engine.cs | 239 ++ .../crypto/engines/HC128Engine.cs.meta | 10 + .../crypto/engines/HC256Engine.cs | 228 ++ .../crypto/engines/HC256Engine.cs.meta | 10 + .../crypto/engines/IdeaEngine.cs | 336 ++ .../crypto/engines/IdeaEngine.cs.meta | 10 + .../crypto/engines/IesEngine.cs | 247 ++ .../crypto/engines/IesEngine.cs.meta | 10 + .../crypto/engines/NoekeonEngine.cs | 245 ++ .../crypto/engines/NoekeonEngine.cs.meta | 10 + .../crypto/engines/RC2Engine.cs | 315 ++ .../crypto/engines/RC2Engine.cs.meta | 10 + .../crypto/engines/RC2WrapEngine.cs | 374 ++ .../crypto/engines/RC2WrapEngine.cs.meta | 10 + .../crypto/engines/RC4Engine.cs | 143 + .../crypto/engines/RC4Engine.cs.meta | 10 + .../crypto/engines/RC532Engine.cs | 302 ++ .../crypto/engines/RC532Engine.cs.meta | 10 + .../crypto/engines/RC564Engine.cs | 303 ++ .../crypto/engines/RC564Engine.cs.meta | 10 + .../crypto/engines/RC6Engine.cs | 365 ++ .../crypto/engines/RC6Engine.cs.meta | 10 + .../crypto/engines/RFC3211WrapEngine.cs | 172 + .../crypto/engines/RFC3211WrapEngine.cs.meta | 10 + .../crypto/engines/RFC3394WrapEngine.cs | 182 + .../crypto/engines/RFC3394WrapEngine.cs.meta | 10 + .../crypto/engines/RSABlindedEngine.cs | 132 + .../crypto/engines/RSABlindedEngine.cs.meta | 10 + .../crypto/engines/RSACoreEngine.cs | 160 + .../crypto/engines/RSACoreEngine.cs.meta | 10 + .../crypto/engines/RijndaelEngine.cs | 746 ++++ .../crypto/engines/RijndaelEngine.cs.meta | 10 + .../crypto/engines/SEEDEngine.cs | 364 ++ .../crypto/engines/SEEDEngine.cs.meta | 10 + .../crypto/engines/SEEDWrapEngine.cs | 20 + .../crypto/engines/SEEDWrapEngine.cs.meta | 10 + .../crypto/engines/Salsa20Engine.cs | 366 ++ .../crypto/engines/Salsa20Engine.cs.meta | 10 + .../crypto/engines/SerpentEngine.cs | 296 ++ .../crypto/engines/SerpentEngine.cs.meta | 10 + .../crypto/engines/SerpentEngineBase.cs | 473 +++ .../crypto/engines/SerpentEngineBase.cs.meta | 10 + .../crypto/engines/SkipjackEngine.cs | 258 ++ .../crypto/engines/SkipjackEngine.cs.meta | 10 + .../crypto/engines/TEAEngine.cs | 170 + .../crypto/engines/TEAEngine.cs.meta | 10 + .../crypto/engines/TwofishEngine.cs | 679 ++++ .../crypto/engines/TwofishEngine.cs.meta | 10 + .../crypto/engines/VMPCEngine.cs | 137 + .../crypto/engines/VMPCEngine.cs.meta | 10 + .../crypto/engines/VMPCKSA3Engine.cs | 55 + .../crypto/engines/VMPCKSA3Engine.cs.meta | 10 + .../crypto/engines/XTEAEngine.cs | 170 + .../crypto/engines/XTEAEngine.cs.meta | 10 + .../SecureProtocol/crypto/generators.meta | 7 + .../generators/DHBasicKeyPairGenerator.cs | 42 + .../DHBasicKeyPairGenerator.cs.meta | 10 + .../crypto/generators/DHKeyGeneratorHelper.cs | 76 + .../generators/DHKeyGeneratorHelper.cs.meta | 10 + .../crypto/generators/DHKeyPairGenerator.cs | 42 + .../generators/DHKeyPairGenerator.cs.meta | 10 + .../crypto/generators/DHParametersHelper.cs | 160 + .../generators/DHParametersHelper.cs.meta | 10 + .../crypto/generators/DsaKeyPairGenerator.cs | 76 + .../generators/DsaKeyPairGenerator.cs.meta | 10 + .../crypto/generators/ECKeyPairGenerator.cs | 166 + .../generators/ECKeyPairGenerator.cs.meta | 10 + .../generators/ElGamalKeyPairGenerator.cs | 44 + .../ElGamalKeyPairGenerator.cs.meta | 10 + .../crypto/generators/Poly1305KeyGenerator.cs | 120 + .../generators/Poly1305KeyGenerator.cs.meta | 10 + .../crypto/generators/RsaKeyPairGenerator.cs | 167 + .../generators/RsaKeyPairGenerator.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/macs.meta | 7 + .../SecureProtocol/crypto/macs/CMac.cs | 261 ++ .../SecureProtocol/crypto/macs/CMac.cs.meta | 10 + .../crypto/macs/CbcBlockCipherMac.cs | 213 + .../crypto/macs/CbcBlockCipherMac.cs.meta | 10 + .../crypto/macs/CfbBlockCipherMac.cs | 372 ++ .../crypto/macs/CfbBlockCipherMac.cs.meta | 10 + .../crypto/macs/GOST28147Mac.cs | 301 ++ .../crypto/macs/GOST28147Mac.cs.meta | 10 + .../SecureProtocol/crypto/macs/HMac.cs | 158 + .../SecureProtocol/crypto/macs/HMac.cs.meta | 10 + .../crypto/macs/ISO9797Alg3Mac.cs | 279 ++ .../crypto/macs/ISO9797Alg3Mac.cs.meta | 10 + .../SecureProtocol/crypto/macs/Poly1305.cs | 299 ++ .../crypto/macs/Poly1305.cs.meta | 10 + .../SecureProtocol/crypto/macs/SipHash.cs | 203 + .../crypto/macs/SipHash.cs.meta | 10 + .../SecureProtocol/crypto/macs/VMPCMac.cs | 177 + .../crypto/macs/VMPCMac.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/modes.meta | 7 + .../crypto/modes/CbcBlockCipher.cs | 245 ++ .../crypto/modes/CbcBlockCipher.cs.meta | 10 + .../crypto/modes/CcmBlockCipher.cs | 453 +++ .../crypto/modes/CcmBlockCipher.cs.meta | 10 + .../crypto/modes/CfbBlockCipher.cs | 228 ++ .../crypto/modes/CfbBlockCipher.cs.meta | 10 + .../crypto/modes/CtsBlockCipher.cs | 257 ++ .../crypto/modes/CtsBlockCipher.cs.meta | 10 + .../crypto/modes/EAXBlockCipher.cs | 383 ++ .../crypto/modes/EAXBlockCipher.cs.meta | 10 + .../crypto/modes/GCMBlockCipher.cs | 569 +++ .../crypto/modes/GCMBlockCipher.cs.meta | 10 + .../crypto/modes/GOFBBlockCipher.cs | 231 ++ .../crypto/modes/GOFBBlockCipher.cs.meta | 10 + .../crypto/modes/IAeadBlockCipher.cs | 109 + .../crypto/modes/IAeadBlockCipher.cs.meta | 10 + .../crypto/modes/OCBBlockCipher.cs | 567 +++ .../crypto/modes/OCBBlockCipher.cs.meta | 10 + .../crypto/modes/OfbBlockCipher.cs | 186 + .../crypto/modes/OfbBlockCipher.cs.meta | 10 + .../crypto/modes/OpenPgpCfbBlockCipher.cs | 341 ++ .../modes/OpenPgpCfbBlockCipher.cs.meta | 10 + .../crypto/modes/SicBlockCipher.cs | 124 + .../crypto/modes/SicBlockCipher.cs.meta | 10 + .../SecureProtocol/crypto/modes/gcm.meta | 7 + .../crypto/modes/gcm/GcmUtilities.cs | 389 ++ .../crypto/modes/gcm/GcmUtilities.cs.meta | 10 + .../crypto/modes/gcm/IGcmExponentiator.cs | 14 + .../modes/gcm/IGcmExponentiator.cs.meta | 10 + .../crypto/modes/gcm/IGcmMultiplier.cs | 14 + .../crypto/modes/gcm/IGcmMultiplier.cs.meta | 10 + .../modes/gcm/Tables1kGcmExponentiator.cs | 63 + .../gcm/Tables1kGcmExponentiator.cs.meta | 10 + .../crypto/modes/gcm/Tables8kGcmMultiplier.cs | 200 + .../modes/gcm/Tables8kGcmMultiplier.cs.meta | 10 + .../SecureProtocol/crypto/operators.meta | 7 + .../crypto/operators/Asn1Signature.cs | 557 +++ .../crypto/operators/Asn1Signature.cs.meta | 10 + .../SecureProtocol/crypto/paddings.meta | 7 + .../crypto/paddings/BlockCipherPadding.cs | 47 + .../paddings/BlockCipherPadding.cs.meta | 10 + .../crypto/paddings/ISO10126d2Padding.cs | 80 + .../crypto/paddings/ISO10126d2Padding.cs.meta | 10 + .../crypto/paddings/ISO7816d4Padding.cs | 83 + .../crypto/paddings/ISO7816d4Padding.cs.meta | 10 + .../paddings/PaddedBufferedBlockCipher.cs | 289 ++ .../PaddedBufferedBlockCipher.cs.meta | 10 + .../crypto/paddings/Pkcs7Padding.cs | 80 + .../crypto/paddings/Pkcs7Padding.cs.meta | 10 + .../crypto/paddings/TbcPadding.cs | 83 + .../crypto/paddings/TbcPadding.cs.meta | 10 + .../crypto/paddings/X923Padding.cs | 86 + .../crypto/paddings/X923Padding.cs.meta | 10 + .../crypto/paddings/ZeroBytePadding.cs | 72 + .../crypto/paddings/ZeroBytePadding.cs.meta | 10 + .../SecureProtocol/crypto/parameters.meta | 7 + .../crypto/parameters/AEADParameters.cs | 69 + .../crypto/parameters/AEADParameters.cs.meta | 10 + .../parameters/DHKeyGenerationParameters.cs | 35 + .../DHKeyGenerationParameters.cs.meta | 10 + .../crypto/parameters/DHKeyParameters.cs | 80 + .../crypto/parameters/DHKeyParameters.cs.meta | 10 + .../crypto/parameters/DHParameters.cs | 189 + .../crypto/parameters/DHParameters.cs.meta | 10 + .../parameters/DHPrivateKeyParameters.cs | 64 + .../parameters/DHPrivateKeyParameters.cs.meta | 10 + .../parameters/DHPublicKeyParameters.cs | 70 + .../parameters/DHPublicKeyParameters.cs.meta | 10 + .../parameters/DHValidationParameters.cs | 63 + .../parameters/DHValidationParameters.cs.meta | 10 + .../crypto/parameters/DesEdeParameters.cs | 144 + .../parameters/DesEdeParameters.cs.meta | 10 + .../crypto/parameters/DesParameters.cs | 143 + .../crypto/parameters/DesParameters.cs.meta | 10 + .../parameters/DsaKeyGenerationParameters.cs | 30 + .../DsaKeyGenerationParameters.cs.meta | 10 + .../crypto/parameters/DsaKeyParameters.cs | 63 + .../parameters/DsaKeyParameters.cs.meta | 10 + .../crypto/parameters/DsaParameters.cs | 89 + .../crypto/parameters/DsaParameters.cs.meta | 10 + .../parameters/DsaPrivateKeyParameters.cs | 57 + .../DsaPrivateKeyParameters.cs.meta | 10 + .../parameters/DsaPublicKeyParameters.cs | 56 + .../parameters/DsaPublicKeyParameters.cs.meta | 10 + .../parameters/DsaValidationParameters.cs | 76 + .../DsaValidationParameters.cs.meta | 10 + .../crypto/parameters/ECDomainParameters.cs | 121 + .../parameters/ECDomainParameters.cs.meta | 10 + .../parameters/ECKeyGenerationParameters.cs | 45 + .../ECKeyGenerationParameters.cs.meta | 10 + .../crypto/parameters/ECKeyParameters.cs | 140 + .../crypto/parameters/ECKeyParameters.cs.meta | 10 + .../parameters/ECPrivateKeyParameters.cs | 91 + .../parameters/ECPrivateKeyParameters.cs.meta | 10 + .../parameters/ECPublicKeyParameters.cs | 90 + .../parameters/ECPublicKeyParameters.cs.meta | 10 + .../ElGamalKeyGenerationParameters.cs | 35 + .../ElGamalKeyGenerationParameters.cs.meta | 10 + .../crypto/parameters/ElGamalKeyParameters.cs | 63 + .../parameters/ElGamalKeyParameters.cs.meta | 10 + .../crypto/parameters/ElGamalParameters.cs | 85 + .../parameters/ElGamalParameters.cs.meta | 10 + .../parameters/ElGamalPrivateKeyParameters.cs | 57 + .../ElGamalPrivateKeyParameters.cs.meta | 10 + .../parameters/ElGamalPublicKeyParameters.cs | 57 + .../ElGamalPublicKeyParameters.cs.meta | 10 + .../parameters/GOST3410KeyParameters.cs | 62 + .../parameters/GOST3410KeyParameters.cs.meta | 10 + .../crypto/parameters/GOST3410Parameters.cs | 90 + .../parameters/GOST3410Parameters.cs.meta | 10 + .../GOST3410PrivateKeyParameters.cs | 45 + .../GOST3410PrivateKeyParameters.cs.meta | 10 + .../parameters/GOST3410PublicKeyParameters.cs | 44 + .../GOST3410PublicKeyParameters.cs.meta | 10 + .../GOST3410ValidationParameters.cs | 55 + .../GOST3410ValidationParameters.cs.meta | 10 + .../parameters/ISO18033KDFParameters.cs | 29 + .../parameters/ISO18033KDFParameters.cs.meta | 10 + .../crypto/parameters/IesParameters.cs | 53 + .../crypto/parameters/IesParameters.cs.meta | 10 + .../parameters/IesWithCipherParameters.cs | 37 + .../IesWithCipherParameters.cs.meta | 10 + .../crypto/parameters/KdfParameters.cs | 37 + .../crypto/parameters/KdfParameters.cs.meta | 10 + .../crypto/parameters/KeyParameter.cs | 47 + .../crypto/parameters/KeyParameter.cs.meta | 10 + .../crypto/parameters/MqvPrivateParameters.cs | 68 + .../parameters/MqvPrivateParameters.cs.meta | 10 + .../crypto/parameters/MqvPublicParameters.cs | 40 + .../parameters/MqvPublicParameters.cs.meta | 10 + .../crypto/parameters/ParametersWithIV.cs | 47 + .../parameters/ParametersWithIV.cs.meta | 10 + .../crypto/parameters/ParametersWithRandom.cs | 52 + .../parameters/ParametersWithRandom.cs.meta | 10 + .../crypto/parameters/ParametersWithSBox.cs | 28 + .../parameters/ParametersWithSBox.cs.meta | 10 + .../crypto/parameters/ParametersWithSalt.cs | 43 + .../parameters/ParametersWithSalt.cs.meta | 10 + .../crypto/parameters/RC2Parameters.cs | 51 + .../crypto/parameters/RC2Parameters.cs.meta | 10 + .../crypto/parameters/RC5Parameters.cs | 31 + .../crypto/parameters/RC5Parameters.cs.meta | 10 + .../parameters/RSABlindingParameters.cs | 38 + .../parameters/RSABlindingParameters.cs.meta | 10 + .../parameters/RsaKeyGenerationParameters.cs | 59 + .../RsaKeyGenerationParameters.cs.meta | 10 + .../crypto/parameters/RsaKeyParameters.cs | 67 + .../parameters/RsaKeyParameters.cs.meta | 10 + .../parameters/RsaPrivateCrtKeyParameters.cs | 108 + .../RsaPrivateCrtKeyParameters.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/prng.meta | 7 + .../crypto/prng/CryptoApiRandomGenerator.cs | 94 + .../prng/CryptoApiRandomGenerator.cs.meta | 10 + .../crypto/prng/DigestRandomGenerator.cs | 131 + .../crypto/prng/DigestRandomGenerator.cs.meta | 10 + .../crypto/prng/IRandomGenerator.cs | 30 + .../crypto/prng/IRandomGenerator.cs.meta | 10 + .../SecureProtocol/crypto/signers.meta | 7 + .../crypto/signers/DsaDigestSigner.cs | 149 + .../crypto/signers/DsaDigestSigner.cs.meta | 10 + .../crypto/signers/DsaSigner.cs | 160 + .../crypto/signers/DsaSigner.cs.meta | 10 + .../crypto/signers/ECDsaSigner.cs | 244 ++ .../crypto/signers/ECDsaSigner.cs.meta | 10 + .../crypto/signers/ECGOST3410Signer.cs | 166 + .../crypto/signers/ECGOST3410Signer.cs.meta | 10 + .../crypto/signers/ECNRSigner.cs | 192 + .../crypto/signers/ECNRSigner.cs.meta | 10 + .../crypto/signers/GOST3410DigestSigner.cs | 149 + .../signers/GOST3410DigestSigner.cs.meta | 10 + .../crypto/signers/GOST3410Signer.cs | 136 + .../crypto/signers/GOST3410Signer.cs.meta | 10 + .../crypto/signers/GenericSigner.cs | 134 + .../crypto/signers/GenericSigner.cs.meta | 10 + .../crypto/signers/HMacDsaKCalculator.cs | 154 + .../crypto/signers/HMacDsaKCalculator.cs.meta | 10 + .../crypto/signers/IDsaKCalculator.cs | 48 + .../crypto/signers/IDsaKCalculator.cs.meta | 10 + .../crypto/signers/Iso9796d2Signer.cs | 554 +++ .../crypto/signers/Iso9796d2Signer.cs.meta | 10 + .../crypto/signers/IsoTrailers.cs | 60 + .../crypto/signers/IsoTrailers.cs.meta | 10 + .../crypto/signers/PssSigner.cs | 390 ++ .../crypto/signers/PssSigner.cs.meta | 10 + .../crypto/signers/RandomDsaKCalculator.cs | 48 + .../signers/RandomDsaKCalculator.cs.meta | 10 + .../crypto/signers/RsaDigestSigner.cs | 221 + .../crypto/signers/RsaDigestSigner.cs.meta | 10 + .../crypto/signers/X931Signer.cs | 229 ++ .../crypto/signers/X931Signer.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/tls.meta | 7 + .../tls/AbstractTlsAgreementCredentials.cs | 16 + .../AbstractTlsAgreementCredentials.cs.meta | 10 + .../crypto/tls/AbstractTlsCipherFactory.cs | 19 + .../tls/AbstractTlsCipherFactory.cs.meta | 10 + .../crypto/tls/AbstractTlsClient.cs | 272 ++ .../crypto/tls/AbstractTlsClient.cs.meta | 10 + .../crypto/tls/AbstractTlsContext.cs | 156 + .../crypto/tls/AbstractTlsContext.cs.meta | 10 + .../crypto/tls/AbstractTlsCredentials.cs | 14 + .../crypto/tls/AbstractTlsCredentials.cs.meta | 10 + .../tls/AbstractTlsEncryptionCredentials.cs | 16 + .../AbstractTlsEncryptionCredentials.cs.meta | 10 + .../crypto/tls/AbstractTlsKeyExchange.cs | 181 + .../crypto/tls/AbstractTlsKeyExchange.cs.meta | 10 + .../crypto/tls/AbstractTlsPeer.cs | 52 + .../crypto/tls/AbstractTlsPeer.cs.meta | 10 + .../crypto/tls/AbstractTlsServer.cs | 353 ++ .../crypto/tls/AbstractTlsServer.cs.meta | 10 + .../crypto/tls/AbstractTlsSigner.cs | 54 + .../crypto/tls/AbstractTlsSigner.cs.meta | 10 + .../tls/AbstractTlsSignerCredentials.cs | 24 + .../tls/AbstractTlsSignerCredentials.cs.meta | 10 + .../crypto/tls/AlertDescription.cs | 308 ++ .../crypto/tls/AlertDescription.cs.meta | 10 + .../SecureProtocol/crypto/tls/AlertLevel.cs | 33 + .../crypto/tls/AlertLevel.cs.meta | 10 + .../crypto/tls/AlwaysValidVerifyer.cs | 26 + .../crypto/tls/AlwaysValidVerifyer.cs.meta | 10 + .../SecureProtocol/crypto/tls/ByteQueue.cs | 151 + .../crypto/tls/ByteQueue.cs.meta | 10 + .../crypto/tls/ByteQueueStream.cs | 114 + .../crypto/tls/ByteQueueStream.cs.meta | 10 + .../crypto/tls/CertChainType.cs | 22 + .../crypto/tls/CertChainType.cs.meta | 10 + .../SecureProtocol/crypto/tls/Certificate.cs | 140 + .../crypto/tls/Certificate.cs.meta | 10 + .../crypto/tls/CertificateRequest.cs | 160 + .../crypto/tls/CertificateRequest.cs.meta | 10 + .../crypto/tls/CertificateStatus.cs | 106 + .../crypto/tls/CertificateStatus.cs.meta | 10 + .../crypto/tls/CertificateStatusRequest.cs | 99 + .../tls/CertificateStatusRequest.cs.meta | 10 + .../crypto/tls/CertificateStatusType.cs | 16 + .../crypto/tls/CertificateStatusType.cs.meta | 10 + .../crypto/tls/Chacha20Poly1305.cs | 203 + .../crypto/tls/Chacha20Poly1305.cs.meta | 10 + .../crypto/tls/ChangeCipherSpec.cs | 13 + .../crypto/tls/ChangeCipherSpec.cs.meta | 10 + .../SecureProtocol/crypto/tls/CipherSuite.cs | 381 ++ .../crypto/tls/CipherSuite.cs.meta | 10 + .../SecureProtocol/crypto/tls/CipherType.cs | 24 + .../crypto/tls/CipherType.cs.meta | 10 + .../crypto/tls/ClientCertificateType.cs | 27 + .../crypto/tls/ClientCertificateType.cs.meta | 10 + .../SecureProtocol/crypto/tls/CombinedHash.cs | 137 + .../crypto/tls/CombinedHash.cs.meta | 10 + .../crypto/tls/CompressionMethod.cs | 26 + .../crypto/tls/CompressionMethod.cs.meta | 10 + .../crypto/tls/ConnectionEnd.cs | 19 + .../crypto/tls/ConnectionEnd.cs.meta | 10 + .../SecureProtocol/crypto/tls/ContentType.cs | 18 + .../crypto/tls/ContentType.cs.meta | 10 + .../crypto/tls/DatagramTransport.cs | 27 + .../crypto/tls/DatagramTransport.cs.meta | 10 + .../crypto/tls/DefaultTlsCipherFactory.cs | 231 ++ .../tls/DefaultTlsCipherFactory.cs.meta | 10 + .../crypto/tls/DefaultTlsClient.cs | 116 + .../crypto/tls/DefaultTlsClient.cs.meta | 10 + .../SecureProtocol/crypto/tls/DeferredHash.cs | 205 + .../crypto/tls/DeferredHash.cs.meta | 10 + .../crypto/tls/DigestInputBuffer.cs | 40 + .../crypto/tls/DigestInputBuffer.cs.meta | 10 + .../crypto/tls/DigitallySigned.cs | 74 + .../crypto/tls/DigitallySigned.cs.meta | 10 + .../SecureProtocol/crypto/tls/ECBasisType.cs | 20 + .../crypto/tls/ECBasisType.cs.meta | 10 + .../SecureProtocol/crypto/tls/ECCurveType.cs | 33 + .../crypto/tls/ECCurveType.cs.meta | 10 + .../crypto/tls/ECPointFormat.cs | 20 + .../crypto/tls/ECPointFormat.cs.meta | 10 + .../crypto/tls/EncryptionAlgorithm.cs | 74 + .../crypto/tls/EncryptionAlgorithm.cs.meta | 10 + .../crypto/tls/ExporterLabel.cs | 41 + .../crypto/tls/ExporterLabel.cs.meta | 10 + .../crypto/tls/ExtensionType.cs | 121 + .../crypto/tls/ExtensionType.cs.meta | 10 + .../crypto/tls/FiniteFieldDheGroup.cs | 25 + .../crypto/tls/FiniteFieldDheGroup.cs.meta | 10 + .../crypto/tls/HandshakeType.cs | 44 + .../crypto/tls/HandshakeType.cs.meta | 10 + .../crypto/tls/HashAlgorithm.cs | 53 + .../crypto/tls/HashAlgorithm.cs.meta | 10 + .../crypto/tls/HeartbeatExtension.cs | 56 + .../crypto/tls/HeartbeatExtension.cs.meta | 10 + .../crypto/tls/HeartbeatMessageType.cs | 22 + .../crypto/tls/HeartbeatMessageType.cs.meta | 10 + .../crypto/tls/HeartbeatMode.cs | 22 + .../crypto/tls/HeartbeatMode.cs.meta | 10 + .../crypto/tls/ICertificateVerifyer.cs | 23 + .../crypto/tls/ICertificateVerifyer.cs.meta | 10 + .../crypto/tls/KeyExchangeAlgorithm.cs | 58 + .../crypto/tls/KeyExchangeAlgorithm.cs.meta | 10 + .../crypto/tls/LegacyTlsAuthentication.cs | 41 + .../tls/LegacyTlsAuthentication.cs.meta | 10 + .../crypto/tls/LegacyTlsClient.cs | 31 + .../crypto/tls/LegacyTlsClient.cs.meta | 10 + .../SecureProtocol/crypto/tls/MacAlgorithm.cs | 29 + .../crypto/tls/MacAlgorithm.cs.meta | 10 + .../crypto/tls/MaxFragmentLength.cs | 24 + .../crypto/tls/MaxFragmentLength.cs.meta | 10 + .../SecureProtocol/crypto/tls/NameType.cs | 21 + .../crypto/tls/NameType.cs.meta | 10 + .../SecureProtocol/crypto/tls/NamedCurve.cs | 81 + .../crypto/tls/NamedCurve.cs.meta | 10 + .../crypto/tls/NewSessionTicket.cs | 57 + .../crypto/tls/NewSessionTicket.cs.meta | 10 + .../crypto/tls/OcspStatusRequest.cs | 134 + .../crypto/tls/OcspStatusRequest.cs.meta | 10 + .../SecureProtocol/crypto/tls/PrfAlgorithm.cs | 28 + .../crypto/tls/PrfAlgorithm.cs.meta | 10 + .../crypto/tls/ProtocolVersion.cs | 163 + .../crypto/tls/ProtocolVersion.cs.meta | 10 + .../SecureProtocol/crypto/tls/RecordStream.cs | 344 ++ .../crypto/tls/RecordStream.cs.meta | 10 + .../crypto/tls/SecurityParameters.cs | 107 + .../crypto/tls/SecurityParameters.cs.meta | 10 + .../crypto/tls/ServerDHParams.cs | 65 + .../crypto/tls/ServerDHParams.cs.meta | 10 + .../SecureProtocol/crypto/tls/ServerName.cs | 109 + .../crypto/tls/ServerName.cs.meta | 10 + .../crypto/tls/ServerNameList.cs | 108 + .../crypto/tls/ServerNameList.cs.meta | 10 + .../crypto/tls/SessionParameters.cs | 169 + .../crypto/tls/SessionParameters.cs.meta | 10 + .../crypto/tls/SignatureAlgorithm.cs | 19 + .../crypto/tls/SignatureAlgorithm.cs.meta | 10 + .../crypto/tls/SignatureAndHashAlgorithm.cs | 98 + .../tls/SignatureAndHashAlgorithm.cs.meta | 10 + .../crypto/tls/SignerInputBuffer.cs | 40 + .../crypto/tls/SignerInputBuffer.cs.meta | 10 + .../SecureProtocol/crypto/tls/Ssl3Mac.cs | 114 + .../SecureProtocol/crypto/tls/Ssl3Mac.cs.meta | 10 + .../crypto/tls/SupplementalDataEntry.cs | 30 + .../crypto/tls/SupplementalDataEntry.cs.meta | 10 + .../crypto/tls/TlsAeadCipher.cs | 253 ++ .../crypto/tls/TlsAeadCipher.cs.meta | 10 + .../crypto/tls/TlsAgreementCredentials.cs | 16 + .../tls/TlsAgreementCredentials.cs.meta | 10 + .../crypto/tls/TlsAuthentication.cs | 35 + .../crypto/tls/TlsAuthentication.cs.meta | 10 + .../crypto/tls/TlsBlockCipher.cs | 390 ++ .../crypto/tls/TlsBlockCipher.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsCipher.cs | 20 + .../crypto/tls/TlsCipher.cs.meta | 10 + .../crypto/tls/TlsCipherFactory.cs | 15 + .../crypto/tls/TlsCipherFactory.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsClient.cs | 154 + .../crypto/tls/TlsClient.cs.meta | 10 + .../crypto/tls/TlsClientContext.cs | 15 + .../crypto/tls/TlsClientContext.cs.meta | 10 + .../crypto/tls/TlsClientContextImpl.cs | 24 + .../crypto/tls/TlsClientContextImpl.cs.meta | 10 + .../crypto/tls/TlsClientProtocol.cs | 911 +++++ .../crypto/tls/TlsClientProtocol.cs.meta | 10 + .../crypto/tls/TlsCompression.cs | 16 + .../crypto/tls/TlsCompression.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsContext.cs | 49 + .../crypto/tls/TlsContext.cs.meta | 10 + .../crypto/tls/TlsCredentials.cs | 13 + .../crypto/tls/TlsCredentials.cs.meta | 10 + .../crypto/tls/TlsDHKeyExchange.cs | 228 ++ .../crypto/tls/TlsDHKeyExchange.cs.meta | 10 + .../crypto/tls/TlsDHUtilities.cs | 482 +++ .../crypto/tls/TlsDHUtilities.cs.meta | 10 + .../crypto/tls/TlsDeflateCompression.cs | 72 + .../crypto/tls/TlsDeflateCompression.cs.meta | 10 + .../crypto/tls/TlsDheKeyExchange.cs | 98 + .../crypto/tls/TlsDheKeyExchange.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsDsaSigner.cs | 86 + .../crypto/tls/TlsDsaSigner.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsDssSigner.cs | 30 + .../crypto/tls/TlsDssSigner.cs.meta | 10 + .../crypto/tls/TlsECDHKeyExchange.cs | 253 ++ .../crypto/tls/TlsECDHKeyExchange.cs.meta | 10 + .../crypto/tls/TlsECDheKeyExchange.cs | 135 + .../crypto/tls/TlsECDheKeyExchange.cs.meta | 10 + .../crypto/tls/TlsECDsaSigner.cs | 30 + .../crypto/tls/TlsECDsaSigner.cs.meta | 10 + .../crypto/tls/TlsEccUtilities.cs | 722 ++++ .../crypto/tls/TlsEccUtilities.cs.meta | 10 + .../crypto/tls/TlsEncryptionCredentials.cs | 16 + .../tls/TlsEncryptionCredentials.cs.meta | 10 + .../crypto/tls/TlsExtensionsUtilities.cs | 296 ++ .../crypto/tls/TlsExtensionsUtilities.cs.meta | 10 + .../crypto/tls/TlsFatalAlert.cs | 31 + .../crypto/tls/TlsFatalAlert.cs.meta | 10 + .../crypto/tls/TlsHandshakeHash.cs | 26 + .../crypto/tls/TlsHandshakeHash.cs.meta | 10 + .../crypto/tls/TlsKeyExchange.cs | 58 + .../crypto/tls/TlsKeyExchange.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsMac.cs | 177 + .../SecureProtocol/crypto/tls/TlsMac.cs.meta | 10 + .../crypto/tls/TlsNullCipher.cs | 122 + .../crypto/tls/TlsNullCipher.cs.meta | 10 + .../crypto/tls/TlsNullCompression.cs | 23 + .../crypto/tls/TlsNullCompression.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsPeer.cs | 66 + .../SecureProtocol/crypto/tls/TlsPeer.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsProtocol.cs | 1388 +++++++ .../crypto/tls/TlsProtocol.cs.meta | 10 + .../crypto/tls/TlsRsaKeyExchange.cs | 144 + .../crypto/tls/TlsRsaKeyExchange.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsRsaSigner.cs | 106 + .../crypto/tls/TlsRsaSigner.cs.meta | 10 + .../crypto/tls/TlsRsaUtilities.cs | 136 + .../crypto/tls/TlsRsaUtilities.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsServer.cs | 97 + .../crypto/tls/TlsServer.cs.meta | 10 + .../crypto/tls/TlsServerContext.cs | 15 + .../crypto/tls/TlsServerContext.cs.meta | 10 + .../crypto/tls/TlsServerContextImpl.cs | 24 + .../crypto/tls/TlsServerContextImpl.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsSession.cs | 19 + .../crypto/tls/TlsSession.cs.meta | 10 + .../crypto/tls/TlsSessionImpl.cs | 58 + .../crypto/tls/TlsSessionImpl.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsSigner.cs | 33 + .../crypto/tls/TlsSigner.cs.meta | 10 + .../crypto/tls/TlsSignerCredentials.cs | 18 + .../crypto/tls/TlsSignerCredentials.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsStream.cs | 101 + .../crypto/tls/TlsStream.cs.meta | 10 + .../crypto/tls/TlsStreamCipher.cs | 156 + .../crypto/tls/TlsStreamCipher.cs.meta | 10 + .../SecureProtocol/crypto/tls/TlsUtilities.cs | 2253 +++++++++++ .../crypto/tls/TlsUtilities.cs.meta | 10 + .../BestHTTP/SecureProtocol/crypto/util.meta | 7 + .../SecureProtocol/crypto/util/Pack.cs | 366 ++ .../SecureProtocol/crypto/util/Pack.cs.meta | 10 + .../BestHTTP/SecureProtocol/math.meta | 7 + .../SecureProtocol/math/BigInteger.cs | 3596 +++++++++++++++++ .../SecureProtocol/math/BigInteger.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/ec.meta | 7 + .../SecureProtocol/math/ec/ECAlgorithms.cs | 483 +++ .../math/ec/ECAlgorithms.cs.meta | 10 + .../SecureProtocol/math/ec/ECCurve.cs | 1132 ++++++ .../SecureProtocol/math/ec/ECCurve.cs.meta | 10 + .../SecureProtocol/math/ec/ECFieldElement.cs | 931 +++++ .../math/ec/ECFieldElement.cs.meta | 10 + .../SecureProtocol/math/ec/ECPoint.cs | 2068 ++++++++++ .../SecureProtocol/math/ec/ECPoint.cs.meta | 10 + .../SecureProtocol/math/ec/ECPointMap.cs | 13 + .../SecureProtocol/math/ec/ECPointMap.cs.meta | 10 + .../SecureProtocol/math/ec/LongArray.cs | 2205 ++++++++++ .../SecureProtocol/math/ec/LongArray.cs.meta | 10 + .../SecureProtocol/math/ec/ScaleXPointMap.cs | 24 + .../math/ec/ScaleXPointMap.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/ec/abc.meta | 7 + .../math/ec/abc/SimpleBigDecimal.cs | 245 ++ .../math/ec/abc/SimpleBigDecimal.cs.meta | 10 + .../SecureProtocol/math/ec/abc/Tnaf.cs | 849 ++++ .../SecureProtocol/math/ec/abc/Tnaf.cs.meta | 10 + .../SecureProtocol/math/ec/abc/ZTauElement.cs | 40 + .../math/ec/abc/ZTauElement.cs.meta | 10 + .../SecureProtocol/math/ec/custom.meta | 7 + .../SecureProtocol/math/ec/custom/djb.meta | 7 + .../math/ec/custom/djb/Curve25519.cs | 81 + .../math/ec/custom/djb/Curve25519.cs.meta | 10 + .../math/ec/custom/djb/Curve25519Field.cs | 257 ++ .../ec/custom/djb/Curve25519Field.cs.meta | 10 + .../ec/custom/djb/Curve25519FieldElement.cs | 237 ++ .../custom/djb/Curve25519FieldElement.cs.meta | 10 + .../math/ec/custom/djb/Curve25519Point.cs | 317 ++ .../ec/custom/djb/Curve25519Point.cs.meta | 10 + .../SecureProtocol/math/ec/custom/sec.meta | 7 + .../math/ec/custom/sec/SecP128R1Curve.cs | 82 + .../math/ec/custom/sec/SecP128R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP128R1Field.cs | 222 + .../math/ec/custom/sec/SecP128R1Field.cs.meta | 10 + .../ec/custom/sec/SecP128R1FieldElement.cs | 202 + .../custom/sec/SecP128R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP128R1Point.cs | 283 ++ .../math/ec/custom/sec/SecP128R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP160K1Curve.cs | 78 + .../math/ec/custom/sec/SecP160K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP160K1Point.cs | 273 ++ .../math/ec/custom/sec/SecP160K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP160R1Curve.cs | 82 + .../math/ec/custom/sec/SecP160R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP160R1Field.cs | 190 + .../math/ec/custom/sec/SecP160R1Field.cs.meta | 10 + .../ec/custom/sec/SecP160R1FieldElement.cs | 207 + .../custom/sec/SecP160R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP160R1Point.cs | 283 ++ .../math/ec/custom/sec/SecP160R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP160R2Curve.cs | 82 + .../math/ec/custom/sec/SecP160R2Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP160R2Field.cs | 182 + .../math/ec/custom/sec/SecP160R2Field.cs.meta | 10 + .../ec/custom/sec/SecP160R2FieldElement.cs | 222 + .../custom/sec/SecP160R2FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP160R2Point.cs | 283 ++ .../math/ec/custom/sec/SecP160R2Point.cs.meta | 10 + .../math/ec/custom/sec/SecP192K1Curve.cs | 79 + .../math/ec/custom/sec/SecP192K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP192K1Field.cs | 182 + .../math/ec/custom/sec/SecP192K1Field.cs.meta | 10 + .../ec/custom/sec/SecP192K1FieldElement.cs | 217 + .../custom/sec/SecP192K1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP192K1Point.cs | 271 ++ .../math/ec/custom/sec/SecP192K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP192R1Curve.cs | 82 + .../math/ec/custom/sec/SecP192R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP192R1Field.cs | 287 ++ .../math/ec/custom/sec/SecP192R1Field.cs.meta | 10 + .../ec/custom/sec/SecP192R1FieldElement.cs | 192 + .../custom/sec/SecP192R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP192R1Point.cs | 283 ++ .../math/ec/custom/sec/SecP192R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP224K1Curve.cs | 79 + .../math/ec/custom/sec/SecP224K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP224K1Field.cs | 183 + .../math/ec/custom/sec/SecP224K1Field.cs.meta | 10 + .../ec/custom/sec/SecP224K1FieldElement.cs | 246 ++ .../custom/sec/SecP224K1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP224K1Point.cs | 271 ++ .../math/ec/custom/sec/SecP224K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP224R1Curve.cs | 82 + .../math/ec/custom/sec/SecP224R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP224R1Field.cs | 301 ++ .../math/ec/custom/sec/SecP224R1Field.cs.meta | 10 + .../ec/custom/sec/SecP224R1FieldElement.cs | 273 ++ .../custom/sec/SecP224R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP224R1Point.cs | 283 ++ .../math/ec/custom/sec/SecP224R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP256K1Curve.cs | 79 + .../math/ec/custom/sec/SecP256K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP256K1Field.cs | 184 + .../math/ec/custom/sec/SecP256K1Field.cs.meta | 10 + .../ec/custom/sec/SecP256K1FieldElement.cs | 218 + .../custom/sec/SecP256K1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP256K1Point.cs | 271 ++ .../math/ec/custom/sec/SecP256K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP256R1Curve.cs | 81 + .../math/ec/custom/sec/SecP256R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP256R1Field.cs | 316 ++ .../math/ec/custom/sec/SecP256R1Field.cs.meta | 10 + .../ec/custom/sec/SecP256R1FieldElement.cs | 192 + .../custom/sec/SecP256R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP256R1Point.cs | 283 ++ .../math/ec/custom/sec/SecP256R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP384R1Curve.cs | 81 + .../math/ec/custom/sec/SecP384R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP384R1Field.cs | 299 ++ .../math/ec/custom/sec/SecP384R1Field.cs.meta | 10 + .../ec/custom/sec/SecP384R1FieldElement.cs | 214 + .../custom/sec/SecP384R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP384R1Point.cs | 284 ++ .../math/ec/custom/sec/SecP384R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecP521R1Curve.cs | 81 + .../math/ec/custom/sec/SecP521R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecP521R1Field.cs | 159 + .../math/ec/custom/sec/SecP521R1Field.cs.meta | 10 + .../ec/custom/sec/SecP521R1FieldElement.cs | 171 + .../custom/sec/SecP521R1FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecP521R1Point.cs | 279 ++ .../math/ec/custom/sec/SecP521R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT113Field.cs | 229 ++ .../math/ec/custom/sec/SecT113Field.cs.meta | 10 + .../math/ec/custom/sec/SecT113FieldElement.cs | 220 + .../ec/custom/sec/SecT113FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT113R1Curve.cs | 192 + .../math/ec/custom/sec/SecT113R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT113R1Point.cs | 285 ++ .../math/ec/custom/sec/SecT113R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT113R2Curve.cs | 102 + .../math/ec/custom/sec/SecT113R2Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT113R2Point.cs | 295 ++ .../math/ec/custom/sec/SecT113R2Point.cs.meta | 10 + .../math/ec/custom/sec/SecT131Field.cs | 334 ++ .../math/ec/custom/sec/SecT131Field.cs.meta | 10 + .../math/ec/custom/sec/SecT131FieldElement.cs | 220 + .../ec/custom/sec/SecT131FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT131R1Curve.cs | 102 + .../math/ec/custom/sec/SecT131R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT131R1Point.cs | 291 ++ .../math/ec/custom/sec/SecT131R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT131R2Curve.cs | 102 + .../math/ec/custom/sec/SecT131R2Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT131R2Point.cs | 287 ++ .../math/ec/custom/sec/SecT131R2Point.cs.meta | 10 + .../math/ec/custom/sec/SecT163Field.cs | 344 ++ .../math/ec/custom/sec/SecT163Field.cs.meta | 10 + .../math/ec/custom/sec/SecT163FieldElement.cs | 220 + .../ec/custom/sec/SecT163FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT163K1Curve.cs | 108 + .../math/ec/custom/sec/SecT163K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT163K1Point.cs | 293 ++ .../math/ec/custom/sec/SecT163K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT163R1Curve.cs | 102 + .../math/ec/custom/sec/SecT163R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT163R1Point.cs | 287 ++ .../math/ec/custom/sec/SecT163R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT163R2Curve.cs | 102 + .../math/ec/custom/sec/SecT163R2Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT163R2Point.cs | 294 ++ .../math/ec/custom/sec/SecT163R2Point.cs.meta | 10 + .../math/ec/custom/sec/SecT193Field.cs | 307 ++ .../math/ec/custom/sec/SecT193Field.cs.meta | 10 + .../math/ec/custom/sec/SecT193FieldElement.cs | 218 + .../ec/custom/sec/SecT193FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT193R1Curve.cs | 101 + .../math/ec/custom/sec/SecT193R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT193R1Point.cs | 286 ++ .../math/ec/custom/sec/SecT193R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT193R2Curve.cs | 100 + .../math/ec/custom/sec/SecT193R2Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT193R2Point.cs | 285 ++ .../math/ec/custom/sec/SecT193R2Point.cs.meta | 10 + .../math/ec/custom/sec/SecT233Field.cs | 321 ++ .../math/ec/custom/sec/SecT233Field.cs.meta | 10 + .../math/ec/custom/sec/SecT233FieldElement.cs | 220 + .../ec/custom/sec/SecT233FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT233K1Curve.cs | 108 + .../math/ec/custom/sec/SecT233K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT233K1Point.cs | 306 ++ .../math/ec/custom/sec/SecT233K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT233R1Curve.cs | 102 + .../math/ec/custom/sec/SecT233R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT233R1Point.cs | 286 ++ .../math/ec/custom/sec/SecT233R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT239Field.cs | 332 ++ .../math/ec/custom/sec/SecT239Field.cs.meta | 10 + .../math/ec/custom/sec/SecT239FieldElement.cs | 220 + .../ec/custom/sec/SecT239FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT239K1Curve.cs | 108 + .../math/ec/custom/sec/SecT239K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT239K1Point.cs | 301 ++ .../math/ec/custom/sec/SecT239K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT283Field.cs | 406 ++ .../math/ec/custom/sec/SecT283Field.cs.meta | 10 + .../math/ec/custom/sec/SecT283FieldElement.cs | 220 + .../ec/custom/sec/SecT283FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT283K1Curve.cs | 108 + .../math/ec/custom/sec/SecT283K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT283K1Point.cs | 300 ++ .../math/ec/custom/sec/SecT283K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT283R1Curve.cs | 102 + .../math/ec/custom/sec/SecT283R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT283R1Point.cs | 286 ++ .../math/ec/custom/sec/SecT283R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT409Field.cs | 335 ++ .../math/ec/custom/sec/SecT409Field.cs.meta | 10 + .../math/ec/custom/sec/SecT409FieldElement.cs | 220 + .../ec/custom/sec/SecT409FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT409K1Curve.cs | 108 + .../math/ec/custom/sec/SecT409K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT409K1Point.cs | 300 ++ .../math/ec/custom/sec/SecT409K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT409R1Curve.cs | 102 + .../math/ec/custom/sec/SecT409R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT409R1Point.cs | 286 ++ .../math/ec/custom/sec/SecT409R1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT571Field.cs | 337 ++ .../math/ec/custom/sec/SecT571Field.cs.meta | 10 + .../math/ec/custom/sec/SecT571FieldElement.cs | 220 + .../ec/custom/sec/SecT571FieldElement.cs.meta | 10 + .../math/ec/custom/sec/SecT571K1Curve.cs | 108 + .../math/ec/custom/sec/SecT571K1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT571K1Point.cs | 300 ++ .../math/ec/custom/sec/SecT571K1Point.cs.meta | 10 + .../math/ec/custom/sec/SecT571R1Curve.cs | 106 + .../math/ec/custom/sec/SecT571R1Curve.cs.meta | 10 + .../math/ec/custom/sec/SecT571R1Point.cs | 290 ++ .../math/ec/custom/sec/SecT571R1Point.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/ec/endo.meta | 7 + .../math/ec/endo/ECEndomorphism.cs | 15 + .../math/ec/endo/ECEndomorphism.cs.meta | 10 + .../math/ec/endo/GlvEndomorphism.cs | 14 + .../math/ec/endo/GlvEndomorphism.cs.meta | 10 + .../math/ec/endo/GlvTypeBEndomorphism.cs | 59 + .../math/ec/endo/GlvTypeBEndomorphism.cs.meta | 10 + .../math/ec/endo/GlvTypeBParameters.cs | 64 + .../math/ec/endo/GlvTypeBParameters.cs.meta | 10 + .../SecureProtocol/math/ec/multiplier.meta | 7 + .../ec/multiplier/AbstractECMultiplier.cs | 28 + .../multiplier/AbstractECMultiplier.cs.meta | 10 + .../math/ec/multiplier/ECMultiplier.cs | 22 + .../math/ec/multiplier/ECMultiplier.cs.meta | 10 + .../ec/multiplier/FixedPointCombMultiplier.cs | 63 + .../FixedPointCombMultiplier.cs.meta | 10 + .../ec/multiplier/FixedPointPreCompInfo.cs | 38 + .../multiplier/FixedPointPreCompInfo.cs.meta | 10 + .../math/ec/multiplier/FixedPointUtilities.cs | 76 + .../ec/multiplier/FixedPointUtilities.cs.meta | 10 + .../math/ec/multiplier/GlvMultiplier.cs | 44 + .../math/ec/multiplier/GlvMultiplier.cs.meta | 10 + .../math/ec/multiplier/PreCompInfo.cs | 15 + .../math/ec/multiplier/PreCompInfo.cs.meta | 10 + .../math/ec/multiplier/WNafL2RMultiplier.cs | 102 + .../ec/multiplier/WNafL2RMultiplier.cs.meta | 10 + .../math/ec/multiplier/WNafPreCompInfo.cs | 50 + .../ec/multiplier/WNafPreCompInfo.cs.meta | 10 + .../math/ec/multiplier/WNafUtilities.cs | 528 +++ .../math/ec/multiplier/WNafUtilities.cs.meta | 10 + .../math/ec/multiplier/WTauNafMultiplier.cs | 129 + .../ec/multiplier/WTauNafMultiplier.cs.meta | 10 + .../math/ec/multiplier/WTauNafPreCompInfo.cs | 28 + .../ec/multiplier/WTauNafPreCompInfo.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/field.meta | 7 + .../SecureProtocol/math/field/FiniteFields.cs | 58 + .../math/field/FiniteFields.cs.meta | 10 + .../math/field/GF2Polynomial.cs | 50 + .../math/field/GF2Polynomial.cs.meta | 10 + .../field/GenericPolynomialExtensionField.cs | 67 + .../GenericPolynomialExtensionField.cs.meta | 10 + .../math/field/IExtensionField.cs | 16 + .../math/field/IExtensionField.cs.meta | 10 + .../SecureProtocol/math/field/IFiniteField.cs | 15 + .../math/field/IFiniteField.cs.meta | 10 + .../SecureProtocol/math/field/IPolynomial.cs | 19 + .../math/field/IPolynomial.cs.meta | 10 + .../math/field/IPolynomialExtensionField.cs | 14 + .../field/IPolynomialExtensionField.cs.meta | 10 + .../SecureProtocol/math/field/PrimeField.cs | 48 + .../math/field/PrimeField.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/raw.meta | 7 + .../SecureProtocol/math/raw/Interleave.cs | 111 + .../math/raw/Interleave.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/raw/Mod.cs | 190 + .../SecureProtocol/math/raw/Mod.cs.meta | 10 + .../BestHTTP/SecureProtocol/math/raw/Nat.cs | 1057 +++++ .../SecureProtocol/math/raw/Nat.cs.meta | 10 + .../SecureProtocol/math/raw/Nat128.cs | 860 ++++ .../SecureProtocol/math/raw/Nat128.cs.meta | 10 + .../SecureProtocol/math/raw/Nat160.cs | 878 ++++ .../SecureProtocol/math/raw/Nat160.cs.meta | 10 + .../SecureProtocol/math/raw/Nat192.cs | 1052 +++++ .../SecureProtocol/math/raw/Nat192.cs.meta | 10 + .../SecureProtocol/math/raw/Nat224.cs | 1180 ++++++ .../SecureProtocol/math/raw/Nat224.cs.meta | 10 + .../SecureProtocol/math/raw/Nat256.cs | 1391 +++++++ .../SecureProtocol/math/raw/Nat256.cs.meta | 10 + .../SecureProtocol/math/raw/Nat320.cs | 102 + .../SecureProtocol/math/raw/Nat320.cs.meta | 10 + .../SecureProtocol/math/raw/Nat384.cs | 50 + .../SecureProtocol/math/raw/Nat384.cs.meta | 10 + .../SecureProtocol/math/raw/Nat448.cs | 104 + .../SecureProtocol/math/raw/Nat448.cs.meta | 10 + .../SecureProtocol/math/raw/Nat512.cs | 50 + .../SecureProtocol/math/raw/Nat512.cs.meta | 10 + .../SecureProtocol/math/raw/Nat576.cs | 106 + .../SecureProtocol/math/raw/Nat576.cs.meta | 10 + .../BestHTTP/SecureProtocol/security.meta | 7 + .../security/DigestUtilities.cs | 226 ++ .../security/DigestUtilities.cs.meta | 10 + .../security/GeneralSecurityException.cs | 33 + .../security/GeneralSecurityException.cs.meta | 10 + .../security/InvalidKeyException.cs | 18 + .../security/InvalidKeyException.cs.meta | 10 + .../security/InvalidParameterException.cs | 18 + .../InvalidParameterException.cs.meta | 10 + .../SecureProtocol/security/KeyException.cs | 18 + .../security/KeyException.cs.meta | 10 + .../SecureProtocol/security/MacUtilities.cs | 260 ++ .../security/MacUtilities.cs.meta | 10 + .../security/PublicKeyFactory.cs | 257 ++ .../security/PublicKeyFactory.cs.meta | 10 + .../SecureProtocol/security/SecureRandom.cs | 266 ++ .../security/SecureRandom.cs.meta | 10 + .../security/SecurityUtilityException.cs | 40 + .../security/SecurityUtilityException.cs.meta | 10 + .../security/SignatureException.cs | 18 + .../security/SignatureException.cs.meta | 10 + .../security/SignerUtilities.cs | 570 +++ .../security/SignerUtilities.cs.meta | 10 + .../SecureProtocol/security/cert.meta | 7 + .../cert/CertificateEncodingException.cs | 18 + .../cert/CertificateEncodingException.cs.meta | 10 + .../security/cert/CertificateException.cs | 18 + .../cert/CertificateException.cs.meta | 10 + .../cert/CertificateExpiredException.cs | 18 + .../cert/CertificateExpiredException.cs.meta | 10 + .../cert/CertificateNotYetValidException.cs | 18 + .../CertificateNotYetValidException.cs.meta | 10 + .../cert/CertificateParsingException.cs | 18 + .../cert/CertificateParsingException.cs.meta | 10 + .../security/cert/CrlException.cs | 18 + .../security/cert/CrlException.cs.meta | 10 + .../BestHTTP/SecureProtocol/util.meta | 7 + .../BestHTTP/SecureProtocol/util/Arrays.cs | 701 ++++ .../SecureProtocol/util/Arrays.cs.meta | 10 + .../SecureProtocol/util/BigIntegers.cs | 94 + .../SecureProtocol/util/BigIntegers.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/Enums.cs | 86 + .../SecureProtocol/util/Enums.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/IMemoable.cs | 33 + .../SecureProtocol/util/IMemoable.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/Integers.cs | 21 + .../SecureProtocol/util/Integers.cs.meta | 10 + .../util/MemoableResetException.cs | 31 + .../util/MemoableResetException.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/Platform.cs | 229 ++ .../SecureProtocol/util/Platform.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/Strings.cs | 107 + .../SecureProtocol/util/Strings.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/Times.cs | 18 + .../SecureProtocol/util/Times.cs.meta | 10 + .../SecureProtocol/util/collections.meta | 7 + .../util/collections/CollectionUtilities.cs | 72 + .../collections/CollectionUtilities.cs.meta | 10 + .../util/collections/EmptyEnumerable.cs | 48 + .../util/collections/EmptyEnumerable.cs.meta | 10 + .../util/collections/EnumerableProxy.cs | 29 + .../util/collections/EnumerableProxy.cs.meta | 10 + .../util/collections/HashSet.cs | 103 + .../util/collections/HashSet.cs.meta | 10 + .../SecureProtocol/util/collections/ISet.cs | 23 + .../util/collections/ISet.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/date.meta | 7 + .../util/date/DateTimeObject.cs | 29 + .../util/date/DateTimeObject.cs.meta | 10 + .../util/date/DateTimeUtilities.cs | 51 + .../util/date/DateTimeUtilities.cs.meta | 10 + .../SecureProtocol/util/encoders.meta | 7 + .../SecureProtocol/util/encoders/Base64.cs | 124 + .../util/encoders/Base64.cs.meta | 10 + .../util/encoders/Base64Encoder.cs | 328 ++ .../util/encoders/Base64Encoder.cs.meta | 10 + .../SecureProtocol/util/encoders/Hex.cs | 134 + .../SecureProtocol/util/encoders/Hex.cs.meta | 10 + .../util/encoders/HexEncoder.cs | 180 + .../util/encoders/HexEncoder.cs.meta | 10 + .../SecureProtocol/util/encoders/IEncoder.cs | 22 + .../util/encoders/IEncoder.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/io.meta | 7 + .../SecureProtocol/util/io/BaseInputStream.cs | 68 + .../util/io/BaseInputStream.cs.meta | 10 + .../util/io/BaseOutputStream.cs | 68 + .../util/io/BaseOutputStream.cs.meta | 10 + .../SecureProtocol/util/io/FilterStream.cs | 82 + .../util/io/FilterStream.cs.meta | 10 + .../SecureProtocol/util/io/PushbackStream.cs | 56 + .../util/io/PushbackStream.cs.meta | 10 + .../util/io/StreamOverflowException.cs | 34 + .../util/io/StreamOverflowException.cs.meta | 10 + .../SecureProtocol/util/io/Streams.cs | 98 + .../SecureProtocol/util/io/Streams.cs.meta | 10 + .../SecureProtocol/util/io/TeeInputStream.cs | 68 + .../util/io/TeeInputStream.cs.meta | 10 + .../SecureProtocol/util/io/TeeOutputStream.cs | 56 + .../util/io/TeeOutputStream.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/io/pem.meta | 7 + .../util/io/pem/PemGenerationException.cs | 33 + .../io/pem/PemGenerationException.cs.meta | 10 + .../SecureProtocol/util/io/pem/PemHeader.cs | 59 + .../util/io/pem/PemHeader.cs.meta | 10 + .../SecureProtocol/util/io/pem/PemObject.cs | 51 + .../util/io/pem/PemObject.cs.meta | 10 + .../util/io/pem/PemObjectGenerator.cs | 17 + .../util/io/pem/PemObjectGenerator.cs.meta | 10 + .../SecureProtocol/util/io/pem/PemReader.cs | 100 + .../util/io/pem/PemReader.cs.meta | 10 + .../SecureProtocol/util/io/pem/PemWriter.cs | 124 + .../util/io/pem/PemWriter.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/net.meta | 7 + .../SecureProtocol/util/net/IPAddress.cs | 201 + .../SecureProtocol/util/net/IPAddress.cs.meta | 10 + .../BestHTTP/SecureProtocol/util/zlib.meta | 7 + .../SecureProtocol/util/zlib/Adler32.cs | 92 + .../SecureProtocol/util/zlib/Adler32.cs.meta | 10 + .../SecureProtocol/util/zlib/Deflate.cs | 1644 ++++++++ .../SecureProtocol/util/zlib/Deflate.cs.meta | 10 + .../SecureProtocol/util/zlib/InfBlocks.cs | 622 +++ .../util/zlib/InfBlocks.cs.meta | 10 + .../SecureProtocol/util/zlib/InfCodes.cs | 615 +++ .../SecureProtocol/util/zlib/InfCodes.cs.meta | 10 + .../SecureProtocol/util/zlib/InfTree.cs | 527 +++ .../SecureProtocol/util/zlib/InfTree.cs.meta | 10 + .../SecureProtocol/util/zlib/Inflate.cs | 391 ++ .../SecureProtocol/util/zlib/Inflate.cs.meta | 10 + .../SecureProtocol/util/zlib/JZlib.cs | 77 + .../SecureProtocol/util/zlib/JZlib.cs.meta | 10 + .../SecureProtocol/util/zlib/StaticTree.cs | 156 + .../util/zlib/StaticTree.cs.meta | 10 + .../SecureProtocol/util/zlib/ZOutputStream.cs | 269 ++ .../util/zlib/ZOutputStream.cs.meta | 10 + .../SecureProtocol/util/zlib/ZStream.cs | 218 + .../SecureProtocol/util/zlib/ZStream.cs.meta | 10 + .../SecureProtocol/util/zlib/ZTree.cs | 371 ++ .../SecureProtocol/util/zlib/ZTree.cs.meta | 10 + .../BestHTTP/SecureProtocol/x509.meta | 7 + .../SecureProtocol/x509/IX509Extension.cs | 31 + .../x509/IX509Extension.cs.meta | 10 + .../BestHTTP/SecureProtocol/x509/PEMParser.cs | 99 + .../SecureProtocol/x509/PEMParser.cs.meta | 10 + .../SecureProtocol/x509/X509Certificate.cs | 608 +++ .../x509/X509Certificate.cs.meta | 10 + .../x509/X509CertificateParser.cs | 187 + .../x509/X509CertificateParser.cs.meta | 10 + .../BestHTTP/SecureProtocol/x509/X509Crl.cs | 430 ++ .../SecureProtocol/x509/X509Crl.cs.meta | 10 + .../SecureProtocol/x509/X509CrlEntry.cs | 205 + .../SecureProtocol/x509/X509CrlEntry.cs.meta | 10 + .../SecureProtocol/x509/X509CrlParser.cs | 199 + .../SecureProtocol/x509/X509CrlParser.cs.meta | 10 + .../SecureProtocol/x509/X509ExtensionBase.cs | 86 + .../x509/X509ExtensionBase.cs.meta | 10 + .../SecureProtocol/x509/X509SignatureUtil.cs | 132 + .../x509/X509SignatureUtil.cs.meta | 10 + .../SecureProtocol/x509/extension.meta | 7 + .../x509/extension/X509ExtensionUtil.cs | 93 + .../x509/extension/X509ExtensionUtil.cs.meta | 10 + .../BestHTTP/ServerSentEvents.meta | 7 + .../BestHTTP/ServerSentEvents/EventSource.cs | 649 +++ .../ServerSentEvents/EventSource.cs.meta | 10 + .../ServerSentEvents/EventSourceResponse.cs | 380 ++ .../EventSourceResponse.cs.meta | 10 + .../BestHTTP/ServerSentEvents/Message.cs | 36 + .../BestHTTP/ServerSentEvents/Message.cs.meta | 10 + Assets/Best HTTP (Pro)/BestHTTP/SignalR.meta | 7 + .../BestHTTP/SignalR/Authentication.meta | 7 + .../Authentication/IAuthenticationProvider.cs | 37 + .../IAuthenticationProvider.cs.meta | 10 + .../BestHTTP/SignalR/Connection.cs | 1306 ++++++ .../BestHTTP/SignalR/Connection.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs | 196 + .../BestHTTP/SignalR/Enums.cs.meta | 10 + .../BestHTTP/SignalR/Hubs.meta | 7 + .../BestHTTP/SignalR/Hubs/Hub.cs | 391 ++ .../BestHTTP/SignalR/Hubs/Hub.cs.meta | 10 + .../BestHTTP/SignalR/Hubs/IHub.cs | 24 + .../BestHTTP/SignalR/Hubs/IHub.cs.meta | 10 + .../BestHTTP/SignalR/JsonEncoders.meta | 7 + .../JsonEncoders/DefaultJsonEncoder.cs | 24 + .../JsonEncoders/DefaultJsonEncoder.cs.meta | 10 + .../SignalR/JsonEncoders/IJsonEncoder.cs | 24 + .../SignalR/JsonEncoders/IJsonEncoder.cs.meta | 10 + .../BestHTTP/SignalR/Messages.meta | 7 + .../SignalR/Messages/ClientMessage.cs | 71 + .../SignalR/Messages/ClientMessage.cs.meta | 10 + .../SignalR/Messages/IServerMessage.cs | 19 + .../SignalR/Messages/IServerMessage.cs.meta | 10 + .../SignalR/Messages/ServerMessages.cs | 354 ++ .../SignalR/Messages/ServerMessages.cs.meta | 10 + .../BestHTTP/SignalR/NegotiationData.cs | 276 ++ .../BestHTTP/SignalR/NegotiationData.cs.meta | 10 + .../BestHTTP/SignalR/Transports.meta | 7 + .../SignalR/Transports/PollingTransport.cs | 256 ++ .../Transports/PollingTransport.cs.meta | 10 + .../Transports/PostSendTransportBase.cs | 103 + .../Transports/PostSendTransportBase.cs.meta | 10 + .../Transports/ServerSentEventsTransport.cs | 171 + .../ServerSentEventsTransport.cs.meta | 10 + .../SignalR/Transports/TransportBase.cs | 386 ++ .../SignalR/Transports/TransportBase.cs.meta | 10 + .../SignalR/Transports/WebSocketTransport.cs | 173 + .../Transports/WebSocketTransport.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/SignalRCore.meta | 10 + .../BestHTTP/SignalRCore/HelperClasses.cs | 147 + .../SignalRCore/HelperClasses.cs.meta | 13 + .../BestHTTP/SignalRCore/HubConnection.cs | 653 +++ .../SignalRCore/HubConnection.cs.meta | 13 + .../SignalRCore/IAuthenticationProvider.cs | 44 + .../IAuthenticationProvider.cs.meta | 13 + .../BestHTTP/SignalRCore/JsonProtocol.cs | 165 + .../BestHTTP/SignalRCore/JsonProtocol.cs.meta | 13 + .../BestHTTP/SignalRCore/Messages.meta | 10 + .../SignalRCore/Messages/Invocation.cs | 21 + .../SignalRCore/Messages/Invocation.cs.meta | 13 + .../BestHTTP/SignalRCore/Messages/Message.cs | 84 + .../SignalRCore/Messages/Message.cs.meta | 13 + .../SignalRCore/Messages/NegotiationResult.cs | 118 + .../Messages/NegotiationResult.cs.meta | 12 + .../BestHTTP/SignalRCore/Transports.meta | 10 + .../Transports/WebsocketTransport.cs | 253 ++ .../Transports/WebsocketTransport.cs.meta | 13 + Assets/Best HTTP (Pro)/BestHTTP/SocketIO.meta | 7 + .../BestHTTP/SocketIO/Enums.cs | 105 + .../BestHTTP/SocketIO/Enums.cs.meta | 10 + .../BestHTTP/SocketIO/Error.cs | 23 + .../BestHTTP/SocketIO/Error.cs.meta | 10 + .../BestHTTP/SocketIO/Events.meta | 7 + .../SocketIO/Events/EventDescriptor.cs | 93 + .../SocketIO/Events/EventDescriptor.cs.meta | 10 + .../BestHTTP/SocketIO/Events/EventNames.cs | 48 + .../SocketIO/Events/EventNames.cs.meta | 10 + .../BestHTTP/SocketIO/Events/EventTable.cs | 154 + .../SocketIO/Events/EventTable.cs.meta | 10 + .../BestHTTP/SocketIO/HandshakeData.cs | 101 + .../BestHTTP/SocketIO/HandshakeData.cs.meta | 10 + .../BestHTTP/SocketIO/Interfaces.cs | 40 + .../BestHTTP/SocketIO/Interfaces.cs.meta | 10 + .../BestHTTP/SocketIO/JsonEncoders.meta | 7 + .../JsonEncoders/DefaultJSonEncoder.cs | 25 + .../JsonEncoders/DefaultJSonEncoder.cs.meta | 10 + .../SocketIO/JsonEncoders/IJSonEncoder.cs | 24 + .../JsonEncoders/IJSonEncoder.cs.meta | 10 + .../BestHTTP/SocketIO/Packet.cs | 611 +++ .../BestHTTP/SocketIO/Packet.cs.meta | 10 + .../BestHTTP/SocketIO/Socket.cs | 475 +++ .../BestHTTP/SocketIO/Socket.cs.meta | 10 + .../BestHTTP/SocketIO/SocketManager.cs | 684 ++++ .../BestHTTP/SocketIO/SocketManager.cs.meta | 10 + .../BestHTTP/SocketIO/SocketOptions.cs | 158 + .../BestHTTP/SocketIO/SocketOptions.cs.meta | 10 + .../BestHTTP/SocketIO/Transports.meta | 7 + .../SocketIO/Transports/ITransport.cs | 104 + .../SocketIO/Transports/ITransport.cs.meta | 10 + .../SocketIO/Transports/PollingTransport.cs | 449 ++ .../Transports/PollingTransport.cs.meta | 10 + .../SocketIO/Transports/WebSocketTransport.cs | 369 ++ .../Transports/WebSocketTransport.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/Statistics.meta | 7 + .../BestHTTP/Statistics/Statistics.cs | 90 + .../BestHTTP/Statistics/Statistics.cs.meta | 10 + .../Best HTTP (Pro)/BestHTTP/WebSocket.meta | 7 + .../BestHTTP/WebSocket/Extensions.meta | 7 + .../WebSocket/Extensions/IExtension.cs | 41 + .../WebSocket/Extensions/IExtension.cs.meta | 10 + .../Extensions/PerMessageCompression.cs | 334 ++ .../Extensions/PerMessageCompression.cs.meta | 10 + .../BestHTTP/WebSocket/Frames.meta | 7 + .../WebSocket/Frames/WebSocketFrame.cs | 170 + .../WebSocket/Frames/WebSocketFrame.cs.meta | 10 + .../WebSocket/Frames/WebSocketFrameReader.cs | 201 + .../Frames/WebSocketFrameReader.cs.meta | 10 + .../WebSocket/Frames/WebSocketFrameTypes.cs | 48 + .../Frames/WebSocketFrameTypes.cs.meta | 10 + .../BestHTTP/WebSocket/WebSocket.cs | 827 ++++ .../BestHTTP/WebSocket/WebSocket.cs.meta | 10 + .../BestHTTP/WebSocket/WebSocketResponse.cs | 705 ++++ .../WebSocket/WebSocketResponse.cs.meta | 10 + .../WebSocket/WebSocketStatusCodes.cs | 83 + .../WebSocket/WebSocketStatusCodes.cs.meta | 10 + .../BestHTTPDocumentationEN.pdf | Bin 0 -> 444035 bytes .../BestHTTPDocumentationEN.pdf.meta | 38 + Assets/Best HTTP (Pro)/Plugins.meta | 7 + Assets/Best HTTP (Pro)/Plugins/WebGL.meta | 7 + .../Plugins/WebGL/BestHTTP_EventSource.jslib | 154 + .../WebGL/BestHTTP_EventSource.jslib.meta | 21 + .../Plugins/WebGL/BestHTTP_WebRequest.jslib | 241 ++ .../WebGL/BestHTTP_WebRequest.jslib.meta | 21 + .../Plugins/WebGL/BestHTTP_WebSocket.jslib | 211 + .../WebGL/BestHTTP_WebSocket.jslib.meta | 21 + Assets/Best HTTP (Pro)/ReleaseNotes.txt | 584 +++ Assets/Best HTTP (Pro)/ReleaseNotes.txt.meta | 38 + .../Unity 2017.2 and up - Editor.csproj.meta | 8 + .../Unity 2017.2 and up - UWP.csproj.meta | 9 + .../Unity 5.x and up - Editor.csproj.meta | 8 + .../Unity 5.x and up - General.csproj.meta | 8 + .../Unity 5.x and up - UWP.csproj.meta | 8 + .../Unity 5.x and up - WebGL.csproj.meta | 8 + Assets/Best HTTP (Pro)/license.txt | 171 + Assets/Best HTTP (Pro)/license.txt.meta | 8 + Assets/Best HTTP (Pro)/link.xml | 11 + Assets/Best HTTP (Pro)/link.xml.meta | 38 + .../Best HTTP (Pro)/link_android_subset.xml | 12 + .../link_android_subset.xml.meta | 6 + Assets/ConcurrentDownloadManager_Test1.cs | 388 ++ .../ConcurrentDownloadManager_Test1.cs.meta | 11 + Assets/ConcurrentDownloadManager_Test2.cs | 384 ++ .../ConcurrentDownloadManager_Test2.cs.meta | 11 + Assets/ConcurrentQueue.cs | 189 + Assets/ConcurrentQueue.cs.meta | 13 + Assets/DistributedDownloadManager.cs | 567 +++ Assets/DistributedDownloadManager.cs.meta | 13 + Assets/DownloadSpeedTest_Test1.cs | 43 + Assets/DownloadSpeedTest_Test1.cs.meta | 11 + Assets/DownloadSpeedTest_Test1.unity | 865 ++++ Assets/DownloadSpeedTest_Test1.unity.meta | 7 + Assets/DownloadSpeedTest_Test2.cs | 46 + Assets/DownloadSpeedTest_Test2.cs.meta | 11 + Assets/DownloadSpeedTest_Test2.unity | 865 ++++ Assets/DownloadSpeedTest_Test2.unity.meta | 7 + Assets/DownloadSpeedTest_Test3.cs | 190 + Assets/DownloadSpeedTest_Test3.cs.meta | 11 + Assets/DownloadSpeedTest_Test3.unity | 865 ++++ Assets/DownloadSpeedTest_Test3.unity.meta | 7 + Assets/SceneLoader.cs | 24 + Assets/SceneLoader.cs.meta | 13 + Assets/SceneLoader.unity | 1019 +++++ Assets/SceneLoader.unity.meta | 9 + ProjectSettings/AudioManager.asset | 17 + ProjectSettings/ClusterInputManager.asset | 6 + ProjectSettings/DynamicsManager.asset | 29 + ProjectSettings/EditorBuildSettings.asset | 19 + ProjectSettings/EditorSettings.asset | 21 + ProjectSettings/GraphicsSettings.asset | 64 + ProjectSettings/InputManager.asset | 295 ++ ProjectSettings/NavMeshAreas.asset | 91 + ProjectSettings/NetworkManager.asset | 8 + ProjectSettings/Physics2DSettings.asset | 37 + ProjectSettings/ProjectSettings.asset | 643 +++ ProjectSettings/ProjectVersion.txt | 1 + ProjectSettings/QualitySettings.asset | 191 + ProjectSettings/TagManager.asset | 43 + ProjectSettings/TimeManager.asset | 9 + ProjectSettings/UnityConnectSettings.asset | 34 + UnityPackageManager/manifest.json | 4 + 1825 files changed, 183959 insertions(+) create mode 100644 Assets/Best HTTP (Pro).meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Cookies.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/InfTree.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/InfTree.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/Inflate.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/Inflate.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/JSON.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Logger.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfTree.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfTree.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Inflate.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Inflate.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/JZlib.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/JZlib.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/StaticTree.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/StaticTree.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZOutputStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZOutputStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Statistics.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs create mode 100644 Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs.meta create mode 100644 Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf create mode 100644 Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf.meta create mode 100644 Assets/Best HTTP (Pro)/Plugins.meta create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL.meta create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib.meta create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebRequest.jslib create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebRequest.jslib.meta create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebSocket.jslib create mode 100644 Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebSocket.jslib.meta create mode 100644 Assets/Best HTTP (Pro)/ReleaseNotes.txt create mode 100644 Assets/Best HTTP (Pro)/ReleaseNotes.txt.meta create mode 100644 Assets/Best HTTP (Pro)/Unity 2017.2 and up - Editor.csproj.meta create mode 100644 Assets/Best HTTP (Pro)/Unity 2017.2 and up - UWP.csproj.meta create mode 100644 Assets/Best HTTP (Pro)/Unity 5.x and up - Editor.csproj.meta create mode 100644 Assets/Best HTTP (Pro)/Unity 5.x and up - General.csproj.meta create mode 100644 Assets/Best HTTP (Pro)/Unity 5.x and up - UWP.csproj.meta create mode 100644 Assets/Best HTTP (Pro)/Unity 5.x and up - WebGL.csproj.meta create mode 100644 Assets/Best HTTP (Pro)/license.txt create mode 100644 Assets/Best HTTP (Pro)/license.txt.meta create mode 100644 Assets/Best HTTP (Pro)/link.xml create mode 100644 Assets/Best HTTP (Pro)/link.xml.meta create mode 100644 Assets/Best HTTP (Pro)/link_android_subset.xml create mode 100644 Assets/Best HTTP (Pro)/link_android_subset.xml.meta create mode 100644 Assets/ConcurrentDownloadManager_Test1.cs create mode 100644 Assets/ConcurrentDownloadManager_Test1.cs.meta create mode 100644 Assets/ConcurrentDownloadManager_Test2.cs create mode 100644 Assets/ConcurrentDownloadManager_Test2.cs.meta create mode 100644 Assets/ConcurrentQueue.cs create mode 100644 Assets/ConcurrentQueue.cs.meta create mode 100644 Assets/DistributedDownloadManager.cs create mode 100644 Assets/DistributedDownloadManager.cs.meta create mode 100644 Assets/DownloadSpeedTest_Test1.cs create mode 100644 Assets/DownloadSpeedTest_Test1.cs.meta create mode 100644 Assets/DownloadSpeedTest_Test1.unity create mode 100644 Assets/DownloadSpeedTest_Test1.unity.meta create mode 100644 Assets/DownloadSpeedTest_Test2.cs create mode 100644 Assets/DownloadSpeedTest_Test2.cs.meta create mode 100644 Assets/DownloadSpeedTest_Test2.unity create mode 100644 Assets/DownloadSpeedTest_Test2.unity.meta create mode 100644 Assets/DownloadSpeedTest_Test3.cs create mode 100644 Assets/DownloadSpeedTest_Test3.cs.meta create mode 100644 Assets/DownloadSpeedTest_Test3.unity create mode 100644 Assets/DownloadSpeedTest_Test3.unity.meta create mode 100644 Assets/SceneLoader.cs create mode 100644 Assets/SceneLoader.cs.meta create mode 100644 Assets/SceneLoader.unity create mode 100644 Assets/SceneLoader.unity.meta create mode 100644 ProjectSettings/AudioManager.asset create mode 100644 ProjectSettings/ClusterInputManager.asset create mode 100644 ProjectSettings/DynamicsManager.asset create mode 100644 ProjectSettings/EditorBuildSettings.asset create mode 100644 ProjectSettings/EditorSettings.asset create mode 100644 ProjectSettings/GraphicsSettings.asset create mode 100644 ProjectSettings/InputManager.asset create mode 100644 ProjectSettings/NavMeshAreas.asset create mode 100644 ProjectSettings/NetworkManager.asset create mode 100644 ProjectSettings/Physics2DSettings.asset create mode 100644 ProjectSettings/ProjectSettings.asset create mode 100644 ProjectSettings/ProjectVersion.txt create mode 100644 ProjectSettings/QualitySettings.asset create mode 100644 ProjectSettings/TagManager.asset create mode 100644 ProjectSettings/TimeManager.asset create mode 100644 ProjectSettings/UnityConnectSettings.asset create mode 100644 UnityPackageManager/manifest.json diff --git a/Assets/Best HTTP (Pro).meta b/Assets/Best HTTP (Pro).meta new file mode 100644 index 0000000..679eab5 --- /dev/null +++ b/Assets/Best HTTP (Pro).meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 33b0e9b090de2a34faf28eae42076320 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP.meta b/Assets/Best HTTP (Pro)/BestHTTP.meta new file mode 100644 index 0000000..958753b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dc57aabb2dd648642bdfb021906367b1 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication.meta b/Assets/Best HTTP (Pro)/BestHTTP/Authentication.meta new file mode 100644 index 0000000..37d02f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e9dc42aeefc20544bb572bce27e3b7b1 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs new file mode 100644 index 0000000..4d87cde --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs @@ -0,0 +1,63 @@ +namespace BestHTTP.Authentication +{ + /// + /// Authentication types that supported by BestHTTP. + /// The authentication is defined by the server, so the Basic and Digest are not interchangeable. If you don't know what to use, the preferred way is to choose Unknow. + /// + public enum AuthenticationTypes + { + /// + /// If the authentication type is not known this will do a challenge turn to receive what methode should be choosen. + /// + Unknown, + + /// + /// The most basic authentication type. It's easy to do, and easy to crack. ;) + /// + Basic, + + /// + /// + /// + Digest + } + + /// + /// Hold all information that required to authenticate to a remote server. + /// + public sealed class Credentials + { + /// + /// The type of the Authentication. If you don't know what to use, the preferred way is to choose Unknow. + /// + public AuthenticationTypes Type { get; private set; } + + /// + /// The username to authenticate on the remote server. + /// + public string UserName { get; private set; } + + /// + /// The password to use in the authentication process. The password will be stored only in this class. + /// + public string Password { get; private set; } + + /// + /// Set up the authentication credentials with the username and password. The Type will be set to Unknown. + /// + public Credentials(string userName, string password) + :this(AuthenticationTypes.Unknown, userName, password) + { + } + + /// + /// Set up the authentication credentials with the given authentication type, username and password. + /// + public Credentials(AuthenticationTypes type, string userName, string password) + { + this.Type = type; + this.UserName = userName; + this.Password = password; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs.meta new file mode 100644 index 0000000..06dea04 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Credentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a6a6217993b733a4e8555355d5d62776 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs new file mode 100644 index 0000000..2d4ae91 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; + +namespace BestHTTP.Authentication +{ + using BestHTTP.Extensions; + using System.Text; + + /// + /// Internal class that stores all information that received from a server in a WWW-Authenticate and need to construct a valid Authorization header. Based on rfc 2617 (http://tools.ietf.org/html/rfc2617). + /// Used only internally by the plugin. + /// + public sealed class Digest + { + #region Public Properties + + /// + /// The Uri that this Digest is bound to. + /// + public Uri Uri { get; private set; } + + public AuthenticationTypes Type { get; private set; } + + /// + /// A string to be displayed to users so they know which username and password to use. + /// This string should contain at least the name of the host performing the authentication and might additionally indicate the collection of users who might have access. + /// + public string Realm { get; private set; } + + /// + /// A flag, indicating that the previous request from the client was rejected because the nonce value was stale. + /// If stale is TRUE (case-insensitive), the client may wish to simply retry the request with a new encrypted response, without the user for a new username and password. + /// The server should only set stale to TRUE if it receives a request for which the nonce is invalid but with a valid digest for that nonce + /// (indicating that the client knows the correct username/password). + /// If stale is FALSE, or anything other than TRUE, or the stale directive is not present, the username and/or password are invalid, and new values must be obtained. + /// + public bool Stale { get; private set; } + + #endregion + + #region Private Properties + + /// + /// A server-specified data string which should be uniquely generated each time a 401 response is made. + /// Specifically, since the string is passed in the header lines as a quoted string, the double-quote character is not allowed. + /// + private string Nonce { get; set; } + + /// + /// A string of data, specified by the server, which should be returned by the client unchanged in the Authorization header of subsequent requests with URIs in the same protection space. + /// It is recommended that this string be base64 or data. + /// + private string Opaque { get; set; } + + /// + /// A string indicating a pair of algorithms used to produce the digest and a checksum. If this is not present it is assumed to be "MD5". + /// If the algorithm is not understood, the challenge should be ignored (and a different one used, if there is more than one). + /// + private string Algorithm { get; set; } + + /// + /// List of URIs, as specified in RFC XURI, that define the protection space. + /// If a URI is an abs_path, it is relative to the canonical root URL (see section 1.2 above) of the server being accessed. + /// An absoluteURI in this list may refer to a different server than the one being accessed. + /// The client can use this list to determine the set of URIs for which the same authentication information may be sent: + /// any URI that has a URI in this list as a prefix (after both have been made absolute) may be assumed to be in the same protection space. + /// If this directive is omitted or its value is empty, the client should assume that the protection space consists of all URIs on the responding server. + /// + public List ProtectedUris { get; private set; } + + /// + /// If present, it is a quoted string of one or more tokens indicating the "quality of protection" values supported by the server. + /// The value "auth" indicates authentication. The value "auth-int" indicates authentication with integrity protection. + /// + private string QualityOfProtections { get; set; } + + /// + /// his MUST be specified if a qop directive is sent (see above), and MUST NOT be specified if the server did not send a qop directive in the WWW-Authenticate header field. + /// The nc-value is the hexadecimal count of the number of requests (including the current request) that the client has sent with the nonce value in this request. + /// + private int NonceCount { get; set; } + + /// + /// Used to store the last HA1 that can be used in the next header generation when Algorithm is set to "md5-sess". + /// + private string HA1Sess { get; set; } + + #endregion + + internal Digest(Uri uri) + { + this.Uri = uri; + this.Algorithm = "md5"; + } + + /// + /// Parses a WWW-Authenticate header's value to retrive all information. + /// + public void ParseChallange(string header) + { + // Reset some values to its defaults. + this.Type = AuthenticationTypes.Unknown; + this.Stale = false; + this.Opaque = null; + this.HA1Sess = null; + this.NonceCount = 0; + this.QualityOfProtections = null; + + if (this.ProtectedUris != null) + this.ProtectedUris.Clear(); + + // Parse the header + WWWAuthenticateHeaderParser qpl = new WWWAuthenticateHeaderParser(header); + + // Then process + foreach (var qp in qpl.Values) + switch (qp.Key) + { + case "basic": this.Type = AuthenticationTypes.Basic; break; + case "digest": this.Type = AuthenticationTypes.Digest; break; + case "realm": this.Realm = qp.Value; break; + case "domain": + { + if (string.IsNullOrEmpty(qp.Value) || qp.Value.Length == 0) + break; + + if (this.ProtectedUris == null) + this.ProtectedUris = new List(); + + int idx = 0; + string val = qp.Value.Read(ref idx, ' '); + do + { + this.ProtectedUris.Add(val); + val = qp.Value.Read(ref idx, ' '); + } while (idx < qp.Value.Length); + + break; + } + case "nonce": this.Nonce = qp.Value; break; + case "qop": this.QualityOfProtections = qp.Value; break; + case "stale": this.Stale = bool.Parse(qp.Value); break; + case "opaque": this.Opaque = qp.Value; break; + case "algorithm": this.Algorithm = qp.Value; break; + } + } + + /// + /// Generates a string that can be set to an Authorization header. + /// + public string GenerateResponseHeader(HTTPRequest request, Credentials credentials, bool isProxy = false) + { + try + { + switch (Type) + { + case AuthenticationTypes.Basic: + return string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", credentials.UserName, credentials.Password)))); + + case AuthenticationTypes.Digest: + { + NonceCount++; + + string HA1 = string.Empty; + + // The cnonce-value is an opaque quoted string value provided by the client and used by both client and server to avoid chosen plaintext attacks, to provide mutual + // authentication, and to provide some message integrity protection. + string cnonce = new System.Random(request.GetHashCode()).Next(int.MinValue, int.MaxValue).ToString("X8"); + + string ncvalue = NonceCount.ToString("X8"); + switch (Algorithm.TrimAndLower()) + { + case "md5": + HA1 = string.Format("{0}:{1}:{2}", credentials.UserName, Realm, credentials.Password).CalculateMD5Hash(); + break; + + case "md5-sess": + if (string.IsNullOrEmpty(this.HA1Sess)) + this.HA1Sess = string.Format("{0}:{1}:{2}:{3}:{4}", credentials.UserName, Realm, credentials.Password, Nonce, ncvalue).CalculateMD5Hash(); + HA1 = this.HA1Sess; + break; + + default: //throw new NotSupportedException("Not supported hash algorithm found in Web Authentication: " + Algorithm); + return string.Empty; + } + + // A string of 32 hex digits, which proves that the user knows a password. Set according to the qop value. + string response = string.Empty; + + // The server sent QoP-value can be a list of supported methodes(if sent at all - in this case it's null). + // The rfc is not specify that this is a space or comma separeted list. So it can be "auth, auth-int" or "auth auth-int". + // We will first check the longer value("auth-int") then the short one ("auth"). If one matches we will reset the qop to the exact value. + string qop = this.QualityOfProtections != null ? this.QualityOfProtections.TrimAndLower() : null; + + // When we authenticate with a proxy and we want to tunnel the request, we have to use the CONNECT method instead of the + // request's, as the proxy will not know about the request itself. + string method = isProxy ? "CONNECT" : request.MethodType.ToString().ToUpper(); + + // When we authenticate with a proxy and we want to tunnel the request, the uri must match what we are sending in the CONNECT request's + // Host header. + string uri = isProxy ? request.CurrentUri.Host + ":" + request.CurrentUri.Port : request.CurrentUri.GetRequestPathAndQueryURL(); + + if (qop == null) + { + string HA2 = string.Concat(request.MethodType.ToString().ToUpper(), ":", request.CurrentUri.GetRequestPathAndQueryURL()).CalculateMD5Hash(); + response = string.Format("{0}:{1}:{2}", HA1, Nonce, HA2).CalculateMD5Hash(); + } + else if (qop.Contains("auth-int")) + { + qop = "auth-int"; + + byte[] entityBody = request.GetEntityBody(); + + if (entityBody == null) + entityBody = string.Empty.GetASCIIBytes(); + + string HA2 = string.Format("{0}:{1}:{2}", method, uri, entityBody.CalculateMD5Hash()).CalculateMD5Hash(); + + response = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, Nonce, ncvalue, cnonce, qop, HA2).CalculateMD5Hash(); + } + else if (qop.Contains("auth")) + { + qop = "auth"; + string HA2 = string.Concat(method, ":", uri).CalculateMD5Hash(); + + response = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, Nonce, ncvalue, cnonce, qop, HA2).CalculateMD5Hash(); + } + else //throw new NotSupportedException("Unrecognized Quality of Protection value found: " + this.QualityOfProtections); + return string.Empty; + + string result = string.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", cnonce=\"{4}\", response=\"{5}\"", + credentials.UserName, Realm, Nonce, uri, cnonce, response); + + if (qop != null) + result += String.Concat(", qop=\"", qop, "\", nc=", ncvalue); + + if (!string.IsNullOrEmpty(Opaque)) + result = String.Concat(result, ", opaque=\"", Opaque, "\""); + + return result; + }// end of case "digest": + + default: + break; + } + } + catch + { + } + + return string.Empty; + } + + public bool IsUriProtected(Uri uri) + { + // http://tools.ietf.org/html/rfc2617#section-3.2.1 + // An absoluteURI in this list may refer to + // a different server than the one being accessed. The client can use + // this list to determine the set of URIs for which the same + // authentication information may be sent: any URI that has a URI in + // this list as a prefix (after both have been made absolute) may be + // assumed to be in the same protection space. If this directive is + // omitted or its value is empty, the client should assume that the + // protection space consists of all URIs on the responding server. + + if (string.CompareOrdinal(uri.Host, this.Uri.Host) != 0) + return false; + + string uriStr = uri.ToString(); + + if (ProtectedUris != null && ProtectedUris.Count > 0) + for (int i = 0; i < ProtectedUris.Count; ++i) + if (uriStr.Contains(ProtectedUris[i])) + return true; + + + return true; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs.meta new file mode 100644 index 0000000..869c596 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 424d976119ee3fc438fe98095013859f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs new file mode 100644 index 0000000..78e7621 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; + +namespace BestHTTP.Authentication +{ + /// + /// Stores and manages already received digest infos. + /// + public static class DigestStore + { + private static Dictionary Digests = new Dictionary(); + + private static object Locker = new object(); + + /// + /// Array of algorithms that the plugin supports. It's in the order of priority(first has the highest priority). + /// + private static string[] SupportedAlgorithms = new string[] { "digest", "basic" }; + + public static Digest Get(Uri uri) + { + lock (Locker) + { + Digest digest = null; + if (Digests.TryGetValue(uri.Host, out digest)) + if (!digest.IsUriProtected(uri)) + return null; + return digest; + } + } + + /// + /// It will retrive or create a new Digest for the given Uri. + /// + /// + /// + public static Digest GetOrCreate(Uri uri) + { + lock (Locker) + { + Digest digest = null; + if (!Digests.TryGetValue(uri.Host, out digest)) + Digests.Add(uri.Host, digest = new Digest(uri)); + return digest; + } + } + + public static void Remove(Uri uri) + { + lock(Locker) + Digests.Remove(uri.Host); + } + + public static string FindBest(List authHeaders) + { + if (authHeaders == null || authHeaders.Count == 0) + return string.Empty; + + List headers = new List(authHeaders.Count); + for (int i = 0; i < authHeaders.Count; ++i) + headers.Add(authHeaders[i].ToLower()); + + for (int i = 0; i < SupportedAlgorithms.Length; ++i) + { + int idx = headers.FindIndex((header) => header.StartsWith(SupportedAlgorithms[i])); + if (idx != -1) + return authHeaders[idx]; + } + + return string.Empty; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs.meta new file mode 100644 index 0000000..280472e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Authentication/DigestStore.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0f808b023553ee2419249f92eb8ac31f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching.meta b/Assets/Best HTTP (Pro)/BestHTTP/Caching.meta new file mode 100644 index 0000000..319ec4f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 26e64cd0d1567634fb40b1386ba0c48d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs new file mode 100644 index 0000000..f8f4530 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs @@ -0,0 +1,403 @@ +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections.Generic; + +#if NETFX_CORE + using FileStream = BestHTTP.PlatformSupport.IO.FileStream; + using Directory = BestHTTP.PlatformSupport.IO.Directory; + using File = BestHTTP.PlatformSupport.IO.File; + + using BestHTTP.PlatformSupport.IO; +#else + using FileStream = System.IO.FileStream; + + using System.IO; +#endif + +namespace BestHTTP.Caching +{ + using BestHTTP.Extensions; + + /// + /// Holds all metadata that need for efficient caching, so we don't need to touch the disk to load headers. + /// + public class HTTPCacheFileInfo : IComparable + { + #region Properties + + /// + /// The uri that this HTTPCacheFileInfo belongs to. + /// + internal Uri Uri { get; set; } + + /// + /// The last access time to this cache entity. The date is in UTC. + /// + internal DateTime LastAccess { get; set; } + + /// + /// The length of the cache entity's body. + /// + public int BodyLength { get; set; } + + /// + /// ETag of the entity. + /// + private string ETag { get; set; } + + /// + /// LastModified date of the entity. + /// + private string LastModified { get; set; } + + /// + /// When the cache will expire. + /// + private DateTime Expires { get; set; } + + /// + /// The age that came with the response + /// + private long Age { get; set; } + + /// + /// Maximum how long the entry should served from the cache without revalidation. + /// + private long MaxAge { get; set; } + + /// + /// The Date that came with the response. + /// + private DateTime Date { get; set; } + + /// + /// Indicates whether the entity must be revalidated with the server or can be serverd directly from the cache without touching the server. + /// + private bool MustRevalidate { get; set; } + + /// + /// The date and time when the HTTPResponse received. + /// + private DateTime Received { get; set; } + + /// + /// Cached path. + /// + private string ConstructedPath { get; set; } + + /// + /// This is the index of the entity. Filenames are generated from this value. + /// + internal UInt64 MappedNameIDX { get; set; } + + #endregion + + #region Constructors + + internal HTTPCacheFileInfo(Uri uri) + :this(uri, DateTime.UtcNow, -1) + { + } + + internal HTTPCacheFileInfo(Uri uri, DateTime lastAcces, int bodyLength) + { + this.Uri = uri; + this.LastAccess = lastAcces; + this.BodyLength = bodyLength; + this.MaxAge = -1; + + this.MappedNameIDX = HTTPCacheService.GetNameIdx(); + } + + internal HTTPCacheFileInfo(Uri uri, System.IO.BinaryReader reader, int version) + { + this.Uri = uri; + this.LastAccess = DateTime.FromBinary(reader.ReadInt64()); + this.BodyLength = reader.ReadInt32(); + + switch(version) + { + case 2: + this.MappedNameIDX = reader.ReadUInt64(); + goto case 1; + + case 1: + { + this.ETag = reader.ReadString(); + this.LastModified = reader.ReadString(); + this.Expires = DateTime.FromBinary(reader.ReadInt64()); + this.Age = reader.ReadInt64(); + this.MaxAge = reader.ReadInt64(); + this.Date = DateTime.FromBinary(reader.ReadInt64()); + this.MustRevalidate = reader.ReadBoolean(); + this.Received = DateTime.FromBinary(reader.ReadInt64()); + break; + } + } + } + + #endregion + + #region Helper Functions + + internal void SaveTo(System.IO.BinaryWriter writer) + { + writer.Write(LastAccess.ToBinary()); + writer.Write(BodyLength); + writer.Write(MappedNameIDX); + writer.Write(ETag); + writer.Write(LastModified); + writer.Write(Expires.ToBinary()); + writer.Write(Age); + writer.Write(MaxAge); + writer.Write(Date.ToBinary()); + writer.Write(MustRevalidate); + writer.Write(Received.ToBinary()); + } + + public string GetPath() + { + if (ConstructedPath != null) + return ConstructedPath; + + return ConstructedPath = System.IO.Path.Combine(HTTPCacheService.CacheFolder, MappedNameIDX.ToString("X")); + } + + public bool IsExists() + { + if (!HTTPCacheService.IsSupported) + return false; + + return File.Exists(GetPath()); + } + + internal void Delete() + { + if (!HTTPCacheService.IsSupported) + return; + + string path = GetPath(); + try + { + File.Delete(path); + } + catch + { } + finally + { + Reset(); + } + } + + private void Reset() + { + // MappedNameIDX will remain the same. When we re-save an entity, it will not reset the MappedNameIDX. + this.BodyLength = -1; + this.ETag = string.Empty; + this.Expires = DateTime.FromBinary(0); + this.LastModified = string.Empty; + this.Age = 0; + this.MaxAge = -1; + this.Date = DateTime.FromBinary(0); + this.MustRevalidate = false; + this.Received = DateTime.FromBinary(0); + } + + #endregion + + #region Caching + + private void SetUpCachingValues(HTTPResponse response) + { + response.CacheFileInfo = this; + + this.ETag = response.GetFirstHeaderValue("ETag").ToStrOrEmpty(); + this.Expires = response.GetFirstHeaderValue("Expires").ToDateTime(DateTime.FromBinary(0)); + this.LastModified = response.GetFirstHeaderValue("Last-Modified").ToStrOrEmpty(); + + this.Age = response.GetFirstHeaderValue("Age").ToInt64(0); + + this.Date = response.GetFirstHeaderValue("Date").ToDateTime(DateTime.FromBinary(0)); + + string cacheControl = response.GetFirstHeaderValue("cache-control"); + if (!string.IsNullOrEmpty(cacheControl)) + { + string[] kvp = cacheControl.FindOption("max-age"); + if (kvp != null) + { + // Some cache proxies will return float values + double maxAge; + if (double.TryParse(kvp[1], out maxAge)) + this.MaxAge = (int)maxAge; + } + + this.MustRevalidate = cacheControl.ToLower().Contains("must-revalidate"); + } + + this.Received = DateTime.UtcNow; + } + + internal bool WillExpireInTheFuture() + { + if (!IsExists()) + return false; + + if (MustRevalidate) + return false; + + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.4 : + // The max-age directive takes priority over Expires + if (MaxAge != -1) + { + // Age calculation: + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.3 + + long apparent_age = Math.Max(0, (long)(Received - Date).TotalSeconds); + long corrected_received_age = Math.Max(apparent_age, Age); + long resident_time = (long)(DateTime.UtcNow - Date).TotalSeconds; + long current_age = corrected_received_age + resident_time; + + return current_age < MaxAge; + } + + return Expires > DateTime.UtcNow; + } + + internal void SetUpRevalidationHeaders(HTTPRequest request) + { + if (!IsExists()) + return; + + // -If an entity tag has been provided by the origin server, MUST use that entity tag in any cache-conditional request (using If-Match or If-None-Match). + // -If only a Last-Modified value has been provided by the origin server, SHOULD use that value in non-subrange cache-conditional requests (using If-Modified-Since). + // -If both an entity tag and a Last-Modified value have been provided by the origin server, SHOULD use both validators in cache-conditional requests. This allows both HTTP/1.0 and HTTP/1.1 caches to respond appropriately. + + if (!string.IsNullOrEmpty(ETag)) + request.AddHeader("If-None-Match", ETag); + + if (!string.IsNullOrEmpty(LastModified)) + request.AddHeader("If-Modified-Since", LastModified); + } + + public System.IO.Stream GetBodyStream(out int length) + { + if (!IsExists()) + { + length = 0; + return null; + } + + length = BodyLength; + + LastAccess = DateTime.UtcNow; + + FileStream stream = new FileStream(GetPath(), FileMode.Open, FileAccess.Read, FileShare.Read); + stream.Seek(-length, System.IO.SeekOrigin.End); + + return stream; + } + + internal HTTPResponse ReadResponseTo(HTTPRequest request) + { + if (!IsExists()) + return null; + + LastAccess = DateTime.UtcNow; + + using (FileStream stream = new FileStream(GetPath(), FileMode.Open, FileAccess.Read, FileShare.Read)) + { + var response = new HTTPResponse(request, stream, request.UseStreaming, true); + response.CacheFileInfo = this; + response.Receive(BodyLength); + return response; + } + } + + internal void Store(HTTPResponse response) + { + if (!HTTPCacheService.IsSupported) + return; + + string path = GetPath(); + + // Path name too long, we don't want to get exceptions + if (path.Length > HTTPManager.MaxPathLength) + return; + + if (File.Exists(path)) + Delete(); + + using (FileStream writer = new FileStream(path, FileMode.Create)) + { + writer.WriteLine("HTTP/1.1 {0} {1}", response.StatusCode, response.Message); + foreach (var kvp in response.Headers) + { + for (int i = 0; i < kvp.Value.Count; ++i) + writer.WriteLine("{0}: {1}", kvp.Key, kvp.Value[i]); + } + + writer.WriteLine(); + + writer.Write(response.Data, 0, response.Data.Length); + } + + BodyLength = response.Data.Length; + LastAccess = DateTime.UtcNow; + + SetUpCachingValues(response); + } + + internal System.IO.Stream GetSaveStream(HTTPResponse response) + { + if (!HTTPCacheService.IsSupported) + return null; + + LastAccess = DateTime.UtcNow; + + string path = GetPath(); + + if (File.Exists(path)) + Delete(); + + // Path name too long, we don't want to get exceptions + if (path.Length > HTTPManager.MaxPathLength) + return null; + + // First write out the headers + using (FileStream writer = new FileStream(path, FileMode.Create)) + { + writer.WriteLine("HTTP/1.1 {0} {1}", response.StatusCode, response.Message); + foreach (var kvp in response.Headers) + { + for (int i = 0; i < kvp.Value.Count; ++i) + writer.WriteLine("{0}: {1}", kvp.Key, kvp.Value[i]); + } + + writer.WriteLine(); + } + + // If caching is enabled and the response is from cache, and no content-length header set, then we set one to the response. + if (response.IsFromCache && !response.Headers.ContainsKey("content-length")) + response.Headers.Add("content-length", new List { BodyLength.ToString() }); + + SetUpCachingValues(response); + + // then create the stream with Append FileMode + return new FileStream(GetPath(), FileMode.Append); + } + + #endregion + + #region IComparable + + public int CompareTo(HTTPCacheFileInfo other) + { + return this.LastAccess.CompareTo(other.LastAccess); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs.meta new file mode 100644 index 0000000..7aa44aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1f50da5c22225384fbe271e0453fe545 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs new file mode 100644 index 0000000..1d55a5e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections.Generic; + +namespace BestHTTP.Caching +{ + sealed class HTTPCacheFileLock + { + private static Dictionary FileLocks = new Dictionary(); + private static object SyncRoot = new object(); + + internal static object Acquire(Uri uri) + { + lock (SyncRoot) + { + object fileLock; + if (!FileLocks.TryGetValue(uri, out fileLock)) + FileLocks.Add(uri, fileLock = new object()); + + return fileLock; + } + } + + internal static void Remove(Uri uri) + { + lock (SyncRoot) + { + if (FileLocks.ContainsKey(uri)) + FileLocks.Remove(uri); + } + } + + internal static void Clear() + { + lock (SyncRoot) + { + FileLocks.Clear(); + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs.meta new file mode 100644 index 0000000..5ee7d6e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheFileLock.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7b141dab023cd9d438e0585b93cf2826 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs new file mode 100644 index 0000000..2c3cc19 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace BestHTTP.Caching +{ + public sealed class HTTPCacheMaintananceParams + { + /// + /// Delete cache entries that accessed older then this value. If TimeSpan.FromSeconds(0) is used then all cache entries will be deleted. With TimeSpan.FromDays(2) entries that older then two days will be deleted. + /// + public TimeSpan DeleteOlder { get; private set; } + + /// + /// If the cache is larger then the MaxCacheSize after the first maintanance step, then the maintanance job will forcedelete cache entries starting with the oldest last accessed one. + /// + public ulong MaxCacheSize { get; private set; } + + public HTTPCacheMaintananceParams(TimeSpan deleteOlder, ulong maxCacheSize) + { + this.DeleteOlder = deleteOlder; + this.MaxCacheSize = maxCacheSize; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs.meta new file mode 100644 index 0000000..0d3225b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheMaintananceParams.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3ce5552e539e38647a8f37ab36951bf7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs new file mode 100644 index 0000000..c38fbe9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs @@ -0,0 +1,727 @@ +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +#if NETFX_CORE + using FileStream = BestHTTP.PlatformSupport.IO.FileStream; + using Directory = BestHTTP.PlatformSupport.IO.Directory; + using File = BestHTTP.PlatformSupport.IO.File; + + using BestHTTP.PlatformSupport.IO; + + //Disable CD4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. + #pragma warning disable 4014 +#else + using FileStream = System.IO.FileStream; + using Directory = System.IO.Directory; + + using System.IO; +#endif + +// +// Version 1: Initial release +// Version 2: Filenames are generated from an index. +// + +namespace BestHTTP.Caching +{ + using BestHTTP.Extensions; + + public sealed class UriComparer : IEqualityComparer + { + public bool Equals(Uri x, Uri y) + { + return Uri.Compare(x, y, UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped, StringComparison.Ordinal) == 0; + } + + public int GetHashCode(Uri uri) + { + return uri.ToString().GetHashCode(); + } + } + + + public static class HTTPCacheService + { + #region Properties & Fields + + /// + /// Library file-format versioning support + /// + private const int LibraryVersion = 2; + + public static bool IsSupported + { + get + { + if (IsSupportCheckDone) + return isSupported; + + try + { + File.Exists(HTTPManager.GetRootCacheFolder()); + isSupported = true; + } + catch + { + isSupported = false; + + HTTPManager.Logger.Warning("HTTPCacheService", "Cache Service Disabled!"); + } + finally + { + IsSupportCheckDone = true; + } + + return isSupported; + } + } + private static bool isSupported; + private static bool IsSupportCheckDone; + + private static Dictionary library; + private static Dictionary Library { get { LoadLibrary(); return library; } } + + private static Dictionary UsedIndexes = new Dictionary(); + + internal static string CacheFolder { get; private set; } + private static string LibraryPath { get; set; } + + private static bool InClearThread; + private static bool InMaintainenceThread; + + /// + /// Stores the index of the next stored entity. The entity's file name is generated from this index. + /// + private static UInt64 NextNameIDX; + + #endregion + + static HTTPCacheService() + { + NextNameIDX = 0x0001; + } + + #region Common Functions + + internal static void CheckSetup() + { + if (!HTTPCacheService.IsSupported) + return; + + try + { + SetupCacheFolder(); + LoadLibrary(); + } + catch + { } + } + + internal static void SetupCacheFolder() + { + if (!HTTPCacheService.IsSupported) + return; + + try + { + if (string.IsNullOrEmpty(CacheFolder) || string.IsNullOrEmpty(LibraryPath)) + { + CacheFolder = System.IO.Path.Combine(HTTPManager.GetRootCacheFolder(), "HTTPCache"); + if (!Directory.Exists(CacheFolder)) + Directory.CreateDirectory(CacheFolder); + + LibraryPath = System.IO.Path.Combine(HTTPManager.GetRootCacheFolder(), "Library"); + } + } + catch + { + isSupported = false; + + HTTPManager.Logger.Warning("HTTPCacheService", "Cache Service Disabled!"); + } + } + + internal static UInt64 GetNameIdx() + { + lock(Library) + { + UInt64 result = NextNameIDX; + + do + { + NextNameIDX = ++NextNameIDX % UInt64.MaxValue; + } while (UsedIndexes.ContainsKey(NextNameIDX)); + + return result; + } + } + + internal static bool HasEntity(Uri uri) + { + if (!IsSupported) + return false; + + lock (Library) + return Library.ContainsKey(uri); + } + + internal static bool DeleteEntity(Uri uri, bool removeFromLibrary = true) + { + if (!IsSupported) + return false; + + object uriLocker = HTTPCacheFileLock.Acquire(uri); + + // Just use lock now: http://forum.unity3d.com/threads/4-6-ios-64-bit-beta.290551/page-6#post-1937033 + + // To avoid a dead-lock we try acquire the lock on this uri only for a little time. + // If we can't acquire it, its better to just return without risking a deadlock. + //if (Monitor.TryEnter(uriLocker, TimeSpan.FromSeconds(0.5f))) + lock(uriLocker) + { + try + { + lock (Library) + { + HTTPCacheFileInfo info; + bool inStats = Library.TryGetValue(uri, out info); + if (inStats) + info.Delete(); + + if (inStats && removeFromLibrary) + { + Library.Remove(uri); + UsedIndexes.Remove(info.MappedNameIDX); + } + + return true; + } + } + finally + { + //Monitor.Exit(uriLocker); + } + } + + //return false; + } + + internal static bool IsCachedEntityExpiresInTheFuture(HTTPRequest request) + { + if (!IsSupported) + return false; + + HTTPCacheFileInfo info; + lock (Library) + if (Library.TryGetValue(request.CurrentUri, out info)) + return info.WillExpireInTheFuture(); + + return false; + } + + /// + /// Utility function to set the cache control headers according to the spec.: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 + /// + /// + internal static void SetHeaders(HTTPRequest request) + { + if (!IsSupported) + return; + + HTTPCacheFileInfo info; + lock (Library) + if (Library.TryGetValue(request.CurrentUri, out info)) + info.SetUpRevalidationHeaders(request); + } + + #endregion + + #region Get Functions + + internal static HTTPCacheFileInfo GetEntity(Uri uri) + { + if (!IsSupported) + return null; + HTTPCacheFileInfo info = null; + lock (Library) + Library.TryGetValue(uri, out info); + return info; + } + + internal static HTTPResponse GetFullResponse(HTTPRequest request) + { + if (!IsSupported) + return null; + + HTTPCacheFileInfo info; + lock (Library) + if (Library.TryGetValue(request.CurrentUri, out info)) + return info.ReadResponseTo(request); + + return null; + } + + #endregion + + #region Storing + + /// + /// Checks if the given response can be cached. http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4 + /// + /// Returns true if cacheable, false otherwise. + internal static bool IsCacheble(Uri uri, HTTPMethods method, HTTPResponse response) + { + if (!IsSupported) + return false; + + if (method != HTTPMethods.Get) + return false; + + if (response == null) + return false; + + // https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.12 - Cache Replacement + // It MAY insert it into cache storage and MAY, if it meets all other requirements, use it to respond to any future requests that would previously have caused the old response to be returned. + //if (response.StatusCode == 304) + // return false; + + if (response.StatusCode < 200 || response.StatusCode >= 400) + return false; + + //http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2 + var cacheControls = response.GetHeaderValues("cache-control"); + if (cacheControls != null) + { + if (cacheControls.Exists(headerValue => { + string value = headerValue.ToLower(); + return value.Contains("no-store") || value.Contains("no-cache"); + })) + return false; + } + + var pragmas = response.GetHeaderValues("pragma"); + if (pragmas != null) + { + if (pragmas.Exists(headerValue => { + string value = headerValue.ToLower(); + return value.Contains("no-store") || value.Contains("no-cache"); + })) + return false; + } + + // Responses with byte ranges not supported yet. + var byteRanges = response.GetHeaderValues("content-range"); + if (byteRanges != null) + return false; + + return true; + } + + internal static HTTPCacheFileInfo Store(Uri uri, HTTPMethods method, HTTPResponse response) + { + if (response == null || response.Data == null || response.Data.Length == 0) + return null; + + if (!IsSupported) + return null; + + HTTPCacheFileInfo info = null; + + lock (Library) + { + if (!Library.TryGetValue(uri, out info)) + { + Library.Add(uri, info = new HTTPCacheFileInfo(uri)); + UsedIndexes.Add(info.MappedNameIDX, info); + } + + try + { + info.Store(response); + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPCacheService", string.Format("{0} - Saved to cache", uri.ToString())); + } + catch + { + // If something happens while we write out the response, than we will delete it because it might be in an invalid state. + DeleteEntity(uri); + + throw; + } + } + + return info; + } + + internal static System.IO.Stream PrepareStreamed(Uri uri, HTTPResponse response) + { + if (!IsSupported) + return null; + + HTTPCacheFileInfo info; + + lock (Library) + { + if (!Library.TryGetValue(uri, out info)) + { + Library.Add(uri, info = new HTTPCacheFileInfo(uri)); + UsedIndexes.Add(info.MappedNameIDX, info); + } + + try + { + return info.GetSaveStream(response); + } + catch + { + // If something happens while we write out the response, than we will delete it because it might be in an invalid state. + DeleteEntity(uri); + + throw; + } + } + } + + #endregion + + #region Public Maintenance Functions + + /// + /// Deletes all cache entity. Non blocking. + /// Call it only if there no requests currently processed, because cache entries can be deleted while a server sends back a 304 result, so there will be no data to read from the cache! + /// + public static void BeginClear() + { + if (!IsSupported) + return; + + if (InClearThread) + return; + InClearThread = true; + + SetupCacheFolder(); + + #if !NETFX_CORE + ThreadPool.QueueUserWorkItem(new WaitCallback((param) => ClearImpl(param))); + //new Thread(ClearImpl).Start(); +#else +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(ClearImpl); +#pragma warning restore 4014 +#endif + } + + private static void ClearImpl(object param) + { + if (!IsSupported) + return; + + try + { + // GetFiles will return a string array that contains the files in the folder with the full path + string[] cacheEntries = Directory.GetFiles(CacheFolder); + + for (int i = 0; i < cacheEntries.Length; ++i) + { + // We need a try-catch block because between the Directory.GetFiles call and the File.Delete calls a maintenance job, or other file operations can delete any file from the cache folder. + // So while there might be some problem with any file, we don't want to abort the whole for loop + try + { + File.Delete(cacheEntries[i]); + } + catch + { } + } + } + finally + { + UsedIndexes.Clear(); + library.Clear(); + NextNameIDX = 0x0001; + + SaveLibrary(); + InClearThread = false; + } + } + + /// + /// Deletes all expired cache entity. + /// Call it only if there no requests currently processed, because cache entries can be deleted while a server sends back a 304 result, so there will be no data to read from the cache! + /// + public static void BeginMaintainence(HTTPCacheMaintananceParams maintananceParam) + { + if (maintananceParam == null) + throw new ArgumentNullException("maintananceParams == null"); + + if (!HTTPCacheService.IsSupported) + return; + + if (InMaintainenceThread) + return; + + InMaintainenceThread = true; + + SetupCacheFolder(); + +#if !NETFX_CORE + ThreadPool.QueueUserWorkItem(new WaitCallback((param) => + //new Thread((param) => +#else +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync((param) => +#pragma warning restore 4014 +#endif + { + try + { + lock (Library) + { + // Delete cache entries older than the given time. + DateTime deleteOlderAccessed = DateTime.UtcNow - maintananceParam.DeleteOlder; + List removedEntities = new List(); + foreach (var kvp in Library) + if (kvp.Value.LastAccess < deleteOlderAccessed) + { + if (DeleteEntity(kvp.Key, false)) + removedEntities.Add(kvp.Value); + } + + for (int i = 0; i < removedEntities.Count; ++i) + { + Library.Remove(removedEntities[i].Uri); + UsedIndexes.Remove(removedEntities[i].MappedNameIDX); + } + removedEntities.Clear(); + + ulong cacheSize = GetCacheSize(); + + // This step will delete all entries starting with the oldest LastAccess property while the cache size greater then the MaxCacheSize in the given param. + if (cacheSize > maintananceParam.MaxCacheSize) + { + List fileInfos = new List(library.Count); + + foreach(var kvp in library) + fileInfos.Add(kvp.Value); + + fileInfos.Sort(); + + int idx = 0; + while (cacheSize >= maintananceParam.MaxCacheSize && idx < fileInfos.Count) + { + try + { + var fi = fileInfos[idx]; + ulong length = (ulong)fi.BodyLength; + + DeleteEntity(fi.Uri); + + cacheSize -= length; + } + catch + {} + finally + { + ++idx; + } + } + } + } + } + finally + { + SaveLibrary(); + InMaintainenceThread = false; + } + } + #if !NETFX_CORE + )); + #else + ); + #endif + } + + public static int GetCacheEntityCount() + { + if (!HTTPCacheService.IsSupported) + return 0; + + CheckSetup(); + + lock(Library) + return Library.Count; + } + + public static ulong GetCacheSize() + { + ulong size = 0; + + if (!IsSupported) + return size; + + CheckSetup(); + + lock (Library) + foreach (var kvp in Library) + if (kvp.Value.BodyLength > 0) + size += (ulong)kvp.Value.BodyLength; + return size; + } + + #endregion + + #region Cache Library Management + + private static void LoadLibrary() + { + // Already loaded? + if (library != null) + return; + + if (!IsSupported) + return; + + library = new Dictionary(new UriComparer()); + + if (!File.Exists(LibraryPath)) + { + DeleteUnusedFiles(); + return; + } + + try + { + int version; + + lock (library) + { + using (var fs = new FileStream(LibraryPath, FileMode.Open)) + using (var br = new System.IO.BinaryReader(fs)) + { + version = br.ReadInt32(); + + if (version > 1) + NextNameIDX = br.ReadUInt64(); + + int statCount = br.ReadInt32(); + + for (int i = 0; i < statCount; ++i) + { + Uri uri = new Uri(br.ReadString()); + + var entity = new HTTPCacheFileInfo(uri, br, version); + if (entity.IsExists()) + { + library.Add(uri, entity); + + if (version > 1) + UsedIndexes.Add(entity.MappedNameIDX, entity); + } + } + } + } + + if (version == 1) + BeginClear(); + else + DeleteUnusedFiles(); + } + catch + {} + } + + internal static void SaveLibrary() + { + if (library == null) + return; + + if (!IsSupported) + return; + + try + { + lock (Library) + { + using (var fs = new FileStream(LibraryPath, FileMode.Create)) + using (var bw = new System.IO.BinaryWriter(fs)) + { + bw.Write(LibraryVersion); + bw.Write(NextNameIDX); + + bw.Write(Library.Count); + foreach (var kvp in Library) + { + bw.Write(kvp.Key.ToString()); + + kvp.Value.SaveTo(bw); + } + } + } + } + catch + {} + } + + + internal static void SetBodyLength(Uri uri, int bodyLength) + { + if (!IsSupported) + return; + + lock (Library) + { + HTTPCacheFileInfo fileInfo; + if (Library.TryGetValue(uri, out fileInfo)) + fileInfo.BodyLength = bodyLength; + else + { + Library.Add(uri, fileInfo = new HTTPCacheFileInfo(uri, DateTime.UtcNow, bodyLength)); + UsedIndexes.Add(fileInfo.MappedNameIDX, fileInfo); + } + } + } + + /// + /// Deletes all files from the cache folder that isn't in the Library. + /// + private static void DeleteUnusedFiles() + { + if (!IsSupported) + return; + + CheckSetup(); + + // GetFiles will return a string array that contains the files in the folder with the full path + string[] cacheEntries = Directory.GetFiles(CacheFolder); + + for (int i = 0; i < cacheEntries.Length; ++i) + { + // We need a try-catch block because between the Directory.GetFiles call and the File.Delete calls a maintenance job, or other file operations can delete any file from the cache folder. + // So while there might be some problem with any file, we don't want to abort the whole for loop + try + { + string filename = System.IO.Path.GetFileName(cacheEntries[i]); + UInt64 idx = 0; + bool deleteFile = false; + if (UInt64.TryParse(filename, System.Globalization.NumberStyles.AllowHexSpecifier, null, out idx)) + lock (Library) + deleteFile = !UsedIndexes.ContainsKey(idx); + else + deleteFile = true; + + if (deleteFile) + File.Delete(cacheEntries[i]); + } + catch + {} + } + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs.meta new file mode 100644 index 0000000..fa7c39f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Caching/HTTPCacheService.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d29e8551599393f4193bc4daa6968607 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections.meta b/Assets/Best HTTP (Pro)/BestHTTP/Connections.meta new file mode 100644 index 0000000..edb913f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 65fae491919869042be9bb2f969bf050 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs new file mode 100644 index 0000000..57317c5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs @@ -0,0 +1,220 @@ +using System; +using System.Threading; + +#if NETFX_CORE + using System.Threading.Tasks; + + //Disable CD4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. + #pragma warning disable 4014 + + //Disable warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + #pragma warning disable 1998 +#endif + +namespace BestHTTP +{ + internal delegate void HTTPConnectionRecycledDelegate(ConnectionBase conn); + + internal abstract class ConnectionBase : IDisposable + { + #region Public Properties + + /// + /// The address of the server that this connection is bound to. + /// + public string ServerAddress { get; protected set; } + + /// + /// The state of this connection. + /// + public HTTPConnectionStates State { get; protected set; } + + /// + /// It's true if this connection is available to process a HTTPRequest. + /// + public bool IsFree { get { return State == HTTPConnectionStates.Initial || State == HTTPConnectionStates.Free; } } + + /// + /// Returns true if it's an active connection. + /// + public bool IsActive { get { return State > HTTPConnectionStates.Initial && State < HTTPConnectionStates.Free; } } + + /// + /// If the State is HTTPConnectionStates.Processing, then it holds a HTTPRequest instance. Otherwise it's null. + /// + public HTTPRequest CurrentRequest { get; protected set; } + + public virtual bool IsRemovable { get { return IsFree && (DateTime.UtcNow - LastProcessTime) > HTTPManager.MaxConnectionIdleTime; } } + + /// + /// When we start to process the current request. It's set after the connection is established. + /// + public DateTime StartTime { get; protected set; } + + /// + /// When this connection timed out. + /// + public DateTime TimedOutStart { get; protected set; } + +#if !BESTHTTP_DISABLE_PROXY + protected HTTPProxy Proxy { get; set; } + public bool HasProxy { get { return Proxy != null; } } +#endif + + public Uri LastProcessedUri { get; protected set; } + + #endregion + + #region Protected Fields + + protected DateTime LastProcessTime; + protected HTTPConnectionRecycledDelegate OnConnectionRecycled = null; + + #endregion + + #region Privates + + private bool IsThreaded; + + #endregion + + public ConnectionBase(string serverAddress) + :this(serverAddress, true) + {} + + public ConnectionBase(string serverAddress, bool threaded) + { + this.ServerAddress = serverAddress; + this.State = HTTPConnectionStates.Initial; + this.LastProcessTime = DateTime.UtcNow; + this.IsThreaded = threaded; + } + + internal abstract void Abort(HTTPConnectionStates hTTPConnectionStates); + + internal void Process(HTTPRequest request) + { + if (State == HTTPConnectionStates.Processing) + throw new Exception("Connection already processing a request!"); + + StartTime = DateTime.MaxValue; + State = HTTPConnectionStates.Processing; + + CurrentRequest = request; + + if (IsThreaded) + { +#if NETFX_CORE +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(ThreadFunc); +#pragma warning restore 4014 +#else + ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc)); + //new Thread(ThreadFunc) + // .Start(); +#endif + } + else + ThreadFunc(null); + } + + protected virtual +#if NETFX_CORE + async +#endif + void ThreadFunc(object param) + { + + } + + internal void HandleProgressCallback() + { + if (CurrentRequest.OnProgress != null && CurrentRequest.DownloadProgressChanged) + { + try + { + CurrentRequest.OnProgress(CurrentRequest, CurrentRequest.Downloaded, CurrentRequest.DownloadLength); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("ConnectionBase", "HandleProgressCallback - OnProgress", ex); + } + + CurrentRequest.DownloadProgressChanged = false; + } + + if (CurrentRequest.OnUploadProgress != null && CurrentRequest.UploadProgressChanged) + { + try + { + CurrentRequest.OnUploadProgress(CurrentRequest, CurrentRequest.Uploaded, CurrentRequest.UploadLength); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("ConnectionBase", "HandleProgressCallback - OnUploadProgress", ex); + } + CurrentRequest.UploadProgressChanged = false; + } + } + + internal void HandleCallback() + { + try + { + HandleProgressCallback(); + + if (State == HTTPConnectionStates.Upgraded) + { + if (CurrentRequest != null && CurrentRequest.Response != null && CurrentRequest.Response.IsUpgraded) + CurrentRequest.UpgradeCallback(); + State = HTTPConnectionStates.WaitForProtocolShutdown; + } + else + CurrentRequest.CallCallback(); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("ConnectionBase", "HandleCallback", ex); + } + } + + internal void Recycle(HTTPConnectionRecycledDelegate onConnectionRecycled) + { + OnConnectionRecycled = onConnectionRecycled; + if (!(State > HTTPConnectionStates.Initial && State < HTTPConnectionStates.WaitForProtocolShutdown) || State == HTTPConnectionStates.Redirected) + RecycleNow(); + } + + protected void RecycleNow() + { + if (State == HTTPConnectionStates.TimedOut || + State == HTTPConnectionStates.Closed) + LastProcessTime = DateTime.MinValue; + + State = HTTPConnectionStates.Free; + CurrentRequest = null; + + if (OnConnectionRecycled != null) + { + OnConnectionRecycled(this); + OnConnectionRecycled = null; + } + } + + #region Dispose Pattern + + protected bool IsDisposed { get; private set; } + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + IsDisposed = true; + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs.meta new file mode 100644 index 0000000..695ea4d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections/ConnectionBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f59e4337e77f0be4d8f6649beaca8362 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs b/Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs new file mode 100644 index 0000000..76654bc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs @@ -0,0 +1,311 @@ +using System; +using System.Collections.Generic; + +#if NETFX_CORE + using FileStream = BestHTTP.PlatformSupport.IO.FileStream; + using FileMode = BestHTTP.PlatformSupport.IO.FileMode; + using FileAccess = BestHTTP.PlatformSupport.IO.FileAccess; + + using Directory = BestHTTP.PlatformSupport.IO.Directory; + using File = BestHTTP.PlatformSupport.IO.File; +#else +using FileStream = System.IO.FileStream; + using FileMode = System.IO.FileMode; + using FileAccess = System.IO.FileAccess; +#endif + +using BestHTTP.Extensions; + +namespace BestHTTP +{ + public sealed class StreamList : System.IO.Stream + { + private System.IO.Stream[] Streams; + private int CurrentIdx; + + public StreamList(params System.IO.Stream[] streams) + { + this.Streams = streams; + this.CurrentIdx = 0; + } + + public override bool CanRead + { + get { + if (CurrentIdx >= Streams.Length) + return false; + return Streams[CurrentIdx].CanRead; + } + } + + public override bool CanSeek { get { return false; } } + + public override bool CanWrite + { + get { + if (CurrentIdx >= Streams.Length) + return false; + return Streams[CurrentIdx].CanWrite; + } + } + + public override void Flush() + { + if (CurrentIdx >= Streams.Length) + return; + + // We have to call the flush to all previous streams, as we may advanced the CurrentIdx + for (int i = 0; i <= CurrentIdx; ++i) + Streams[i].Flush(); + } + + public override long Length + { + get { + if (CurrentIdx >= Streams.Length) + return 0; + + long length = 0; + for (int i = 0; i < Streams.Length; ++i) + length += Streams[i].Length; + + return length; + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (CurrentIdx >= Streams.Length) + return -1; + + int readCount = Streams[CurrentIdx].Read(buffer, offset, count); + + while (readCount < count && CurrentIdx++ < Streams.Length) + { + readCount += Streams[CurrentIdx].Read(buffer, offset + readCount, count - readCount); + } + + return readCount; + } + + public override void Write(byte[] buffer, int offset, int count) + { + if (CurrentIdx >= Streams.Length) + return; + + Streams[CurrentIdx].Write(buffer, offset, count); + } + + public void Write(string str) + { + byte[] bytes = str.GetASCIIBytes(); + + this.Write(bytes, 0, bytes.Length); + } + + protected override void Dispose(bool disposing) + { + for (int i = 0; i < Streams.Length; ++i) + { + try + { + Streams[i].Dispose(); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("StreamList", "Dispose", ex); + } + } + } + + public override long Position + { + get + { + throw new NotImplementedException("Position get"); + } + set + { + throw new NotImplementedException("Position set"); + } + } + + public override long Seek(long offset, System.IO.SeekOrigin origin) + { + if (CurrentIdx >= Streams.Length) + return 0; + + return Streams[CurrentIdx].Seek(offset, origin); + } + + public override void SetLength(long value) + { + throw new NotImplementedException("SetLength"); + } + } + + /*public static class AndroidFileHelper + { + // AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + // AndroidJavaObject jo = jc.GetStatic("currentActivity"); + + public static Stream GetAPKFileStream(string path) + { + UnityEngine.AndroidJavaClass up = new UnityEngine.AndroidJavaClass("com.unity3d.player.UnityPlayer"); + UnityEngine.AndroidJavaObject cActivity = up.GetStatic("currentActivity"); + + UnityEngine.AndroidJavaObject assetManager = cActivity.GetStatic("getAssets"); + + return new AndroidInputStream(assetManager.Call("open", path)); + } + } + + public sealed class AndroidInputStream : Stream + { + private UnityEngine.AndroidJavaObject baseStream; + + public override bool CanRead + { + get { throw new NotImplementedException(); } + } + + public override bool CanSeek + { + get { throw new NotImplementedException(); } + } + + public override bool CanWrite + { + get { throw new NotImplementedException(); } + } + + public override void Flush() + { + throw new NotImplementedException(); + } + + public override long Length + { + get { throw new NotImplementedException(); } + } + + public override long Position + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + + public AndroidInputStream(UnityEngine.AndroidJavaObject inputStream) + { + this.baseStream = inputStream; + } + + public override int Read(byte[] buffer, int offset, int count) + { + return this.baseStream.Call("read", buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + }*/ + + internal sealed class FileConnection : ConnectionBase + { + public FileConnection(string serverAddress) + :base(serverAddress) + { } + + internal override void Abort(HTTPConnectionStates newState) + { + State = newState; + + switch (State) + { + case HTTPConnectionStates.TimedOut: TimedOutStart = DateTime.UtcNow; break; + } + + throw new NotImplementedException(); + } + + protected override void ThreadFunc(object param) + { + try + { + // Step 1 : create a stream with header information + // Step 2 : create a stream from the file + // Step 3 : create a StreamList + // Step 4 : create a HTTPResponse object + // Step 5 : call the Receive function of the response object + + using (FileStream fs = new FileStream(this.CurrentRequest.CurrentUri.LocalPath, FileMode.Open, FileAccess.Read)) + //using (Stream fs = AndroidFileHelper.GetAPKFileStream(this.CurrentRequest.CurrentUri.LocalPath)) + using (StreamList stream = new StreamList(new System.IO.MemoryStream(), fs)) + { + // This will write to the MemoryStream + stream.Write("HTTP/1.1 200 Ok\r\n"); + stream.Write("Content-Type: application/octet-stream\r\n"); + stream.Write("Content-Length: " + fs.Length.ToString() + "\r\n"); + stream.Write("\r\n"); + + stream.Seek(0, System.IO.SeekOrigin.Begin); + + base.CurrentRequest.Response = new HTTPResponse(base.CurrentRequest, stream, base.CurrentRequest.UseStreaming, false); + + if (!CurrentRequest.Response.Receive()) + CurrentRequest.Response = null; + } + } + catch(Exception ex) + { + if (CurrentRequest != null) + { + // Something gone bad, Response must be null! + CurrentRequest.Response = null; + + switch (State) + { + case HTTPConnectionStates.AbortRequested: + CurrentRequest.State = HTTPRequestStates.Aborted; + break; + case HTTPConnectionStates.TimedOut: + CurrentRequest.State = HTTPRequestStates.TimedOut; + break; + default: + CurrentRequest.Exception = ex; + CurrentRequest.State = HTTPRequestStates.Error; + break; + } + } + } + finally + { + State = HTTPConnectionStates.Closed; + if (CurrentRequest.State == HTTPRequestStates.Processing) + { + if (CurrentRequest.Response != null) + CurrentRequest.State = HTTPRequestStates.Finished; + else + CurrentRequest.State = HTTPRequestStates.Error; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs.meta new file mode 100644 index 0000000..8d899f8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections/FileConnection.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 24106f78264881a419f83ef4b760ded7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs b/Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs new file mode 100644 index 0000000..92fe6f5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs @@ -0,0 +1,395 @@ +#if UNITY_WEBGL && !UNITY_EDITOR + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; + +using BestHTTP.Authentication; + +namespace BestHTTP +{ + delegate void OnWebGLRequestHandlerDelegate(int nativeId, int httpStatus, IntPtr pBuffer, int length, int zero); + delegate void OnWebGLBufferDelegate(int nativeId, IntPtr pBuffer, int length); + delegate void OnWebGLProgressDelegate(int nativeId, int downloaded, int total); + delegate void OnWebGLErrorDelegate(int nativeId, string error); + delegate void OnWebGLTimeoutDelegate(int nativeId); + delegate void OnWebGLAbortedDelegate(int nativeId); + + internal sealed class WebGLConnection : ConnectionBase + { + static Dictionary Connections = new Dictionary(4); + + int NativeId; + MemoryStream Stream; + + public WebGLConnection(string serverAddress) + : base(serverAddress, false) + { + XHR_SetLoglevel((byte)HTTPManager.Logger.Level); + } + + internal override void Abort(HTTPConnectionStates newState) + { + State = newState; + + switch (State) + { + case HTTPConnectionStates.TimedOut: TimedOutStart = DateTime.UtcNow; break; + } + + XHR_Abort(this.NativeId); + } + + protected override void ThreadFunc(object param /*null*/) + { + // XmlHttpRequest setup + + this.NativeId = XHR_Create(HTTPRequest.MethodNames[(byte)CurrentRequest.MethodType], + CurrentRequest.CurrentUri.OriginalString, + CurrentRequest.Credentials != null ? CurrentRequest.Credentials.UserName : null, + CurrentRequest.Credentials != null ? CurrentRequest.Credentials.Password : null); + Connections.Add(NativeId, this); + + CurrentRequest.EnumerateHeaders((header, values) => + { + if (header != "Content-Length") + for (int i = 0; i < values.Count; ++i) + XHR_SetRequestHeader(NativeId, header, values[i]); + }, /*callBeforeSendCallback:*/ true); + + byte[] body = CurrentRequest.GetEntityBody(); + + XHR_SetResponseHandler(NativeId, WebGLConnection.OnResponse, WebGLConnection.OnError, WebGLConnection.OnTimeout, WebGLConnection.OnAborted); + XHR_SetProgressHandler(NativeId, WebGLConnection.OnDownloadProgress, WebGLConnection.OnUploadProgress); + + XHR_SetTimeout(NativeId, (uint)(CurrentRequest.ConnectTimeout.TotalMilliseconds + CurrentRequest.Timeout.TotalMilliseconds)); + + XHR_Send(NativeId, body, body != null ? body.Length : 0); + } + + #region Callback Implementations + + void OnResponse(int httpStatus, byte[] buffer) + { + try + { + using (MemoryStream ms = new MemoryStream()) + { + Stream = ms; + + XHR_GetStatusLine(NativeId, OnBufferCallback); + XHR_GetResponseHeaders(NativeId, OnBufferCallback); + + if (buffer != null && buffer.Length > 0) + ms.Write(buffer, 0, buffer.Length); + + ms.Seek(0L, SeekOrigin.Begin); + + SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler; + CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, ms, CurrentRequest.UseStreaming, false); + + CurrentRequest.Response.Receive(buffer != null && buffer.Length > 0 ? (int)buffer.Length : -1, true); + } + } + catch (Exception e) + { + HTTPManager.Logger.Exception(this.NativeId + " WebGLConnection", "OnResponse", e); + + if (CurrentRequest != null) + { + // Something gone bad, Response must be null! + CurrentRequest.Response = null; + + switch (State) + { + case HTTPConnectionStates.AbortRequested: + CurrentRequest.State = HTTPRequestStates.Aborted; + break; + case HTTPConnectionStates.TimedOut: + CurrentRequest.State = HTTPRequestStates.TimedOut; + break; + default: + CurrentRequest.Exception = e; + CurrentRequest.State = HTTPRequestStates.Error; + break; + } + } + } + finally + { + Connections.Remove(NativeId); + + Stream = null; + + if (CurrentRequest != null) + lock (HTTPManager.Locker) + { + State = HTTPConnectionStates.Closed; + if (CurrentRequest.State == HTTPRequestStates.Processing) + { + if (CurrentRequest.Response != null) + CurrentRequest.State = HTTPRequestStates.Finished; + else + CurrentRequest.State = HTTPRequestStates.Error; + } + } + + LastProcessTime = DateTime.UtcNow; + + if (OnConnectionRecycled != null) + RecycleNow(); + + XHR_Release(NativeId); + } + } + + void OnBuffer(byte[] buffer) + { + if (Stream != null) + { + Stream.Write(buffer, 0, buffer.Length); + Stream.Write(new byte[2] { HTTPResponse.CR, HTTPResponse.LF }, 0, 2); + } + } + + void OnDownloadProgress(int down, int total) + { + CurrentRequest.Downloaded = down; + CurrentRequest.DownloadLength = total; + CurrentRequest.DownloadProgressChanged = true; + } + + void OnUploadProgress(int up, int total) + { + CurrentRequest.Uploaded = up; + CurrentRequest.UploadLength = total; + CurrentRequest.UploadProgressChanged = true; + } + + void OnError(string error) + { + HTTPManager.Logger.Information(this.NativeId + " WebGLConnection - OnError", error); + + Connections.Remove(NativeId); + + Stream = null; + + if (CurrentRequest != null) + lock (HTTPManager.Locker) + { + State = HTTPConnectionStates.Closed; + CurrentRequest.State = HTTPRequestStates.Error; + CurrentRequest.Exception = new Exception(error); + } + + LastProcessTime = DateTime.UtcNow; + + if (OnConnectionRecycled != null) + RecycleNow(); + + XHR_Release(NativeId); + } + + void OnTimeout() + { + HTTPManager.Logger.Information(this.NativeId + " WebGLConnection - OnResponse", string.Empty); + + Connections.Remove(NativeId); + + Stream = null; + + if (CurrentRequest != null) + lock (HTTPManager.Locker) + { + State = HTTPConnectionStates.Closed; + CurrentRequest.State = HTTPRequestStates.TimedOut; + } + + LastProcessTime = DateTime.UtcNow; + + if (OnConnectionRecycled != null) + RecycleNow(); + + XHR_Release(NativeId); + } + + void OnAborted() + { + HTTPManager.Logger.Information(this.NativeId + " WebGLConnection - OnAborted", string.Empty); + + Connections.Remove(NativeId); + + Stream = null; + + if (CurrentRequest != null) + lock (HTTPManager.Locker) + { + State = HTTPConnectionStates.Closed; + CurrentRequest.State = HTTPRequestStates.Aborted; + } + + LastProcessTime = DateTime.UtcNow; + + if (OnConnectionRecycled != null) + RecycleNow(); + + XHR_Release(NativeId); + } + + #endregion + + #region WebGL Static Callbacks + + [AOT.MonoPInvokeCallback(typeof(OnWebGLRequestHandlerDelegate))] + static void OnResponse(int nativeId, int httpStatus, IntPtr pBuffer, int length, int err) + { + HTTPManager.Logger.Information("WebGLConnection - OnResponse", string.Format("{0} {1} {2} {3}", nativeId, httpStatus, length, err)); + + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnResponse", "No WebGL connection found for nativeId: " + nativeId.ToString()); + return; + } + + byte[] buffer = new byte[length]; + + // Copy data from the 'unmanaged' memory to managed memory. Buffer will be reclaimed by the GC. + Marshal.Copy(pBuffer, buffer, 0, length); + + conn.OnResponse(httpStatus, buffer); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLBufferDelegate))] + static void OnBufferCallback(int nativeId, IntPtr pBuffer, int length) + { + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnBufferCallback", "No WebGL connection found for nativeId: " + nativeId.ToString()); + return; + } + + byte[] buffer = new byte[length]; + + // Copy data from the 'unmanaged' memory to managed memory. Buffer will be reclaimed by the GC. + Marshal.Copy(pBuffer, buffer, 0, length); + + conn.OnBuffer(buffer); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLProgressDelegate))] + static void OnDownloadProgress(int nativeId, int downloaded, int total) + { + HTTPManager.Logger.Information(nativeId + " OnDownloadProgress", downloaded.ToString() + " / " + total.ToString()); + + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnDownloadProgress", "No WebGL connection found for nativeId: " + nativeId.ToString()); + return; + } + + conn.OnDownloadProgress(downloaded, total); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLProgressDelegate))] + static void OnUploadProgress(int nativeId, int uploaded, int total) + { + HTTPManager.Logger.Information(nativeId + " OnUploadProgress", uploaded.ToString() + " / " + total.ToString()); + + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnUploadProgress", "No WebGL connection found for nativeId: " + nativeId.ToString()); + return; + } + + conn.OnUploadProgress(uploaded, total); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLErrorDelegate))] + static void OnError(int nativeId, string error) + { + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnError", "No WebGL connection found for nativeId: " + nativeId.ToString() + " Error: " + error); + return; + } + + conn.OnError(error); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLTimeoutDelegate))] + static void OnTimeout(int nativeId) + { + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnTimeout", "No WebGL connection found for nativeId: " + nativeId.ToString()); + return; + } + + conn.OnTimeout(); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLAbortedDelegate))] + static void OnAborted(int nativeId) + { + WebGLConnection conn = null; + if (!Connections.TryGetValue(nativeId, out conn)) + { + HTTPManager.Logger.Error("WebGLConnection - OnAborted", "No WebGL connection found for nativeId: " + nativeId.ToString()); + return; + } + + conn.OnAborted(); + } + + #endregion + + #region WebGL Interface + + [DllImport("__Internal")] + private static extern int XHR_Create(string method, string url, string userName, string passwd); + + /// + /// Is an unsigned long representing the number of milliseconds a request can take before automatically being terminated. A value of 0 (which is the default) means there is no timeout. + /// + [DllImport("__Internal")] + private static extern void XHR_SetTimeout(int nativeId, uint timeout); + + [DllImport("__Internal")] + private static extern void XHR_SetRequestHeader(int nativeId, string header, string value); + + [DllImport("__Internal")] + private static extern void XHR_SetResponseHandler(int nativeId, OnWebGLRequestHandlerDelegate onresponse, OnWebGLErrorDelegate onerror, OnWebGLTimeoutDelegate ontimeout, OnWebGLAbortedDelegate onabort); + + [DllImport("__Internal")] + private static extern void XHR_SetProgressHandler(int nativeId, OnWebGLProgressDelegate onDownloadProgress, OnWebGLProgressDelegate onUploadProgress); + + [DllImport("__Internal")] + private static extern void XHR_Send(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] body, int length); + + [DllImport("__Internal")] + private static extern void XHR_GetResponseHeaders(int nativeId, OnWebGLBufferDelegate callback); + + [DllImport("__Internal")] + private static extern void XHR_GetStatusLine(int nativeId, OnWebGLBufferDelegate callback); + + [DllImport("__Internal")] + private static extern void XHR_Abort(int nativeId); + + [DllImport("__Internal")] + private static extern void XHR_Release(int nativeId); + + [DllImport("__Internal")] + private static extern void XHR_SetLoglevel(int logLevel); + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs.meta new file mode 100644 index 0000000..a8744f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Connections/WebGLConnection.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cca5a5d266418134dbb9c0b87c68e62a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Cookies.meta b/Assets/Best HTTP (Pro)/BestHTTP/Cookies.meta new file mode 100644 index 0000000..3767b0f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Cookies.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e138652289c643d4ca6bff547a5bd4f0 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs new file mode 100644 index 0000000..ef18180 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs @@ -0,0 +1,358 @@ +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections.Generic; +using BestHTTP.Extensions; +using System.IO; + +namespace BestHTTP.Cookies +{ + /// + /// The Cookie implementation based on RFC 6265(http://tools.ietf.org/html/rfc6265). + /// + public sealed class Cookie : IComparable, IEquatable + { + private const int Version = 1; + + #region Public Properties + + /// + /// The name of the cookie. + /// + public string Name { get; private set; } + + /// + /// The value of the cookie. + /// + public string Value { get; private set; } + + /// + /// The Date when the Cookie is registered. + /// + public DateTime Date { get; internal set; } + + /// + /// When this Cookie last used in a request. + /// + public DateTime LastAccess { get; set; } + + /// + /// The Expires attribute indicates the maximum lifetime of the cookie, represented as the date and time at which the cookie expires. + /// The user agent is not required to retain the cookie until the specified date has passed. + /// In fact, user agents often evict cookies due to memory pressure or privacy concerns. + /// + public DateTime Expires { get; private set; } + + /// + /// The Max-Age attribute indicates the maximum lifetime of the cookie, represented as the number of seconds until the cookie expires. + /// The user agent is not required to retain the cookie for the specified duration. + /// In fact, user agents often evict cookies due to memory pressure or privacy concerns. + /// + public long MaxAge { get; private set; } + + /// + /// If a cookie has neither the Max-Age nor the Expires attribute, the user agent will retain the cookie until "the current session is over". + /// + public bool IsSession { get; private set; } + + /// + /// The Domain attribute specifies those hosts to which the cookie will be sent. + /// For example, if the value of the Domain attribute is "example.com", the user agent will include the cookie + /// in the Cookie header when making HTTP requests to example.com, www.example.com, and www.corp.example.com. + /// If the server omits the Domain attribute, the user agent will return the cookie only to the origin server. + /// + public string Domain { get; private set; } + + /// + /// The scope of each cookie is limited to a set of paths, controlled by the Path attribute. + /// If the server omits the Path attribute, the user agent will use the "directory" of the request-uri's path component as the default value. + /// + public string Path { get; private set; } + + /// + /// The Secure attribute limits the scope of the cookie to "secure" channels (where "secure" is defined by the user agent). + /// When a cookie has the Secure attribute, the user agent will include the cookie in an HTTP request only if the request is + /// transmitted over a secure channel (typically HTTP over Transport Layer Security (TLS)). + /// + public bool IsSecure { get; private set; } + + /// + /// The HttpOnly attribute limits the scope of the cookie to HTTP requests. + /// In particular, the attribute instructs the user agent to omit the cookie when providing access to + /// cookies via "non-HTTP" APIs (such as a web browser API that exposes cookies to scripts). + /// + public bool IsHttpOnly { get; private set; } + + #endregion + + #region Public Constructors + + public Cookie(string name, string value) + :this(name, value, "/", string.Empty) + {} + + public Cookie(string name, string value, string path) + : this(name, value, path, string.Empty) + {} + + public Cookie(string name, string value, string path, string domain) + :this() // call the parameter-less constructor to set default values + { + this.Name = name; + this.Value = value; + this.Path = path; + this.Domain = domain; + } + + public Cookie(Uri uri, string name, string value, DateTime expires, bool isSession = true) + :this(name, value, uri.AbsolutePath, uri.Host) + { + this.Expires = expires; + this.IsSession = isSession; + this.Date = DateTime.UtcNow; + } + + public Cookie(Uri uri, string name, string value, long maxAge = -1, bool isSession = true) + :this(name, value, uri.AbsolutePath, uri.Host) + { + this.MaxAge = maxAge; + this.IsSession = isSession; + this.Date = DateTime.UtcNow; + } + + #endregion + + internal Cookie() + { + // If a cookie has neither the Max-Age nor the Expires attribute, the user agent will retain the cookie + // until "the current session is over" (as defined by the user agent). + IsSession = true; + MaxAge = -1; + LastAccess = DateTime.UtcNow; + } + + public bool WillExpireInTheFuture() + { + // No Expires or Max-Age value sent from the server, we will fake the return value so we will not delete the newly came Cookie + if (IsSession) + return true; + + // If a cookie has both the Max-Age and the Expires attribute, the Max-Age attribute has precedence and controls the expiration date of the cookie. + return MaxAge != -1 ? + Math.Max(0, (long)(DateTime.UtcNow - Date).TotalSeconds) < MaxAge : + Expires > DateTime.UtcNow; + } + + /// + /// Guess the storage size of the cookie. + /// + /// + public uint GuessSize() + { + return (uint)((Name != null ? Name.Length * sizeof(char) : 0) + + (Value != null ? Value.Length * sizeof(char) : 0) + + (Domain != null ? Domain.Length * sizeof(char) : 0) + + (Path != null ? Path.Length * sizeof(char) : 0) + + (sizeof(long) * 4) + + (sizeof(bool) * 3)); + } + + public static Cookie Parse(string header, Uri defaultDomain) + { + Cookie cookie = new Cookie(); + try + { + var kvps = ParseCookieHeader(header); + + foreach (var kvp in kvps) + { + switch (kvp.Key.ToLowerInvariant()) + { + case "path": + // If the attribute-value is empty or if the first character of the attribute-value is not %x2F ("/"): + // Let cookie-path be the default-path. + cookie.Path = string.IsNullOrEmpty(kvp.Value) || !kvp.Value.StartsWith("/") ? "/" : cookie.Path = kvp.Value; + break; + + case "domain": + // If the attribute-value is empty, the behavior is undefined. However, the user agent SHOULD ignore the cookie-av entirely. + if (string.IsNullOrEmpty(kvp.Value)) + return null; + + // If the first character of the attribute-value string is %x2E ("."): + // Let cookie-domain be the attribute-value without the leading %x2E (".") character. + cookie.Domain = kvp.Value.StartsWith(".") ? kvp.Value.Substring(1) : kvp.Value; + break; + + case "expires": + cookie.Expires = kvp.Value.ToDateTime(DateTime.FromBinary(0)); + cookie.IsSession = false; + break; + + case "max-age": + cookie.MaxAge = kvp.Value.ToInt64(-1); + cookie.IsSession = false; + break; + + case "secure": + cookie.IsSecure = true; + break; + + case "httponly": + cookie.IsHttpOnly = true; + break; + + default: + cookie.Name = kvp.Key; + cookie.Value = kvp.Value; + break; + } + } + + // Some user agents provide users the option of preventing persistent storage of cookies across sessions. + // When configured thusly, user agents MUST treat all received cookies as if the persistent-flag were set to false. + if (HTTPManager.EnablePrivateBrowsing) + cookie.IsSession = true; + + // http://tools.ietf.org/html/rfc6265#section-4.1.2.3 + // WARNING: Some existing user agents treat an absent Domain attribute as if the Domain attribute were present and contained the current host name. + // For example, if example.com returns a Set-Cookie header without a Domain attribute, these user agents will erroneously send the cookie to www.example.com as well. + if (string.IsNullOrEmpty(cookie.Domain)) + cookie.Domain = defaultDomain.Host; + + // http://tools.ietf.org/html/rfc6265#section-5.3 section 7: + // If the cookie-attribute-list contains an attribute with an attribute-name of "Path", + // set the cookie's path to attribute-value of the last attribute in the cookie-attribute-list with an attribute-name of "Path". + // __Otherwise, set the cookie's path to the default-path of the request-uri.__ + if (string.IsNullOrEmpty(cookie.Path)) + cookie.Path = defaultDomain.AbsolutePath; + + cookie.Date = cookie.LastAccess = DateTime.UtcNow; + } + catch + { + } + return cookie; + } + + #region Save & Load + + internal void SaveTo(BinaryWriter stream) + { + stream.Write(Version); + stream.Write(Name ?? string.Empty); + stream.Write(Value ?? string.Empty); + stream.Write(Date.ToBinary()); + stream.Write(LastAccess.ToBinary()); + stream.Write(Expires.ToBinary()); + stream.Write(MaxAge); + stream.Write(IsSession); + stream.Write(Domain ?? string.Empty); + stream.Write(Path ?? string.Empty); + stream.Write(IsSecure); + stream.Write(IsHttpOnly); + } + + internal void LoadFrom(BinaryReader stream) + { + /*int version = */stream.ReadInt32(); + this.Name = stream.ReadString(); + this.Value = stream.ReadString(); + this.Date = DateTime.FromBinary(stream.ReadInt64()); + this.LastAccess = DateTime.FromBinary(stream.ReadInt64()); + this.Expires = DateTime.FromBinary(stream.ReadInt64()); + this.MaxAge = stream.ReadInt64(); + this.IsSession = stream.ReadBoolean(); + this.Domain = stream.ReadString(); + this.Path = stream.ReadString(); + this.IsSecure = stream.ReadBoolean(); + this.IsHttpOnly = stream.ReadBoolean(); + } + + #endregion + + #region Overrides and new Equals function + + public override string ToString() + { + return string.Concat(this.Name, "=", this.Value); + } + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + return this.Equals(obj as Cookie); + } + + public bool Equals(Cookie cookie) + { + if (cookie == null) + return false; + + if (Object.ReferenceEquals(this, cookie)) + return true; + + return this.Name.Equals(cookie.Name, StringComparison.Ordinal) && + ((this.Domain == null && cookie.Domain == null) || this.Domain.Equals(cookie.Domain, StringComparison.Ordinal)) && + ((this.Path == null && cookie.Path == null) || this.Path.Equals(cookie.Path, StringComparison.Ordinal)); + } + + public override int GetHashCode() + { + return this.ToString().GetHashCode(); + } + + #endregion + + #region Private Helper Functions + + private static string ReadValue(string str, ref int pos) + { + string result = string.Empty; + if (str == null) + return result; + + return str.Read(ref pos, ';'); + } + + private static List ParseCookieHeader(string str) + { + List result = new List(); + + if (str == null) + return result; + + int idx = 0; + + // process the rest of the text + while (idx < str.Length) + { + // Read key + string key = str.Read(ref idx, (ch) => ch != '=' && ch != ';').Trim(); + HeaderValue qp = new HeaderValue(key); + + if (idx < str.Length && str[idx - 1] == '=') + qp.Value = ReadValue(str, ref idx); + + result.Add(qp); + } + + return result; + } + + #endregion + + #region IComparable implementation + + public int CompareTo(Cookie other) + { + return this.LastAccess.CompareTo(other.LastAccess); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs.meta new file mode 100644 index 0000000..cee7bf1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/Cookie.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3c89f8c2ca77c56448d03216927e0546 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs new file mode 100644 index 0000000..7b92938 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs @@ -0,0 +1,491 @@ +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +#if NETFX_CORE +using FileStream = BestHTTP.PlatformSupport.IO.FileStream; +using Directory = BestHTTP.PlatformSupport.IO.Directory; +using File = BestHTTP.PlatformSupport.IO.File; + +using BestHTTP.PlatformSupport.IO; +#else +using FileStream = System.IO.FileStream; +using Directory = System.IO.Directory; + +using System.IO; +#endif + +namespace BestHTTP.Cookies +{ + /// + /// The Cookie Jar implementation based on RFC 6265(http://tools.ietf.org/html/rfc6265). + /// + public static class CookieJar + { + // Version of the cookie store. It may be used in a future version for maintaining compatibility. + private const int Version = 1; + + /// + /// Returns true if File apis are supported. + /// + public static bool IsSavingSupported + { + get + { + if (IsSupportCheckDone) + return _isSavingSupported; + + try + { + File.Exists(HTTPManager.GetRootCacheFolder()); + _isSavingSupported = true; + } + catch + { + _isSavingSupported = false; + + HTTPManager.Logger.Warning("CookieJar", "Cookie saving and loading disabled!"); + } + finally + { + IsSupportCheckDone = true; + } + + return _isSavingSupported; + } + } + + /// + /// The plugin will delete cookies that are accessed this threshold ago. Its default value is 7 days. + /// + public static TimeSpan AccessThreshold = TimeSpan.FromDays(7); + + #region Privates + + /// + /// List of the Cookies + /// + private static List Cookies = new List(); + private static string CookieFolder { get; set; } + private static string LibraryPath { get; set; } + + /// + /// Synchronization object for thread safety. + /// + private static object Locker = new object(); + + private static bool _isSavingSupported; + private static bool IsSupportCheckDone; + + private static bool Loaded; + #endregion + + #region Internal Functions + + internal static void SetupFolder() + { + if (!CookieJar.IsSavingSupported) + return; + + try + { + if (string.IsNullOrEmpty(CookieFolder) || string.IsNullOrEmpty(LibraryPath)) + { + CookieFolder = System.IO.Path.Combine(HTTPManager.GetRootCacheFolder(), "Cookies"); + LibraryPath = System.IO.Path.Combine(CookieFolder, "Library"); + } + } + catch + { } + } + + /// + /// Will set or update all cookies from the response object. + /// + internal static void Set(HTTPResponse response) + { + if (response == null) + return; + + lock(Locker) + { + try + { + Maintain(); + + List newCookies = new List(); + var setCookieHeaders = response.GetHeaderValues("set-cookie"); + + // No cookies. :'( + if (setCookieHeaders == null) + return; + + foreach (var cookieHeader in setCookieHeaders) + { + try + { + Cookie cookie = Cookie.Parse(cookieHeader, response.baseRequest.CurrentUri); + + if (cookie != null) + { + int idx; + var old = Find(cookie, out idx); + + // if no value for the cookie or already expired then the server asked us to delete the cookie + bool expired = string.IsNullOrEmpty(cookie.Value) || !cookie.WillExpireInTheFuture(); + + if (!expired) + { + // no old cookie, add it straight to the list + if (old == null) + { + Cookies.Add(cookie); + + newCookies.Add(cookie); + } + else + { + // Update the creation-time of the newly created cookie to match the creation-time of the old-cookie. + cookie.Date = old.Date; + Cookies[idx] = cookie; + + newCookies.Add(cookie); + } + } + else if (idx != -1) // delete the cookie + Cookies.RemoveAt(idx); + } + } + catch + { + // Ignore cookie on error + } + } + + response.Cookies = newCookies; + } + catch + {} + } + } + + /// + /// Deletes all expired or 'old' cookies, and will keep the sum size of cookies under the given size. + /// + internal static void Maintain() + { + // It's not the same as in the rfc: + // http://tools.ietf.org/html/rfc6265#section-5.3 + + lock (Locker) + { + try + { + uint size = 0; + + for (int i = 0; i < Cookies.Count; ) + { + var cookie = Cookies[i]; + + // Remove expired or not used cookies + if (!cookie.WillExpireInTheFuture() || (cookie.LastAccess + AccessThreshold) < DateTime.UtcNow) + Cookies.RemoveAt(i); + else + { + if (!cookie.IsSession) + size += cookie.GuessSize(); + i++; + } + } + + if (size > HTTPManager.CookieJarSize) + { + Cookies.Sort(); + + while (size > HTTPManager.CookieJarSize && Cookies.Count > 0) + { + var cookie = Cookies[0]; + Cookies.RemoveAt(0); + + size -= cookie.GuessSize(); + } + } + } + catch + { } + } + } + + /// + /// Saves the Cookie Jar to a file. + /// + /// Not implemented under Unity WebPlayer + internal static void Persist() + { + if (!IsSavingSupported) + return; + + lock (Locker) + { + if (!Loaded) + return; + + try + { + // Delete any expired cookie + Maintain(); + + if (!Directory.Exists(CookieFolder)) + Directory.CreateDirectory(CookieFolder); + + using (var fs = new FileStream(LibraryPath, FileMode.Create)) + using (var bw = new System.IO.BinaryWriter(fs)) + { + bw.Write(Version); + + // Count how many non-session cookies we have + int count = 0; + foreach (var cookie in Cookies) + if (!cookie.IsSession) + count++; + + bw.Write(count); + + // Save only the persistable cookies + foreach (var cookie in Cookies) + if (!cookie.IsSession) + cookie.SaveTo(bw); + } + } + catch + { } + } + } + + /// + /// Load previously persisted cookie library from the file. + /// + internal static void Load() + { + if (!IsSavingSupported) + return; + + lock (Locker) + { + if (Loaded) + return; + + SetupFolder(); + + try + { + Cookies.Clear(); + + if (!Directory.Exists(CookieFolder)) + Directory.CreateDirectory(CookieFolder); + + if (!File.Exists(LibraryPath)) + return; + + using (var fs = new FileStream(LibraryPath, FileMode.Open)) + using (var br = new System.IO.BinaryReader(fs)) + { + /*int version = */br.ReadInt32(); + int cookieCount = br.ReadInt32(); + + for (int i = 0; i < cookieCount; ++i) + { + Cookie cookie = new Cookie(); + cookie.LoadFrom(br); + + if (cookie.WillExpireInTheFuture()) + Cookies.Add(cookie); + } + } + } + catch + { + Cookies.Clear(); + } + finally + { + Loaded = true; + } + } + } + + #endregion + + #region Public Functions + + /// + /// Returns all Cookies that corresponds to the given Uri. + /// + public static List Get(Uri uri) + { + lock (Locker) + { + Load(); + + List result = null; + + for (int i = 0; i < Cookies.Count; ++i) + { + Cookie cookie = Cookies[i]; + if (cookie.WillExpireInTheFuture() && uri.Host.IndexOf(cookie.Domain) != -1 && uri.AbsolutePath.StartsWith(cookie.Path)) + { + if (result == null) + result = new List(); + + result.Add(cookie); + } + } + + return result; + } + } + + /// + /// Will add a new, or overwrite an old cookie if already exists. + /// + public static void Set(Uri uri, Cookie cookie) + { + Set(cookie); + } + + /// + /// Will add a new, or overwrite an old cookie if already exists. + /// + public static void Set(Cookie cookie) + { + lock (Locker) + { + Load(); + + int idx; + Find(cookie, out idx); + + if (idx >= 0) + Cookies[idx] = cookie; + else + Cookies.Add(cookie); + } + } + + public static List GetAll() + { + lock (Locker) + { + Load(); + + return Cookies; + } + } + + /// + /// Deletes all cookies from the Jar. + /// + public static void Clear() + { + lock (Locker) + { + Load(); + + Cookies.Clear(); + } + } + + /// + /// Removes cookies that older than the given parameter. + /// + public static void Clear(TimeSpan olderThan) + { + lock (Locker) + { + Load(); + + for (int i = 0; i < Cookies.Count; ) + { + var cookie = Cookies[i]; + + // Remove expired or not used cookies + if (!cookie.WillExpireInTheFuture() || (cookie.Date + olderThan) < DateTime.UtcNow) + Cookies.RemoveAt(i); + else + i++; + } + } + } + + /// + /// Removes cookies that matches to the given domain. + /// + public static void Clear(string domain) + { + lock (Locker) + { + Load(); + + for (int i = 0; i < Cookies.Count; ) + { + var cookie = Cookies[i]; + + // Remove expired or not used cookies + if (!cookie.WillExpireInTheFuture() || cookie.Domain.IndexOf(domain) != -1) + Cookies.RemoveAt(i); + else + i++; + } + } + } + + public static void Remove(Uri uri, string name) + { + lock(Locker) + { + Load(); + + for (int i = 0; i < Cookies.Count; ) + { + var cookie = Cookies[i]; + + if (cookie.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && uri.Host.IndexOf(cookie.Domain) != -1) + Cookies.RemoveAt(i); + else + i++; + } + } + } + + #endregion + + #region Private Helper Functions + + /// + /// Find and return a Cookie and his index in the list. + /// + private static Cookie Find(Cookie cookie, out int idx) + { + for (int i = 0; i < Cookies.Count; ++i) + { + Cookie c = Cookies[i]; + + if (c.Equals(cookie)) + { + idx = i; + return c; + } + } + + idx = -1; + return null; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs.meta new file mode 100644 index 0000000..83631dc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Cookies/CookieJar.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b6b22cd983735ee46908eac3f37eb798 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression.meta new file mode 100644 index 0000000..14dbc3b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4d4075eb3d5bdee4c9f373d710808d60 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs new file mode 100644 index 0000000..a7065d7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs @@ -0,0 +1,473 @@ +// CRC32.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2011 Dino Chiesa. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// Last Saved: <2011-August-02 18:25:54> +// +// ------------------------------------------------------------------ +// +// This module defines the CRC32 class, which can do the CRC32 algorithm, using +// arbitrary starting polynomials, and bit reversal. The bit reversal is what +// distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP +// files, or GZIP files. This class does both. +// +// ------------------------------------------------------------------ + + +using System; +using Interop = System.Runtime.InteropServices; + +namespace BestHTTP.Decompression.Crc +{ + /// + /// Computes a CRC-32. The CRC-32 algorithm is parameterized - you + /// can set the polynomial and enable or disable bit + /// reversal. This can be used for GZIP, BZip2, or ZIP. + /// + /// + /// This type is used internally by DotNetZip; it is generally not used + /// directly by applications wishing to create, read, or manipulate zip + /// archive files. + /// + + internal class CRC32 + { + /// + /// Indicates the total number of bytes applied to the CRC. + /// + public Int64 TotalBytesRead + { + get + { + return _TotalBytesRead; + } + } + + /// + /// Indicates the current CRC for all blocks slurped in. + /// + public Int32 Crc32Result + { + get + { + return unchecked((Int32)(~_register)); + } + } + + /// + /// Returns the CRC32 for the specified stream. + /// + /// The stream over which to calculate the CRC32 + /// the CRC32 calculation + public Int32 GetCrc32(System.IO.Stream input) + { + return GetCrc32AndCopy(input, null); + } + + /// + /// Returns the CRC32 for the specified stream, and writes the input into the + /// output stream. + /// + /// The stream over which to calculate the CRC32 + /// The stream into which to deflate the input + /// the CRC32 calculation + public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output) + { + if (input == null) + throw new Exception("The input stream must not be null."); + + unchecked + { + byte[] buffer = new byte[BUFFER_SIZE]; + int readSize = BUFFER_SIZE; + + _TotalBytesRead = 0; + int count = input.Read(buffer, 0, readSize); + if (output != null) output.Write(buffer, 0, count); + _TotalBytesRead += count; + while (count > 0) + { + SlurpBlock(buffer, 0, count); + count = input.Read(buffer, 0, readSize); + if (output != null) output.Write(buffer, 0, count); + _TotalBytesRead += count; + } + + return (Int32)(~_register); + } + } + + + /// + /// Get the CRC32 for the given (word,byte) combo. This is a + /// computation defined by PKzip for PKZIP 2.0 (weak) encryption. + /// + /// The word to start with. + /// The byte to combine it with. + /// The CRC-ized result. + public Int32 ComputeCrc32(Int32 W, byte B) + { + return _InternalComputeCrc32((UInt32)W, B); + } + + internal Int32 _InternalComputeCrc32(UInt32 W, byte B) + { + return (Int32)(crc32Table[(W ^ B) & 0xFF] ^ (W >> 8)); + } + + + /// + /// Update the value for the running CRC32 using the given block of bytes. + /// This is useful when using the CRC32() class in a Stream. + /// + /// block of bytes to slurp + /// starting point in the block + /// how many bytes within the block to slurp + public void SlurpBlock(byte[] block, int offset, int count) + { + if (block == null) + throw new Exception("The data buffer must not be null."); + + // bzip algorithm + for (int i = 0; i < count; i++) + { + int x = offset + i; + byte b = block[x]; + if (this.reverseBits) + { + UInt32 temp = (_register >> 24) ^ b; + _register = (_register << 8) ^ crc32Table[temp]; + } + else + { + UInt32 temp = (_register & 0x000000FF) ^ b; + _register = (_register >> 8) ^ crc32Table[temp]; + } + } + _TotalBytesRead += count; + } + + + /// + /// Process one byte in the CRC. + /// + /// the byte to include into the CRC . + public void UpdateCRC(byte b) + { + if (this.reverseBits) + { + UInt32 temp = (_register >> 24) ^ b; + _register = (_register << 8) ^ crc32Table[temp]; + } + else + { + UInt32 temp = (_register & 0x000000FF) ^ b; + _register = (_register >> 8) ^ crc32Table[temp]; + } + } + + /// + /// Process a run of N identical bytes into the CRC. + /// + /// + /// + /// This method serves as an optimization for updating the CRC when a + /// run of identical bytes is found. Rather than passing in a buffer of + /// length n, containing all identical bytes b, this method accepts the + /// byte value and the length of the (virtual) buffer - the length of + /// the run. + /// + /// + /// the byte to include into the CRC. + /// the number of times that byte should be repeated. + public void UpdateCRC(byte b, int n) + { + while (n-- > 0) + { + if (this.reverseBits) + { + uint temp = (_register >> 24) ^ b; + _register = (_register << 8) ^ crc32Table[(temp >= 0) + ? temp + : (temp + 256)]; + } + else + { + UInt32 temp = (_register & 0x000000FF) ^ b; + _register = (_register >> 8) ^ crc32Table[(temp >= 0) + ? temp + : (temp + 256)]; + + } + } + } + + + + private static uint ReverseBits(uint data) + { + unchecked + { + uint ret = data; + ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555; + ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333; + ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F; + ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24); + return ret; + } + } + + private static byte ReverseBits(byte data) + { + unchecked + { + uint u = (uint)data * 0x00020202; + uint m = 0x01044010; + uint s = u & m; + uint t = (u << 2) & (m << 1); + return (byte)((0x01001001 * (s + t)) >> 24); + } + } + + + + private void GenerateLookupTable() + { + crc32Table = new UInt32[256]; + unchecked + { + UInt32 dwCrc; + byte i = 0; + do + { + dwCrc = i; + for (byte j = 8; j > 0; j--) + { + if ((dwCrc & 1) == 1) + { + dwCrc = (dwCrc >> 1) ^ dwPolynomial; + } + else + { + dwCrc >>= 1; + } + } + if (reverseBits) + { + crc32Table[ReverseBits(i)] = ReverseBits(dwCrc); + } + else + { + crc32Table[i] = dwCrc; + } + i++; + } while (i!=0); + } + +#if VERBOSE + Console.WriteLine(); + Console.WriteLine("private static readonly UInt32[] crc32Table = {"); + for (int i = 0; i < crc32Table.Length; i+=4) + { + Console.Write(" "); + for (int j=0; j < 4; j++) + { + Console.Write(" 0x{0:X8}U,", crc32Table[i+j]); + } + Console.WriteLine(); + } + Console.WriteLine("};"); + Console.WriteLine(); +#endif + } + + + private uint gf2_matrix_times(uint[] matrix, uint vec) + { + uint sum = 0; + int i=0; + while (vec != 0) + { + if ((vec & 0x01)== 0x01) + sum ^= matrix[i]; + vec >>= 1; + i++; + } + return sum; + } + + private void gf2_matrix_square(uint[] square, uint[] mat) + { + for (int i = 0; i < 32; i++) + square[i] = gf2_matrix_times(mat, mat[i]); + } + + + + /// + /// Combines the given CRC32 value with the current running total. + /// + /// + /// This is useful when using a divide-and-conquer approach to + /// calculating a CRC. Multiple threads can each calculate a + /// CRC32 on a segment of the data, and then combine the + /// individual CRC32 values at the end. + /// + /// the crc value to be combined with this one + /// the length of data the CRC value was calculated on + public void Combine(int crc, int length) + { + uint[] even = new uint[32]; // even-power-of-two zeros operator + uint[] odd = new uint[32]; // odd-power-of-two zeros operator + + if (length == 0) + return; + + uint crc1= ~_register; + uint crc2= (uint) crc; + + // put operator for one zero bit in odd + odd[0] = this.dwPolynomial; // the CRC-32 polynomial + uint row = 1; + for (int i = 1; i < 32; i++) + { + odd[i] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + uint len2 = (uint) length; + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + + if ((len2 & 1)== 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)==1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + + } while (len2 != 0); + + crc1 ^= crc2; + + _register= ~crc1; + + //return (int) crc1; + return; + } + + + /// + /// Create an instance of the CRC32 class using the default settings: no + /// bit reversal, and a polynomial of 0xEDB88320. + /// + public CRC32() : this(false) + { + } + + /// + /// Create an instance of the CRC32 class, specifying whether to reverse + /// data bits or not. + /// + /// + /// specify true if the instance should reverse data bits. + /// + /// + /// + /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you + /// want a CRC32 with compatibility with BZip2, you should pass true + /// here. In the CRC-32 used by GZIP and PKZIP, the bits are not + /// reversed; Therefore if you want a CRC32 with compatibility with + /// those, you should pass false. + /// + /// + public CRC32(bool reverseBits) : + this( unchecked((int)0xEDB88320), reverseBits) + { + } + + + /// + /// Create an instance of the CRC32 class, specifying the polynomial and + /// whether to reverse data bits or not. + /// + /// + /// The polynomial to use for the CRC, expressed in the reversed (LSB) + /// format: the highest ordered bit in the polynomial value is the + /// coefficient of the 0th power; the second-highest order bit is the + /// coefficient of the 1 power, and so on. Expressed this way, the + /// polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320. + /// + /// + /// specify true if the instance should reverse data bits. + /// + /// + /// + /// + /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you + /// want a CRC32 with compatibility with BZip2, you should pass true + /// here for the reverseBits parameter. In the CRC-32 used by + /// GZIP and PKZIP, the bits are not reversed; Therefore if you want a + /// CRC32 with compatibility with those, you should pass false for the + /// reverseBits parameter. + /// + /// + public CRC32(int polynomial, bool reverseBits) + { + this.reverseBits = reverseBits; + this.dwPolynomial = (uint) polynomial; + this.GenerateLookupTable(); + } + + /// + /// Reset the CRC-32 class - clear the CRC "remainder register." + /// + /// + /// + /// Use this when employing a single instance of this class to compute + /// multiple, distinct CRCs on multiple, distinct data blocks. + /// + /// + public void Reset() + { + _register = 0xFFFFFFFFU; + } + + // private member vars + private UInt32 dwPolynomial; + private Int64 _TotalBytesRead; + private bool reverseBits; + private UInt32[] crc32Table; + private const int BUFFER_SIZE = 8192; + private UInt32 _register = 0xFFFFFFFFU; + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs.meta new file mode 100644 index 0000000..3128420 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/CRC32.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 16fc99dd9503b7046bed4bfdbbfec3c0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs new file mode 100644 index 0000000..31b34b1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs @@ -0,0 +1,1881 @@ +// Deflate.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-August-03 19:52:15> +// +// ------------------------------------------------------------------ +// +// This module defines logic for handling the Deflate or compression. +// +// This code is based on multiple sources: +// - the original zlib v1.2.3 source, which is Copyright (C) 1995-2005 Jean-loup Gailly. +// - the original jzlib, which is Copyright (c) 2000-2003 ymnk, JCraft,Inc. +// +// However, this code is significantly different from both. +// The object model is not the same, and many of the behaviors are different. +// +// In keeping with the license for these other works, the copyrights for +// jzlib and zlib are here. +// +// ----------------------------------------------------------------------- +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; + +#pragma warning disable 0675 + +namespace BestHTTP.Decompression.Zlib +{ + + internal enum BlockState + { + NeedMore = 0, // block not completed, need more input or more output + BlockDone, // block flush performed + FinishStarted, // finish started, need only more output at next deflate + FinishDone // finish done, accept no more input or output + } + + internal enum DeflateFlavor + { + Store, + Fast, + Slow + } + + internal sealed class DeflateManager + { + private static readonly int MEM_LEVEL_MAX = 9; + private static readonly int MEM_LEVEL_DEFAULT = 8; + + internal delegate BlockState CompressFunc(FlushType flush); + + internal class Config + { + // Use a faster search when the previous match is longer than this + internal int GoodLength; // reduce lazy search above this match length + + // Attempt to find a better match only when the current match is + // strictly smaller than this value. This mechanism is used only for + // compression levels >= 4. For levels 1,2,3: MaxLazy is actually + // MaxInsertLength. (See DeflateFast) + + internal int MaxLazy; // do not perform lazy search above this match length + + internal int NiceLength; // quit search above this match length + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + + internal int MaxChainLength; + + internal DeflateFlavor Flavor; + + private Config(int goodLength, int maxLazy, int niceLength, int maxChainLength, DeflateFlavor flavor) + { + this.GoodLength = goodLength; + this.MaxLazy = maxLazy; + this.NiceLength = niceLength; + this.MaxChainLength = maxChainLength; + this.Flavor = flavor; + } + + public static Config Lookup(CompressionLevel level) + { + return Table[(int)level]; + } + + + static Config() + { + Table = new Config[] { + new Config(0, 0, 0, 0, DeflateFlavor.Store), + new Config(4, 4, 8, 4, DeflateFlavor.Fast), + new Config(4, 5, 16, 8, DeflateFlavor.Fast), + new Config(4, 6, 32, 32, DeflateFlavor.Fast), + + new Config(4, 4, 16, 16, DeflateFlavor.Slow), + new Config(8, 16, 32, 32, DeflateFlavor.Slow), + new Config(8, 16, 128, 128, DeflateFlavor.Slow), + new Config(8, 32, 128, 256, DeflateFlavor.Slow), + new Config(32, 128, 258, 1024, DeflateFlavor.Slow), + new Config(32, 258, 258, 4096, DeflateFlavor.Slow), + }; + } + + private static readonly Config[] Table; + } + + + private CompressFunc DeflateFunction; + + private static readonly System.String[] _ErrorMessage = new System.String[] + { + "need dictionary", + "stream end", + "", + "file error", + "stream error", + "data error", + "insufficient memory", + "buffer error", + "incompatible version", + "" + }; + + // preset dictionary flag in zlib header + private static readonly int PRESET_DICT = 0x20; + + private static readonly int INIT_STATE = 42; + private static readonly int BUSY_STATE = 113; + private static readonly int FINISH_STATE = 666; + + // The deflate compression method + private static readonly int Z_DEFLATED = 8; + + private static readonly int STORED_BLOCK = 0; + private static readonly int STATIC_TREES = 1; + private static readonly int DYN_TREES = 2; + + // The three kinds of block type + private static readonly int Z_BINARY = 0; + private static readonly int Z_ASCII = 1; + private static readonly int Z_UNKNOWN = 2; + + private static readonly int Buf_size = 8 * 2; + + private static readonly int MIN_MATCH = 3; + private static readonly int MAX_MATCH = 258; + + private static readonly int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + + private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); + + private static readonly int END_BLOCK = 256; + + internal ZlibCodec _codec; // the zlib encoder/decoder + internal int status; // as the name implies + internal byte[] pending; // output still pending - waiting to be compressed + internal int nextPending; // index of next pending byte to output to the stream + internal int pendingCount; // number of bytes in the pending buffer + + internal sbyte data_type; // UNKNOWN, BINARY or ASCII + internal int last_flush; // value of flush param for previous deflate call + + internal int w_size; // LZ77 window size (32K by default) + internal int w_bits; // log2(w_size) (8..16) + internal int w_mask; // w_size - 1 + + //internal byte[] dictionary; + internal byte[] window; + + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. + // + // To do: use the user input buffer as sliding window. + + internal int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + internal short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + internal short[] head; // Heads of the hash chains or NIL. + + internal int ins_h; // hash index of string to be inserted + internal int hash_size; // number of elements in hash table + internal int hash_bits; // log2(hash_size) + internal int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + internal int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + internal int block_start; + + Config config; + internal int match_length; // length of best match + internal int prev_match; // previous match + internal int match_available; // set if previous match exists + internal int strstart; // start of string to insert into.....???? + internal int match_start; // start of matching string + internal int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + internal int prev_length; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + internal CompressionLevel compressionLevel; // compression level (1..9) + internal CompressionStrategy compressionStrategy; // favor or force Huffman coding + + + internal short[] dyn_ltree; // literal and length tree + internal short[] dyn_dtree; // distance tree + internal short[] bl_tree; // Huffman tree for bit lengths + + internal ZTree treeLiterals = new ZTree(); // desc for literal tree + internal ZTree treeDistances = new ZTree(); // desc for distance tree + internal ZTree treeBitLengths = new ZTree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + internal short[] bl_count = new short[InternalConstants.MAX_BITS + 1]; + + // heap used to build the Huffman trees + internal int[] heap = new int[2 * InternalConstants.L_CODES + 1]; + + internal int heap_len; // number of elements in the heap + internal int heap_max; // element of largest frequency + + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + internal sbyte[] depth = new sbyte[2 * InternalConstants.L_CODES + 1]; + + internal int _lengthOffset; // index for literals or lengths + + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + + internal int lit_bufsize; + + internal int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + internal int _distanceOffset; // index into pending; points to distance data?? + + internal int opt_len; // bit length of current block with optimal trees + internal int static_len; // bit length of current block with static trees + internal int matches; // number of string matches in current block + internal int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + internal short bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + internal int bi_valid; + + + internal DeflateManager() + { + dyn_ltree = new short[HEAP_SIZE * 2]; + dyn_dtree = new short[(2 * InternalConstants.D_CODES + 1) * 2]; // distance tree + bl_tree = new short[(2 * InternalConstants.BL_CODES + 1) * 2]; // Huffman tree for bit lengths + } + + + // lm_init + private void _InitializeLazyMatch() + { + window_size = 2 * w_size; + + // clear the hash - workitem 9063 + Array.Clear(head, 0, hash_size); + //for (int i = 0; i < hash_size; i++) head[i] = 0; + + config = Config.Lookup(compressionLevel); + SetDeflater(); + + strstart = 0; + block_start = 0; + lookahead = 0; + match_length = prev_length = MIN_MATCH - 1; + match_available = 0; + ins_h = 0; + } + + // Initialize the tree data structures for a new zlib stream. + private void _InitializeTreeData() + { + treeLiterals.dyn_tree = dyn_ltree; + treeLiterals.staticTree = StaticTree.Literals; + + treeDistances.dyn_tree = dyn_dtree; + treeDistances.staticTree = StaticTree.Distances; + + treeBitLengths.dyn_tree = bl_tree; + treeBitLengths.staticTree = StaticTree.BitLengths; + + bi_buf = 0; + bi_valid = 0; + last_eob_len = 8; // enough lookahead for inflate + + // Initialize the first block of the first file: + _InitializeBlocks(); + } + + internal void _InitializeBlocks() + { + // Initialize the trees. + for (int i = 0; i < InternalConstants.L_CODES; i++) + dyn_ltree[i * 2] = 0; + for (int i = 0; i < InternalConstants.D_CODES; i++) + dyn_dtree[i * 2] = 0; + for (int i = 0; i < InternalConstants.BL_CODES; i++) + bl_tree[i * 2] = 0; + + dyn_ltree[END_BLOCK * 2] = 1; + opt_len = static_len = 0; + last_lit = matches = 0; + } + + // Restore the heap property by moving down the tree starting at node k, + // exchanging a node with the smallest of its two sons if necessary, stopping + // when the heap property is re-established (each father smaller than its + // two sons). + internal void pqdownheap(short[] tree, int k) + { + int v = heap[k]; + int j = k << 1; // left son of k + while (j <= heap_len) + { + // Set j to the smallest of the two sons: + if (j < heap_len && _IsSmaller(tree, heap[j + 1], heap[j], depth)) + { + j++; + } + // Exit if v is smaller than both sons + if (_IsSmaller(tree, v, heap[j], depth)) + break; + + // Exchange v with the smallest son + heap[k] = heap[j]; k = j; + // And continue down the tree, setting j to the left son of k + j <<= 1; + } + heap[k] = v; + } + + internal static bool _IsSmaller(short[] tree, int n, int m, sbyte[] depth) + { + short tn2 = tree[n * 2]; + short tm2 = tree[m * 2]; + return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m])); + } + + + // Scan a literal or distance tree to determine the frequencies of the codes + // in the bit length tree. + internal void scan_tree(short[] tree, int max_code) + { + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = (int)tree[0 * 2 + 1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + tree[(max_code + 1) * 2 + 1] = (short)0x7fff; // guard //?? + + for (n = 0; n <= max_code; n++) + { + curlen = nextlen; nextlen = (int)tree[(n + 1) * 2 + 1]; + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + bl_tree[curlen * 2] = (short)(bl_tree[curlen * 2] + count); + } + else if (curlen != 0) + { + if (curlen != prevlen) + bl_tree[curlen * 2]++; + bl_tree[InternalConstants.REP_3_6 * 2]++; + } + else if (count <= 10) + { + bl_tree[InternalConstants.REPZ_3_10 * 2]++; + } + else + { + bl_tree[InternalConstants.REPZ_11_138 * 2]++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6; min_count = 3; + } + else + { + max_count = 7; min_count = 4; + } + } + } + + // Construct the Huffman tree for the bit lengths and return the index in + // bl_order of the last bit length code to send. + internal int build_bl_tree() + { + int max_blindex; // index of last bit length code of non zero freq + + // Determine the bit length frequencies for literal and distance trees + scan_tree(dyn_ltree, treeLiterals.max_code); + scan_tree(dyn_dtree, treeDistances.max_code); + + // Build the bit length tree: + treeBitLengths.build_tree(this); + // opt_len now includes the length of the tree representations, except + // the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + + // Determine the number of bit length codes to send. The pkzip format + // requires that at least 4 bit length codes be sent. (appnote.txt says + // 3 but the actual value used is 4.) + for (max_blindex = InternalConstants.BL_CODES - 1; max_blindex >= 3; max_blindex--) + { + if (bl_tree[ZTree.bl_order[max_blindex] * 2 + 1] != 0) + break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + internal void send_all_trees(int lcodes, int dcodes, int blcodes) + { + int rank; // index in bl_order + + send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes - 1, 5); + send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) + { + send_bits(bl_tree[ZTree.bl_order[rank] * 2 + 1], 3); + } + send_tree(dyn_ltree, lcodes - 1); // literal tree + send_tree(dyn_dtree, dcodes - 1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + internal void send_tree(short[] tree, int max_code) + { + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0 * 2 + 1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + + for (n = 0; n <= max_code; n++) + { + curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1]; + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + do + { + send_code(curlen, bl_tree); + } + while (--count != 0); + } + else if (curlen != 0) + { + if (curlen != prevlen) + { + send_code(curlen, bl_tree); count--; + } + send_code(InternalConstants.REP_3_6, bl_tree); + send_bits(count - 3, 2); + } + else if (count <= 10) + { + send_code(InternalConstants.REPZ_3_10, bl_tree); + send_bits(count - 3, 3); + } + else + { + send_code(InternalConstants.REPZ_11_138, bl_tree); + send_bits(count - 11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) + { + max_count = 138; min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6; min_count = 3; + } + else + { + max_count = 7; min_count = 4; + } + } + } + + // Output a block of bytes on the stream. + // IN assertion: there is enough room in pending_buf. + private void put_bytes(byte[] p, int start, int len) + { + Array.Copy(p, start, pending, pendingCount, len); + pendingCount += len; + } + +#if NOTNEEDED + private void put_byte(byte c) + { + pending[pendingCount++] = c; + } + internal void put_short(int b) + { + unchecked + { + pending[pendingCount++] = (byte)b; + pending[pendingCount++] = (byte)(b >> 8); + } + } + internal void putShortMSB(int b) + { + unchecked + { + pending[pendingCount++] = (byte)(b >> 8); + pending[pendingCount++] = (byte)b; + } + } +#endif + + internal void send_code(int c, short[] tree) + { + int c2 = c * 2; + send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff)); + } + + internal void send_bits(int value, int length) + { + int len = length; + unchecked + { + if (bi_valid > (int)Buf_size - len) + { + //int val = value; + // bi_buf |= (val << bi_valid); + + bi_buf |= (short)((value << bi_valid) & 0xffff); + //put_short(bi_buf); + pending[pendingCount++] = (byte)bi_buf; + pending[pendingCount++] = (byte)(bi_buf >> 8); + + + bi_buf = (short)((uint)value >> (Buf_size - bi_valid)); + bi_valid += len - Buf_size; + } + else + { + // bi_buf |= (value) << bi_valid; + bi_buf |= (short)((value << bi_valid) & 0xffff); + bi_valid += len; + } + } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + internal void _tr_align() + { + send_bits(STATIC_TREES << 1, 3); + send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) + { + send_bits(STATIC_TREES << 1, 3); + send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + internal bool _tr_tally(int dist, int lc) + { + pending[_distanceOffset + last_lit * 2] = unchecked((byte) ( (uint)dist >> 8 ) ); + pending[_distanceOffset + last_lit * 2 + 1] = unchecked((byte)dist); + pending[_lengthOffset + last_lit] = unchecked((byte)lc); + last_lit++; + + if (dist == 0) + { + // lc is the unmatched char + dyn_ltree[lc * 2]++; + } + else + { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(ZTree.LengthCode[lc] + InternalConstants.LITERALS + 1) * 2]++; + dyn_dtree[ZTree.DistanceCode(dist) * 2]++; + } + + if ((last_lit & 0x1fff) == 0 && (int)compressionLevel > 2) + { + // Compute an upper bound for the compressed length + int out_length = last_lit << 3; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < InternalConstants.D_CODES; dcode++) + { + out_length = (int)(out_length + (int)dyn_dtree[dcode * 2] * (5L + ZTree.ExtraDistanceBits[dcode])); + } + out_length >>= 3; + if ((matches < (last_lit / 2)) && out_length < in_length / 2) + return true; + } + + return (last_lit == lit_bufsize - 1) || (last_lit == lit_bufsize); + // dinoch - wraparound? + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + + + // Send the block data compressed using the given Huffman trees + internal void send_compressed_block(short[] ltree, short[] dtree) + { + int distance; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0) + { + do + { + int ix = _distanceOffset + lx * 2; + distance = ((pending[ix] << 8) & 0xff00) | + (pending[ix + 1] & 0xff); + lc = (pending[_lengthOffset + lx]) & 0xff; + lx++; + + if (distance == 0) + { + send_code(lc, ltree); // send a literal byte + } + else + { + // literal or match pair + // Here, lc is the match length - MIN_MATCH + code = ZTree.LengthCode[lc]; + + // send the length code + send_code(code + InternalConstants.LITERALS + 1, ltree); + extra = ZTree.ExtraLengthBits[code]; + if (extra != 0) + { + // send the extra length bits + lc -= ZTree.LengthBase[code]; + send_bits(lc, extra); + } + distance--; // dist is now the match distance - 1 + code = ZTree.DistanceCode(distance); + + // send the distance code + send_code(code, dtree); + + extra = ZTree.ExtraDistanceBits[code]; + if (extra != 0) + { + // send the extra distance bits + distance -= ZTree.DistanceBase[code]; + send_bits(distance, extra); + } + } + + // Check that the overlay between pending and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK * 2 + 1]; + } + + + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + internal void set_data_type() + { + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while (n < 7) + { + bin_freq += dyn_ltree[n * 2]; n++; + } + while (n < 128) + { + ascii_freq += dyn_ltree[n * 2]; n++; + } + while (n < InternalConstants.LITERALS) + { + bin_freq += dyn_ltree[n * 2]; n++; + } + data_type = (sbyte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); + } + + + + // Flush the bit buffer, keeping at most 7 bits in it. + internal void bi_flush() + { + if (bi_valid == 16) + { + pending[pendingCount++] = (byte)bi_buf; + pending[pendingCount++] = (byte)(bi_buf >> 8); + bi_buf = 0; + bi_valid = 0; + } + else if (bi_valid >= 8) + { + //put_byte((byte)bi_buf); + pending[pendingCount++] = (byte)bi_buf; + bi_buf >>= 8; + bi_valid -= 8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + internal void bi_windup() + { + if (bi_valid > 8) + { + pending[pendingCount++] = (byte)bi_buf; + pending[pendingCount++] = (byte)(bi_buf >> 8); + } + else if (bi_valid > 0) + { + //put_byte((byte)bi_buf); + pending[pendingCount++] = (byte)bi_buf; + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + internal void copy_block(int buf, int len, bool header) + { + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) + unchecked + { + //put_short((short)len); + pending[pendingCount++] = (byte)len; + pending[pendingCount++] = (byte)(len >> 8); + //put_short((short)~len); + pending[pendingCount++] = (byte)~len; + pending[pendingCount++] = (byte)(~len >> 8); + } + + put_bytes(window, buf, len); + } + + internal void flush_block_only(bool eof) + { + _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof); + block_start = strstart; + _codec.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + internal BlockState DeflateNone(FlushType flush) + { + // Stored blocks are limited to 0xffff bytes, pending is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if (max_block_size > pending.Length - 5) + { + max_block_size = pending.Length - 5; + } + + // Copy as much as possible from input to output: + while (true) + { + // Fill the window as much as possible: + if (lookahead <= 1) + { + _fillWindow(); + if (lookahead == 0 && flush == FlushType.None) + return BlockState.NeedMore; + if (lookahead == 0) + break; // flush the current block + } + + strstart += lookahead; + lookahead = 0; + + // Emit a stored block if pending will be full: + max_start = block_start + max_block_size; + if (strstart == 0 || strstart >= max_start) + { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart - max_start); + strstart = (int)max_start; + + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if (strstart - block_start >= w_size - MIN_LOOKAHEAD) + { + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + } + + flush_block_only(flush == FlushType.Finish); + if (_codec.AvailableBytesOut == 0) + return (flush == FlushType.Finish) ? BlockState.FinishStarted : BlockState.NeedMore; + + return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; + } + + + // Send a stored block + internal void _tr_stored_block(int buf, int stored_len, bool eof) + { + send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + internal void _tr_flush_block(int buf, int stored_len, bool eof) + { + int opt_lenb, static_lenb; // opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if (compressionLevel > 0) + { + // Check if the file is ascii or binary + if (data_type == Z_UNKNOWN) + set_data_type(); + + // Construct the literal and distance trees + treeLiterals.build_tree(this); + + treeDistances.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex = build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb = (opt_len + 3 + 7) >> 3; + static_lenb = (static_len + 3 + 7) >> 3; + + if (static_lenb <= opt_lenb) + opt_lenb = static_lenb; + } + else + { + opt_lenb = static_lenb = stored_len + 5; // force a stored block + } + + if (stored_len + 4 <= opt_lenb && buf != -1) + { + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if (static_lenb == opt_lenb) + { + send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3); + send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes); + } + else + { + send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3); + send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, max_blindex + 1); + send_compressed_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + _InitializeBlocks(); + + if (eof) + { + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + private void _fillWindow() + { + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do + { + more = (window_size - lookahead - strstart); + + // Deal with !@#$% 64K limit: + if (more == 0 && strstart == 0 && lookahead == 0) + { + more = w_size; + } + else if (more == -1) + { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) + { + Array.Copy(window, w_size, window, 0, w_size); + match_start -= w_size; + strstart -= w_size; // we now have strstart >= MAX_DIST + block_start -= w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p = n; + do + { + m = (head[--p] & 0xffff); + head[p] = (short)((m >= w_size) ? (m - w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do + { + m = (prev[--p] & 0xffff); + prev[p] = (short)((m >= w_size) ? (m - w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n != 0); + more += w_size; + } + + if (_codec.AvailableBytesIn == 0) + return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = _codec.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if (lookahead >= MIN_MATCH) + { + ins_h = window[strstart] & 0xff; + ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; + } + // If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + // but this is not important since only literal bytes will be emitted. + } + while (lookahead < MIN_LOOKAHEAD && _codec.AvailableBytesIn != 0); + } + + // Compress as much as possible from the input stream, return the current + // block state. + // This function does not perform lazy evaluation of matches and inserts + // new strings in the dictionary only for unmatched strings or for short + // matches. It is used only for the fast compression options. + internal BlockState DeflateFast(FlushType flush) + { + // short hash_head = 0; // head of the hash chain + int hash_head = 0; // head of the hash chain + bool bflush; // set if current block must be flushed + + while (true) + { + // Make sure that we always have enough lookahead, except + // at the end of the input file. We need MAX_MATCH bytes + // for the next match, plus MIN_MATCH bytes to insert the + // string following the next match. + if (lookahead < MIN_LOOKAHEAD) + { + _fillWindow(); + if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None) + { + return BlockState.NeedMore; + } + if (lookahead == 0) + break; // flush the current block + } + + // Insert the string window[strstart .. strstart+2] in the + // dictionary, and set hash_head to the head of the hash chain: + if (lookahead >= MIN_MATCH) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + + // prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + } + + // Find the longest match, discarding those <= prev_length. + // At this point we have always match_length < MIN_MATCH + + if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) + { + // To simplify the code, we prevent matches with the string + // of window index 0 (in particular we have to avoid a match + // of the string with itself at the start of the input file). + if (compressionStrategy != CompressionStrategy.HuffmanOnly) + { + match_length = longest_match(hash_head); + } + // longest_match() sets match_start + } + if (match_length >= MIN_MATCH) + { + // check_match(strstart, match_start, match_length); + + bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH) + { + match_length--; // string at strstart already in hash table + do + { + strstart++; + + ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + // prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + + // strstart never exceeds WSIZE-MAX_MATCH, so there are + // always MIN_MATCH bytes ahead. + } + while (--match_length != 0); + strstart++; + } + else + { + strstart += match_length; + match_length = 0; + ins_h = window[strstart] & 0xff; + + ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; + // If lookahead < MIN_MATCH, ins_h is garbage, but it does not + // matter since it will be recomputed at next deflate call. + } + } + else + { + // No match, output a literal byte + + bflush = _tr_tally(0, window[strstart] & 0xff); + lookahead--; + strstart++; + } + if (bflush) + { + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + } + + flush_block_only(flush == FlushType.Finish); + if (_codec.AvailableBytesOut == 0) + { + if (flush == FlushType.Finish) + return BlockState.FinishStarted; + else + return BlockState.NeedMore; + } + return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; + } + + // Same as above, but achieves better compression. We use a lazy + // evaluation for matches: a match is finally adopted only if there is + // no better match at the next window position. + internal BlockState DeflateSlow(FlushType flush) + { + // short hash_head = 0; // head of hash chain + int hash_head = 0; // head of hash chain + bool bflush; // set if current block must be flushed + + // Process the input block. + while (true) + { + // Make sure that we always have enough lookahead, except + // at the end of the input file. We need MAX_MATCH bytes + // for the next match, plus MIN_MATCH bytes to insert the + // string following the next match. + + if (lookahead < MIN_LOOKAHEAD) + { + _fillWindow(); + if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None) + return BlockState.NeedMore; + + if (lookahead == 0) + break; // flush the current block + } + + // Insert the string window[strstart .. strstart+2] in the + // dictionary, and set hash_head to the head of the hash chain: + + if (lookahead >= MIN_MATCH) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + // prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + } + + // Find the longest match, discarding those <= prev_length. + prev_length = match_length; + prev_match = match_start; + match_length = MIN_MATCH - 1; + + if (hash_head != 0 && prev_length < config.MaxLazy && + ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) + { + // To simplify the code, we prevent matches with the string + // of window index 0 (in particular we have to avoid a match + // of the string with itself at the start of the input file). + + if (compressionStrategy != CompressionStrategy.HuffmanOnly) + { + match_length = longest_match(hash_head); + } + // longest_match() sets match_start + + if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered || + (match_length == MIN_MATCH && strstart - match_start > 4096))) + { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH - 1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if (prev_length >= MIN_MATCH && match_length <= prev_length) + { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= (prev_length - 1); + prev_length -= 2; + do + { + if (++strstart <= max_insert) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + //prev[strstart&w_mask]=hash_head=head[ins_h]; + hash_head = (head[ins_h] & 0xffff); + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = unchecked((short)strstart); + } + } + while (--prev_length != 0); + match_available = 0; + match_length = MIN_MATCH - 1; + strstart++; + + if (bflush) + { + flush_block_only(false); + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + } + else if (match_available != 0) + { + + // If there was no match at the previous position, output a + // single literal. If there was a match but the current match + // is longer, truncate the previous match to a single literal. + + bflush = _tr_tally(0, window[strstart - 1] & 0xff); + + if (bflush) + { + flush_block_only(false); + } + strstart++; + lookahead--; + if (_codec.AvailableBytesOut == 0) + return BlockState.NeedMore; + } + else + { + // There is no previous match to compare with, wait for + // the next step to decide. + + match_available = 1; + strstart++; + lookahead--; + } + } + + if (match_available != 0) + { + bflush = _tr_tally(0, window[strstart - 1] & 0xff); + match_available = 0; + } + flush_block_only(flush == FlushType.Finish); + + if (_codec.AvailableBytesOut == 0) + { + if (flush == FlushType.Finish) + return BlockState.FinishStarted; + else + return BlockState.NeedMore; + } + + return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; + } + + + internal int longest_match(int cur_match) + { + int chain_length = config.MaxChainLength; // max hash chain length + int scan = strstart; // current string + int match; // matched string + int len; // length of current match + int best_len = prev_length; // best match length so far + int limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0; + + int niceLength = config.NiceLength; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan + best_len - 1]; + byte scan_end = window[scan + best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= config.GoodLength) + { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (niceLength > lookahead) + niceLength = lookahead; + + do + { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match + best_len] != scan_end || + window[match + best_len - 1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan + 1]) + continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do + { + } + while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) + { + match_start = cur_match; + best_len = len; + if (len >= niceLength) + break; + scan_end1 = window[scan + best_len - 1]; + scan_end = window[scan + best_len]; + } + } + while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0); + + if (best_len <= lookahead) + return best_len; + return lookahead; + } + + + private bool Rfc1950BytesEmitted = false; + private bool _WantRfc1950HeaderBytes = true; + internal bool WantRfc1950HeaderBytes + { + get { return _WantRfc1950HeaderBytes; } + set { _WantRfc1950HeaderBytes = value; } + } + + + internal int Initialize(ZlibCodec codec, CompressionLevel level) + { + return Initialize(codec, level, ZlibConstants.WindowBitsMax); + } + + internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits) + { + return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, CompressionStrategy.Default); + } + + internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits, CompressionStrategy compressionStrategy) + { + return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, compressionStrategy); + } + + internal int Initialize(ZlibCodec codec, CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy) + { + _codec = codec; + _codec.Message = null; + + // validation + if (windowBits < 9 || windowBits > 15) + throw new ZlibException("windowBits must be in the range 9..15."); + + if (memLevel < 1 || memLevel > MEM_LEVEL_MAX) + throw new ZlibException(String.Format("memLevel must be in the range 1.. {0}", MEM_LEVEL_MAX)); + + _codec.dstate = this; + + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + window = new byte[w_size * 2]; + prev = new short[w_size]; + head = new short[hash_size]; + + // for memLevel==8, this will be 16384, 16k + lit_bufsize = 1 << (memLevel + 6); + + // Use a single array as the buffer for data pending compression, + // the output distance codes, and the output length codes (aka tree). + // orig comment: This works just fine since the average + // output size for (length,distance) codes is <= 24 bits. + pending = new byte[lit_bufsize * 4]; + _distanceOffset = lit_bufsize; + _lengthOffset = (1 + 2) * lit_bufsize; + + // So, for memLevel 8, the length of the pending buffer is 65536. 64k. + // The first 16k are pending bytes. + // The middle slice, of 32k, is used for distance codes. + // The final 16k are length codes. + + this.compressionLevel = level; + this.compressionStrategy = strategy; + + Reset(); + return ZlibConstants.Z_OK; + } + + + internal void Reset() + { + _codec.TotalBytesIn = _codec.TotalBytesOut = 0; + _codec.Message = null; + //strm.data_type = Z_UNKNOWN; + + pendingCount = 0; + nextPending = 0; + + Rfc1950BytesEmitted = false; + + status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE; + _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + + last_flush = (int)FlushType.None; + + _InitializeTreeData(); + _InitializeLazyMatch(); + } + + + internal int End() + { + if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) + { + return ZlibConstants.Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending = null; + head = null; + prev = null; + window = null; + // free + // dstate=null; + return status == BUSY_STATE ? ZlibConstants.Z_DATA_ERROR : ZlibConstants.Z_OK; + } + + + private void SetDeflater() + { + switch (config.Flavor) + { + case DeflateFlavor.Store: + DeflateFunction = DeflateNone; + break; + case DeflateFlavor.Fast: + DeflateFunction = DeflateFast; + break; + case DeflateFlavor.Slow: + DeflateFunction = DeflateSlow; + break; + } + } + + + internal int SetParams(CompressionLevel level, CompressionStrategy strategy) + { + int result = ZlibConstants.Z_OK; + + if (compressionLevel != level) + { + Config newConfig = Config.Lookup(level); + + // change in the deflate flavor (Fast vs slow vs none)? + if (newConfig.Flavor != config.Flavor && _codec.TotalBytesIn != 0) + { + // Flush the last buffer: + result = _codec.Deflate(FlushType.Partial); + } + + compressionLevel = level; + config = newConfig; + SetDeflater(); + } + + // no need to flush with change in strategy? Really? + compressionStrategy = strategy; + + return result; + } + + + internal int SetDictionary(byte[] dictionary) + { + int length = dictionary.Length; + int index = 0; + + if (dictionary == null || status != INIT_STATE) + throw new ZlibException("Stream error."); + + _codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length); + + if (length < MIN_MATCH) + return ZlibConstants.Z_OK; + if (length > w_size - MIN_LOOKAHEAD) + { + length = w_size - MIN_LOOKAHEAD; + index = dictionary.Length - length; // use the tail of the dictionary + } + Array.Copy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0] & 0xff; + ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask; + + for (int n = 0; n <= length - MIN_MATCH; n++) + { + ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; + prev[n & w_mask] = head[ins_h]; + head[ins_h] = (short)n; + } + return ZlibConstants.Z_OK; + } + + + + internal int Deflate(FlushType flush) + { + int old_flush; + + if (_codec.OutputBuffer == null || + (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) || + (status == FINISH_STATE && flush != FlushType.Finish)) + { + _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_STREAM_ERROR)]; + throw new ZlibException(String.Format("Something is fishy. [{0}]", _codec.Message)); + } + if (_codec.AvailableBytesOut == 0) + { + _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; + throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)"); + } + + old_flush = last_flush; + last_flush = (int)flush; + + // Write the zlib (rfc1950) header bytes + if (status == INIT_STATE) + { + int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8; + int level_flags = (((int)compressionLevel - 1) & 0xff) >> 1; + + if (level_flags > 3) + level_flags = 3; + header |= (level_flags << 6); + if (strstart != 0) + header |= PRESET_DICT; + header += 31 - (header % 31); + + status = BUSY_STATE; + //putShortMSB(header); + unchecked + { + pending[pendingCount++] = (byte)(header >> 8); + pending[pendingCount++] = (byte)header; + } + // Save the adler32 of the preset dictionary: + if (strstart != 0) + { + pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); + pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); + } + _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + } + + // Flush as much pending output as possible + if (pendingCount != 0) + { + _codec.flush_pending(); + if (_codec.AvailableBytesOut == 0) + { + //System.out.println(" avail_out==0"); + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return ZlibConstants.Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if (_codec.AvailableBytesIn == 0 && + (int)flush <= old_flush && + flush != FlushType.Finish) + { + // workitem 8557 + // + // Not sure why this needs to be an error. pendingCount == 0, which + // means there's nothing to deflate. And the caller has not asked + // for a FlushType.Finish, but... that seems very non-fatal. We + // can just say "OK" and do nothing. + + // _codec.Message = z_errmsg[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; + // throw new ZlibException("AvailableBytesIn == 0 && flush<=old_flush && flush != FlushType.Finish"); + + return ZlibConstants.Z_OK; + } + + // User must not provide more input after the first FINISH: + if (status == FINISH_STATE && _codec.AvailableBytesIn != 0) + { + _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; + throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0"); + } + + // Start a new block or continue the current one. + if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != FlushType.None && status != FINISH_STATE)) + { + BlockState bstate = DeflateFunction(flush); + + if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone) + { + status = FINISH_STATE; + } + if (bstate == BlockState.NeedMore || bstate == BlockState.FinishStarted) + { + if (_codec.AvailableBytesOut == 0) + { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return ZlibConstants.Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate == BlockState.BlockDone) + { + if (flush == FlushType.Partial) + { + _tr_align(); + } + else + { + // FlushType.Full or FlushType.Sync + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if (flush == FlushType.Full) + { + // clear hash (forget the history) + for (int i = 0; i < hash_size; i++) + head[i] = 0; + } + } + _codec.flush_pending(); + if (_codec.AvailableBytesOut == 0) + { + last_flush = -1; // avoid BUF_ERROR at next call, see above + return ZlibConstants.Z_OK; + } + } + } + + if (flush != FlushType.Finish) + return ZlibConstants.Z_OK; + + if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted) + return ZlibConstants.Z_STREAM_END; + + // Write the zlib trailer (adler32) + pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16); + pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); + pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); + //putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16))); + //putShortMSB((int)(_codec._Adler32 & 0xffff)); + + _codec.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + + Rfc1950BytesEmitted = true; // write the trailer only once! + + return pendingCount != 0 ? ZlibConstants.Z_OK : ZlibConstants.Z_STREAM_END; + } + + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs.meta new file mode 100644 index 0000000..dc34019 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Deflate.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ad45ad0b3a07a2f4181d9f4243b82395 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs new file mode 100644 index 0000000..b0f95a8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs @@ -0,0 +1,804 @@ +// DeflateStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009-2010 Dino Chiesa. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-July-31 14:48:11> +// +// ------------------------------------------------------------------ +// +// This module defines the DeflateStream class, which can be used as a replacement for +// the System.IO.Compression.DeflateStream class in the .NET BCL. +// +// ------------------------------------------------------------------ + + +using System; + +namespace BestHTTP.Decompression.Zlib +{ + /// + /// A class for compressing and decompressing streams using the Deflate algorithm. + /// + /// + /// + /// + /// + /// The DeflateStream is a Decorator on a . It adds DEFLATE compression or decompression to any + /// stream. + /// + /// + /// + /// Using this stream, applications can compress or decompress data via stream + /// Read and Write operations. Either compresssion or decompression + /// can occur through either reading or writing. The compression format used is + /// DEFLATE, which is documented in IETF RFC 1951, "DEFLATE + /// Compressed Data Format Specification version 1.3.". + /// + /// + /// + /// + /// + internal class DeflateStream : System.IO.Stream + { + internal ZlibBaseStream _baseStream; + internal System.IO.Stream _innerStream; + bool _disposed; + + /// + /// Create a DeflateStream using the specified CompressionMode. + /// + /// + /// + /// When mode is CompressionMode.Compress, the DeflateStream will use + /// the default compression level. The "captive" stream will be closed when + /// the DeflateStream is closed. + /// + /// + /// + /// This example uses a DeflateStream to compress data from a file, and writes + /// the compressed data to another file. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".deflated") + /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the DeflateStream will compress or decompress. + public DeflateStream(System.IO.Stream stream, CompressionMode mode) + : this(stream, mode, CompressionLevel.Default, false) + { + } + + /// + /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is + /// ignored. The "captive" stream will be closed when the DeflateStream is + /// closed. + /// + /// + /// + /// + /// + /// + /// This example uses a DeflateStream to compress data from a file, and writes + /// the compressed data to another file. + /// + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (Stream compressor = new DeflateStream(raw, + /// CompressionMode.Compress, + /// CompressionLevel.BestCompression)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n= -1; + /// while (n != 0) + /// { + /// if (n > 0) + /// compressor.Write(buffer, 0, n); + /// n= input.Read(buffer, 0, buffer.Length); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".deflated") + /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream to be read or written while deflating or inflating. + /// Indicates whether the DeflateStream will compress or decompress. + /// A tuning knob to trade speed for effectiveness. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) + : this(stream, mode, level, false) + { + } + + /// + /// Create a DeflateStream using the specified + /// CompressionMode, and explicitly specify whether the + /// stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// memory stream that will be re-read after compression. Specify true for + /// the parameter to leave the stream open. + /// + /// + /// + /// The DeflateStream will use the default compression level. + /// + /// + /// + /// See the other overloads of this constructor for example code. + /// + /// + /// + /// + /// The stream which will be read or written. This is called the + /// "captive" stream in other places in this documentation. + /// + /// + /// + /// Indicates whether the DeflateStream will compress or decompress. + /// + /// + /// true if the application would like the stream to + /// remain open after inflation/deflation. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) + : this(stream, mode, CompressionLevel.Default, leaveOpen) + { + } + + /// + /// Create a DeflateStream using the specified CompressionMode + /// and the specified CompressionLevel, and explicitly specify whether + /// the stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is ignored. + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// that will be re-read after + /// compression. Specify true for the parameter + /// to leave the stream open. + /// + /// + /// + /// + /// + /// + /// This example shows how to use a DeflateStream to compress data from + /// a file, and store the compressed data into another file. + /// + /// + /// using (var output = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n= -1; + /// while (n != 0) + /// { + /// if (n > 0) + /// compressor.Write(buffer, 0, n); + /// n= input.Read(buffer, 0, buffer.Length); + /// } + /// } + /// } + /// // can write additional data to the output stream here + /// } + /// + /// + /// + /// Using output As FileStream = File.Create(fileToCompress & ".deflated") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// ' can write additional data to the output stream here. + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the DeflateStream will compress or decompress. + /// true if the application would like the stream to remain open after inflation/deflation. + /// A tuning knob to trade speed for effectiveness. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) + { + _innerStream = stream; + _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen); + } + + /// + /// Create a DeflateStream using the specified CompressionMode + /// and the specified CompressionLevel, and explicitly specify whether + /// the stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// When mode is CompressionMode.Decompress, the level parameter is ignored. + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// that will be re-read after + /// compression. Specify true for the parameter + /// to leave the stream open. + /// + /// + /// + /// + /// + /// + /// This example shows how to use a DeflateStream to compress data from + /// a file, and store the compressed data into another file. + /// + /// + /// using (var output = System.IO.File.Create(fileToCompress + ".deflated")) + /// { + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n= -1; + /// while (n != 0) + /// { + /// if (n > 0) + /// compressor.Write(buffer, 0, n); + /// n= input.Read(buffer, 0, buffer.Length); + /// } + /// } + /// } + /// // can write additional data to the output stream here + /// } + /// + /// + /// + /// Using output As FileStream = File.Create(fileToCompress & ".deflated") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// ' can write additional data to the output stream here. + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the DeflateStream will compress or decompress. + /// true if the application would like the stream to remain open after inflation/deflation. + /// A tuning knob to trade speed for effectiveness. + /// Desired window bits. + public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen, int windowBits) + { + _innerStream = stream; + _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen, windowBits); + } + + #region Zlib properties + + /// + /// This property sets the flush behavior on the stream. + /// + /// See the ZLIB documentation for the meaning of the flush behavior. + /// + virtual public FlushType FlushMode + { + get { return (this._baseStream._flushMode); } + set + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + this._baseStream._flushMode = value; + } + } + + /// + /// The size of the working buffer for the compression codec. + /// + /// + /// + /// + /// The working buffer is used for all stream operations. The default size is + /// 1024 bytes. The minimum size is 128 bytes. You may get better performance + /// with a larger buffer. Then again, you might not. You would have to test + /// it. + /// + /// + /// + /// Set this before the first call to Read() or Write() on the + /// stream. If you try to set it afterwards, it will throw. + /// + /// + public int BufferSize + { + get + { + return this._baseStream._bufferSize; + } + set + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + if (this._baseStream._workingBuffer != null) + throw new ZlibException("The working buffer is already set."); + if (value < ZlibConstants.WorkingBufferSizeMin) + throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); + this._baseStream._bufferSize = value; + } + } + + /// + /// The ZLIB strategy to be used during compression. + /// + /// + /// + /// By tweaking this parameter, you may be able to optimize the compression for + /// data with particular characteristics. + /// + public CompressionStrategy Strategy + { + get + { + return this._baseStream.Strategy; + } + set + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + this._baseStream.Strategy = value; + } + } + + /// Returns the total number of bytes input so far. + virtual public long TotalIn + { + get + { + return this._baseStream._z.TotalBytesIn; + } + } + + /// Returns the total number of bytes output so far. + virtual public long TotalOut + { + get + { + return this._baseStream._z.TotalBytesOut; + } + } + + #endregion + + #region System.IO.Stream methods + /// + /// Dispose the stream. + /// + /// + /// + /// This may or may not result in a Close() call on the captive + /// stream. See the constructors that have a leaveOpen parameter + /// for more information. + /// + /// + /// Application code won't call this code directly. This method may be + /// invoked in two distinct scenarios. If disposing == true, the method + /// has been called directly or indirectly by a user's code, for example + /// via the public Dispose() method. In this case, both managed and + /// unmanaged resources can be referenced and disposed. If disposing == + /// false, the method has been called by the runtime from inside the + /// object finalizer and this method should not reference other objects; + /// in that case only unmanaged resources must be referenced or + /// disposed. + /// + /// + /// + /// true if the Dispose method was invoked by user code. + /// + protected override void Dispose(bool disposing) + { + try + { + if (!_disposed) + { + if (disposing && (this._baseStream != null)) + this._baseStream.Close(); + _disposed = true; + } + } + finally + { + base.Dispose(disposing); + } + } + + + + /// + /// Indicates whether the stream can be read. + /// + /// + /// The return value depends on whether the captive stream supports reading. + /// + public override bool CanRead + { + get + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + return _baseStream._stream.CanRead; + } + } + + /// + /// Indicates whether the stream supports Seek operations. + /// + /// + /// Always returns false. + /// + public override bool CanSeek + { + get { return false; } + } + + + /// + /// Indicates whether the stream can be written. + /// + /// + /// The return value depends on whether the captive stream supports writing. + /// + public override bool CanWrite + { + get + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + return _baseStream._stream.CanWrite; + } + } + + /// + /// Flush the stream. + /// + public override void Flush() + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + _baseStream.Flush(); + } + + /// + /// Reading this property always throws a . + /// + public override long Length + { + get { throw new NotImplementedException(); } + } + + /// + /// The position of the stream pointer. + /// + /// + /// + /// Setting this property always throws a . Reading will return the total bytes + /// written out, if used in writing, or the total bytes read in, if used in + /// reading. The count may refer to compressed bytes or uncompressed bytes, + /// depending on how you've used the stream. + /// + public override long Position + { + get + { + if (this._baseStream._streamMode == BestHTTP.Decompression.Zlib.ZlibBaseStream.StreamMode.Writer) + return this._baseStream._z.TotalBytesOut; + if (this._baseStream._streamMode == BestHTTP.Decompression.Zlib.ZlibBaseStream.StreamMode.Reader) + return this._baseStream._z.TotalBytesIn; + return 0; + } + set { throw new NotImplementedException(); } + } + + /// + /// Read data from the stream. + /// + /// + /// + /// + /// If you wish to use the DeflateStream to compress data while + /// reading, you can create a DeflateStream with + /// CompressionMode.Compress, providing an uncompressed data stream. + /// Then call Read() on that DeflateStream, and the data read will be + /// compressed as you read. If you wish to use the DeflateStream to + /// decompress data while reading, you can create a DeflateStream with + /// CompressionMode.Decompress, providing a readable compressed data + /// stream. Then call Read() on that DeflateStream, and the data read + /// will be decompressed as you read. + /// + /// + /// + /// A DeflateStream can be used for Read() or Write(), but not both. + /// + /// + /// + /// The buffer into which the read data should be placed. + /// the offset within that data array to put the first byte read. + /// the number of bytes to read. + /// the number of bytes actually read + public override int Read(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + return _baseStream.Read(buffer, offset, count); + } + + + /// + /// Calling this method always throws a . + /// + /// this is irrelevant, since it will always throw! + /// this is irrelevant, since it will always throw! + /// irrelevant! + public override long Seek(long offset, System.IO.SeekOrigin origin) + { + throw new NotImplementedException(); + } + + /// + /// Will call the base stream's SetLength method. + /// + public override void SetLength(long value) + { + _baseStream.SetLength(value); + } + + /// + /// Write data to the stream. + /// + /// + /// + /// + /// If you wish to use the DeflateStream to compress data while + /// writing, you can create a DeflateStream with + /// CompressionMode.Compress, and a writable output stream. Then call + /// Write() on that DeflateStream, providing uncompressed data + /// as input. The data sent to the output stream will be the compressed form + /// of the data written. If you wish to use the DeflateStream to + /// decompress data while writing, you can create a DeflateStream with + /// CompressionMode.Decompress, and a writable output stream. Then + /// call Write() on that stream, providing previously compressed + /// data. The data sent to the output stream will be the decompressed form of + /// the data written. + /// + /// + /// + /// A DeflateStream can be used for Read() or Write(), + /// but not both. + /// + /// + /// + /// + /// The buffer holding data to write to the stream. + /// the offset within that data array to find the first byte to write. + /// the number of bytes to write. + public override void Write(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("DeflateStream"); + _baseStream.Write(buffer, offset, count); + } + #endregion + + + + + /// + /// Compress a string into a byte array using DEFLATE (RFC 1951). + /// + /// + /// + /// Uncompress it with . + /// + /// + /// DeflateStream.UncompressString(byte[]) + /// DeflateStream.CompressBuffer(byte[]) + /// GZipStream.CompressString(string) + /// + /// + /// A string to compress. The string will first be encoded + /// using UTF8, then compressed. + /// + /// + /// The string in compressed form + public static byte[] CompressString(String s) + { + using (var ms = new System.IO.MemoryStream()) + { + System.IO.Stream compressor = + new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); + ZlibBaseStream.CompressString(s, compressor); + return ms.ToArray(); + } + } + + + /// + /// Compress a byte array into a new byte array using DEFLATE. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// DeflateStream.CompressString(string) + /// DeflateStream.UncompressBuffer(byte[]) + /// GZipStream.CompressBuffer(byte[]) + /// + /// + /// A buffer to compress. + /// + /// + /// The data in compressed form + public static byte[] CompressBuffer(byte[] b) + { + using (var ms = new System.IO.MemoryStream()) + { + System.IO.Stream compressor = + new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); + + ZlibBaseStream.CompressBuffer(b, compressor); + return ms.ToArray(); + } + } + + + /// + /// Uncompress a DEFLATE'd byte array into a single string. + /// + /// + /// DeflateStream.CompressString(String) + /// DeflateStream.UncompressBuffer(byte[]) + /// GZipStream.UncompressString(byte[]) + /// + /// + /// A buffer containing DEFLATE-compressed data. + /// + /// + /// The uncompressed string + public static String UncompressString(byte[] compressed) + { + using (var input = new System.IO.MemoryStream(compressed)) + { + System.IO.Stream decompressor = + new DeflateStream(input, CompressionMode.Decompress); + + return ZlibBaseStream.UncompressString(compressed, decompressor); + } + } + + + /// + /// Uncompress a DEFLATE'd byte array into a byte array. + /// + /// + /// DeflateStream.CompressBuffer(byte[]) + /// DeflateStream.UncompressString(byte[]) + /// GZipStream.UncompressBuffer(byte[]) + /// + /// + /// A buffer containing data that has been compressed with DEFLATE. + /// + /// + /// The data in uncompressed form + public static byte[] UncompressBuffer(byte[] compressed) + { + using (var input = new System.IO.MemoryStream(compressed)) + { + System.IO.Stream decompressor = new DeflateStream( input, CompressionMode.Decompress ); + + return ZlibBaseStream.UncompressBuffer(compressed, decompressor); + } + } + + } + +} + diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs.meta new file mode 100644 index 0000000..e4d5ac6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/DeflateStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8b7a3b80f9aa82941a62c619c263ff5e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs new file mode 100644 index 0000000..3b6630d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs @@ -0,0 +1,1023 @@ +// GZipStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-July-11 21:42:34> +// +// ------------------------------------------------------------------ +// +// This module defines the GZipStream class, which can be used as a replacement for +// the System.IO.Compression.GZipStream class in the .NET BCL. NB: The design is not +// completely OO clean: there is some intelligence in the ZlibBaseStream that reads the +// GZip header. +// +// ------------------------------------------------------------------ + + +using System; +using System.IO; + +namespace BestHTTP.Decompression.Zlib +{ + /// + /// A class for compressing and decompressing GZIP streams. + /// + /// + /// + /// + /// The GZipStream is a Decorator on a + /// . It adds GZIP compression or decompression to any + /// stream. + /// + /// + /// + /// Like the System.IO.Compression.GZipStream in the .NET Base Class Library, the + /// Ionic.Zlib.GZipStream can compress while writing, or decompress while + /// reading, but not vice versa. The compression method used is GZIP, which is + /// documented in IETF RFC + /// 1952, "GZIP file format specification version 4.3". + /// + /// + /// A GZipStream can be used to decompress data (through Read()) or + /// to compress data (through Write()), but not both. + /// + /// + /// + /// If you wish to use the GZipStream to compress data, you must wrap it + /// around a write-able stream. As you call Write() on the GZipStream, the + /// data will be compressed into the GZIP format. If you want to decompress data, + /// you must wrap the GZipStream around a readable stream that contains an + /// IETF RFC 1952-compliant stream. The data will be decompressed as you call + /// Read() on the GZipStream. + /// + /// + /// + /// Though the GZIP format allows data from multiple files to be concatenated + /// together, this stream handles only a single segment of GZIP format, typically + /// representing a single file. + /// + /// + /// + /// + /// + internal class GZipStream : System.IO.Stream + { + // GZip format + // source: http://tools.ietf.org/html/rfc1952 + // + // header id: 2 bytes 1F 8B + // compress method 1 byte 8= DEFLATE (none other supported) + // flag 1 byte bitfield (See below) + // mtime 4 bytes time_t (seconds since jan 1, 1970 UTC of the file. + // xflg 1 byte 2 = max compress used , 4 = max speed (can be ignored) + // OS 1 byte OS for originating archive. set to 0xFF in compression. + // extra field length 2 bytes optional - only if FEXTRA is set. + // extra field varies + // filename varies optional - if FNAME is set. zero terminated. ISO-8859-1. + // file comment varies optional - if FCOMMENT is set. zero terminated. ISO-8859-1. + // crc16 1 byte optional - present only if FHCRC bit is set + // compressed data varies + // CRC32 4 bytes + // isize 4 bytes data size modulo 2^32 + // + // FLG (FLaGs) + // bit 0 FTEXT - indicates file is ASCII text (can be safely ignored) + // bit 1 FHCRC - there is a CRC16 for the header immediately following the header + // bit 2 FEXTRA - extra fields are present + // bit 3 FNAME - the zero-terminated filename is present. encoding; ISO-8859-1. + // bit 4 FCOMMENT - a zero-terminated file comment is present. encoding: ISO-8859-1 + // bit 5 reserved + // bit 6 reserved + // bit 7 reserved + // + // On consumption: + // Extra field is a bunch of nonsense and can be safely ignored. + // Header CRC and OS, likewise. + // + // on generation: + // all optional fields get 0, except for the OS, which gets 255. + // + + + + /// + /// The comment on the GZIP stream. + /// + /// + /// + /// + /// The GZIP format allows for each file to optionally have an associated + /// comment stored with the file. The comment is encoded with the ISO-8859-1 + /// code page. To include a comment in a GZIP stream you create, set this + /// property before calling Write() for the first time on the + /// GZipStream. + /// + /// + /// + /// When using GZipStream to decompress, you can retrieve this property + /// after the first call to Read(). If no comment has been set in the + /// GZIP bytestream, the Comment property will return null + /// (Nothing in VB). + /// + /// + public String Comment + { + get + { + return _Comment; + } + set + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + _Comment = value; + } + } + + /// + /// The FileName for the GZIP stream. + /// + /// + /// + /// + /// + /// The GZIP format optionally allows each file to have an associated + /// filename. When compressing data (through Write()), set this + /// FileName before calling Write() the first time on the GZipStream. + /// The actual filename is encoded into the GZIP bytestream with the + /// ISO-8859-1 code page, according to RFC 1952. It is the application's + /// responsibility to insure that the FileName can be encoded and decoded + /// correctly with this code page. + /// + /// + /// + /// When decompressing (through Read()), you can retrieve this value + /// any time after the first Read(). In the case where there was no filename + /// encoded into the GZIP bytestream, the property will return null (Nothing + /// in VB). + /// + /// + public String FileName + { + get { return _FileName; } + set + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + _FileName = value; + if (_FileName == null) return; + if (_FileName.IndexOf("/") != -1) + { + _FileName = _FileName.Replace("/", "\\"); + } + if (_FileName.EndsWith("\\")) + throw new Exception("Illegal filename"); + if (_FileName.IndexOf("\\") != -1) + { + // trim any leading path + _FileName = Path.GetFileName(_FileName); + } + } + } + + /// + /// The last modified time for the GZIP stream. + /// + /// + /// + /// GZIP allows the storage of a last modified time with each GZIP entity. + /// When compressing data, you can set this before the first call to + /// Write(). When decompressing, you can retrieve this value any time + /// after the first call to Read(). + /// + public DateTime? LastModified; + + /// + /// The CRC on the GZIP stream. + /// + /// + /// This is used for internal error checking. You probably don't need to look at this property. + /// + public int Crc32 { get { return _Crc32; } } + + private int _headerByteCount; + internal ZlibBaseStream _baseStream; + bool _disposed; + bool _firstReadDone; + string _FileName; + string _Comment; + int _Crc32; + + + /// + /// Create a GZipStream using the specified CompressionMode. + /// + /// + /// + /// + /// When mode is CompressionMode.Compress, the GZipStream will use the + /// default compression level. + /// + /// + /// + /// As noted in the class documentation, the CompressionMode (Compress + /// or Decompress) also establishes the "direction" of the stream. A + /// GZipStream with CompressionMode.Compress works only through + /// Write(). A GZipStream with + /// CompressionMode.Decompress works only through Read(). + /// + /// + /// + /// + /// + /// This example shows how to use a GZipStream to compress data. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(outputFile)) + /// { + /// using (Stream compressor = new GZipStream(raw, CompressionMode.Compress)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// Dim outputFile As String = (fileToCompress & ".compressed") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(outputFile) + /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// + /// + /// This example shows how to use a GZipStream to uncompress a file. + /// + /// private void GunZipFile(string filename) + /// { + /// if (!filename.EndsWith(".gz)) + /// throw new ArgumentException("filename"); + /// var DecompressedFile = filename.Substring(0,filename.Length-3); + /// byte[] working = new byte[WORKING_BUFFER_SIZE]; + /// int n= 1; + /// using (System.IO.Stream input = System.IO.File.OpenRead(filename)) + /// { + /// using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true)) + /// { + /// using (var output = System.IO.File.Create(DecompressedFile)) + /// { + /// while (n !=0) + /// { + /// n= decompressor.Read(working, 0, working.Length); + /// if (n > 0) + /// { + /// output.Write(working, 0, n); + /// } + /// } + /// } + /// } + /// } + /// } + /// + /// + /// + /// Private Sub GunZipFile(ByVal filename as String) + /// If Not (filename.EndsWith(".gz)) Then + /// Throw New ArgumentException("filename") + /// End If + /// Dim DecompressedFile as String = filename.Substring(0,filename.Length-3) + /// Dim working(WORKING_BUFFER_SIZE) as Byte + /// Dim n As Integer = 1 + /// Using input As Stream = File.OpenRead(filename) + /// Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True) + /// Using output As Stream = File.Create(UncompressedFile) + /// Do + /// n= decompressor.Read(working, 0, working.Length) + /// If n > 0 Then + /// output.Write(working, 0, n) + /// End IF + /// Loop While (n > 0) + /// End Using + /// End Using + /// End Using + /// End Sub + /// + /// + /// + /// The stream which will be read or written. + /// Indicates whether the GZipStream will compress or decompress. + public GZipStream(Stream stream, CompressionMode mode) + : this(stream, mode, CompressionLevel.Default, false) + { + } + + /// + /// Create a GZipStream using the specified CompressionMode and + /// the specified CompressionLevel. + /// + /// + /// + /// + /// The CompressionMode (Compress or Decompress) also establishes the + /// "direction" of the stream. A GZipStream with + /// CompressionMode.Compress works only through Write(). A + /// GZipStream with CompressionMode.Decompress works only + /// through Read(). + /// + /// + /// + /// + /// + /// + /// This example shows how to use a GZipStream to compress a file into a .gz file. + /// + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(fileToCompress + ".gz")) + /// { + /// using (Stream compressor = new GZipStream(raw, + /// CompressionMode.Compress, + /// CompressionLevel.BestCompression)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(fileToCompress & ".gz") + /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream to be read or written while deflating or inflating. + /// Indicates whether the GZipStream will compress or decompress. + /// A tuning knob to trade speed for effectiveness. + public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level) + : this(stream, mode, level, false) + { + } + + /// + /// Create a GZipStream using the specified CompressionMode, and + /// explicitly specify whether the stream should be left open after Deflation + /// or Inflation. + /// + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// memory stream that will be re-read after compressed data has been written + /// to it. Specify true for the parameter to leave + /// the stream open. + /// + /// + /// + /// The (Compress or Decompress) also + /// establishes the "direction" of the stream. A GZipStream with + /// CompressionMode.Compress works only through Write(). A GZipStream + /// with CompressionMode.Decompress works only through Read(). + /// + /// + /// + /// The GZipStream will use the default compression level. If you want + /// to specify the compression level, see . + /// + /// + /// + /// See the other overloads of this constructor for example code. + /// + /// + /// + /// + /// + /// The stream which will be read or written. This is called the "captive" + /// stream in other places in this documentation. + /// + /// + /// Indicates whether the GZipStream will compress or decompress. + /// + /// + /// + /// true if the application would like the base stream to remain open after + /// inflation/deflation. + /// + public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen) + : this(stream, mode, CompressionLevel.Default, leaveOpen) + { + } + + /// + /// Create a GZipStream using the specified CompressionMode and the + /// specified CompressionLevel, and explicitly specify whether the + /// stream should be left open after Deflation or Inflation. + /// + /// + /// + /// + /// + /// This constructor allows the application to request that the captive stream + /// remain open after the deflation or inflation occurs. By default, after + /// Close() is called on the stream, the captive stream is also + /// closed. In some cases this is not desired, for example if the stream is a + /// memory stream that will be re-read after compressed data has been written + /// to it. Specify true for the parameter to + /// leave the stream open. + /// + /// + /// + /// As noted in the class documentation, the CompressionMode (Compress + /// or Decompress) also establishes the "direction" of the stream. A + /// GZipStream with CompressionMode.Compress works only through + /// Write(). A GZipStream with CompressionMode.Decompress works only + /// through Read(). + /// + /// + /// + /// + /// + /// This example shows how to use a GZipStream to compress data. + /// + /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) + /// { + /// using (var raw = System.IO.File.Create(outputFile)) + /// { + /// using (Stream compressor = new GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, true)) + /// { + /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; + /// int n; + /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) + /// { + /// compressor.Write(buffer, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// Dim outputFile As String = (fileToCompress & ".compressed") + /// Using input As Stream = File.OpenRead(fileToCompress) + /// Using raw As FileStream = File.Create(outputFile) + /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, True) + /// Dim buffer As Byte() = New Byte(4096) {} + /// Dim n As Integer = -1 + /// Do While (n <> 0) + /// If (n > 0) Then + /// compressor.Write(buffer, 0, n) + /// End If + /// n = input.Read(buffer, 0, buffer.Length) + /// Loop + /// End Using + /// End Using + /// End Using + /// + /// + /// The stream which will be read or written. + /// Indicates whether the GZipStream will compress or decompress. + /// true if the application would like the stream to remain open after inflation/deflation. + /// A tuning knob to trade speed for effectiveness. + public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) + { + _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen); + } + + #region Zlib properties + + /// + /// This property sets the flush behavior on the stream. + /// + virtual public FlushType FlushMode + { + get { return (this._baseStream._flushMode); } + set { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + this._baseStream._flushMode = value; + } + } + + /// + /// The size of the working buffer for the compression codec. + /// + /// + /// + /// + /// The working buffer is used for all stream operations. The default size is + /// 1024 bytes. The minimum size is 128 bytes. You may get better performance + /// with a larger buffer. Then again, you might not. You would have to test + /// it. + /// + /// + /// + /// Set this before the first call to Read() or Write() on the + /// stream. If you try to set it afterwards, it will throw. + /// + /// + public int BufferSize + { + get + { + return this._baseStream._bufferSize; + } + set + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + if (this._baseStream._workingBuffer != null) + throw new ZlibException("The working buffer is already set."); + if (value < ZlibConstants.WorkingBufferSizeMin) + throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); + this._baseStream._bufferSize = value; + } + } + + + /// Returns the total number of bytes input so far. + virtual public long TotalIn + { + get + { + return this._baseStream._z.TotalBytesIn; + } + } + + /// Returns the total number of bytes output so far. + virtual public long TotalOut + { + get + { + return this._baseStream._z.TotalBytesOut; + } + } + + #endregion + + #region Stream methods + + /// + /// Dispose the stream. + /// + /// + /// + /// This may or may not result in a Close() call on the captive + /// stream. See the constructors that have a leaveOpen parameter + /// for more information. + /// + /// + /// This method may be invoked in two distinct scenarios. If disposing + /// == true, the method has been called directly or indirectly by a + /// user's code, for example via the public Dispose() method. In this + /// case, both managed and unmanaged resources can be referenced and + /// disposed. If disposing == false, the method has been called by the + /// runtime from inside the object finalizer and this method should not + /// reference other objects; in that case only unmanaged resources must + /// be referenced or disposed. + /// + /// + /// + /// indicates whether the Dispose method was invoked by user code. + /// + protected override void Dispose(bool disposing) + { + try + { + if (!_disposed) + { + if (disposing && (this._baseStream != null)) + { + this._baseStream.Close(); + this._Crc32 = _baseStream.Crc32; + } + _disposed = true; + } + } + finally + { + base.Dispose(disposing); + } + } + + + /// + /// Indicates whether the stream can be read. + /// + /// + /// The return value depends on whether the captive stream supports reading. + /// + public override bool CanRead + { + get + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + return _baseStream._stream.CanRead; + } + } + + /// + /// Indicates whether the stream supports Seek operations. + /// + /// + /// Always returns false. + /// + public override bool CanSeek + { + get { return false; } + } + + + /// + /// Indicates whether the stream can be written. + /// + /// + /// The return value depends on whether the captive stream supports writing. + /// + public override bool CanWrite + { + get + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + return _baseStream._stream.CanWrite; + } + } + + /// + /// Flush the stream. + /// + public override void Flush() + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + _baseStream.Flush(); + } + + /// + /// Reading this property always throws a . + /// + public override long Length + { + get { throw new NotImplementedException(); } + } + + /// + /// The position of the stream pointer. + /// + /// + /// + /// Setting this property always throws a . Reading will return the total bytes + /// written out, if used in writing, or the total bytes read in, if used in + /// reading. The count may refer to compressed bytes or uncompressed bytes, + /// depending on how you've used the stream. + /// + public override long Position + { + get + { + if (this._baseStream._streamMode == BestHTTP.Decompression.Zlib.ZlibBaseStream.StreamMode.Writer) + return this._baseStream._z.TotalBytesOut + _headerByteCount; + if (this._baseStream._streamMode == BestHTTP.Decompression.Zlib.ZlibBaseStream.StreamMode.Reader) + return this._baseStream._z.TotalBytesIn + this._baseStream._gzipHeaderByteCount; + return 0; + } + + set { throw new NotImplementedException(); } + } + + /// + /// Read and decompress data from the source stream. + /// + /// + /// + /// With a GZipStream, decompression is done through reading. + /// + /// + /// + /// + /// byte[] working = new byte[WORKING_BUFFER_SIZE]; + /// using (System.IO.Stream input = System.IO.File.OpenRead(_CompressedFile)) + /// { + /// using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true)) + /// { + /// using (var output = System.IO.File.Create(_DecompressedFile)) + /// { + /// int n; + /// while ((n= decompressor.Read(working, 0, working.Length)) !=0) + /// { + /// output.Write(working, 0, n); + /// } + /// } + /// } + /// } + /// + /// + /// The buffer into which the decompressed data should be placed. + /// the offset within that data array to put the first byte read. + /// the number of bytes to read. + /// the number of bytes actually read + public override int Read(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + int n = _baseStream.Read(buffer, offset, count); + + // Console.WriteLine("GZipStream::Read(buffer, off({0}), c({1}) = {2}", offset, count, n); + // Console.WriteLine( Util.FormatByteArray(buffer, offset, n) ); + + if (!_firstReadDone) + { + _firstReadDone = true; + FileName = _baseStream._GzipFileName; + Comment = _baseStream._GzipComment; + } + return n; + } + + + + /// + /// Calling this method always throws a . + /// + /// irrelevant; it will always throw! + /// irrelevant; it will always throw! + /// irrelevant! + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + /// + /// Calling this method always throws a . + /// + /// irrelevant; this method will always throw! + public override void SetLength(long value) + { + //throw new NotImplementedException(); + _baseStream.SetLength(value); + } + + /// + /// Write data to the stream. + /// + /// + /// + /// + /// If you wish to use the GZipStream to compress data while writing, + /// you can create a GZipStream with CompressionMode.Compress, and a + /// writable output stream. Then call Write() on that GZipStream, + /// providing uncompressed data as input. The data sent to the output stream + /// will be the compressed form of the data written. + /// + /// + /// + /// A GZipStream can be used for Read() or Write(), but not + /// both. Writing implies compression. Reading implies decompression. + /// + /// + /// + /// The buffer holding data to write to the stream. + /// the offset within that data array to find the first byte to write. + /// the number of bytes to write. + public override void Write(byte[] buffer, int offset, int count) + { + if (_disposed) throw new ObjectDisposedException("GZipStream"); + if (_baseStream._streamMode == BestHTTP.Decompression.Zlib.ZlibBaseStream.StreamMode.Undefined) + { + //Console.WriteLine("GZipStream: First write"); + if (_baseStream._wantCompress) + { + // first write in compression, therefore, emit the GZIP header + _headerByteCount = EmitHeader(); + } + else + { + throw new InvalidOperationException(); + } + } + + _baseStream.Write(buffer, offset, count); + } + #endregion + + + internal static readonly System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + internal static readonly System.Text.Encoding iso8859dash1 = System.Text.Encoding.GetEncoding("iso-8859-1"); + + + private int EmitHeader() + { + byte[] commentBytes = (Comment == null) ? null : iso8859dash1.GetBytes(Comment); + byte[] filenameBytes = (FileName == null) ? null : iso8859dash1.GetBytes(FileName); + + int cbLength = (Comment == null) ? 0 : commentBytes.Length + 1; + int fnLength = (FileName == null) ? 0 : filenameBytes.Length + 1; + + int bufferLength = 10 + cbLength + fnLength; + byte[] header = new byte[bufferLength]; + int i = 0; + // ID + header[i++] = 0x1F; + header[i++] = 0x8B; + + // compression method + header[i++] = 8; + byte flag = 0; + if (Comment != null) + flag ^= 0x10; + if (FileName != null) + flag ^= 0x8; + + // flag + header[i++] = flag; + + // mtime + if (!LastModified.HasValue) LastModified = DateTime.Now; + System.TimeSpan delta = LastModified.Value - _unixEpoch; + Int32 timet = (Int32)delta.TotalSeconds; + Array.Copy(BitConverter.GetBytes(timet), 0, header, i, 4); + i += 4; + + // xflg + header[i++] = 0; // this field is totally useless + // OS + header[i++] = 0xFF; // 0xFF == unspecified + + // extra field length - only if FEXTRA is set, which it is not. + //header[i++]= 0; + //header[i++]= 0; + + // filename + if (fnLength != 0) + { + Array.Copy(filenameBytes, 0, header, i, fnLength - 1); + i += fnLength - 1; + header[i++] = 0; // terminate + } + + // comment + if (cbLength != 0) + { + Array.Copy(commentBytes, 0, header, i, cbLength - 1); + i += cbLength - 1; + header[i++] = 0; // terminate + } + + _baseStream._stream.Write(header, 0, header.Length); + + return header.Length; // bytes written + } + + + + /// + /// Compress a string into a byte array using GZip. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// + /// + /// + /// + /// A string to compress. The string will first be encoded + /// using UTF8, then compressed. + /// + /// + /// The string in compressed form + public static byte[] CompressString(String s) + { + using (var ms = new MemoryStream()) + { + System.IO.Stream compressor = + new GZipStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); + ZlibBaseStream.CompressString(s, compressor); + return ms.ToArray(); + } + } + + + /// + /// Compress a byte array into a new byte array using GZip. + /// + /// + /// + /// Uncompress it with . + /// + /// + /// + /// + /// + /// + /// A buffer to compress. + /// + /// + /// The data in compressed form + public static byte[] CompressBuffer(byte[] b) + { + using (var ms = new MemoryStream()) + { + System.IO.Stream compressor = + new GZipStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); + + ZlibBaseStream.CompressBuffer(b, compressor); + return ms.ToArray(); + } + } + + + /// + /// Uncompress a GZip'ed byte array into a single string. + /// + /// + /// + /// + /// + /// + /// A buffer containing GZIP-compressed data. + /// + /// + /// The uncompressed string + public static String UncompressString(byte[] compressed) + { + using (var input = new MemoryStream(compressed)) + { + Stream decompressor = new GZipStream(input, CompressionMode.Decompress); + return ZlibBaseStream.UncompressString(compressed, decompressor); + } + } + + + /// + /// Uncompress a GZip'ed byte array into a byte array. + /// + /// + /// + /// + /// + /// + /// A buffer containing data that has been compressed with GZip. + /// + /// + /// The data in uncompressed form + public static byte[] UncompressBuffer(byte[] compressed) + { + using (var input = new System.IO.MemoryStream(compressed)) + { + System.IO.Stream decompressor = + new GZipStream( input, CompressionMode.Decompress ); + + return ZlibBaseStream.UncompressBuffer(compressed, decompressor); + } + } + + + } +} diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs.meta new file mode 100644 index 0000000..7d859b3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/GZipStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: be79ee53ca164d04cbbb654f7de657f5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/InfTree.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/InfTree.cs new file mode 100644 index 0000000..3fdb425 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/InfTree.cs @@ -0,0 +1,436 @@ +// Inftree.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-October-28 12:43:54> +// +// ------------------------------------------------------------------ +// +// This module defines classes used in decompression. This code is derived +// from the jzlib implementation of zlib. In keeping with the license for jzlib, +// the copyright to that code is below. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + + +using System; +namespace BestHTTP.Decompression.Zlib +{ + + sealed class InfTree + { + + private const int MANY = 1440; + + private const int Z_OK = 0; + private const int Z_STREAM_END = 1; + private const int Z_NEED_DICT = 2; + private const int Z_ERRNO = - 1; + private const int Z_STREAM_ERROR = - 2; + private const int Z_DATA_ERROR = - 3; + private const int Z_MEM_ERROR = - 4; + private const int Z_BUF_ERROR = - 5; + private const int Z_VERSION_ERROR = - 6; + + internal const int fixed_bl = 9; + internal const int fixed_bd = 5; + + //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, + 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, + 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; + //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577}; + + // Tables for deflate from PKZIP's appnote.txt. + //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + + // see note #13 above about 258 + //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; + + //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + + //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" + internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + internal const int BMAX = 15; // maximum bit length of any code + + internal int[] hn = null; // hufts used in space + internal int[] v = null; // work area for huft_build + internal int[] c = null; // bit length count table + internal int[] r = null; // table entity for structure assignment + internal int[] u = null; // table stack + internal int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) + { + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do + { + c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX + } + while (i != 0); + + if (c[0] == n) + { + // null input--all zero length codes + t[0] = - 1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if (c[j] != 0) + break; + k = j; // minimum code length + if (l < j) + { + l = j; + } + for (i = BMAX; i != 0; i--) + { + if (c[i] != 0) + break; + } + g = i; // maximum code length + if (l > i) + { + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1) + { + if ((y -= c[j]) < 0) + { + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0) + { + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i != 0) + { + // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do + { + if ((j = b[bindex + p]) != 0) + { + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = - 1; // no tables yet--level -1 + w = - l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++) + { + a = c[k]; + while (a-- != 0) + { + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l) + { + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l)?l:z; // table size upper limit + if ((f = 1 << (j = k - w)) > a + 1) + { + // try a k-w bit table + // too few codes for k-w bit table + f -= (a + 1); // deduct codes from patterns left + xp = k; + if (j < z) + { + while (++j < z) + { + // try smaller tables up to z bits + if ((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY) + { + // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if (h != 0) + { + x[h] = i; // save pattern for backing up + r[0] = (sbyte) j; // bits in this table + r[1] = (sbyte) l; // bits to dump before this table + j = SharedUtils.URShift(i, (w - l)); + r[2] = (int) (q - u[h - 1] - j); // offset to this table + Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table + } + else + { + t[0] = q; // first table is returned result + } + } + + // set up table entity in r + r[1] = (sbyte) (k - w); + if (p >= n) + { + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s) + { + r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else + { + r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists + r[2] = d[v[p++] - s]; + } + + // fill code-like entries with r + f = 1 << (k - w); + for (j = SharedUtils.URShift(i, w); j < z; j += f) + { + Array.Copy(r, 0, hp, (q + j) * 3, 3); + } + + // backwards increment the k-bit code i + for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) + { + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]) + { + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1?Z_BUF_ERROR:Z_OK; + } + + internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z) + { + int result; + initWorkArea(19); + hn[0] = 0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed dynamic bit lengths tree"; + } + else if (result == Z_BUF_ERROR || bb[0] == 0) + { + z.Message = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z) + { + int result; + + // build literal/length tree + initWorkArea(288); + hn[0] = 0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0) + { + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR) + { + z.Message = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)) + { + if (result == Z_DATA_ERROR) + { + z.Message = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) + { + z.Message = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR) + { + z.Message = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z) + { + bl[0] = fixed_bl; + bd[0] = fixed_bd; + tl[0] = fixed_tl; + td[0] = fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize) + { + if (hn == null) + { + hn = new int[1]; + v = new int[vsize]; + c = new int[BMAX + 1]; + r = new int[3]; + u = new int[BMAX]; + x = new int[BMAX + 1]; + } + else + { + if (v.Length < vsize) + { + v = new int[vsize]; + } + Array.Clear(v,0,vsize); + Array.Clear(c,0,BMAX+1); + r[0]=0; r[1]=0; r[2]=0; + // for(int i=0; i +// +// ------------------------------------------------------------------ +// +// This module defines classes for decompression. This code is derived +// from the jzlib implementation of zlib, but significantly modified. +// The object model is not the same, and many of the behaviors are +// different. Nonetheless, in keeping with the license for jzlib, I am +// reproducing the copyright to that code here. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; +namespace BestHTTP.Decompression.Zlib +{ + sealed class InflateBlocks + { + private const int MANY = 1440; + + // Table for deflate from PKZIP's appnote.txt. + internal static readonly int[] border = new int[] + { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + + private enum InflateBlockMode + { + TYPE = 0, // get type bits (3, including end bit) + LENS = 1, // get lengths for stored + STORED = 2, // processing stored block + TABLE = 3, // get table lengths + BTREE = 4, // get bit lengths tree for a dynamic block + DTREE = 5, // get length, distance trees for a dynamic block + CODES = 6, // processing fixed or dynamic block + DRY = 7, // output remaining window bytes + DONE = 8, // finished last block, done + BAD = 9, // ot a data error--stuck here + } + + private InflateBlockMode mode; // current inflate_block mode + + internal int left; // if STORED, bytes left to copy + + internal int table; // table lengths (14 bits) + internal int index; // index into blens (or border) + internal int[] blens; // bit lengths of codes + internal int[] bb = new int[1]; // bit length tree depth + internal int[] tb = new int[1]; // bit length decoding tree + + internal InflateCodes codes = new InflateCodes(); // if CODES, current state + + internal int last; // true if this block is the last block + + internal ZlibCodec _codec; // pointer back to this zlib stream + + // mode independent information + internal int bitk; // bits in bit buffer + internal int bitb; // bit buffer + internal int[] hufts; // single malloc for tree space + internal byte[] window; // sliding window + internal int end; // one byte after sliding window + internal int readAt; // window read pointer + internal int writeAt; // window write pointer + internal System.Object checkfn; // check function + internal uint check; // check on output + + internal InfTree inftree = new InfTree(); + + internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w) + { + _codec = codec; + hufts = new int[MANY * 3]; + window = new byte[w]; + end = w; + this.checkfn = checkfn; + mode = InflateBlockMode.TYPE; + Reset(); + } + + internal uint Reset() + { + uint oldCheck = check; + mode = InflateBlockMode.TYPE; + bitk = 0; + bitb = 0; + readAt = writeAt = 0; + + if (checkfn != null) + _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0); + return oldCheck; + } + + + internal int Process(int r) + { + int t; // temporary storage + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + + p = _codec.NextIn; + n = _codec.AvailableBytesIn; + b = bitb; + k = bitk; + + q = writeAt; + m = (int)(q < readAt ? readAt - q - 1 : end - q); + + + // process input based on current state + while (true) + { + switch (mode) + { + case InflateBlockMode.TYPE: + + while (k < (3)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + t = (int)(b & 7); + last = t & 1; + + switch ((uint)t >> 1) + { + case 0: // stored + b >>= 3; k -= (3); + t = k & 7; // go to byte boundary + b >>= t; k -= t; + mode = InflateBlockMode.LENS; // get length of stored block + break; + + case 1: // fixed + int[] bl = new int[1]; + int[] bd = new int[1]; + int[][] tl = new int[1][]; + int[][] td = new int[1][]; + InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec); + codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0); + b >>= 3; k -= 3; + mode = InflateBlockMode.CODES; + break; + + case 2: // dynamic + b >>= 3; k -= 3; + mode = InflateBlockMode.TABLE; + break; + + case 3: // illegal + b >>= 3; k -= 3; + mode = InflateBlockMode.BAD; + _codec.Message = "invalid block type"; + r = ZlibConstants.Z_DATA_ERROR; + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + break; + + case InflateBlockMode.LENS: + + while (k < (32)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + ; + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + if ( ( ((~b)>>16) & 0xffff) != (b & 0xffff)) + { + mode = InflateBlockMode.BAD; + _codec.Message = "invalid stored block lengths"; + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE); + break; + + case InflateBlockMode.STORED: + if (n == 0) + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + if (m == 0) + { + if (q == end && readAt != 0) + { + q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q); + } + if (m == 0) + { + writeAt = q; + r = Flush(r); + q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q); + if (q == end && readAt != 0) + { + q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q); + } + if (m == 0) + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + } + } + r = ZlibConstants.Z_OK; + + t = left; + if (t > n) + t = n; + if (t > m) + t = m; + Array.Copy(_codec.InputBuffer, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE; + break; + + case InflateBlockMode.TABLE: + + while (k < (14)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + table = t = (b & 0x3fff); + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + mode = InflateBlockMode.BAD; + _codec.Message = "too many length or distance symbols"; + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (blens == null || blens.Length < t) + { + blens = new int[t]; + } + else + { + Array.Clear(blens, 0, t); + // for (int i = 0; i < t; i++) + // { + // blens[i] = 0; + // } + } + + b >>= 14; + k -= 14; + + + index = 0; + mode = InflateBlockMode.BTREE; + goto case InflateBlockMode.BTREE; + + case InflateBlockMode.BTREE: + while (index < 4 + (table >> 10)) + { + while (k < (3)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + blens[border[index++]] = b & 7; + + b >>= 3; k -= 3; + } + + while (index < 19) + { + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec); + if (t != ZlibConstants.Z_OK) + { + r = t; + if (r == ZlibConstants.Z_DATA_ERROR) + { + blens = null; + mode = InflateBlockMode.BAD; + } + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + index = 0; + mode = InflateBlockMode.DTREE; + goto case InflateBlockMode.DTREE; + + case InflateBlockMode.DTREE: + while (true) + { + t = table; + if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) + { + break; + } + + int i, j, c; + + t = bb[0]; + + while (k < t) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1]; + c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2]; + + if (c < 16) + { + b >>= t; k -= t; + blens[index++] = c; + } + else + { + // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while (k < (t + i)) + { + if (n != 0) + { + r = ZlibConstants.Z_OK; + } + else + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + n--; + b |= (_codec.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + b >>= t; k -= t; + + j += (b & InternalInflateConstants.InflateMask[i]); + + b >>= i; k -= i; + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) + { + blens = null; + mode = InflateBlockMode.BAD; + _codec.Message = "invalid bit length repeat"; + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + + c = (c == 16) ? blens[i-1] : 0; + do + { + blens[i++] = c; + } + while (--j != 0); + index = i; + } + } + + tb[0] = -1; + { + int[] bl = new int[] { 9 }; // must be <= 9 for lookahead assumptions + int[] bd = new int[] { 6 }; // must be <= 9 for lookahead assumptions + int[] tl = new int[1]; + int[] td = new int[1]; + + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, _codec); + + if (t != ZlibConstants.Z_OK) + { + if (t == ZlibConstants.Z_DATA_ERROR) + { + blens = null; + mode = InflateBlockMode.BAD; + } + r = t; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]); + } + mode = InflateBlockMode.CODES; + goto case InflateBlockMode.CODES; + + case InflateBlockMode.CODES: + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + + r = codes.Process(this, r); + if (r != ZlibConstants.Z_STREAM_END) + { + return Flush(r); + } + + r = ZlibConstants.Z_OK; + p = _codec.NextIn; + n = _codec.AvailableBytesIn; + b = bitb; + k = bitk; + q = writeAt; + m = (int)(q < readAt ? readAt - q - 1 : end - q); + + if (last == 0) + { + mode = InflateBlockMode.TYPE; + break; + } + mode = InflateBlockMode.DRY; + goto case InflateBlockMode.DRY; + + case InflateBlockMode.DRY: + writeAt = q; + r = Flush(r); + q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q); + if (readAt != writeAt) + { + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + mode = InflateBlockMode.DONE; + goto case InflateBlockMode.DONE; + + case InflateBlockMode.DONE: + r = ZlibConstants.Z_STREAM_END; + bitb = b; + bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + + case InflateBlockMode.BAD: + r = ZlibConstants.Z_DATA_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + + + default: + r = ZlibConstants.Z_STREAM_ERROR; + + bitb = b; bitk = k; + _codec.AvailableBytesIn = n; + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + writeAt = q; + return Flush(r); + } + } + } + + + internal void Free() + { + Reset(); + window = null; + hufts = null; + } + + internal void SetDictionary(byte[] d, int start, int n) + { + Array.Copy(d, start, window, 0, n); + readAt = writeAt = n; + } + + // Returns true if inflate is currently at the end of a block generated + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. + internal int SyncPoint() + { + return mode == InflateBlockMode.LENS ? 1 : 0; + } + + // copy as much as possible from the sliding window to the output area + internal int Flush(int r) + { + int nBytes; + + for (int pass=0; pass < 2; pass++) + { + if (pass==0) + { + // compute number of bytes to copy as far as end of window + nBytes = (int)((readAt <= writeAt ? writeAt : end) - readAt); + } + else + { + // compute bytes to copy + nBytes = writeAt - readAt; + } + + // workitem 8870 + if (nBytes == 0) + { + if (r == ZlibConstants.Z_BUF_ERROR) + r = ZlibConstants.Z_OK; + return r; + } + + if (nBytes > _codec.AvailableBytesOut) + nBytes = _codec.AvailableBytesOut; + + if (nBytes != 0 && r == ZlibConstants.Z_BUF_ERROR) + r = ZlibConstants.Z_OK; + + // update counters + _codec.AvailableBytesOut -= nBytes; + _codec.TotalBytesOut += nBytes; + + // update check information + if (checkfn != null) + _codec._Adler32 = check = Adler.Adler32(check, window, readAt, nBytes); + + // copy as far as end of window + Array.Copy(window, readAt, _codec.OutputBuffer, _codec.NextOut, nBytes); + _codec.NextOut += nBytes; + readAt += nBytes; + + // see if more to copy at beginning of window + if (readAt == end && pass == 0) + { + // wrap pointers + readAt = 0; + if (writeAt == end) + writeAt = 0; + } + else pass++; + } + + // done + return r; + } + } + + + internal static class InternalInflateConstants + { + // And'ing with mask[n] masks the lower n bits + internal static readonly int[] InflateMask = new int[] { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff }; + } + + + sealed class InflateCodes + { + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + private const int START = 0; // x: set up for LEN + private const int LEN = 1; // i: get length/literal/eob next + private const int LENEXT = 2; // i: getting length extra (have base) + private const int DIST = 3; // i: get distance next + private const int DISTEXT = 4; // i: getting distance extra + private const int COPY = 5; // o: copying bytes in window, waiting for space + private const int LIT = 6; // o: got literal, waiting for output space + private const int WASH = 7; // o: got eob, possibly still output waiting + private const int END = 8; // x: got eob and all data flushed + private const int BADCODE = 9; // x: got error + + internal int mode; // current inflate_codes mode + + // mode dependent information + internal int len; + + internal int[] tree; // pointer into tree + internal int tree_index = 0; + internal int need; // bits needed + + internal int lit; + + // if EXT or COPY, where and how much + internal int bitsToGet; // bits to get for extra + internal int dist; // distance back to copy from + + internal byte lbits; // ltree bits decoded per branch + internal byte dbits; // dtree bits decoder per branch + internal int[] ltree; // literal/length/eob tree + internal int ltree_index; // literal/length/eob tree + internal int[] dtree; // distance tree + internal int dtree_index; // distance tree + + internal InflateCodes() + { + } + + internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index) + { + mode = START; + lbits = (byte)bl; + dbits = (byte)bd; + ltree = tl; + ltree_index = tl_index; + dtree = td; + dtree_index = td_index; + tree = null; + } + + internal int Process(InflateBlocks blocks, int r) + { + int j; // temporary storage + int tindex; // temporary pointer + int e; // extra bits or operation + int b = 0; // bit buffer + int k = 0; // bits in bit buffer + int p = 0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + ZlibCodec z = blocks._codec; + + // copy input/output information to locals (UPDATE macro restores) + p = z.NextIn; + n = z.AvailableBytesIn; + b = blocks.bitb; + k = blocks.bitk; + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + // process input and output based on current state + while (true) + { + switch (mode) + { + // waiting for "i:"=input, "o:"=output, "x:"=nothing + case START: // x: set up for LEN + if (m >= 258 && n >= 10) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z); + + p = z.NextIn; + n = z.AvailableBytesIn; + b = blocks.bitb; + k = blocks.bitk; + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (r != ZlibConstants.Z_OK) + { + mode = (r == ZlibConstants.Z_STREAM_END) ? WASH : BADCODE; + break; + } + } + need = lbits; + tree = ltree; + tree_index = ltree_index; + + mode = LEN; + goto case LEN; + + case LEN: // i: get length/literal/eob next + j = need; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; + + b >>= (tree[tindex + 1]); + k -= (tree[tindex + 1]); + + e = tree[tindex]; + + if (e == 0) + { + // literal + lit = tree[tindex + 2]; + mode = LIT; + break; + } + if ((e & 16) != 0) + { + // length + bitsToGet = e & 15; + len = tree[tindex + 2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0) + { + // next table + need = e; + tree_index = tindex / 3 + tree[tindex + 2]; + break; + } + if ((e & 32) != 0) + { + // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.Message = "invalid literal/length code"; + r = ZlibConstants.Z_DATA_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + + case LENEXT: // i: getting length extra (have base) + j = bitsToGet; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + len += (b & InternalInflateConstants.InflateMask[j]); + + b >>= j; + k -= j; + + need = dbits; + tree = dtree; + tree_index = dtree_index; + mode = DIST; + goto case DIST; + + case DIST: // i: get distance next + j = need; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; + + b >>= tree[tindex + 1]; + k -= tree[tindex + 1]; + + e = (tree[tindex]); + if ((e & 0x10) != 0) + { + // distance + bitsToGet = e & 15; + dist = tree[tindex + 2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0) + { + // next table + need = e; + tree_index = tindex / 3 + tree[tindex + 2]; + break; + } + mode = BADCODE; // invalid code + z.Message = "invalid distance code"; + r = ZlibConstants.Z_DATA_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + + case DISTEXT: // i: getting distance extra + j = bitsToGet; + + while (k < j) + { + if (n != 0) + r = ZlibConstants.Z_OK; + else + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + n--; b |= (z.InputBuffer[p++] & 0xff) << k; + k += 8; + } + + dist += (b & InternalInflateConstants.InflateMask[j]); + + b >>= j; + k -= j; + + mode = COPY; + goto case COPY; + + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while (f < 0) + { + // modulo window size-"while" instead + f += blocks.end; // of "if" handles invalid distances + } + while (len != 0) + { + if (m == 0) + { + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + if (m == 0) + { + blocks.writeAt = q; r = blocks.Flush(r); + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + + if (m == 0) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; + z.TotalBytesIn += p - z.NextIn; + z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + } + } + + blocks.window[q++] = blocks.window[f++]; m--; + + if (f == blocks.end) + f = 0; + len--; + } + mode = START; + break; + + case LIT: // o: got literal, waiting for output space + if (m == 0) + { + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + if (m == 0) + { + blocks.writeAt = q; r = blocks.Flush(r); + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (q == blocks.end && blocks.readAt != 0) + { + q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + } + if (m == 0) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + } + } + r = ZlibConstants.Z_OK; + + blocks.window[q++] = (byte)lit; m--; + + mode = START; + break; + + case WASH: // o: got eob, possibly more output + if (k > 7) + { + // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + blocks.writeAt = q; r = blocks.Flush(r); + q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; + + if (blocks.readAt != blocks.writeAt) + { + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + mode = END; + goto case END; + + case END: + r = ZlibConstants.Z_STREAM_END; + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + case BADCODE: // x: got error + + r = ZlibConstants.Z_DATA_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + + default: + r = ZlibConstants.Z_STREAM_ERROR; + + blocks.bitb = b; blocks.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + blocks.writeAt = q; + return blocks.Flush(r); + } + } + } + + + // Called with number of bytes left to write in window at least 258 + // (the maximum string length) and number of input bytes available + // at least ten. The ten bytes are six bytes for the longest length/ + // distance pair plus four bytes for overloading the bit buffer. + + internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z) + { + int t; // temporary pointer + int[] tp; // temporary pointer + int tp_index; // temporary pointer + int e; // extra bits or operation + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int ml; // mask for literal/length tree + int md; // mask for distance tree + int c; // bytes to copy + int d; // distance back to copy from + int r; // copy source pointer + + int tp_index_t_3; // (tp_index+t)*3 + + // load input, output, bit values + p = z.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk; + q = s.writeAt; m = q < s.readAt ? s.readAt - q - 1 : s.end - q; + + // initialize masks + ml = InternalInflateConstants.InflateMask[bl]; + md = InternalInflateConstants.InflateMask[bd]; + + // do until not enough input or output space for fast loop + do + { + // assume called with m >= 258 && n >= 10 + // get literal/length code + while (k < (20)) + { + // max bits for literal/length code + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; + } + + t = b & ml; + tp = tl; + tp_index = tl_index; + tp_index_t_3 = (tp_index + t) * 3; + if ((e = tp[tp_index_t_3]) == 0) + { + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + + s.window[q++] = (byte)tp[tp_index_t_3 + 2]; + m--; + continue; + } + do + { + + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + + if ((e & 16) != 0) + { + e &= 15; + c = tp[tp_index_t_3 + 2] + ((int)b & InternalInflateConstants.InflateMask[e]); + + b >>= e; k -= e; + + // decode distance base of block to copy + while (k < 15) + { + // max bits for distance code + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; + } + + t = b & md; + tp = td; + tp_index = td_index; + tp_index_t_3 = (tp_index + t) * 3; + e = tp[tp_index_t_3]; + + do + { + + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + + if ((e & 16) != 0) + { + // get extra bits to add to distance base + e &= 15; + while (k < e) + { + // get extra bits (up to 13) + n--; + b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; + } + + d = tp[tp_index_t_3 + 2] + (b & InternalInflateConstants.InflateMask[e]); + + b >>= e; k -= e; + + // do the copy + m -= c; + if (q >= d) + { + // offset before dest + // just copy + r = q - d; + if (q - r > 0 && 2 > (q - r)) + { + s.window[q++] = s.window[r++]; // minimum count is three, + s.window[q++] = s.window[r++]; // so unroll loop a little + c -= 2; + } + else + { + Array.Copy(s.window, r, s.window, q, 2); + q += 2; r += 2; c -= 2; + } + } + else + { + // else offset after destination + r = q - d; + do + { + r += s.end; // force pointer in window + } + while (r < 0); // covers invalid distances + e = s.end - r; + if (c > e) + { + // if source crosses, + c -= e; // wrapped copy + if (q - r > 0 && e > (q - r)) + { + do + { + s.window[q++] = s.window[r++]; + } + while (--e != 0); + } + else + { + Array.Copy(s.window, r, s.window, q, e); + q += e; r += e; e = 0; + } + r = 0; // copy rest from start of window + } + } + + // copy all or what's left + if (q - r > 0 && c > (q - r)) + { + do + { + s.window[q++] = s.window[r++]; + } + while (--c != 0); + } + else + { + Array.Copy(s.window, r, s.window, q, c); + q += c; r += c; c = 0; + } + break; + } + else if ((e & 64) == 0) + { + t += tp[tp_index_t_3 + 2]; + t += (b & InternalInflateConstants.InflateMask[e]); + tp_index_t_3 = (tp_index + t) * 3; + e = tp[tp_index_t_3]; + } + else + { + z.Message = "invalid distance code"; + + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_DATA_ERROR; + } + } + while (true); + break; + } + + if ((e & 64) == 0) + { + t += tp[tp_index_t_3 + 2]; + t += (b & InternalInflateConstants.InflateMask[e]); + tp_index_t_3 = (tp_index + t) * 3; + if ((e = tp[tp_index_t_3]) == 0) + { + b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); + s.window[q++] = (byte)tp[tp_index_t_3 + 2]; + m--; + break; + } + } + else if ((e & 32) != 0) + { + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_STREAM_END; + } + else + { + z.Message = "invalid literal/length code"; + + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_DATA_ERROR; + } + } + while (true); + } + while (m >= 258 && n >= 10); + + // not enough input or output--restore pointers and return + c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); + + s.bitb = b; s.bitk = k; + z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; + s.writeAt = q; + + return ZlibConstants.Z_OK; + } + } + + + internal sealed class InflateManager + { + // preset dictionary flag in zlib header + private const int PRESET_DICT = 0x20; + + private const int Z_DEFLATED = 8; + + private enum InflateManagerMode + { + METHOD = 0, // waiting for method byte + FLAG = 1, // waiting for flag byte + DICT4 = 2, // four dictionary check bytes to go + DICT3 = 3, // three dictionary check bytes to go + DICT2 = 4, // two dictionary check bytes to go + DICT1 = 5, // one dictionary check byte to go + DICT0 = 6, // waiting for inflateSetDictionary + BLOCKS = 7, // decompressing blocks + CHECK4 = 8, // four check bytes to go + CHECK3 = 9, // three check bytes to go + CHECK2 = 10, // two check bytes to go + CHECK1 = 11, // one check byte to go + DONE = 12, // finished check, done + BAD = 13, // got an error--stay here + } + + private InflateManagerMode mode; // current inflate mode + internal ZlibCodec _codec; // pointer back to this zlib stream + + // mode dependent information + internal int method; // if FLAGS, method byte + + // if CHECK, check values to compare + internal uint computedCheck; // computed check value + internal uint expectedCheck; // stream check value + + // if BAD, inflateSync's marker bytes count + internal int marker; + + // mode independent information + //internal int nowrap; // flag for no wrapper + private bool _handleRfc1950HeaderBytes = true; + internal bool HandleRfc1950HeaderBytes + { + get { return _handleRfc1950HeaderBytes; } + set { _handleRfc1950HeaderBytes = value; } + } + internal int wbits; // log2(window size) (8..15, defaults to 15) + + internal InflateBlocks blocks; // current inflate_blocks state + + public InflateManager() { } + + public InflateManager(bool expectRfc1950HeaderBytes) + { + _handleRfc1950HeaderBytes = expectRfc1950HeaderBytes; + } + + internal int Reset() + { + _codec.TotalBytesIn = _codec.TotalBytesOut = 0; + _codec.Message = null; + mode = HandleRfc1950HeaderBytes ? InflateManagerMode.METHOD : InflateManagerMode.BLOCKS; + blocks.Reset(); + return ZlibConstants.Z_OK; + } + + internal int End() + { + if (blocks != null) + blocks.Free(); + blocks = null; + return ZlibConstants.Z_OK; + } + + internal int Initialize(ZlibCodec codec, int w) + { + _codec = codec; + _codec.Message = null; + blocks = null; + + // handle undocumented nowrap option (no zlib header or check) + //nowrap = 0; + //if (w < 0) + //{ + // w = - w; + // nowrap = 1; + //} + + // set window size + if (w < 8 || w > 15) + { + End(); + throw new ZlibException("Bad window size."); + + //return ZlibConstants.Z_STREAM_ERROR; + } + wbits = w; + + blocks = new InflateBlocks(codec, + HandleRfc1950HeaderBytes ? this : null, + 1 << w); + + // reset state + Reset(); + return ZlibConstants.Z_OK; + } + + + internal int Inflate(FlushType flush) + { + int b; + + if (_codec.InputBuffer == null) + throw new ZlibException("InputBuffer is null. "); + +// int f = (flush == FlushType.Finish) +// ? ZlibConstants.Z_BUF_ERROR +// : ZlibConstants.Z_OK; + + // workitem 8870 + int f = ZlibConstants.Z_OK; + int r = ZlibConstants.Z_BUF_ERROR; + + while (true) + { + switch (mode) + { + case InflateManagerMode.METHOD: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED) + { + mode = InflateManagerMode.BAD; + _codec.Message = String.Format("unknown compression method (0x{0:X2})", method); + marker = 5; // can't try inflateSync + break; + } + if ((method >> 4) + 8 > wbits) + { + mode = InflateManagerMode.BAD; + _codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8); + marker = 5; // can't try inflateSync + break; + } + mode = InflateManagerMode.FLAG; + break; + + + case InflateManagerMode.FLAG: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff; + + if ((((method << 8) + b) % 31) != 0) + { + mode = InflateManagerMode.BAD; + _codec.Message = "incorrect header check"; + marker = 5; // can't try inflateSync + break; + } + + mode = ((b & PRESET_DICT) == 0) + ? InflateManagerMode.BLOCKS + : InflateManagerMode.DICT4; + break; + + case InflateManagerMode.DICT4: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000); + mode = InflateManagerMode.DICT3; + break; + + case InflateManagerMode.DICT3: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000); + mode = InflateManagerMode.DICT2; + break; + + case InflateManagerMode.DICT2: + + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00); + mode = InflateManagerMode.DICT1; + break; + + + case InflateManagerMode.DICT1: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; _codec.TotalBytesIn++; + expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff); + _codec._Adler32 = expectedCheck; + mode = InflateManagerMode.DICT0; + return ZlibConstants.Z_NEED_DICT; + + + case InflateManagerMode.DICT0: + mode = InflateManagerMode.BAD; + _codec.Message = "need dictionary"; + marker = 0; // can try inflateSync + return ZlibConstants.Z_STREAM_ERROR; + + + case InflateManagerMode.BLOCKS: + r = blocks.Process(r); + if (r == ZlibConstants.Z_DATA_ERROR) + { + mode = InflateManagerMode.BAD; + marker = 0; // can try inflateSync + break; + } + + if (r == ZlibConstants.Z_OK) r = f; + + if (r != ZlibConstants.Z_STREAM_END) + return r; + + r = f; + computedCheck = blocks.Reset(); + if (!HandleRfc1950HeaderBytes) + { + mode = InflateManagerMode.DONE; + return ZlibConstants.Z_STREAM_END; + } + mode = InflateManagerMode.CHECK4; + break; + + case InflateManagerMode.CHECK4: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000); + mode = InflateManagerMode.CHECK3; + break; + + case InflateManagerMode.CHECK3: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000); + mode = InflateManagerMode.CHECK2; + break; + + case InflateManagerMode.CHECK2: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; + _codec.TotalBytesIn++; + expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00); + mode = InflateManagerMode.CHECK1; + break; + + case InflateManagerMode.CHECK1: + if (_codec.AvailableBytesIn == 0) return r; + r = f; + _codec.AvailableBytesIn--; _codec.TotalBytesIn++; + expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff); + if (computedCheck != expectedCheck) + { + mode = InflateManagerMode.BAD; + _codec.Message = "incorrect data check"; + marker = 5; // can't try inflateSync + break; + } + mode = InflateManagerMode.DONE; + return ZlibConstants.Z_STREAM_END; + + case InflateManagerMode.DONE: + return ZlibConstants.Z_STREAM_END; + + case InflateManagerMode.BAD: + throw new ZlibException(String.Format("Bad state ({0})", _codec.Message)); + + default: + throw new ZlibException("Stream error."); + + } + } + } + + + + internal int SetDictionary(byte[] dictionary) + { + int index = 0; + int length = dictionary.Length; + if (mode != InflateManagerMode.DICT0) + throw new ZlibException("Stream error."); + + if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32) + { + return ZlibConstants.Z_DATA_ERROR; + } + + _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + + if (length >= (1 << wbits)) + { + length = (1 << wbits) - 1; + index = dictionary.Length - length; + } + blocks.SetDictionary(dictionary, index, length); + mode = InflateManagerMode.BLOCKS; + return ZlibConstants.Z_OK; + } + + + private static readonly byte[] mark = new byte[] { 0, 0, 0xff, 0xff }; + + internal int Sync() + { + int n; // number of bytes to look at + int p; // pointer to bytes + int m; // number of marker bytes found in a row + long r, w; // temporaries to save total_in and total_out + + // set up + if (mode != InflateManagerMode.BAD) + { + mode = InflateManagerMode.BAD; + marker = 0; + } + if ((n = _codec.AvailableBytesIn) == 0) + return ZlibConstants.Z_BUF_ERROR; + p = _codec.NextIn; + m = marker; + + // search + while (n != 0 && m < 4) + { + if (_codec.InputBuffer[p] == mark[m]) + { + m++; + } + else if (_codec.InputBuffer[p] != 0) + { + m = 0; + } + else + { + m = 4 - m; + } + p++; n--; + } + + // restore + _codec.TotalBytesIn += p - _codec.NextIn; + _codec.NextIn = p; + _codec.AvailableBytesIn = n; + marker = m; + + // return no joy or set up to restart on a new block + if (m != 4) + { + return ZlibConstants.Z_DATA_ERROR; + } + r = _codec.TotalBytesIn; + w = _codec.TotalBytesOut; + Reset(); + _codec.TotalBytesIn = r; + _codec.TotalBytesOut = w; + mode = InflateManagerMode.BLOCKS; + return ZlibConstants.Z_OK; + } + + + // Returns true if inflate is currently at the end of a block generated + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + // but removes the length bytes of the resulting empty stored block. When + // decompressing, PPP checks that at the end of input packet, inflate is + // waiting for these length bytes. + internal int SyncPoint(ZlibCodec z) + { + return blocks.SyncPoint(); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Inflate.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Inflate.cs.meta new file mode 100644 index 0000000..7eb68f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Inflate.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 01ece23e3663e424ba8672d6d3d50f19 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs new file mode 100644 index 0000000..04437d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs @@ -0,0 +1,423 @@ +// Tree.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-October-28 13:29:50> +// +// ------------------------------------------------------------------ +// +// This module defines classes for zlib compression and +// decompression. This code is derived from the jzlib implementation of +// zlib. In keeping with the license for jzlib, the copyright to that +// code is below. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; + +namespace BestHTTP.Decompression.Zlib +{ + sealed class ZTree + { + private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); + + // extra bits for each length code + internal static readonly int[] ExtraLengthBits = new int[] + { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 + }; + + // extra bits for each distance code + internal static readonly int[] ExtraDistanceBits = new int[] + { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 + }; + + // extra bits for each bit length code + internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; + + internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + internal const int Buf_size = 8 * 2; + + // see definition of array dist_code below + //internal const int DIST_CODE_LEN = 512; + + private static readonly sbyte[] _dist_code = new sbyte[] + { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + internal static readonly sbyte[] LengthCode = new sbyte[] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + + internal static readonly int[] LengthBase = new int[] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, + 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + + internal static readonly int[] DistanceBase = new int[] + { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, + 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + + /// + /// Map from a distance to a distance code. + /// + /// + /// No side effects. _dist_code[256] and _dist_code[257] are never used. + /// + internal static int DistanceCode(int dist) + { + return (dist < 256) + ? _dist_code[dist] + : _dist_code[256 + SharedUtils.URShift(dist, 7)]; + } + + internal short[] dyn_tree; // the dynamic tree + internal int max_code; // largest code with non zero frequency + internal StaticTree staticTree; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + internal void gen_bitlen(DeflateManager s) + { + short[] tree = dyn_tree; + short[] stree = staticTree.treeCodes; + int[] extra = staticTree.extraBits; + int base_Renamed = staticTree.extraBase; + int max_length = staticTree.maxLength; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++) + s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap + + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) + { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; + if (bits > max_length) + { + bits = max_length; overflow++; + } + tree[n * 2 + 1] = (short) bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) + continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= base_Renamed) + xbits = extra[n - base_Renamed]; + f = tree[n * 2]; + s.opt_len += f * (bits + xbits); + if (stree != null) + s.static_len += f * (stree[n * 2 + 1] + xbits); + } + if (overflow == 0) + return ; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do + { + bits = max_length - 1; + while (s.bl_count[bits] == 0) + bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) + { + n = s.bl_count[bits]; + while (n != 0) + { + m = s.heap[--h]; + if (m > max_code) + continue; + if (tree[m * 2 + 1] != bits) + { + s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); + tree[m * 2 + 1] = (short) bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + internal void build_tree(DeflateManager s) + { + short[] tree = dyn_tree; + short[] stree = staticTree.treeCodes; + int elems = staticTree.elems; + int n, m; // iterate over heap elements + int max_code = -1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) + { + if (tree[n * 2] != 0) + { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + } + else + { + tree[n * 2 + 1] = 0; + } + } + + // The pkzip format requires that at least one distance code exists, + // and that at least one bit should be sent even if there is only one + // possible code. So to avoid special checks later on we force at least + // two codes of non zero frequency. + while (s.heap_len < 2) + { + node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0); + tree[node * 2] = 1; + s.depth[node] = 0; + s.opt_len--; + if (stree != null) + s.static_len -= stree[node * 2 + 1]; + // node is 0 or 1 so it does not have extra bits + } + this.max_code = max_code; + + // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + // establish sub-heaps of increasing lengths: + + for (n = s.heap_len / 2; n >= 1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node = elems; // next internal node of the tree + do + { + // n = node of least frequency + n = s.heap[1]; + s.heap[1] = s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m = s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2])); + s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1); + tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + internal static void gen_codes(short[] tree, int max_code, short[] bl_count) + { + short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++) + unchecked { + next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>= 1; //SharedUtils.URShift(code, 1); + res <<= 1; + } + while (--len > 0); + return res >> 1; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs.meta new file mode 100644 index 0000000..47691c8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZTree.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 567080ac494bf3b47acca3e05bf46e84 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs new file mode 100644 index 0000000..082232d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs @@ -0,0 +1,546 @@ +// Zlib.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// Last Saved: <2011-August-03 19:52:28> +// +// ------------------------------------------------------------------ +// +// This module defines classes for ZLIB compression and +// decompression. This code is derived from the jzlib implementation of +// zlib, but significantly modified. The object model is not the same, +// and many of the behaviors are new or different. Nonetheless, in +// keeping with the license for jzlib, the copyright to that code is +// included below. +// +// ------------------------------------------------------------------ +// +// The following notice applies to jzlib: +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// jzlib is based on zlib-1.1.3. +// +// The following notice applies to zlib: +// +// ----------------------------------------------------------------------- +// +// Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler +// +// The ZLIB software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Jean-loup Gailly jloup@gzip.org +// Mark Adler madler@alumni.caltech.edu +// +// ----------------------------------------------------------------------- + + + +using System; +using Interop=System.Runtime.InteropServices; + +namespace BestHTTP.Decompression.Zlib +{ + + /// + /// Describes how to flush the current deflate operation. + /// + /// + /// The different FlushType values are useful when using a Deflate in a streaming application. + /// + public enum FlushType + { + /// No flush at all. + None = 0, + + /// Closes the current block, but doesn't flush it to + /// the output. Used internally only in hypothetical + /// scenarios. This was supposed to be removed by Zlib, but it is + /// still in use in some edge cases. + /// + Partial, + + /// + /// Use this during compression to specify that all pending output should be + /// flushed to the output buffer and the output should be aligned on a byte + /// boundary. You might use this in a streaming communication scenario, so that + /// the decompressor can get all input data available so far. When using this + /// with a ZlibCodec, AvailableBytesIn will be zero after the call if + /// enough output space has been provided before the call. Flushing will + /// degrade compression and so it should be used only when necessary. + /// + Sync, + + /// + /// Use this during compression to specify that all output should be flushed, as + /// with FlushType.Sync, but also, the compression state should be reset + /// so that decompression can restart from this point if previous compressed + /// data has been damaged or if random access is desired. Using + /// FlushType.Full too often can significantly degrade the compression. + /// + Full, + + /// Signals the end of the compression/decompression stream. + Finish, + } + + + /// + /// The compression level to be used when using a DeflateStream or ZlibStream with CompressionMode.Compress. + /// + public enum CompressionLevel + { + /// + /// None means that the data will be simply stored, with no change at all. + /// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None + /// cannot be opened with the default zip reader. Use a different CompressionLevel. + /// + None= 0, + /// + /// Same as None. + /// + Level0 = 0, + + /// + /// The fastest but least effective compression. + /// + BestSpeed = 1, + + /// + /// A synonym for BestSpeed. + /// + Level1 = 1, + + /// + /// A little slower, but better, than level 1. + /// + Level2 = 2, + + /// + /// A little slower, but better, than level 2. + /// + Level3 = 3, + + /// + /// A little slower, but better, than level 3. + /// + Level4 = 4, + + /// + /// A little slower than level 4, but with better compression. + /// + Level5 = 5, + + /// + /// The default compression level, with a good balance of speed and compression efficiency. + /// + Default = 6, + /// + /// A synonym for Default. + /// + Level6 = 6, + + /// + /// Pretty good compression! + /// + Level7 = 7, + + /// + /// Better compression than Level7! + /// + Level8 = 8, + + /// + /// The "best" compression, where best means greatest reduction in size of the input data stream. + /// This is also the slowest compression. + /// + BestCompression = 9, + + /// + /// A synonym for BestCompression. + /// + Level9 = 9, + } + + /// + /// Describes options for how the compression algorithm is executed. Different strategies + /// work better on different sorts of data. The strategy parameter can affect the compression + /// ratio and the speed of compression but not the correctness of the compresssion. + /// + public enum CompressionStrategy + { + /// + /// The default strategy is probably the best for normal data. + /// + Default = 0, + + /// + /// The Filtered strategy is intended to be used most effectively with data produced by a + /// filter or predictor. By this definition, filtered data consists mostly of small + /// values with a somewhat random distribution. In this case, the compression algorithm + /// is tuned to compress them better. The effect of Filtered is to force more Huffman + /// coding and less string matching; it is a half-step between Default and HuffmanOnly. + /// + Filtered = 1, + + /// + /// Using HuffmanOnly will force the compressor to do Huffman encoding only, with no + /// string matching. + /// + HuffmanOnly = 2, + } + + + /// + /// An enum to specify the direction of transcoding - whether to compress or decompress. + /// + public enum CompressionMode + { + /// + /// Used to specify that the stream should compress the data. + /// + Compress= 0, + /// + /// Used to specify that the stream should decompress the data. + /// + Decompress = 1, + } + + + /// + /// A general purpose exception class for exceptions in the Zlib library. + /// + [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")] + internal class ZlibException : System.Exception + { + /// + /// The ZlibException class captures exception information generated + /// by the Zlib library. + /// + public ZlibException() + : base() + { + } + + /// + /// This ctor collects a message attached to the exception. + /// + /// the message for the exception. + public ZlibException(System.String s) + : base(s) + { + } + } + + + internal class SharedUtils + { + /// + /// Performs an unsigned bitwise right shift with the specified number + /// + /// Number to operate on + /// Ammount of bits to shift + /// The resulting number from the shift operation + public static int URShift(int number, int bits) + { + return (int)((uint)number >> bits); + } + +#if NOT + /// + /// Performs an unsigned bitwise right shift with the specified number + /// + /// Number to operate on + /// Ammount of bits to shift + /// The resulting number from the shift operation + public static long URShift(long number, int bits) + { + return (long) ((UInt64)number >> bits); + } +#endif + + /// + /// Reads a number of characters from the current source TextReader and writes + /// the data to the target array at the specified index. + /// + /// + /// The source TextReader to read from + /// Contains the array of characteres read from the source TextReader. + /// The starting index of the target array. + /// The maximum number of characters to read from the source TextReader. + /// + /// + /// The number of characters read. The number will be less than or equal to + /// count depending on the data available in the source TextReader. Returns -1 + /// if the end of the stream is reached. + /// + public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count) + { + // Returns 0 bytes if not enough space in target + if (target.Length == 0) return 0; + + char[] charArray = new char[target.Length]; + int bytesRead = sourceTextReader.Read(charArray, start, count); + + // Returns -1 if EOF + if (bytesRead == 0) return -1; + + for (int index = start; index < start + bytesRead; index++) + target[index] = (byte)charArray[index]; + + return bytesRead; + } + + + internal static byte[] ToByteArray(System.String sourceString) + { + return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); + } + + + internal static char[] ToCharArray(byte[] byteArray) + { + return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); + } + } + + internal static class InternalConstants + { + internal static readonly int MAX_BITS = 15; + internal static readonly int BL_CODES = 19; + internal static readonly int D_CODES = 30; + internal static readonly int LITERALS = 256; + internal static readonly int LENGTH_CODES = 29; + internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES); + + // Bit length codes must not exceed MAX_BL_BITS bits + internal static readonly int MAX_BL_BITS = 7; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + internal static readonly int REP_3_6 = 16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + internal static readonly int REPZ_3_10 = 17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + internal static readonly int REPZ_11_138 = 18; + + } + + internal sealed class StaticTree + { + internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, + 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, + 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, + 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, + 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, + 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, + 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, + 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, + 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, + 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, + 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, + 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, + 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, + 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, + 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, + 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, + 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, + 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, + 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, + 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, + 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, + 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, + 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, + 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, + 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, + 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, + 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, + 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, + 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8 + }; + + internal static readonly short[] distTreeCodes = new short[] { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, + 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, + 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, + 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 }; + + internal static readonly StaticTree Literals; + internal static readonly StaticTree Distances; + internal static readonly StaticTree BitLengths; + + internal short[] treeCodes; // static tree or null + internal int[] extraBits; // extra bits for each code or null + internal int extraBase; // base index for extra_bits + internal int elems; // max number of elements in the tree + internal int maxLength; // max bit length for the codes + + private StaticTree(short[] treeCodes, int[] extraBits, int extraBase, int elems, int maxLength) + { + this.treeCodes = treeCodes; + this.extraBits = extraBits; + this.extraBase = extraBase; + this.elems = elems; + this.maxLength = maxLength; + } + static StaticTree() + { + Literals = new StaticTree(lengthAndLiteralsTreeCodes, ZTree.ExtraLengthBits, InternalConstants.LITERALS + 1, InternalConstants.L_CODES, InternalConstants.MAX_BITS); + Distances = new StaticTree(distTreeCodes, ZTree.ExtraDistanceBits, 0, InternalConstants.D_CODES, InternalConstants.MAX_BITS); + BitLengths = new StaticTree(null, ZTree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS); + } + } + + + + /// + /// Computes an Adler-32 checksum. + /// + /// + /// The Adler checksum is similar to a CRC checksum, but faster to compute, though less + /// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum + /// is a required part of the "ZLIB" standard. Applications will almost never need to + /// use this class directly. + /// + /// + /// + public sealed class Adler + { + // largest prime smaller than 65536 + private static readonly uint BASE = 65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + private static readonly int NMAX = 5552; + + +#pragma warning disable 3001 +#pragma warning disable 3002 + + /// + /// Calculates the Adler32 checksum. + /// + /// + /// + /// This is used within ZLIB. You probably don't need to use this directly. + /// + /// + /// + /// To compute an Adler32 checksum on a byte array: + /// + /// var adler = Adler.Adler32(0, null, 0, 0); + /// adler = Adler.Adler32(adler, buffer, index, length); + /// + /// + public static uint Adler32(uint adler, byte[] buf, int index, int len) + { + if (buf == null) + return 1; + + uint s1 = (uint) (adler & 0xffff); + uint s2 = (uint) ((adler >> 16) & 0xffff); + + while (len > 0) + { + int k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) + { + //s1 += (buf[index++] & 0xff); s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + s1 += buf[index++]; s2 += s1; + k -= 16; + } + if (k != 0) + { + do + { + s1 += buf[index++]; + s2 += s1; + } + while (--k != 0); + } + s1 %= BASE; + s2 %= BASE; + } + return (uint)((s2 << 16) | s1); + } +#pragma warning restore 3001 +#pragma warning restore 3002 + + } + +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs.meta new file mode 100644 index 0000000..a81b918 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/Zlib.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7d946fbf5f38d4049a7b50fe52bd8b0e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs new file mode 100644 index 0000000..045ffa8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs @@ -0,0 +1,643 @@ +// ZlibBaseStream.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2011-August-06 21:22:38> +// +// ------------------------------------------------------------------ +// +// This module defines the ZlibBaseStream class, which is an intnernal +// base class for DeflateStream, ZlibStream and GZipStream. +// +// ------------------------------------------------------------------ + +using System; +using System.IO; + +namespace BestHTTP.Decompression.Zlib +{ + + internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 } + + internal class ZlibBaseStream : System.IO.Stream + { + protected internal ZlibCodec _z = null; // deferred init... new ZlibCodec(); + + protected internal StreamMode _streamMode = StreamMode.Undefined; + protected internal FlushType _flushMode; + protected internal ZlibStreamFlavor _flavor; + protected internal CompressionMode _compressionMode; + protected internal CompressionLevel _level; + protected internal bool _leaveOpen; + protected internal byte[] _workingBuffer; + protected internal int _bufferSize = ZlibConstants.WorkingBufferSizeDefault; + protected internal int windowBitsMax; + protected internal byte[] _buf1 = new byte[1]; + + protected internal System.IO.Stream _stream; + protected internal CompressionStrategy Strategy = CompressionStrategy.Default; + + // workitem 7159 + BestHTTP.Decompression.Crc.CRC32 crc; + protected internal string _GzipFileName; + protected internal string _GzipComment; + protected internal DateTime _GzipMtime; + protected internal int _gzipHeaderByteCount; + + internal int Crc32 { get { if (crc == null) return 0; return crc.Crc32Result; } } + + public ZlibBaseStream(System.IO.Stream stream, + CompressionMode compressionMode, + CompressionLevel level, + ZlibStreamFlavor flavor, + bool leaveOpen) + :this(stream, compressionMode, level, flavor,leaveOpen, ZlibConstants.WindowBitsDefault) + { } + + public ZlibBaseStream(System.IO.Stream stream, + CompressionMode compressionMode, + CompressionLevel level, + ZlibStreamFlavor flavor, + bool leaveOpen, + int windowBits) + : base() + { + this._flushMode = FlushType.None; + //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT]; + this._stream = stream; + this._leaveOpen = leaveOpen; + this._compressionMode = compressionMode; + this._flavor = flavor; + this._level = level; + this.windowBitsMax = windowBits; + // workitem 7159 + if (flavor == ZlibStreamFlavor.GZIP) + { + this.crc = new BestHTTP.Decompression.Crc.CRC32(); + } + } + + + protected internal bool _wantCompress + { + get + { + return (this._compressionMode == CompressionMode.Compress); + } + } + + private ZlibCodec z + { + get + { + if (_z == null) + { + bool wantRfc1950Header = (this._flavor == ZlibStreamFlavor.ZLIB); + _z = new ZlibCodec(); + if (this._compressionMode == CompressionMode.Decompress) + { + _z.InitializeInflate(this.windowBitsMax, wantRfc1950Header); + } + else + { + _z.Strategy = Strategy; + _z.InitializeDeflate(this._level, this.windowBitsMax, wantRfc1950Header); + } + } + return _z; + } + } + + + + private byte[] workingBuffer + { + get + { + if (_workingBuffer == null) + _workingBuffer = new byte[_bufferSize]; + return _workingBuffer; + } + } + + + + public override void Write(System.Byte[] buffer, int offset, int count) + { + // workitem 7159 + // calculate the CRC on the unccompressed data (before writing) + if (crc != null) + crc.SlurpBlock(buffer, offset, count); + + if (_streamMode == StreamMode.Undefined) + _streamMode = StreamMode.Writer; + else if (_streamMode != StreamMode.Writer) + throw new ZlibException("Cannot Write after Reading."); + + if (count == 0) + return; + + // first reference of z property will initialize the private var _z + z.InputBuffer = buffer; + _z.NextIn = offset; + _z.AvailableBytesIn = count; + bool done = false; + do + { + _z.OutputBuffer = workingBuffer; + _z.NextOut = 0; + _z.AvailableBytesOut = _workingBuffer.Length; + int rc = (_wantCompress) + ? _z.Deflate(_flushMode) + : _z.Inflate(_flushMode); + if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message); + + //if (_workingBuffer.Length - _z.AvailableBytesOut > 0) + _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); + + done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; + + // If GZIP and de-compress, we're done when 8 bytes remain. + if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) + done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); + + } + while (!done); + } + + + + private void finish() + { + if (_z == null) return; + + if (_streamMode == StreamMode.Writer) + { + bool done = false; + do + { + _z.OutputBuffer = workingBuffer; + _z.NextOut = 0; + _z.AvailableBytesOut = _workingBuffer.Length; + int rc = (_wantCompress) + ? _z.Deflate(FlushType.Finish) + : _z.Inflate(FlushType.Finish); + + if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) + { + string verb = (_wantCompress ? "de" : "in") + "flating"; + if (_z.Message == null) + throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc)); + else + throw new ZlibException(verb + ": " + _z.Message); + } + + if (_workingBuffer.Length - _z.AvailableBytesOut > 0) + { + _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); + } + + done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; + // If GZIP and de-compress, we're done when 8 bytes remain. + if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) + done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); + + } + while (!done); + + Flush(); + + // workitem 7159 + if (_flavor == ZlibStreamFlavor.GZIP) + { + if (_wantCompress) + { + // Emit the GZIP trailer: CRC32 and size mod 2^32 + int c1 = crc.Crc32Result; + _stream.Write(BitConverter.GetBytes(c1), 0, 4); + int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF); + _stream.Write(BitConverter.GetBytes(c2), 0, 4); + } + else + { + throw new ZlibException("Writing with decompression is not supported."); + } + } + } + // workitem 7159 + else if (_streamMode == StreamMode.Reader) + { + if (_flavor == ZlibStreamFlavor.GZIP) + { + if (!_wantCompress) + { + // workitem 8501: handle edge case (decompress empty stream) + if (_z.TotalBytesOut == 0L) + return; + + // Read and potentially verify the GZIP trailer: + // CRC32 and size mod 2^32 + byte[] trailer = new byte[8]; + + // workitems 8679 & 12554 + if (_z.AvailableBytesIn < 8) + { + // Make sure we have read to the end of the stream + Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, _z.AvailableBytesIn); + int bytesNeeded = 8 - _z.AvailableBytesIn; + int bytesRead = _stream.Read(trailer, + _z.AvailableBytesIn, + bytesNeeded); + if (bytesNeeded != bytesRead) + { + throw new ZlibException(String.Format("Missing or incomplete GZIP trailer. Expected 8 bytes, got {0}.", + _z.AvailableBytesIn + bytesRead)); + } + } + else + { + Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length); + } + + Int32 crc32_expected = BitConverter.ToInt32(trailer, 0); + Int32 crc32_actual = crc.Crc32Result; + Int32 isize_expected = BitConverter.ToInt32(trailer, 4); + Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF); + + if (crc32_actual != crc32_expected) + throw new ZlibException(String.Format("Bad CRC32 in GZIP trailer. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected)); + + if (isize_actual != isize_expected) + throw new ZlibException(String.Format("Bad size in GZIP trailer. (actual({0})!=expected({1}))", isize_actual, isize_expected)); + + } + else + { + throw new ZlibException("Reading with compression is not supported."); + } + } + } + } + + + private void end() + { + if (z == null) + return; + if (_wantCompress) + { + _z.EndDeflate(); + } + else + { + _z.EndInflate(); + } + _z = null; + } + + + public +#if !NETFX_CORE + override +#endif + void Close() + { + if (_stream == null) return; + try + { + finish(); + } + finally + { + end(); + if (!_leaveOpen) _stream.Dispose(); + _stream = null; + } + } + + public override void Flush() + { + _stream.Flush(); + } + + public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) + { + throw new NotImplementedException(); + //_outStream.Seek(offset, origin); + } + public override void SetLength(System.Int64 value) + { + _stream.SetLength(value); + nomoreinput = false; + } + + +#if NOT + public int Read() + { + if (Read(_buf1, 0, 1) == 0) + return 0; + // calculate CRC after reading + if (crc!=null) + crc.SlurpBlock(_buf1,0,1); + return (_buf1[0] & 0xFF); + } +#endif + + private bool nomoreinput = false; + + + + private string ReadZeroTerminatedString() + { + var list = new System.Collections.Generic.List(); + bool done = false; + do + { + // workitem 7740 + int n = _stream.Read(_buf1, 0, 1); + if (n != 1) + throw new ZlibException("Unexpected EOF reading GZIP header."); + else + { + if (_buf1[0] == 0) + done = true; + else + list.Add(_buf1[0]); + } + } while (!done); + byte[] a = list.ToArray(); + return GZipStream.iso8859dash1.GetString(a, 0, a.Length); + } + + + private int _ReadAndValidateGzipHeader() + { + int totalBytesRead = 0; + // read the header on the first read + byte[] header = new byte[10]; + int n = _stream.Read(header, 0, header.Length); + + // workitem 8501: handle edge case (decompress empty stream) + if (n == 0) + return 0; + + if (n != 10) + throw new ZlibException("Not a valid GZIP stream."); + + if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8) + throw new ZlibException("Bad GZIP header."); + + Int32 timet = BitConverter.ToInt32(header, 4); + _GzipMtime = GZipStream._unixEpoch.AddSeconds(timet); + totalBytesRead += n; + if ((header[3] & 0x04) == 0x04) + { + // read and discard extra field + n = _stream.Read(header, 0, 2); // 2-byte length field + totalBytesRead += n; + + Int16 extraLength = (Int16)(header[0] + header[1] * 256); + byte[] extra = new byte[extraLength]; + n = _stream.Read(extra, 0, extra.Length); + if (n != extraLength) + throw new ZlibException("Unexpected end-of-file reading GZIP header."); + totalBytesRead += n; + } + if ((header[3] & 0x08) == 0x08) + _GzipFileName = ReadZeroTerminatedString(); + if ((header[3] & 0x10) == 0x010) + _GzipComment = ReadZeroTerminatedString(); + if ((header[3] & 0x02) == 0x02) + Read(_buf1, 0, 1); // CRC16, ignore + + return totalBytesRead; + } + + + + public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count) + { + // According to MS documentation, any implementation of the IO.Stream.Read function must: + // (a) throw an exception if offset & count reference an invalid part of the buffer, + // or if count < 0, or if buffer is null + // (b) return 0 only upon EOF, or if count = 0 + // (c) if not EOF, then return at least 1 byte, up to bytes + + if (_streamMode == StreamMode.Undefined) + { + if (!this._stream.CanRead) throw new ZlibException("The stream is not readable."); + // for the first read, set up some controls. + _streamMode = StreamMode.Reader; + // (The first reference to _z goes through the private accessor which + // may initialize it.) + z.AvailableBytesIn = 0; + if (_flavor == ZlibStreamFlavor.GZIP) + { + _gzipHeaderByteCount = _ReadAndValidateGzipHeader(); + // workitem 8501: handle edge case (decompress empty stream) + if (_gzipHeaderByteCount == 0) + return 0; + } + } + + if (_streamMode != StreamMode.Reader) + throw new ZlibException("Cannot Read after Writing."); + + if (count == 0) return 0; + if (nomoreinput && _wantCompress) return 0; // workitem 8557 + if (buffer == null) throw new ArgumentNullException("buffer"); + if (count < 0) throw new ArgumentOutOfRangeException("count"); + if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset"); + if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count"); + + int rc = 0; + + // set up the output of the deflate/inflate codec: + _z.OutputBuffer = buffer; + _z.NextOut = offset; + _z.AvailableBytesOut = count; + + // This is necessary in case _workingBuffer has been resized. (new byte[]) + // (The first reference to _workingBuffer goes through the private accessor which + // may initialize it.) + _z.InputBuffer = workingBuffer; + + do + { + // need data in _workingBuffer in order to deflate/inflate. Here, we check if we have any. + if ((_z.AvailableBytesIn == 0) && (!nomoreinput)) + { + // No data available, so try to Read data from the captive stream. + _z.NextIn = 0; + _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length); + if (_z.AvailableBytesIn == 0) + nomoreinput = true; + + } + // we have data in InputBuffer; now compress or decompress as appropriate + rc = (_wantCompress) + ? _z.Deflate(_flushMode) + : _z.Inflate(_flushMode); + + if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR)) + return 0; + + if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + throw new ZlibException(String.Format("{0}flating: rc={1} msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message)); + + if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count)) + break; // nothing more to read + } + //while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK); + while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK); + + + // workitem 8557 + // is there more room in output? + if (_z.AvailableBytesOut > 0) + { + if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0) + { + // deferred + } + + // are we completely done reading? + if (nomoreinput) + { + // and in compression? + if (_wantCompress) + { + // no more input data available; therefore we flush to + // try to complete the read + rc = _z.Deflate(FlushType.Finish); + + if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + throw new ZlibException(String.Format("Deflating: rc={0} msg={1}", rc, _z.Message)); + } + } + } + + + rc = (count - _z.AvailableBytesOut); + + // calculate CRC after reading + if (crc != null) + crc.SlurpBlock(buffer, offset, rc); + + return rc; + } + + + + public override System.Boolean CanRead + { + get { return this._stream.CanRead; } + } + + public override System.Boolean CanSeek + { + get { return this._stream.CanSeek; } + } + + public override System.Boolean CanWrite + { + get { return this._stream.CanWrite; } + } + + public override System.Int64 Length + { + get { return _stream.Length; } + } + + public override long Position + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + internal enum StreamMode + { + Writer, + Reader, + Undefined, + } + + + public static void CompressString(String s, Stream compressor) + { + byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(s); + using (compressor) + { + compressor.Write(uncompressed, 0, uncompressed.Length); + } + } + + public static void CompressBuffer(byte[] b, Stream compressor) + { + // workitem 8460 + using (compressor) + { + compressor.Write(b, 0, b.Length); + } + } + + public static String UncompressString(byte[] compressed, Stream decompressor) + { + // workitem 8460 + byte[] working = new byte[1024]; + var encoding = System.Text.Encoding.UTF8; + using (var output = new MemoryStream()) + { + using (decompressor) + { + int n; + while ((n = decompressor.Read(working, 0, working.Length)) != 0) + { + output.Write(working, 0, n); + } + } + + // reset to allow read from start + output.Seek(0, SeekOrigin.Begin); + var sr = new StreamReader(output, encoding); + return sr.ReadToEnd(); + } + } + + public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor) + { + // workitem 8460 + byte[] working = new byte[1024]; + using (var output = new MemoryStream()) + { + using (decompressor) + { + int n; + while ((n = decompressor.Read(working, 0, working.Length)) != 0) + { + output.Write(working, 0, n); + } + } + return output.ToArray(); + } + } + + } + + +} diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs.meta new file mode 100644 index 0000000..7824525 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibBaseStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b34dd239e486b474aad68fb4080797c8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs new file mode 100644 index 0000000..2e45ee7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs @@ -0,0 +1,712 @@ +// ZlibCodec.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-November-03 15:40:51> +// +// ------------------------------------------------------------------ +// +// This module defines a Codec for ZLIB compression and +// decompression. This code extends code that was based the jzlib +// implementation of zlib, but this code is completely novel. The codec +// class is new, and encapsulates some behaviors that are new, and some +// that were present in other classes in the jzlib code base. In +// keeping with the license for jzlib, the copyright to the jzlib code +// is included below. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; +using Interop=System.Runtime.InteropServices; + +namespace BestHTTP.Decompression.Zlib +{ + /// + /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951). + /// + /// + /// + /// This class compresses and decompresses data according to the Deflate algorithm + /// and optionally, the ZLIB format, as documented in RFC 1950 - ZLIB and RFC 1951 - DEFLATE. + /// + sealed internal class ZlibCodec + { + /// + /// The buffer from which data is taken. + /// + public byte[] InputBuffer; + + /// + /// An index into the InputBuffer array, indicating where to start reading. + /// + public int NextIn; + + /// + /// The number of bytes available in the InputBuffer, starting at NextIn. + /// + /// + /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. + /// The class will update this number as calls to Inflate/Deflate are made. + /// + public int AvailableBytesIn; + + /// + /// Total number of bytes read so far, through all calls to Inflate()/Deflate(). + /// + public long TotalBytesIn; + + /// + /// Buffer to store output data. + /// + public byte[] OutputBuffer; + + /// + /// An index into the OutputBuffer array, indicating where to start writing. + /// + public int NextOut; + + /// + /// The number of bytes available in the OutputBuffer, starting at NextOut. + /// + /// + /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. + /// The class will update this number as calls to Inflate/Deflate are made. + /// + public int AvailableBytesOut; + + /// + /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate(). + /// + public long TotalBytesOut; + + /// + /// used for diagnostics, when something goes wrong! + /// + public System.String Message; + + internal DeflateManager dstate; + internal InflateManager istate; + + internal uint _Adler32; + + /// + /// The compression level to use in this codec. Useful only in compression mode. + /// + public CompressionLevel CompressLevel = CompressionLevel.Default; + + /// + /// The number of Window Bits to use. + /// + /// + /// This gauges the size of the sliding window, and hence the + /// compression effectiveness as well as memory consumption. It's best to just leave this + /// setting alone if you don't know what it is. The maximum value is 15 bits, which implies + /// a 32k window. + /// + public int WindowBits = ZlibConstants.WindowBitsDefault; + + /// + /// The compression strategy to use. + /// + /// + /// This is only effective in compression. The theory offered by ZLIB is that different + /// strategies could potentially produce significant differences in compression behavior + /// for different data sets. Unfortunately I don't have any good recommendations for how + /// to set it differently. When I tested changing the strategy I got minimally different + /// compression performance. It's best to leave this property alone if you don't have a + /// good feel for it. Or, you may want to produce a test harness that runs through the + /// different strategy options and evaluates them on different file types. If you do that, + /// let me know your results. + /// + public CompressionStrategy Strategy = CompressionStrategy.Default; + + + /// + /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. + /// + public int Adler32 { get { return (int)_Adler32; } } + + + /// + /// Create a ZlibCodec. + /// + /// + /// If you use this default constructor, you will later have to explicitly call + /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress + /// or decompress. + /// + public ZlibCodec() { } + + /// + /// Create a ZlibCodec that either compresses or decompresses. + /// + /// + /// Indicates whether the codec should compress (deflate) or decompress (inflate). + /// + public ZlibCodec(CompressionMode mode) + { + if (mode == CompressionMode.Compress) + { + int rc = InitializeDeflate(); + if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate."); + } + else if (mode == CompressionMode.Decompress) + { + int rc = InitializeInflate(); + if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate."); + } + else throw new ZlibException("Invalid ZlibStreamFlavor."); + } + + /// + /// Initialize the inflation state. + /// + /// + /// It is not necessary to call this before using the ZlibCodec to inflate data; + /// It is implicitly called when you call the constructor. + /// + /// Z_OK if everything goes well. + public int InitializeInflate() + { + return InitializeInflate(this.WindowBits); + } + + /// + /// Initialize the inflation state with an explicit flag to + /// govern the handling of RFC1950 header bytes. + /// + /// + /// + /// By default, the ZLIB header defined in RFC 1950 is expected. If + /// you want to read a zlib stream you should specify true for + /// expectRfc1950Header. If you have a deflate stream, you will want to specify + /// false. It is only necessary to invoke this initializer explicitly if you + /// want to specify false. + /// + /// + /// whether to expect an RFC1950 header byte + /// pair when reading the stream of data to be inflated. + /// + /// Z_OK if everything goes well. + public int InitializeInflate(bool expectRfc1950Header) + { + return InitializeInflate(this.WindowBits, expectRfc1950Header); + } + + /// + /// Initialize the ZlibCodec for inflation, with the specified number of window bits. + /// + /// The number of window bits to use. If you need to ask what that is, + /// then you shouldn't be calling this initializer. + /// Z_OK if all goes well. + public int InitializeInflate(int windowBits) + { + this.WindowBits = windowBits; + return InitializeInflate(windowBits, true); + } + + /// + /// Initialize the inflation state with an explicit flag to govern the handling of + /// RFC1950 header bytes. + /// + /// + /// + /// If you want to read a zlib stream you should specify true for + /// expectRfc1950Header. In this case, the library will expect to find a ZLIB + /// header, as defined in RFC + /// 1950, in the compressed stream. If you will be reading a DEFLATE or + /// GZIP stream, which does not have such a header, you will want to specify + /// false. + /// + /// + /// whether to expect an RFC1950 header byte pair when reading + /// the stream of data to be inflated. + /// The number of window bits to use. If you need to ask what that is, + /// then you shouldn't be calling this initializer. + /// Z_OK if everything goes well. + public int InitializeInflate(int windowBits, bool expectRfc1950Header) + { + this.WindowBits = windowBits; + if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate()."); + istate = new InflateManager(expectRfc1950Header); + return istate.Initialize(this, windowBits); + } + + /// + /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. + /// + /// + /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and + /// AvailableBytesOut before calling this method. + /// + /// + /// + /// private void InflateBuffer() + /// { + /// int bufferSize = 1024; + /// byte[] buffer = new byte[bufferSize]; + /// ZlibCodec decompressor = new ZlibCodec(); + /// + /// Console.WriteLine("\n============================================"); + /// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); + /// MemoryStream ms = new MemoryStream(DecompressedBytes); + /// + /// int rc = decompressor.InitializeInflate(); + /// + /// decompressor.InputBuffer = CompressedBytes; + /// decompressor.NextIn = 0; + /// decompressor.AvailableBytesIn = CompressedBytes.Length; + /// + /// decompressor.OutputBuffer = buffer; + /// + /// // pass 1: inflate + /// do + /// { + /// decompressor.NextOut = 0; + /// decompressor.AvailableBytesOut = buffer.Length; + /// rc = decompressor.Inflate(FlushType.None); + /// + /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + /// throw new Exception("inflating: " + decompressor.Message); + /// + /// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); + /// } + /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); + /// + /// // pass 2: finish and flush + /// do + /// { + /// decompressor.NextOut = 0; + /// decompressor.AvailableBytesOut = buffer.Length; + /// rc = decompressor.Inflate(FlushType.Finish); + /// + /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) + /// throw new Exception("inflating: " + decompressor.Message); + /// + /// if (buffer.Length - decompressor.AvailableBytesOut > 0) + /// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); + /// } + /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); + /// + /// decompressor.EndInflate(); + /// } + /// + /// + /// + /// The flush to use when inflating. + /// Z_OK if everything goes well. + public int Inflate(FlushType flush) + { + if (istate == null) + throw new ZlibException("No Inflate State!"); + return istate.Inflate(flush); + } + + + /// + /// Ends an inflation session. + /// + /// + /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. + /// After calling this you cannot call Inflate() without a intervening call to one of the + /// InitializeInflate() overloads. + /// + /// Z_OK if everything goes well. + public int EndInflate() + { + if (istate == null) + throw new ZlibException("No Inflate State!"); + int ret = istate.End(); + istate = null; + return ret; + } + + /// + /// I don't know what this does! + /// + /// Z_OK if everything goes well. + public int SyncInflate() + { + if (istate == null) + throw new ZlibException("No Inflate State!"); + return istate.Sync(); + } + + /// + /// Initialize the ZlibCodec for deflation operation. + /// + /// + /// The codec will use the MAX window bits and the default level of compression. + /// + /// + /// + /// int bufferSize = 40000; + /// byte[] CompressedBytes = new byte[bufferSize]; + /// byte[] DecompressedBytes = new byte[bufferSize]; + /// + /// ZlibCodec compressor = new ZlibCodec(); + /// + /// compressor.InitializeDeflate(CompressionLevel.Default); + /// + /// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); + /// compressor.NextIn = 0; + /// compressor.AvailableBytesIn = compressor.InputBuffer.Length; + /// + /// compressor.OutputBuffer = CompressedBytes; + /// compressor.NextOut = 0; + /// compressor.AvailableBytesOut = CompressedBytes.Length; + /// + /// while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) + /// { + /// compressor.Deflate(FlushType.None); + /// } + /// + /// while (true) + /// { + /// int rc= compressor.Deflate(FlushType.Finish); + /// if (rc == ZlibConstants.Z_STREAM_END) break; + /// } + /// + /// compressor.EndDeflate(); + /// + /// + /// + /// Z_OK if all goes well. You generally don't need to check the return code. + public int InitializeDeflate() + { + return _InternalInitializeDeflate(true); + } + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel. + /// + /// + /// The codec will use the maximum window bits (15) and the specified + /// CompressionLevel. It will emit a ZLIB stream as it compresses. + /// + /// The compression level for the codec. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level) + { + this.CompressLevel = level; + return _InternalInitializeDeflate(true); + } + + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, + /// and the explicit flag governing whether to emit an RFC1950 header byte pair. + /// + /// + /// The codec will use the maximum window bits (15) and the specified CompressionLevel. + /// If you want to generate a zlib stream, you should specify true for + /// wantRfc1950Header. In this case, the library will emit a ZLIB + /// header, as defined in RFC + /// 1950, in the compressed stream. + /// + /// The compression level for the codec. + /// whether to emit an initial RFC1950 byte pair in the compressed stream. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header) + { + this.CompressLevel = level; + return _InternalInitializeDeflate(wantRfc1950Header); + } + + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, + /// and the specified number of window bits. + /// + /// + /// The codec will use the specified number of window bits and the specified CompressionLevel. + /// + /// The compression level for the codec. + /// the number of window bits to use. If you don't know what this means, don't use this method. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level, int bits) + { + this.CompressLevel = level; + this.WindowBits = bits; + return _InternalInitializeDeflate(true); + } + + /// + /// Initialize the ZlibCodec for deflation operation, using the specified + /// CompressionLevel, the specified number of window bits, and the explicit flag + /// governing whether to emit an RFC1950 header byte pair. + /// + /// + /// The compression level for the codec. + /// whether to emit an initial RFC1950 byte pair in the compressed stream. + /// the number of window bits to use. If you don't know what this means, don't use this method. + /// Z_OK if all goes well. + public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header) + { + this.CompressLevel = level; + this.WindowBits = bits; + return _InternalInitializeDeflate(wantRfc1950Header); + } + + private int _InternalInitializeDeflate(bool wantRfc1950Header) + { + if (istate != null) throw new ZlibException("You may not call InitializeDeflate() after calling InitializeInflate()."); + dstate = new DeflateManager(); + dstate.WantRfc1950HeaderBytes = wantRfc1950Header; + + return dstate.Initialize(this, this.CompressLevel, this.WindowBits, this.Strategy); + } + + /// + /// Deflate one batch of data. + /// + /// + /// You must have set InputBuffer and OutputBuffer before calling this method. + /// + /// + /// + /// private void DeflateBuffer(CompressionLevel level) + /// { + /// int bufferSize = 1024; + /// byte[] buffer = new byte[bufferSize]; + /// ZlibCodec compressor = new ZlibCodec(); + /// + /// Console.WriteLine("\n============================================"); + /// Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length); + /// MemoryStream ms = new MemoryStream(); + /// + /// int rc = compressor.InitializeDeflate(level); + /// + /// compressor.InputBuffer = UncompressedBytes; + /// compressor.NextIn = 0; + /// compressor.AvailableBytesIn = UncompressedBytes.Length; + /// + /// compressor.OutputBuffer = buffer; + /// + /// // pass 1: deflate + /// do + /// { + /// compressor.NextOut = 0; + /// compressor.AvailableBytesOut = buffer.Length; + /// rc = compressor.Deflate(FlushType.None); + /// + /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) + /// throw new Exception("deflating: " + compressor.Message); + /// + /// ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut); + /// } + /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); + /// + /// // pass 2: finish and flush + /// do + /// { + /// compressor.NextOut = 0; + /// compressor.AvailableBytesOut = buffer.Length; + /// rc = compressor.Deflate(FlushType.Finish); + /// + /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) + /// throw new Exception("deflating: " + compressor.Message); + /// + /// if (buffer.Length - compressor.AvailableBytesOut > 0) + /// ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); + /// } + /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); + /// + /// compressor.EndDeflate(); + /// + /// ms.Seek(0, SeekOrigin.Begin); + /// CompressedBytes = new byte[compressor.TotalBytesOut]; + /// ms.Read(CompressedBytes, 0, CompressedBytes.Length); + /// } + /// + /// + /// whether to flush all data as you deflate. Generally you will want to + /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to + /// flush everything. + /// + /// Z_OK if all goes well. + public int Deflate(FlushType flush) + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + return dstate.Deflate(flush); + } + + /// + /// End a deflation session. + /// + /// + /// Call this after making a series of one or more calls to Deflate(). All buffers are flushed. + /// + /// Z_OK if all goes well. + public int EndDeflate() + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + // TODO: dinoch Tue, 03 Nov 2009 15:39 (test this) + //int ret = dstate.End(); + dstate = null; + return ZlibConstants.Z_OK; //ret; + } + + /// + /// Reset a codec for another deflation session. + /// + /// + /// Call this to reset the deflation state. For example if a thread is deflating + /// non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first + /// block and before the next Deflate(None) of the second block. + /// + /// Z_OK if all goes well. + public void ResetDeflate() + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + dstate.Reset(); + } + + + /// + /// Set the CompressionStrategy and CompressionLevel for a deflation session. + /// + /// the level of compression to use. + /// the strategy to use for compression. + /// Z_OK if all goes well. + public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy) + { + if (dstate == null) + throw new ZlibException("No Deflate State!"); + return dstate.SetParams(level, strategy); + } + + + /// + /// Set the dictionary to be used for either Inflation or Deflation. + /// + /// The dictionary bytes to use. + /// Z_OK if all goes well. + public int SetDictionary(byte[] dictionary) + { + if (istate != null) + return istate.SetDictionary(dictionary); + + if (dstate != null) + return dstate.SetDictionary(dictionary); + + throw new ZlibException("No Inflate or Deflate state!"); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + internal void flush_pending() + { + int len = dstate.pendingCount; + + if (len > AvailableBytesOut) + len = AvailableBytesOut; + if (len == 0) + return; + + if (dstate.pending.Length <= dstate.nextPending || + OutputBuffer.Length <= NextOut || + dstate.pending.Length < (dstate.nextPending + len) || + OutputBuffer.Length < (NextOut + len)) + { + throw new ZlibException(String.Format("Invalid State. (pending.Length={0}, pendingCount={1})", + dstate.pending.Length, dstate.pendingCount)); + } + + Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len); + + NextOut += len; + dstate.nextPending += len; + TotalBytesOut += len; + AvailableBytesOut -= len; + dstate.pendingCount -= len; + if (dstate.pendingCount == 0) + { + dstate.nextPending = 0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + internal int read_buf(byte[] buf, int start, int size) + { + int len = AvailableBytesIn; + + if (len > size) + len = size; + if (len == 0) + return 0; + + AvailableBytesIn -= len; + + if (dstate.WantRfc1950HeaderBytes) + { + _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len); + } + Array.Copy(InputBuffer, NextIn, buf, start, len); + NextIn += len; + TotalBytesIn += len; + return len; + } + + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs.meta new file mode 100644 index 0000000..a017f14 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibCodec.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bc104cfa5b2ba31408766b86b9977226 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs new file mode 100644 index 0000000..b530c39 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs @@ -0,0 +1,128 @@ +// ZlibConstants.cs +// ------------------------------------------------------------------ +// +// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. +// All rights reserved. +// +// This code module is part of DotNetZip, a zipfile class library. +// +// ------------------------------------------------------------------ +// +// This code is licensed under the Microsoft Public License. +// See the file License.txt for the license details. +// More info on: http://dotnetzip.codeplex.com +// +// ------------------------------------------------------------------ +// +// last saved (in emacs): +// Time-stamp: <2009-November-03 18:50:19> +// +// ------------------------------------------------------------------ +// +// This module defines constants used by the zlib class library. This +// code is derived from the jzlib implementation of zlib, but +// significantly modified. In keeping with the license for jzlib, the +// copyright to that code is included here. +// +// ------------------------------------------------------------------ +// +// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the distribution. +// +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------- +// +// This program is based on zlib-1.1.3; credit to authors +// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) +// and contributors of zlib. +// +// ----------------------------------------------------------------------- + + +using System; + +namespace BestHTTP.Decompression.Zlib +{ + /// + /// A bunch of constants used in the Zlib interface. + /// + public static class ZlibConstants + { + /// + /// The maximum number of window bits for the Deflate algorithm. + /// + public const int WindowBitsMax = 15; // 32K LZ77 window + + /// + /// The default number of window bits for the Deflate algorithm. + /// + public const int WindowBitsDefault = WindowBitsMax; + + /// + /// indicates everything is A-OK + /// + public const int Z_OK = 0; + + /// + /// Indicates that the last operation reached the end of the stream. + /// + public const int Z_STREAM_END = 1; + + /// + /// The operation ended in need of a dictionary. + /// + public const int Z_NEED_DICT = 2; + + /// + /// There was an error with the stream - not enough data, not open and readable, etc. + /// + public const int Z_STREAM_ERROR = -2; + + /// + /// There was an error with the data - not enough data, bad data, etc. + /// + public const int Z_DATA_ERROR = -3; + + /// + /// There was an error with the working buffer. + /// + public const int Z_BUF_ERROR = -5; + + /// + /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes. + /// +#if NETCF + public const int WorkingBufferSizeDefault = 8192; +#else + public const int WorkingBufferSizeDefault = 16384; +#endif + /// + /// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes. + /// + public const int WorkingBufferSizeMin = 1024; + } + +} + diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs.meta new file mode 100644 index 0000000..a1659c4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Decompression/ZlibConstants.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4cd9445fbeecd0642955b4ea35e211c8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions.meta new file mode 100644 index 0000000..ee824e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e3ba637693c35a745aeb4052cfb287cb +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs new file mode 100644 index 0000000..9d1d5a6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs @@ -0,0 +1,55 @@ +using System; + +namespace BestHTTP.Extensions +{ + public sealed class CircularBuffer + { + public int Capacity { get; private set; } + public int Count { get; private set; } + + public T this[int idx] + { + get + { + int realIdx = (this.startIdx + idx) % this.Capacity; + + return this.buffer[realIdx]; + } + + set + { + int realIdx = (this.startIdx + idx) % this.Capacity; + + this.buffer[realIdx] = value; + } + } + + private T[] buffer; + private int startIdx; + private int endIdx; + + public CircularBuffer(int capacity) + { + this.Capacity = capacity; + } + + public void Add(T element) + { + if (this.buffer == null) + this.buffer = new T[this.Capacity]; + + this.buffer[this.endIdx] = element; + + this.endIdx = (this.endIdx + 1) % this.Capacity; + if (this.endIdx == this.startIdx) + this.startIdx = (this.startIdx + 1) % this.Capacity; + + this.Count = Math.Min(this.Count + 1, this.Capacity); + } + + public void Clear() + { + this.startIdx = this.endIdx = 0; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs.meta new file mode 100644 index 0000000..8953d83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/CircularBuffer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d3e42ed97af74b54fba27235416b1191 +timeCreated: 1508423928 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs new file mode 100644 index 0000000..c70b895 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs @@ -0,0 +1,449 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +#if NETFX_CORE + using Windows.Security.Cryptography; + using Windows.Security.Cryptography.Core; + using Windows.Storage.Streams; + using BestHTTP.PlatformSupport.IO; + + using FileStream = BestHTTP.PlatformSupport.IO.FileStream; +#elif UNITY_WP8 + using Cryptography = BestHTTP.PlatformSupport.Cryptography; +#else + using Cryptography = System.Security.Cryptography; + using FileStream = System.IO.FileStream; +#endif + +namespace BestHTTP.Extensions +{ + public static class Extensions + { + #region ASCII Encoding (These are required because Windows Phone doesn't supports the Encoding.ASCII class.) + + /// + /// On WP8 platform there are no ASCII encoding. + /// + public static string AsciiToString(this byte[] bytes) + { + StringBuilder sb = new StringBuilder(bytes.Length); + foreach (byte b in bytes) + sb.Append(b <= 0x7f ? (char)b : '?'); + return sb.ToString(); + } + + /// + /// On WP8 platform there are no ASCII encoding. + /// + public static byte[] GetASCIIBytes(this string str) + { + byte[] result = new byte[str.Length]; + for (int i = 0; i < str.Length; ++i) + { + char ch = str[i]; + result[i] = (byte)((ch < (char)0x80) ? ch : '?'); + } + + return result; + } + + public static void SendAsASCII(this BinaryWriter stream, string str) + { + for (int i = 0; i < str.Length; ++i) + { + char ch = str[i]; + + stream.Write((byte)((ch < (char)0x80) ? ch : '?')); + } + } + + #endregion + + #region FileSystem WriteLine function support + + public static void WriteLine(this FileStream fs) + { + fs.Write(HTTPRequest.EOL, 0, 2); + } + + public static void WriteLine(this FileStream fs, string line) + { + var buff = line.GetASCIIBytes(); + fs.Write(buff, 0, buff.Length); + fs.WriteLine(); + } + + public static void WriteLine(this FileStream fs, string format, params object[] values) + { + var buff = string.Format(format, values).GetASCIIBytes(); + fs.Write(buff, 0, buff.Length); + fs.WriteLine(); + } + + #endregion + + #region Other Extensions + + public static string GetRequestPathAndQueryURL(this Uri uri) + { + string requestPathAndQuery = uri.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped); + + // http://forum.unity3d.com/threads/best-http-released.200006/page-26#post-2723250 + if (string.IsNullOrEmpty(requestPathAndQuery)) + requestPathAndQuery = "/"; + + return requestPathAndQuery; + } + + public static string[] FindOption(this string str, string option) + { + //s-maxage=2678400, must-revalidate, max-age=0 + string[] options = str.ToLower().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + option = option.ToLower(); + + for (int i = 0; i < options.Length; ++i) + if (options[i].Contains(option)) + return options[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); + + return null; + } + + public static void WriteArray(this Stream stream, byte[] array) + { + stream.Write(array, 0, array.Length); + } + + /// + /// Returns true if the Uri's host is a valid IPv4 or IPv6 address. + /// + public static bool IsHostIsAnIPAddress(this Uri uri) + { + if (uri == null) + return false; + + return IsIpV4AddressValid(uri.Host) || IsIpV6AddressValid(uri.Host); + } + + // Original idea from: https://www.code4copy.com/csharp/c-validate-ip-address-string/ + // Working regex: https://www.regular-expressions.info/ip.html + private static readonly System.Text.RegularExpressions.Regex validIpV4AddressRegex = new System.Text.RegularExpressions.Regex("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b", System.Text.RegularExpressions.RegexOptions.IgnoreCase); + + /// + /// Validates an IPv4 address. + /// + public static bool IsIpV4AddressValid(string address) + { + if (!string.IsNullOrEmpty(address)) + return validIpV4AddressRegex.IsMatch(address.Trim()); + + return false; + } + + /// + /// Validates an IPv6 address. + /// + public static bool IsIpV6AddressValid(string address) + { +#if !NETFX_CORE + if (!string.IsNullOrEmpty(address)) + { + System.Net.IPAddress ip; + if (System.Net.IPAddress.TryParse(address, out ip)) + return ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6; + } +#endif + return false; + } + + #endregion + + #region String Conversions + + public static int ToInt32(this string str, int defaultValue = default(int)) + { + if (str == null) + return defaultValue; + + try + { + return int.Parse(str); + } + catch + { + return defaultValue; + } + } + + public static long ToInt64(this string str, long defaultValue = default(long)) + { + if (str == null) + return defaultValue; + + try + { + return long.Parse(str); + } + catch + { + return defaultValue; + } + } + + public static DateTime ToDateTime(this string str, DateTime defaultValue = default(DateTime)) + { + if (str == null) + return defaultValue; + + try + { + DateTime.TryParse(str, out defaultValue); + return defaultValue.ToUniversalTime(); + } + catch + { + return defaultValue; + } + } + + public static string ToStrOrEmpty(this string str) + { + if (str == null) + return String.Empty; + + return str; + } + + #endregion + + #region MD5 Hashing + + public static string CalculateMD5Hash(this string input) + { + return input.GetASCIIBytes().CalculateMD5Hash(); + } + + public static string CalculateMD5Hash(this byte[] input) + { +#if NETFX_CORE + var alg = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5); + IBuffer buff = CryptographicBuffer.CreateFromByteArray(input); + var hashed = alg.HashData(buff); + var res = CryptographicBuffer.EncodeToHexString(hashed); + return res; +#else + var hash = Cryptography.MD5.Create().ComputeHash(input); + var sb = new StringBuilder(); + foreach (var b in hash) + sb.Append(b.ToString("x2")); + return sb.ToString(); +#endif + } + + #endregion + + #region Efficient String Parsing Helpers + + internal static string Read(this string str, ref int pos, char block, bool needResult = true) + { + return str.Read(ref pos, (ch) => ch != block, needResult); + } + + internal static string Read(this string str, ref int pos, Func block, bool needResult = true) + { + if (pos >= str.Length) + return string.Empty; + + str.SkipWhiteSpace(ref pos); + + int startPos = pos; + + while (pos < str.Length && block(str[pos])) + pos++; + + string result = needResult ? str.Substring(startPos, pos - startPos) : null; + + // set position to the next char + pos++; + + return result; + } + + internal static string ReadPossibleQuotedText(this string str, ref int pos) + { + string result = string.Empty; + if (str == null) + return result; + + // It's a quoted text? + if (str[pos] == '\"') + { + // Skip the starting quote + str.Read(ref pos, '\"', false); + + // Read the text until the ending quote + result = str.Read(ref pos, '\"'); + + // Next option + str.Read(ref pos, ',', false); + } + else + // It's not a quoted text, so we will read until the next option + result = str.Read(ref pos, (ch) => ch != ',' && ch != ';'); + + return result; + } + + internal static void SkipWhiteSpace(this string str, ref int pos) + { + if (pos >= str.Length) + return; + + while (pos < str.Length && char.IsWhiteSpace(str[pos])) + pos++; + } + + internal static string TrimAndLower(this string str) + { + if (str == null) + return null; + + char[] buffer = new char[str.Length]; + int length = 0; + + for (int i = 0; i < str.Length; ++i) + { + char ch = str[i]; + if (!char.IsWhiteSpace(ch) && !char.IsControl(ch)) + buffer[length++] = char.ToLowerInvariant(ch); + } + + return new string(buffer, 0, length); + } + + internal static char? Peek(this string str, int pos) + { + if (pos < 0 || pos >= str.Length) + return null; + + return str[pos]; + } + + #endregion + + #region Specialized String Parsers + + //public, max-age=2592000 + internal static List ParseOptionalHeader(this string str) + { + List result = new List(); + + if (str == null) + return result; + + int idx = 0; + + // process the rest of the text + while (idx < str.Length) + { + // Read key + string key = str.Read(ref idx, (ch) => ch != '=' && ch != ',').TrimAndLower(); + HeaderValue qp = new HeaderValue(key); + + if (str[idx - 1] == '=') + qp.Value = str.ReadPossibleQuotedText(ref idx); + + result.Add(qp); + } + + return result; + } + + //deflate, gzip, x-gzip, identity, *;q=0 + internal static List ParseQualityParams(this string str) + { + List result = new List(); + + if (str == null) + return result; + + int idx = 0; + while (idx < str.Length) + { + string key = str.Read(ref idx, (ch) => ch != ',' && ch != ';').TrimAndLower(); + + HeaderValue qp = new HeaderValue(key); + + if (str[idx - 1] == ';') + { + str.Read(ref idx, '=', false); + qp.Value = str.Read(ref idx, ','); + } + + result.Add(qp); + } + + return result; + } + + #endregion + + #region Buffer Filling + + /// + /// Will fill the entire buffer from the stream. Will throw an exception when the underlying stream is closed. + /// + public static void ReadBuffer(this Stream stream, byte[] buffer) + { + int count = 0; + + do + { + int read = stream.Read(buffer, count, buffer.Length - count); + + if (read <= 0) + throw ExceptionHelper.ServerClosedTCPStream(); + + count += read; + } while (count < buffer.Length); + } + + #endregion + + #region MemoryStream + + public static void WriteAll(this MemoryStream ms, byte[] buffer) + { + ms.Write(buffer, 0, buffer.Length); + } + + public static void WriteString(this MemoryStream ms, string str) + { + byte[] buffer = Encoding.UTF8.GetBytes(str); + ms.WriteAll(buffer); + } + + public static void WriteLine(this MemoryStream ms) + { + ms.WriteAll(HTTPRequest.EOL); + } + + public static void WriteLine(this MemoryStream ms, string str) + { + ms.WriteString(str); + ms.WriteLine(); + } + + #endregion + } + + public static class ExceptionHelper + { + public static Exception ServerClosedTCPStream() + { + return new Exception("TCP Stream closed unexpectedly by the remote server"); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs.meta new file mode 100644 index 0000000..d37e2a4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Extensions.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3ed17defed57cb64697daf74b5bb5873 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs new file mode 100644 index 0000000..238c90e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs @@ -0,0 +1,398 @@ +// Based on https://github.com/nickgravelyn/UnityToolbag/blob/master/Future/Future.cs +/* + * The MIT License (MIT) + +Copyright (c) 2017, Nick Gravelyn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + * */ + +using System; +using System.Collections.Generic; + +namespace BestHTTP.Futures +{ + /// + /// Describes the state of a future. + /// + public enum FutureState + { + /// + /// The future hasn't begun to resolve a value. + /// + Pending, + + /// + /// The future is working on resolving a value. + /// + Processing, + + /// + /// The future has a value ready. + /// + Success, + + /// + /// The future failed to resolve a value. + /// + Error + } + + /// + /// Defines the interface of an object that can be used to track a future value. + /// + /// The type of object being retrieved. + public interface IFuture + { + /// + /// Gets the state of the future. + /// + FutureState state { get; } + + /// + /// Gets the value if the State is Success. + /// + T value { get; } + + /// + /// Gets the failure exception if the State is Error. + /// + Exception error { get; } + + /// + /// Adds a new callback to invoke when an intermediate result is known. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + IFuture OnItem(FutureValueCallback callback); + + /// + /// Adds a new callback to invoke if the future value is retrieved successfully. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + IFuture OnSuccess(FutureValueCallback callback); + + /// + /// Adds a new callback to invoke if the future has an error. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + IFuture OnError(FutureErrorCallback callback); + + /// + /// Adds a new callback to invoke if the future value is retrieved successfully or has an error. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + IFuture OnComplete(FutureCallback callback); + } + + /// + /// Defines the signature for callbacks used by the future. + /// + /// The future. + public delegate void FutureCallback(IFuture future); + + public delegate void FutureValueCallback(T value); + public delegate void FutureErrorCallback(Exception error); + + /// + /// An implementation of that can be used internally by methods that return futures. + /// + /// + /// Methods should always return the interface when calling code requests a future. + /// This class is intended to be constructed internally in the method to provide a simple implementation of + /// the interface. By returning the interface instead of the class it ensures the implementation can change + /// later on if requirements change, without affecting the calling code. + /// + /// The type of object being retrieved. + public class Future : IFuture + { + private volatile FutureState _state; + private T _value; + private Exception _error; + private Func _processFunc; + + private readonly List> _itemCallbacks = new List>(); + private readonly List> _successCallbacks = new List>(); + private readonly List _errorCallbacks = new List(); + private readonly List> _complationCallbacks = new List>(); + + /// + /// Gets the state of the future. + /// + public FutureState state { get { return _state; } } + + /// + /// Gets the value if the State is Success. + /// + public T value + { + get + { + if (_state != FutureState.Success && _state != FutureState.Processing) + { + throw new InvalidOperationException("value is not available unless state is Success or Processing."); + } + + return _value; + } + } + + /// + /// Gets the failure exception if the State is Error. + /// + public Exception error + { + get + { + if (_state != FutureState.Error) + { + throw new InvalidOperationException("error is not available unless state is Error."); + } + + return _error; + } + } + + /// + /// Initializes a new instance of the class. + /// + public Future() + { + _state = FutureState.Pending; + } + + public IFuture OnItem(FutureValueCallback callback) + { + if (_state < FutureState.Success && !_itemCallbacks.Contains(callback)) + _itemCallbacks.Add(callback); + + return this; + } + + /// + /// Adds a new callback to invoke if the future value is retrieved successfully. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + public IFuture OnSuccess(FutureValueCallback callback) + { + if (_state == FutureState.Success) + { + callback(this.value); + } + else if (_state != FutureState.Error && !_successCallbacks.Contains(callback)) + { + _successCallbacks.Add(callback); + } + + return this; + } + + /// + /// Adds a new callback to invoke if the future has an error. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + public IFuture OnError(FutureErrorCallback callback) + { + if (_state == FutureState.Error) + { + callback(this.error); + } + else if (_state != FutureState.Success && !_errorCallbacks.Contains(callback)) + { + _errorCallbacks.Add(callback); + } + + return this; + } + + /// + /// Adds a new callback to invoke if the future value is retrieved successfully or has an error. + /// + /// The callback to invoke. + /// The future so additional calls can be chained together. + public IFuture OnComplete(FutureCallback callback) + { + if (_state == FutureState.Success || _state == FutureState.Error) + { + callback(this); + } + else + { + if (!_complationCallbacks.Contains(callback)) + _complationCallbacks.Add(callback); + } + + return this; + } + + /// + /// Begins running a given function on a background thread to resolve the future's value, as long + /// as it is still in the Pending state. + /// + /// The function that will retrieve the desired value. + public IFuture Process(Func func) + { + if (_state != FutureState.Pending) + { + throw new InvalidOperationException("Cannot process a future that isn't in the Pending state."); + } + + BeginProcess(); + _processFunc = func; + +#if NETFX_CORE +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(ThreadFunc); +#pragma warning restore 4014 +#else + System.Threading.ThreadPool.QueueUserWorkItem(ThreadFunc); +#endif + + return this; + } + + private +#if NETFX_CORE + async +#endif + void ThreadFunc(object param) + { + try + { + // Directly call the Impl version to avoid the state validation of the public method + AssignImpl(_processFunc()); + } + catch (Exception e) + { + // Directly call the Impl version to avoid the state validation of the public method + FailImpl(e); + } + finally + { + _processFunc = null; + } + } + + /// + /// Allows manually assigning a value to a future, as long as it is still in the pending state. + /// + /// + /// There are times where you may not need to do background processing for a value. For example, + /// you may have a cache of values and can just hand one out. In those cases you still want to + /// return a future for the method signature, but can just call this method to fill in the future. + /// + /// The value to assign the future. + public void Assign(T value) + { + if (_state != FutureState.Pending && _state != FutureState.Processing) + { + throw new InvalidOperationException("Cannot assign a value to a future that isn't in the Pending or Processing state."); + } + + AssignImpl(value); + } + + public void BeginProcess(T initialItem = default(T)) + { + _state = FutureState.Processing; + _value = initialItem; + } + + public void AssignItem(T value) + { + _value = value; + _error = null; + + foreach (var callback in _itemCallbacks) + callback(this.value); + } + + /// + /// Allows manually failing a future, as long as it is still in the pending state. + /// + /// + /// As with the Assign method, there are times where you may know a future value is a failure without + /// doing any background work. In those cases you can simply fail the future manually and return it. + /// + /// The exception to use to fail the future. + public void Fail(Exception error) + { + if (_state != FutureState.Pending && _state != FutureState.Processing) + { + throw new InvalidOperationException("Cannot fail future that isn't in the Pending or Processing state."); + } + + FailImpl(error); + } + + private void AssignImpl(T value) + { + _value = value; + _error = null; + _state = FutureState.Success; + + FlushSuccessCallbacks(); + } + + private void FailImpl(Exception error) + { + _value = default(T); + _error = error; + _state = FutureState.Error; + + FlushErrorCallbacks(); + } + + private void FlushSuccessCallbacks() + { + foreach (var callback in _successCallbacks) + callback(this.value); + + FlushComplationCallbacks(); + } + + private void FlushErrorCallbacks() + { + foreach (var callback in _errorCallbacks) + callback(this.error); + + FlushComplationCallbacks(); + } + + private void FlushComplationCallbacks() + { + foreach (var callback in _complationCallbacks) + callback(this); + ClearCallbacks(); + } + + private void ClearCallbacks() + { + _itemCallbacks.Clear(); + _successCallbacks.Clear(); + _errorCallbacks.Clear(); + _complationCallbacks.Clear(); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs.meta new file mode 100644 index 0000000..0d8059d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/Future.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: a9009e6f5e86bd5459d443846e42be9e +timeCreated: 1515175777 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs new file mode 100644 index 0000000..a2a63ad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; + +namespace BestHTTP.Extensions +{ + /// + /// Will parse a comma-separeted header value + /// + public sealed class HeaderParser : KeyValuePairList + { + public HeaderParser(string headerStr) + { + base.Values = Parse(headerStr); + } + + private List Parse(string headerStr) + { + List result = new List(); + + int pos = 0; + + try + { + while (pos < headerStr.Length) + { + HeaderValue current = new HeaderValue(); + + current.Parse(headerStr, ref pos); + + result.Add(current); + } + } + catch(System.Exception ex) + { + HTTPManager.Logger.Exception("HeaderParser - Parse", headerStr, ex); + } + + return result; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs.meta new file mode 100644 index 0000000..3fffbec --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 40ea771765c2ae549abc4c264e500b76 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs new file mode 100644 index 0000000..923b53a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Extensions +{ + /// + /// Used in string parsers. Its Value is optional. + /// + public sealed class HeaderValue + { + #region Public Properties + + public string Key { get; set; } + public string Value { get; set; } + public List Options { get; set; } + + public bool HasValue { get { return !string.IsNullOrEmpty(this.Value); } } + + #endregion + + #region Constructors + + public HeaderValue() + { } + + public HeaderValue(string key) + { + this.Key = key; + } + + #endregion + + #region Public Helper Functions + + public void Parse(string headerStr, ref int pos) + { + ParseImplementation(headerStr, ref pos, true); + } + + public bool TryGetOption(string key, out HeaderValue option) + { + option = null; + + if (Options == null || Options.Count == 0) + return false; + + for (int i = 0; i < Options.Count; ++i) + if (String.Equals(Options[i].Key, key, StringComparison.OrdinalIgnoreCase)) + { + option = Options[i]; + return true; + } + + return false; + } + + #endregion + + #region Private Helper Functions + + private void ParseImplementation(string headerStr, ref int pos, bool isOptionIsAnOption) + { + string key = headerStr.Read(ref pos, (ch) => ch != ';' && ch != '=' && ch != ',', true); + this.Key = key; + + char? skippedChar = headerStr.Peek(pos - 1); + bool isValue = skippedChar == '='; + bool isOption = isOptionIsAnOption && skippedChar == ';'; + + while (skippedChar != null && isValue || isOption) + { + + if (isValue) + { + string value = headerStr.ReadPossibleQuotedText(ref pos); + this.Value = value; + } + else if (isOption) + { + HeaderValue option = new HeaderValue(); + option.ParseImplementation(headerStr, ref pos, false); + + if (this.Options == null) + this.Options = new List(); + + this.Options.Add(option); + } + + if (!isOptionIsAnOption) + return; + + skippedChar = headerStr.Peek(pos - 1); + isValue = skippedChar == '='; + isOption = isOptionIsAnOption && skippedChar == ';'; + } + } + + #endregion + + #region Overrides + + public override string ToString() + { + if (!string.IsNullOrEmpty(Value)) + return String.Concat(Key, '=', Value); + else + return Key; + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs.meta new file mode 100644 index 0000000..b2c250c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeaderValue.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1465d4183951bf64dad0047b7c6e7243 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs new file mode 100644 index 0000000..f768fa2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Extensions +{ + public interface IHeartbeat + { + void OnHeartbeatUpdate(TimeSpan dif); + } + + /// + /// A manager class that can handle subscribing and unsubscribeing in the same update. + /// + public sealed class HeartbeatManager + { + private List Heartbeats = new List(); + private IHeartbeat[] UpdateArray; + private DateTime LastUpdate = DateTime.MinValue; + + public void Subscribe(IHeartbeat heartbeat) + { + lock (Heartbeats) + { + if (!Heartbeats.Contains(heartbeat)) + Heartbeats.Add(heartbeat); + } + } + + public void Unsubscribe(IHeartbeat heartbeat) + { + lock (Heartbeats) + Heartbeats.Remove(heartbeat); + } + + public void Update() + { + if (LastUpdate == DateTime.MinValue) + LastUpdate = DateTime.UtcNow; + else + { + TimeSpan dif = DateTime.UtcNow - LastUpdate; + LastUpdate = DateTime.UtcNow; + + int count = 0; + + lock (Heartbeats) + { + if (UpdateArray == null || UpdateArray.Length < Heartbeats.Count) + Array.Resize(ref UpdateArray, Heartbeats.Count); + + Heartbeats.CopyTo(0, UpdateArray, 0, Heartbeats.Count); + + count = Heartbeats.Count; + } + + for (int i = 0; i < count; ++i) + { + try + { + UpdateArray[i].OnHeartbeatUpdate(dif); + } + catch + { } + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs.meta new file mode 100644 index 0000000..c9d056e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/HeartbeatManager.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c610eeb580ec8e4c90789edb631cc76 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs new file mode 100644 index 0000000..c18c18b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Extensions +{ + /// + /// Base class for specialized parsers + /// + public class KeyValuePairList + { + public List Values { get; protected set; } + + public bool TryGet(string valueKeyName, out HeaderValue @param) + { + @param = null; + for (int i = 0; i < Values.Count; ++i) + if (string.CompareOrdinal(Values[i].Key, valueKeyName) == 0) + { + @param = Values[i]; + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs.meta new file mode 100644 index 0000000..5c6d9fc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/KeyValuePairList.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 834cc34ef3418894589ef2e8389ff8c0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs new file mode 100644 index 0000000..3af73ee --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Extensions +{ + /// + /// Used for parsing WWW-Authenticate headers: + /// Digest realm="my realm", nonce="4664b327a2963503ba58bbe13ad672c0", qop=auth, opaque="f7e38bdc1c66fce214f9019ffe43117c" + /// + public sealed class WWWAuthenticateHeaderParser : KeyValuePairList + { + public WWWAuthenticateHeaderParser(string headerValue) + { + Values = ParseQuotedHeader(headerValue); + } + + private List ParseQuotedHeader(string str) + { + List result = new List(); + + if (str != null) + { + + int idx = 0; + + // Read Type (Basic|Digest) + string type = str.Read(ref idx, (ch) => !char.IsWhiteSpace(ch) && !char.IsControl(ch)).TrimAndLower(); + result.Add(new HeaderValue(type)); + + // process the rest of the text + while (idx < str.Length) + { + // Read key + string key = str.Read(ref idx, '=').TrimAndLower(); + HeaderValue qp = new HeaderValue(key); + + // Skip any white space + str.SkipWhiteSpace(ref idx); + + qp.Value = str.ReadPossibleQuotedText(ref idx); + + result.Add(qp); + } + } + return result; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs.meta new file mode 100644 index 0000000..d26dda6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WWWAuthenticateHeaderParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4cba91161fe643c419eedafefdf1f959 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs new file mode 100644 index 0000000..b1aeeb7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs @@ -0,0 +1,70 @@ +using System; +using System.IO; + +namespace BestHTTP.Extensions +{ + /// + /// A custom buffer stream implementation that will not close the underlying stream. + /// + public sealed class WriteOnlyBufferedStream : Stream + { + public override bool CanRead { get { return false; } } + public override bool CanSeek { get { return false; } } + public override bool CanWrite { get { return true; } } + public override long Length { get { return this.buffer.Length; } } + + public override long Position { get { return this._position; } set { throw new NotImplementedException("Position set"); } } + private int _position; + + private byte[] buffer; + private Stream stream; + + public WriteOnlyBufferedStream(Stream stream, int bufferSize) + { + this.stream = stream; + + this.buffer = new byte[bufferSize]; + this._position = 0; + } + + public override void Flush() + { + if (this._position > 0) + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Information("BufferStream", string.Format("Flushing {0:N0} bytes", this._position)); + + this.stream.Write(this.buffer, 0, this._position); + this._position = 0; + } + } + + public override void Write(byte[] bufferFrom, int offset, int count) + { + while (count > 0) + { + int writeCount = Math.Min(count, this.buffer.Length - this._position); + Array.Copy(bufferFrom, offset, this.buffer, this._position, writeCount); + + this._position += writeCount; + offset += writeCount; + count -= writeCount; + + if (this._position == this.buffer.Length) + this.Flush(); + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + return 0; + } + + public override long Seek(long offset, SeekOrigin origin) + { + return 0; + } + + public override void SetLength(long value) { } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs.meta new file mode 100644 index 0000000..01a1523 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Extensions/WriteOnlyBufferedStream.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2df120a767773ee478acf872b86ae326 +timeCreated: 1530027551 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms.meta new file mode 100644 index 0000000..dbba7c2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 867abf3a1ab01c84681b6c85becf6b6d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs new file mode 100644 index 0000000..5ff5e79 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Forms +{ + /// + /// This class represents a HTTP Form's field. + /// + public class HTTPFieldData + { + /// + /// The form's field. + /// + public string Name { get; set; } + + /// + /// Filename of the field. Optional. + /// + public string FileName { get; set; } + + /// + /// Mime-type of the field. Optional + /// + public string MimeType { get; set; } + + /// + /// Encoding of the data. Optional + /// + public Encoding Encoding { get; set; } + + /// + /// The field's textual data. + /// + public string Text { get; set; } + + /// + /// The field's binary data. + /// + public byte[] Binary { get; set; } + + /// + /// Will return with the binary data, or if it's not present the textual data will be decoded to binary. + /// + public byte[] Payload + { + get + { + if (Binary != null) + return Binary; + + if (Encoding == null) + Encoding = Encoding.UTF8; + + return Binary = Encoding.GetBytes(Text); + } + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs.meta new file mode 100644 index 0000000..27f683c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFieldData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bdf9d0d59653fa8418a86f22360ff91e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs new file mode 100644 index 0000000..949dfd7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Forms +{ + /// + /// Base class of a concrete implementation. Don't use it to create a form, use instead one of the already wrote implementation(HTTPMultiPartForm, HTTPUrlEncodedForm), or create a new one by inheriting from this base class. + /// + public class HTTPFormBase + { + const int LongLength = 256; + + #region Properties + + /// + /// A list that holds the form's fields. + /// + public List Fields { get; set; } + + /// + /// Returns true if the Fields has no element. + /// + public bool IsEmpty { get { return Fields == null || Fields.Count == 0; } } + + /// + /// True if new fields has been added to our list. + /// + public bool IsChanged { get; protected set; } + + /// + /// True if there are at least one form-field with binary data. + /// + public bool HasBinary { get; protected set; } + + /// + /// True if there are at least one form-field with a long textual data. + /// + public bool HasLongValue { get; protected set; } + + #endregion + + #region Field Management + + public void AddBinaryData(string fieldName, byte[] content) + { + AddBinaryData(fieldName, content, null, null); + } + + public void AddBinaryData(string fieldName, byte[] content, string fileName) + { + AddBinaryData(fieldName, content, fileName, null); + } + + public void AddBinaryData(string fieldName, byte[] content, string fileName, string mimeType) + { + if (Fields == null) + Fields = new List(); + + HTTPFieldData field = new HTTPFieldData(); + field.Name = fieldName; + + if (fileName == null) + field.FileName = fieldName + ".dat"; + else + field.FileName = fileName; + + if (mimeType == null) + field.MimeType = "application/octet-stream"; + else + field.MimeType = mimeType; + + field.Binary = content; + + Fields.Add(field); + + HasBinary = IsChanged = true; + } + + public void AddField(string fieldName, string value) + { + AddField(fieldName, value, System.Text.Encoding.UTF8); + } + + public void AddField(string fieldName, string value, System.Text.Encoding e) + { + if (Fields == null) + Fields = new List(); + + HTTPFieldData field = new HTTPFieldData(); + field.Name = fieldName; + field.FileName = null; + if (e != null) + field.MimeType = "text/plain; charset=" + e.WebName; + field.Text = value; + field.Encoding = e; + + Fields.Add(field); + + IsChanged = true; + + HasLongValue |= value.Length > LongLength; + } + + #endregion + + #region Virtual Functions + + /// + /// It should 'clone' all the data from the given HTTPFormBase object. + /// Called after the form-implementation created. + /// + public virtual void CopyFrom(HTTPFormBase fields) + { + this.Fields = new List(fields.Fields); + this.IsChanged = true; + + this.HasBinary = fields.HasBinary; + this.HasLongValue = fields.HasLongValue; + } + + /// + /// Prepares the request to sending a form. It should set only the headers. + /// + public virtual void PrepareRequest(HTTPRequest request) + { + throw new NotImplementedException(); + } + + /// + /// Prepares and returns with the form's raw data. + /// + public virtual byte[] GetData() + { + throw new NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs.meta new file mode 100644 index 0000000..88b2c9a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7d275ec92441f18449bffc98e08d44e8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs new file mode 100644 index 0000000..67a4e37 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Forms +{ + public enum HTTPFormUsage + { + /// + /// The plugin will try to choose the best form sending method. + /// + Automatic, + + /// + /// The plugin will use the Url-Encoded form sending. + /// + UrlEncoded, + + /// + /// The plugin will use the Multipart form sending. + /// + Multipart, + + /// + /// Using this type of form, the plugin will send the data converted to a JSon string. + /// + RawJSon, + +#if !BESTHTTP_DISABLE_UNITY_FORM + /// + /// The legacy, Unity-based form sending. + /// + Unity +#endif + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs.meta new file mode 100644 index 0000000..f23208a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/HTTPFormUsage.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fc8643409dcf53d4db0bf0f654ad8500 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations.meta new file mode 100644 index 0000000..f742325 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: acc326f47252d77498d6489dce7ff997 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs new file mode 100644 index 0000000..8765ed8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs @@ -0,0 +1,79 @@ +using BestHTTP.Extensions; + +namespace BestHTTP.Forms +{ + /// + /// A HTTP Form implementation to send textual and binary values. + /// + public sealed class HTTPMultiPartForm : HTTPFormBase + { + #region Private Fields + + /// + /// A random boundary generated in the constructor. + /// + private string Boundary; + + /// + /// + /// + private byte[] CachedData; + + #endregion + + public HTTPMultiPartForm() + { + this.Boundary = "BestHTTP_HTTPMultiPartForm_" + this.GetHashCode().ToString("X"); + } + + #region IHTTPForm Implementation + + public override void PrepareRequest(HTTPRequest request) + { + // Set up Content-Type header for the request + request.SetHeader("Content-Type", "multipart/form-data; boundary=\"" + Boundary + "\""); + } + + public override byte[] GetData() + { + if (CachedData != null) + return CachedData; + + using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) + { + for (int i = 0; i < Fields.Count; ++i) + { + HTTPFieldData field = Fields[i]; + + // Set the boundary + ms.WriteLine("--" + Boundary); + + // Set up Content-Disposition header to our form with the name + ms.WriteLine("Content-Disposition: form-data; name=\"" + field.Name + "\"" + (!string.IsNullOrEmpty(field.FileName) ? "; filename=\"" + field.FileName + "\"" : string.Empty)); + + // Set up Content-Type head for the form. + if (!string.IsNullOrEmpty(field.MimeType)) + ms.WriteLine("Content-Type: " + field.MimeType); + + ms.WriteLine("Content-Length: " + field.Payload.Length.ToString()); + ms.WriteLine(); + + // Write the actual data to the MemoryStream + ms.Write(field.Payload, 0, field.Payload.Length); + + ms.Write(HTTPRequest.EOL, 0, HTTPRequest.EOL.Length); + } + + // Write out the trailing boundary + ms.WriteLine("--" + Boundary + "--"); + + IsChanged = false; + + // Set the RawData of our request + return CachedData = ms.ToArray(); + } + } + + #endregion + }; +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs.meta new file mode 100644 index 0000000..d223b1f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPMultiPartForm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5f9390c7b6f72b845805363b01dfbba9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs new file mode 100644 index 0000000..694123d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Forms +{ + /// + /// A HTTP Form implementation to send textual values. + /// + public sealed class HTTPUrlEncodedForm : HTTPFormBase + { + private const int EscapeTreshold = 256; + + private byte[] CachedData; + + public override void PrepareRequest(HTTPRequest request) + { + request.SetHeader("Content-Type", "application/x-www-form-urlencoded"); + } + + public override byte[] GetData() + { + if (CachedData != null && !IsChanged) + return CachedData; + + StringBuilder sb = new StringBuilder(); + + // Create a "field1=value1&field2=value2" formatted string + for (int i = 0; i < Fields.Count; ++i) + { + var field = Fields[i]; + + if (i > 0) + sb.Append("&"); + + sb.Append(EscapeString(field.Name)); + sb.Append("="); + + if (!string.IsNullOrEmpty(field.Text) || field.Binary == null) + sb.Append(EscapeString(field.Text)); + else + // If forced to this form type with binary data, we will create a string from the binary data first and encode this string. + sb.Append(EscapeString(Encoding.UTF8.GetString(field.Binary, 0, field.Binary.Length))); + } + + IsChanged = false; + return CachedData = Encoding.UTF8.GetBytes(sb.ToString()); + } + + public static string EscapeString(string originalString) + { + if (originalString.Length < EscapeTreshold) + return Uri.EscapeDataString(originalString); + else + { + int loops = originalString.Length / EscapeTreshold; + StringBuilder sb = new StringBuilder(loops); + + for (int i = 0; i <= loops; i++) + sb.Append(i < loops ? + Uri.EscapeDataString(originalString.Substring(EscapeTreshold * i, EscapeTreshold)) : + Uri.EscapeDataString(originalString.Substring(EscapeTreshold * i))); + return sb.ToString(); + } + } + + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs.meta new file mode 100644 index 0000000..74123e8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/HTTPUrlEncodedForm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 023a00e6d3a980b4babe8c70a7d00088 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs new file mode 100644 index 0000000..123fd30 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs @@ -0,0 +1,36 @@ +// Contributed by Matt Senne from conjoinedcats.com +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Forms +{ + public sealed class RawJsonForm : HTTPFormBase + { + private byte[] CachedData; + + /// + /// Prepares the request to sending a form. It should set only the headers. + /// + public override void PrepareRequest(HTTPRequest request) + { + request.SetHeader("Content-Type", "application/json"); + } + + /// + /// Prepares and returns with the form's raw data. + /// + public override byte[] GetData() + { + if (CachedData != null && !IsChanged) + return CachedData; + + Dictionary dict = Fields.ToDictionary(x => x.Name, x => x.Text); + string json = JSON.Json.Encode(dict); + + IsChanged = false; + return CachedData = Encoding.UTF8.GetBytes(json); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs.meta new file mode 100644 index 0000000..03d9d0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/RawJSonForm.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 23946220d212ad04aaff31e9eccd4018 +timeCreated: 1493280601 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs new file mode 100644 index 0000000..a733944 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs @@ -0,0 +1,58 @@ +#if !BESTHTTP_DISABLE_UNITY_FORM +using UnityEngine; + +namespace BestHTTP.Forms +{ + /// + /// For backward compatibility. + /// + public sealed class UnityForm : HTTPFormBase + { + public WWWForm Form { get; set; } + + public UnityForm() + { + } + + public UnityForm(WWWForm form) + { + Form = form; + } + + public override void CopyFrom(HTTPFormBase fields) + { + this.Fields = fields.Fields; + this.IsChanged = true; + + if (Form == null) + { + Form = new WWWForm(); + + if (Fields != null) + for (int i = 0; i < Fields.Count; ++i) + { + var field = Fields[i]; + + if (string.IsNullOrEmpty(field.Text) && field.Binary != null) + Form.AddBinaryData(field.Name, field.Binary, field.FileName, field.MimeType); + else + Form.AddField(field.Name, field.Text, field.Encoding); + } + } + } + + public override void PrepareRequest(HTTPRequest request) + { + if (Form.headers.ContainsKey("Content-Type")) + request.SetHeader("Content-Type", Form.headers["Content-Type"] as string); + else + request.SetHeader("Content-Type", "application/x-www-form-urlencoded"); + } + + public override byte[] GetData() + { + return Form.data; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs.meta new file mode 100644 index 0000000..0544a39 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Forms/Implementations/UnityForm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1ab404a2f1bd3424684f1178b910d2d6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs new file mode 100644 index 0000000..918e860 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs @@ -0,0 +1,889 @@ +using System; +using System.Collections.Generic; +using System.IO; + +using System.Text; +using System.Threading; +using BestHTTP.Extensions; +using BestHTTP.Authentication; + +#if (!NETFX_CORE && !UNITY_WP8) || UNITY_EDITOR + using System.Net.Security; +#endif + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + using BestHTTP.Caching; +#endif + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + using Org.BouncyCastle.Crypto.Tls; +#endif + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + using BestHTTP.Cookies; +#endif + +#if NETFX_CORE || BUILD_FOR_WP8 + using System.Threading.Tasks; + using Windows.Networking.Sockets; + + using TcpClient = BestHTTP.PlatformSupport.TcpClient.WinRT.TcpClient; + + //Disable CD4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. + #pragma warning disable 4014 +#elif UNITY_WP8 && !UNITY_EDITOR + using TcpClient = BestHTTP.PlatformSupport.TcpClient.WP8.TcpClient; +#else + using TcpClient = BestHTTP.PlatformSupport.TcpClient.General.TcpClient; +#endif + +namespace BestHTTP +{ + /// + /// https://tools.ietf.org/html/draft-thomson-hybi-http-timeout-03 + /// Test servers: http://tools.ietf.org/ http://nginx.org/ + /// + internal sealed class KeepAliveHeader + { + /// + /// A host sets the value of the "timeout" parameter to the time that the host will allow an idle connection to remain open before it is closed. A connection is idle if no data is sent or received by a host. + /// + public TimeSpan TimeOut { get; private set; } + + /// + /// The "max" parameter has been used to indicate the maximum number of requests that would be made on the connection.This parameter is deprecated.Any limit on requests can be enforced by sending "Connection: close" and closing the connection. + /// + public int MaxRequests { get; private set; } + + public void Parse(List headerValues) + { + HeaderParser parser = new HeaderParser(headerValues[0]); + HeaderValue value; + if (parser.TryGet("timeout", out value) && value.HasValue) + { + int intValue = 0; + if (int.TryParse(value.Value, out intValue)) + this.TimeOut = TimeSpan.FromSeconds(intValue); + else + this.TimeOut = TimeSpan.MaxValue; + } + + if (parser.TryGet("max", out value) && value.HasValue) + { + int intValue = 0; + if (int.TryParse("max", out intValue)) + this.MaxRequests = intValue; + else + this.MaxRequests = int.MaxValue; + } + } + } + + internal enum RetryCauses + { + /// + /// The request processed without any special case. + /// + None, + + /// + /// If the server closed the connection while we sending a request we should reconnect and send the request again. But we will try it once. + /// + Reconnect, + + /// + /// We need an another try with Authorization header set. + /// + Authenticate, + +#if !BESTHTTP_DISABLE_PROXY + /// + /// The proxy needs authentication. + /// + ProxyAuthenticate, +#endif + } + + /// + /// Represents and manages a connection to a server. + /// + internal sealed class HTTPConnection : ConnectionBase + { + public override bool IsRemovable + { + get + { + // Plugin's own connection pooling + if (base.IsRemovable) + return true; + + // Overridden keep-alive timeout by a Keep-Alive header + if (IsFree && KeepAlive != null && (DateTime.UtcNow - base.LastProcessTime) >= KeepAlive.TimeOut) + return true; + + return false; + } + } + + #region Private Properties + + private TcpClient Client; + private Stream Stream; + private KeepAliveHeader KeepAlive; + + #endregion + + internal HTTPConnection(string serverAddress) + :base(serverAddress) + {} + + #region Request Processing Implementation + + protected override +#if NETFX_CORE + async +#endif + void ThreadFunc(object param) + { + bool alreadyReconnected = false; + bool redirected = false; + + RetryCauses cause = RetryCauses.None; + + try + { +#if !BESTHTTP_DISABLE_PROXY + if (!HasProxy && CurrentRequest.HasProxy) + Proxy = CurrentRequest.Proxy; +#endif + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + // Try load the full response from an already saved cache entity. If the response + if (TryLoadAllFromCache()) + return; +#endif + + if (Client != null && !Client.IsConnected()) + Close(); + + do // of while (reconnect) + { + if (cause == RetryCauses.Reconnect) + { + Close(); +#if NETFX_CORE + await Task.Delay(100); +#else + Thread.Sleep(100); +#endif + } + + LastProcessedUri = CurrentRequest.CurrentUri; + + cause = RetryCauses.None; + + // Connect to the server + Connect(); + + if (State == HTTPConnectionStates.AbortRequested) + throw new Exception("AbortRequested"); + + #if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + // Setup cache control headers before we send out the request + if (!CurrentRequest.DisableCache) + HTTPCacheService.SetHeaders(CurrentRequest); + #endif + + // Write the request to the stream + // sentRequest will be true if the request sent out successfully(no SocketException), so we can try read the response + bool sentRequest = false; + try + { +#if !NETFX_CORE + Client.NoDelay = CurrentRequest.TryToMinimizeTCPLatency; +#endif + CurrentRequest.SendOutTo(Stream); + + sentRequest = true; + } + catch (Exception ex) + { + Close(); + + if (State == HTTPConnectionStates.TimedOut || + State == HTTPConnectionStates.AbortRequested) + throw new Exception("AbortRequested"); + + // We will try again only once + if (!alreadyReconnected && !CurrentRequest.DisableRetry) + { + alreadyReconnected = true; + cause = RetryCauses.Reconnect; + } + else // rethrow exception + throw ex; + } + + // If sending out the request succeeded, we will try read the response. + if (sentRequest) + { + bool received = Receive(); + + if (State == HTTPConnectionStates.TimedOut || + State == HTTPConnectionStates.AbortRequested) + throw new Exception("AbortRequested"); + + if (!received && !alreadyReconnected && !CurrentRequest.DisableRetry) + { + alreadyReconnected = true; + cause = RetryCauses.Reconnect; + } + + if (CurrentRequest.Response != null) + { +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + // Try to store cookies before we do anything else, as we may remove the response deleting the cookies as well. + if (CurrentRequest.IsCookiesEnabled) + CookieJar.Set(CurrentRequest.Response); +#endif + + switch (CurrentRequest.Response.StatusCode) + { + // Not authorized + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 + case 401: + { + string authHeader = DigestStore.FindBest(CurrentRequest.Response.GetHeaderValues("www-authenticate")); + if (!string.IsNullOrEmpty(authHeader)) + { + var digest = DigestStore.GetOrCreate(CurrentRequest.CurrentUri); + digest.ParseChallange(authHeader); + + if (CurrentRequest.Credentials != null && digest.IsUriProtected(CurrentRequest.CurrentUri) && (!CurrentRequest.HasHeader("Authorization") || digest.Stale)) + cause = RetryCauses.Authenticate; + } + + goto default; + } + +#if !BESTHTTP_DISABLE_PROXY + // Proxy authentication required + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 + case 407: + { + if (CurrentRequest.HasProxy) + { + string authHeader = DigestStore.FindBest(CurrentRequest.Response.GetHeaderValues("proxy-authenticate")); + if (!string.IsNullOrEmpty(authHeader)) + { + var digest = DigestStore.GetOrCreate(CurrentRequest.Proxy.Address); + digest.ParseChallange(authHeader); + + if (CurrentRequest.Proxy.Credentials != null && digest.IsUriProtected(CurrentRequest.Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale)) + cause = RetryCauses.ProxyAuthenticate; + } + } + + goto default; + } +#endif + + // Redirected + case 301: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2 + case 302: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3 + case 307: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8 + case 308: // http://tools.ietf.org/html/rfc7238 + { + if (CurrentRequest.RedirectCount >= CurrentRequest.MaxRedirects) + goto default; + CurrentRequest.RedirectCount++; + + string location = CurrentRequest.Response.GetFirstHeaderValue("location"); + if (!string.IsNullOrEmpty(location)) + { + Uri redirectUri = GetRedirectUri(location); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Redirected to Location: '{1}' redirectUri: '{1}'", this.CurrentRequest.CurrentUri.ToString(), location, redirectUri)); + + // Let the user to take some control over the redirection + if (!CurrentRequest.CallOnBeforeRedirection(redirectUri)) + { + HTTPManager.Logger.Information("HTTPConnection", "OnBeforeRedirection returned False"); + goto default; + } + + // Remove the previously set Host header. + CurrentRequest.RemoveHeader("Host"); + + // Set the Referer header to the last Uri. + CurrentRequest.SetHeader("Referer", CurrentRequest.CurrentUri.ToString()); + + // Set the new Uri, the CurrentUri will return this while the IsRedirected property is true + CurrentRequest.RedirectUri = redirectUri; + + // Discard the redirect response, we don't need it any more + CurrentRequest.Response = null; + + redirected = CurrentRequest.IsRedirected = true; + } + else + #if !NETFX_CORE + throw new MissingFieldException(string.Format("Got redirect status({0}) without 'location' header!", CurrentRequest.Response.StatusCode.ToString())); + #else + throw new Exception(string.Format("Got redirect status({0}) without 'location' header!", CurrentRequest.Response.StatusCode.ToString())); + #endif + + goto default; + } + + + default: +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + TryStoreInCache(); +#endif + break; + } + + // Closing the stream is done manually + if (CurrentRequest.Response == null || !CurrentRequest.Response.IsClosedManually) { + // If we have a response and the server telling us that it closed the connection after the message sent to us, then + // we will close the connection too. + bool closeByServer = CurrentRequest.Response == null || CurrentRequest.Response.HasHeaderWithValue("connection", "close"); + bool closeByClient = !CurrentRequest.IsKeepAlive; + + if (closeByServer || closeByClient) + Close(); + else if (CurrentRequest.Response != null) + { + var keepAliveheaderValues = CurrentRequest.Response.GetHeaderValues("keep-alive"); + if (keepAliveheaderValues != null && keepAliveheaderValues.Count > 0) + { + if (KeepAlive == null) + KeepAlive = new KeepAliveHeader(); + KeepAlive.Parse(keepAliveheaderValues); + } + } + } + } + } + + } while (cause != RetryCauses.None); + } + catch(TimeoutException e) + { + CurrentRequest.Response = null; + CurrentRequest.Exception = e; + CurrentRequest.State = HTTPRequestStates.ConnectionTimedOut; + + Close(); + } + catch (Exception e) + { + if (CurrentRequest != null) + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (CurrentRequest.UseStreaming) + HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri); +#endif + + // Something gone bad, Response must be null! + CurrentRequest.Response = null; + + switch (State) + { + case HTTPConnectionStates.Closed: + case HTTPConnectionStates.AbortRequested: + CurrentRequest.State = HTTPRequestStates.Aborted; + break; + case HTTPConnectionStates.TimedOut: + CurrentRequest.State = HTTPRequestStates.TimedOut; + break; + default: + CurrentRequest.Exception = e; + CurrentRequest.State = HTTPRequestStates.Error; + break; + } + } + + Close(); + } + finally + { + if (CurrentRequest != null) + { + // Avoid state changes. While we are in this block changing the connection's State, on Unity's main thread + // the HTTPManager's OnUpdate will check the connections's State and call functions that can change the inner state of + // the object. (Like setting the CurrentRequest to null in function Recycle() causing a NullRef exception) + lock (HTTPManager.Locker) + { + if (CurrentRequest != null && CurrentRequest.Response != null && CurrentRequest.Response.IsUpgraded) + State = HTTPConnectionStates.Upgraded; + else + State = redirected ? HTTPConnectionStates.Redirected : (Client == null ? HTTPConnectionStates.Closed : HTTPConnectionStates.WaitForRecycle); + + // Change the request's state only when the whole processing finished + if (CurrentRequest.State == HTTPRequestStates.Processing && (State == HTTPConnectionStates.Closed || State == HTTPConnectionStates.WaitForRecycle)) + { + if (CurrentRequest.Response != null) + CurrentRequest.State = HTTPRequestStates.Finished; + else + { + CurrentRequest.Exception = new Exception(string.Format("Remote server closed the connection before sending response header! Previous request state: {0}. Connection state: {1}", + CurrentRequest.State.ToString(), + State.ToString())); + CurrentRequest.State = HTTPRequestStates.Error; + } + } + + if (CurrentRequest.State == HTTPRequestStates.ConnectionTimedOut) + State = HTTPConnectionStates.Closed; + + LastProcessTime = DateTime.UtcNow; + + if (OnConnectionRecycled != null) + RecycleNow(); + } + + #if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPCacheService.SaveLibrary(); + #endif + + #if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + CookieJar.Persist(); + #endif + } + } + } + + private void Connect() + { + Uri uri = +#if !BESTHTTP_DISABLE_PROXY + CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : +#endif + CurrentRequest.CurrentUri; + + #region TCP Connection + + if (Client == null) + Client = new TcpClient(); + + if (!Client.Connected) + { + Client.ConnectTimeout = CurrentRequest.ConnectTimeout; + +#if NETFX_CORE || (UNITY_WP8 && !UNITY_EDITOR) + Client.UseHTTPSProtocol = + #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + !CurrentRequest.UseAlternateSSL && + #endif + HTTPProtocolFactory.IsSecureProtocol(uri); +#endif + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Connecting to {1}:{2}", this.CurrentRequest.CurrentUri.ToString(), uri.Host, uri.Port.ToString())); + +#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) + Client.SendBufferSize = HTTPManager.SendBufferSize; + Client.ReceiveBufferSize = HTTPManager.ReceiveBufferSize; + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("'{0}' - Buffer sizes - Send: {1} Receive: {2} Blocking: {3}", this.CurrentRequest.CurrentUri.ToString(), Client.SendBufferSize.ToString(), Client.ReceiveBufferSize.ToString(), Client.Client.Blocking.ToString())); +#endif + + Client.Connect(uri.Host, uri.Port); + + if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) + HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString()); + } + else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) + HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString()); + + #endregion + + StartTime = DateTime.UtcNow; + + if (Stream == null) + { + bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri); + + Stream = Client.GetStream(); + /*if (Stream.CanTimeout) + Stream.ReadTimeout = Stream.WriteTimeout = (int)CurrentRequest.Timeout.TotalMilliseconds;*/ + + +#if !BESTHTTP_DISABLE_PROXY + #region Proxy Handling + + if (HasProxy && (!Proxy.IsTransparent || (isSecure && Proxy.NonTransparentForHTTPS))) + { + var outStream = new BinaryWriter(new WriteOnlyBufferedStream(Stream, HTTPRequest.UploadChunkSize)); + + bool retry; + do + { + // If we have to because of a authentication request, we will switch it to true + retry = false; + + string connectStr = string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port); + + HTTPManager.Logger.Information("HTTPConnection", "Sending " + connectStr); + + outStream.SendAsASCII(connectStr); + outStream.Write(HTTPRequest.EOL); + + outStream.SendAsASCII("Proxy-Connection: Keep-Alive"); + outStream.Write(HTTPRequest.EOL); + + outStream.SendAsASCII("Connection: Keep-Alive"); + outStream.Write(HTTPRequest.EOL); + + outStream.SendAsASCII(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port)); + outStream.Write(HTTPRequest.EOL); + + // Proxy Authentication + if (HasProxy && Proxy.Credentials != null) + { + switch (Proxy.Credentials.Type) + { + case AuthenticationTypes.Basic: + // With Basic authentication we don't want to wait for a challenge, we will send the hash with the first request + outStream.Write(string.Format("Proxy-Authorization: {0}", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))).GetASCIIBytes()); + outStream.Write(HTTPRequest.EOL); + break; + + case AuthenticationTypes.Unknown: + case AuthenticationTypes.Digest: + var digest = DigestStore.Get(Proxy.Address); + if (digest != null) + { + string authentication = digest.GenerateResponseHeader(CurrentRequest, Proxy.Credentials, true); + if (!string.IsNullOrEmpty(authentication)) + { + string auth = string.Format("Proxy-Authorization: {0}", authentication); + if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) + HTTPManager.Logger.Information("HTTPConnection", "Sending proxy authorization header: " + auth); + + outStream.Write(auth.GetASCIIBytes()); + outStream.Write(HTTPRequest.EOL); + } + } + + break; + } + } + + outStream.Write(HTTPRequest.EOL); + + // Make sure to send all the wrote data to the wire + outStream.Flush(); + + CurrentRequest.ProxyResponse = new HTTPResponse(CurrentRequest, Stream, false, false); + + // Read back the response of the proxy + if (!CurrentRequest.ProxyResponse.Receive(-1, true)) + throw new Exception("Connection to the Proxy Server failed!"); + + if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) + HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + CurrentRequest.ProxyResponse.StatusCode + " message: " + CurrentRequest.ProxyResponse.Message + " Body: " + CurrentRequest.ProxyResponse.DataAsText); + + switch(CurrentRequest.ProxyResponse.StatusCode) + { + // Proxy authentication required + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8 + case 407: + { + string authHeader = DigestStore.FindBest(CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate")); + if (!string.IsNullOrEmpty(authHeader)) + { + var digest = DigestStore.GetOrCreate(Proxy.Address); + digest.ParseChallange(authHeader); + + if (Proxy.Credentials != null && digest.IsUriProtected(Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale)) + retry = true; + } + break; + } + + default: + if (!CurrentRequest.ProxyResponse.IsSuccess) + throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", CurrentRequest.ProxyResponse.StatusCode, CurrentRequest.ProxyResponse.Message, CurrentRequest.ProxyResponse.DataAsText)); + break; + } + + } while (retry); + } + #endregion +#endif // #if !BESTHTTP_DISABLE_PROXY + + // We have to use CurrentRequest.CurrentUri here, because uri can be a proxy uri with a different protocol + if (isSecure) + { + // Under the new experimental runtime there's a bug in the Socket.Send implementation that can cause a + // connection when the TLS protocol is used. +#if !NETFX_CORE && (!UNITY_WEBGL || UNITY_EDITOR) && NET_4_6 + //Client.SendBufferSize = 0; +#endif + +#region SSL Upgrade + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + if (CurrentRequest.UseAlternateSSL) + { + var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom()); + + // http://tools.ietf.org/html/rfc3546#section-3.1 + // -It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type. + // -Literal IPv4 and IPv6 addresses are not permitted in "HostName". + + // User-defined list has a higher priority + List hostNames = CurrentRequest.CustomTLSServerNameList; + + // If there's no user defined one and the host isn't an IP address, add the default one + if ((hostNames == null || hostNames.Count == 0) && !CurrentRequest.CurrentUri.IsHostIsAnIPAddress()) + { + hostNames = new List(1); + hostNames.Add(CurrentRequest.CurrentUri.Host); + } + + handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri, + CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer, + CurrentRequest.CustomClientCredentialsProvider, + hostNames)); + + Stream = handler.Stream; + } + else +#endif + { +#if !NETFX_CORE && !UNITY_WP8 + SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) => + { + return CurrentRequest.CallCustomCertificationValidator(cert, chain); + }); + + if (!sslStream.IsAuthenticated) + sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host); + Stream = sslStream; +#else + Stream = Client.GetStream(); +#endif + } + +#endregion + } + } + } + + private bool Receive() + { + SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler; + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - protocol: {1}", this.CurrentRequest.CurrentUri.ToString(), protocol.ToString())); + + CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, Stream, CurrentRequest.UseStreaming, false); + + if (!CurrentRequest.Response.Receive()) + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - Failed! Response will be null, returning with false.", this.CurrentRequest.CurrentUri.ToString())); + CurrentRequest.Response = null; + return false; + } + + if (CurrentRequest.Response.StatusCode == 304 +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + && !CurrentRequest.DisableCache +#endif + ) + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (CurrentRequest.IsRedirected) + { + if (!LoadFromCache(CurrentRequest.RedirectUri)) + LoadFromCache(CurrentRequest.Uri); + } + else + LoadFromCache(CurrentRequest.Uri); +#else + return false; +#endif + } + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Receive - Finished Successfully!", this.CurrentRequest.CurrentUri.ToString())); + + return true; + } + +#endregion + +#region Helper Functions + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + + private bool LoadFromCache(Uri uri) + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - LoadFromCache for Uri: {1}", this.CurrentRequest.CurrentUri.ToString(), uri.ToString())); + + var cacheEntity = HTTPCacheService.GetEntity(uri); + if (cacheEntity == null) + { + HTTPManager.Logger.Warning("HTTPConnection", string.Format("{0} - LoadFromCache for Uri: {1} - Cached entity not found!", this.CurrentRequest.CurrentUri.ToString(), uri.ToString())); + return false; + } + + CurrentRequest.Response.CacheFileInfo = cacheEntity; + + int bodyLength; + using (var cacheStream = cacheEntity.GetBodyStream(out bodyLength)) + { + if (cacheStream == null) + return false; + + if (!CurrentRequest.Response.HasHeader("content-length")) + CurrentRequest.Response.Headers.Add("content-length", new List(1) { bodyLength.ToString() }); + CurrentRequest.Response.IsFromCache = true; + + if (!CurrentRequest.CacheOnly) + CurrentRequest.Response.ReadRaw(cacheStream, bodyLength); + } + + return true; + } + + private bool TryLoadAllFromCache() + { + if (CurrentRequest.DisableCache || !HTTPCacheService.IsSupported) + return false; + + // We will try read the response from the cache, but if something happens we will fallback to the normal way. + try + { + //Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entity, + // MAY return it without validation if it is fresh, and MAY return it after successful validation. + // MAY return it without validation if it is fresh! + if (HTTPCacheService.IsCachedEntityExpiresInTheFuture(CurrentRequest)) + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - TryLoadAllFromCache - whole response loading from cache", this.CurrentRequest.CurrentUri.ToString())); + + CurrentRequest.Response = HTTPCacheService.GetFullResponse(CurrentRequest); + + if (CurrentRequest.Response != null) + return true; + } + } + catch + { + HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri); + } + + return false; + } +#endif + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + private void TryStoreInCache() + { + // if UseStreaming && !DisableCache then we already wrote the response to the cache + if (!CurrentRequest.UseStreaming && + !CurrentRequest.DisableCache && + CurrentRequest.Response != null && + HTTPCacheService.IsSupported && + HTTPCacheService.IsCacheble(CurrentRequest.CurrentUri, CurrentRequest.MethodType, CurrentRequest.Response)) + { + if(CurrentRequest.IsRedirected) + HTTPCacheService.Store(CurrentRequest.Uri, CurrentRequest.MethodType, CurrentRequest.Response); + else + HTTPCacheService.Store(CurrentRequest.CurrentUri, CurrentRequest.MethodType, CurrentRequest.Response); + } + } +#endif + + private Uri GetRedirectUri(string location) + { + Uri result = null; + try + { + result = new Uri(location); + + if (result.IsFile || result.AbsolutePath == location) + result = null; + } +#if !NETFX_CORE + catch (UriFormatException) +#else + catch +#endif + { + // Sometimes the server sends back only the path and query component of the new uri + result = null; + } + + if (result == null) + { + var uri = CurrentRequest.Uri; + var builder = new UriBuilder(uri.Scheme, uri.Host, uri.Port, location); + result = builder.Uri; + + } + + return result; + } + + internal override void Abort(HTTPConnectionStates newState) + { + State = newState; + + switch(State) + { + case HTTPConnectionStates.TimedOut: TimedOutStart = DateTime.UtcNow; break; + } + + if (Stream != null) + { + try + { + Stream.Dispose(); + } + catch + { } + } + } + + private void Close() + { + KeepAlive = null; + LastProcessedUri = null; + if (Client != null) + { + try + { + Client.Close(); + } + catch + { + + } + finally + { + Stream = null; + Client = null; + } + } + } + +#endregion + + protected override void Dispose(bool disposing) + { + Close(); + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs.meta new file mode 100644 index 0000000..997691d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c6e10f65ea45b8e4682ebe6a0c885e06 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs new file mode 100644 index 0000000..90f2465 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs @@ -0,0 +1,59 @@ +namespace BestHTTP +{ + /// + /// Possible states of a Http Connection. + /// The ideal lifecycle of a connection that has KeepAlive is the following: Initial => [Processing => WaitForRecycle => Free] => Closed. + /// + internal enum HTTPConnectionStates + { + /// + /// This Connection instance is just created. + /// + Initial, + + /// + /// This Connection is processing a request + /// + Processing, + + /// + /// The request redirected. + /// + Redirected, + + /// + /// The connection is upgraded from http. + /// + Upgraded, + + /// + /// Wait for the upgraded protocol to shut down. + /// + WaitForProtocolShutdown, + + /// + /// The Connection is finished processing the request, it's waiting now to deliver it's result. + /// + WaitForRecycle, + + /// + /// The request result's delivered, it's now up to processing again. + /// + Free, + + /// + /// A request from outside of the plugin to abort the connection. + /// + AbortRequested, + + /// + /// The request is not finished in the given time. + /// + TimedOut, + + /// + /// If it's not a KeepAlive connection, or something happend, then we close this connection and remove from the pool. + /// + Closed + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs.meta new file mode 100644 index 0000000..3ead1f3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPConnectionStates.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ae2c4bf49da6b1b4097d46250f2ff3bf +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs new file mode 100644 index 0000000..5abb572 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs @@ -0,0 +1,802 @@ +using System; +using System.Collections.Generic; + +using UnityEngine; + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + using BestHTTP.Caching; +#endif + +using BestHTTP.Extensions; +using BestHTTP.Logger; +using BestHTTP.Statistics; + +namespace BestHTTP +{ + /// + /// + /// + public static class HTTPManager + { + // Static constructor. Setup default values + static HTTPManager() + { + MaxConnectionPerServer = 4; + KeepAliveDefaultValue = true; + MaxPathLength = 255; + MaxConnectionIdleTime = TimeSpan.FromSeconds(20); + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + IsCookiesEnabled = true; +#endif + + CookieJarSize = 10 * 1024 * 1024; + EnablePrivateBrowsing = false; + ConnectTimeout = TimeSpan.FromSeconds(20); + RequestTimeout = TimeSpan.FromSeconds(60); + + // Set the default logger mechanism + logger = new BestHTTP.Logger.DefaultLogger(); + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + DefaultCertificateVerifyer = null; + UseAlternateSSLDefaultValue = true; +#endif + } + + #region Global Options + + /// + /// The maximum active TCP connections that the client will maintain to a server. Default value is 4. Minimum value is 1. + /// + public static byte MaxConnectionPerServer + { + get{ return maxConnectionPerServer; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException("MaxConnectionPerServer must be greater than 0!"); + maxConnectionPerServer = value; + } + } + private static byte maxConnectionPerServer; + + /// + /// Default value of a HTTP request's IsKeepAlive value. Default value is true. If you make rare request to the server it should be changed to false. + /// + public static bool KeepAliveDefaultValue { get; set; } + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Set to true, if caching is prohibited. + /// + public static bool IsCachingDisabled { get; set; } +#endif + + /// + /// How many time must be passed to destroy that connection after a connection finished its last request. Its default value is 20 seconds. + /// + public static TimeSpan MaxConnectionIdleTime { get; set; } + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Set to false to disable all Cookie. It's default value is true. + /// + public static bool IsCookiesEnabled { get; set; } +#endif + + /// + /// Size of the Cookie Jar in bytes. It's default value is 10485760 (10 MB). + /// + public static uint CookieJarSize { get; set; } + + /// + /// If this property is set to true, then new cookies treated as session cookies and these cookies are not saved to disk. Its default value is false; + /// + public static bool EnablePrivateBrowsing { get; set; } + + /// + /// Global, default value of the HTTPRequest's ConnectTimeout property. If set to TimeSpan.Zero or lower, no connect timeout logic is executed. Default value is 20 seconds. + /// + public static TimeSpan ConnectTimeout { get; set; } + + /// + /// Global, default value of the HTTPRequest's Timeout property. Default value is 60 seconds. + /// + public static TimeSpan RequestTimeout { get; set; } + +#if !((BESTHTTP_DISABLE_CACHING && BESTHTTP_DISABLE_COOKIES) || (UNITY_WEBGL && !UNITY_EDITOR)) + /// + /// By default the plugin will save all cache and cookie data under the path returned by Application.persistentDataPath. + /// You can assign a function to this delegate to return a custom root path to define a new path. + /// This delegate will be called on a non Unity thread! + /// + public static System.Func RootCacheFolderProvider { get; set; } +#endif + +#if !BESTHTTP_DISABLE_PROXY + /// + /// The global, default proxy for all HTTPRequests. The HTTPRequest's Proxy still can be changed per-request. Default value is null. + /// + public static HTTPProxy Proxy { get; set; } +#endif + + /// + /// Heartbeat manager to use less threads in the plugin. The heartbeat updates are called from the OnUpdate function. + /// + public static HeartbeatManager Heartbeats + { + get + { + if (heartbeats == null) + heartbeats = new HeartbeatManager(); + return heartbeats; + } + } + private static HeartbeatManager heartbeats; + + /// + /// A basic BestHTTP.Logger.ILogger implementation to be able to log intelligently additional informations about the plugin's internal mechanism. + /// + public static BestHTTP.Logger.ILogger Logger + { + get + { + // Make sure that it has a valid logger instance. + if (logger == null) + { + logger = new DefaultLogger(); + logger.Level = Loglevels.None; + } + + return logger; + } + + set { logger = value; } + } + private static BestHTTP.Logger.ILogger logger; + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// The default ICertificateVerifyer implementation that the plugin will use when the request's UseAlternateSSL property is set to true. + /// + public static Org.BouncyCastle.Crypto.Tls.ICertificateVerifyer DefaultCertificateVerifyer { get; set; } + + /// + /// The default IClientCredentialsProvider implementation that the plugin will use when the request's UseAlternateSSL property is set to true. + /// + public static Org.BouncyCastle.Crypto.Tls.IClientCredentialsProvider DefaultClientCredentialsProvider { get; set; } + + /// + /// The default value for the HTTPRequest's UseAlternateSSL property. + /// + public static bool UseAlternateSSLDefaultValue { get; set; } +#endif + +#if !NETFX_CORE && !UNITY_WP8 + public static Func DefaultCertificationValidator { get; set; } +#endif + + /// + /// Setting this option to true, the processing connection will set the TCP NoDelay option to send out data as soon as it can. + /// + public static bool TryToMinimizeTCPLatency = false; + + public static int SendBufferSize = 65 * 1024; + public static int ReceiveBufferSize = 65 * 1024; + + /// + /// On most systems the maximum length of a path is around 255 character. If a cache entity's path is longer than this value it doesn't get cached. There no platform independent API to query the exact value on the current system, but it's + /// exposed here and can be overridden. It's default value is 255. + /// + internal static int MaxPathLength { get; set; } + + #endregion + + #region Manager variables + + /// + /// All connection has a reference in this Dictionary until it's removed completely. + /// + private static Dictionary> Connections = new Dictionary>(); + + /// + /// Active connections. These connections all has a request to process. + /// + private static List ActiveConnections = new List(); + + /// + /// Free connections. They can be removed completely after a specified time. + /// + private static List FreeConnections = new List(); + + /// + /// Connections that recycled in the Update loop. If they are not used in the same loop to process a request, they will be transferred to the FreeConnections list. + /// + private static List RecycledConnections = new List(); + + /// + /// List of request that have to wait until there is a free connection to the server. + /// + private static List RequestQueue = new List(); + private static bool IsCallingCallbacks; + + internal static System.Object Locker = new System.Object(); + + internal static bool IsQuitting { get; private set; } + + #endregion + + #region Public Interface + + public static void Setup() + { + HTTPUpdateDelegator.CheckInstance(); + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPCacheService.CheckSetup(); +#endif + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + Cookies.CookieJar.SetupFolder(); +#endif + } + + public static HTTPRequest SendRequest(string url, OnRequestFinishedDelegate callback) + { + return SendRequest(new HTTPRequest(new Uri(url), HTTPMethods.Get, callback)); + } + + public static HTTPRequest SendRequest(string url, HTTPMethods methodType, OnRequestFinishedDelegate callback) + { + return SendRequest(new HTTPRequest(new Uri(url), methodType, callback)); + } + + public static HTTPRequest SendRequest(string url, HTTPMethods methodType, bool isKeepAlive, OnRequestFinishedDelegate callback) + { + return SendRequest(new HTTPRequest(new Uri(url), methodType, isKeepAlive, callback)); + } + + public static HTTPRequest SendRequest(string url, HTTPMethods methodType, bool isKeepAlive, bool disableCache, OnRequestFinishedDelegate callback) + { + return SendRequest(new HTTPRequest(new Uri(url), methodType, isKeepAlive, disableCache, callback)); + } + + public static HTTPRequest SendRequest(HTTPRequest request) + { + lock (Locker) + { + Setup(); + + if (IsCallingCallbacks) + { + request.State = HTTPRequestStates.Queued; + RequestQueue.Add(request); + } + else + SendRequestImpl(request); + + return request; + } + } + + public static GeneralStatistics GetGeneralStatistics(StatisticsQueryFlags queryFlags) + { + GeneralStatistics stat = new GeneralStatistics(); + + stat.QueryFlags = queryFlags; + + if ((queryFlags & StatisticsQueryFlags.Connections) != 0) + { + int connections = 0; + foreach(var conn in HTTPManager.Connections) + { + if (conn.Value != null) + connections += conn.Value.Count; + } + +#if !BESTHTTP_DISABLE_WEBSOCKET && UNITY_WEBGL && !UNITY_EDITOR + connections += WebSocket.WebSocket.WebSockets.Count; +#endif + + stat.Connections = connections; + stat.ActiveConnections = ActiveConnections.Count +#if !BESTHTTP_DISABLE_WEBSOCKET && UNITY_WEBGL && !UNITY_EDITOR + + WebSocket.WebSocket.WebSockets.Count +#endif + ; + stat.FreeConnections = FreeConnections.Count; + stat.RecycledConnections = RecycledConnections.Count; + stat.RequestsInQueue = RequestQueue.Count; + } + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if ((queryFlags & StatisticsQueryFlags.Cache) != 0) + { + stat.CacheEntityCount = HTTPCacheService.GetCacheEntityCount(); + stat.CacheSize = HTTPCacheService.GetCacheSize(); + } +#endif + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + if ((queryFlags & StatisticsQueryFlags.Cookies) != 0) + { + List cookies = Cookies.CookieJar.GetAll(); + stat.CookieCount = cookies.Count; + uint cookiesSize = 0; + for (int i = 0; i < cookies.Count; ++i) + cookiesSize += cookies[i].GuessSize(); + stat.CookieJarSize = cookiesSize; + } +#endif + + return stat; + } + + #endregion + + #region Private Functions + + private static void SendRequestImpl(HTTPRequest request) + { + ConnectionBase conn = FindOrCreateFreeConnection(request); + + if (conn != null) + { + // found a free connection: put it in the ActiveConnection list(they will be checked periodically in the OnUpdate call) + if (ActiveConnections.Find((c) => c == conn) == null) + ActiveConnections.Add(conn); + + FreeConnections.Remove(conn); + + request.State = HTTPRequestStates.Processing; + + request.Prepare(); + + // then start process the request + conn.Process(request); + } + else + { + // If no free connection found and creation prohibited, we will put back to the queue + request.State = HTTPRequestStates.Queued; + RequestQueue.Add(request); + } + } + + private static string GetKeyForRequest(HTTPRequest request) + { + if (request.CurrentUri.IsFile) + return request.CurrentUri.ToString(); + + // proxyUri + requestUri + // HTTP and HTTPS needs different connections. + return +#if !BESTHTTP_DISABLE_PROXY + (request.Proxy != null ? new UriBuilder(request.Proxy.Address.Scheme, request.Proxy.Address.Host, request.Proxy.Address.Port).Uri.ToString() : string.Empty) + +#endif + new UriBuilder(request.CurrentUri.Scheme, request.CurrentUri.Host, request.CurrentUri.Port).Uri.ToString(); + } + + /// + /// Factory method to create a concrete connection object. + /// + private static ConnectionBase CreateConnection(HTTPRequest request, string serverUrl) + { + if (request.CurrentUri.IsFile && Application.platform != RuntimePlatform.WebGLPlayer) + return new FileConnection(serverUrl); + +#if UNITY_WEBGL && !UNITY_EDITOR + return new WebGLConnection(serverUrl); +#else + return new HTTPConnection(serverUrl); +#endif + } + + private static ConnectionBase FindOrCreateFreeConnection(HTTPRequest request) + { + ConnectionBase conn = null; + List connections; + + string serverUrl = GetKeyForRequest(request); + + if (Connections.TryGetValue(serverUrl, out connections)) + { + // count active connections + + int activeConnections = 0; + for (int i = 0; i < connections.Count; ++i) + if (connections[i].IsActive) + activeConnections++; + + if (activeConnections <= MaxConnectionPerServer) + // search for a Free connection + for (int i = 0; i < connections.Count && conn == null; ++i) + { + var tmpConn = connections[i]; + + if (tmpConn != null && + tmpConn.IsFree && + ( +#if !BESTHTTP_DISABLE_PROXY + !tmpConn.HasProxy || +#endif + tmpConn.LastProcessedUri == null || + tmpConn.LastProcessedUri.Host.Equals(request.CurrentUri.Host, StringComparison.OrdinalIgnoreCase))) + conn = tmpConn; + } + } + else + Connections.Add(serverUrl, connections = new List(MaxConnectionPerServer)); + + // No free connection found? + if (conn == null) + { + // Max connection reached? + if (connections.Count >= MaxConnectionPerServer) + return null; + + // if no, create a new one + connections.Add(conn = CreateConnection(request, serverUrl)); + } + + return conn; + } + + /// + /// Will return with true when there at least one request that can be processed from the RequestQueue. + /// + private static bool CanProcessFromQueue() + { + for (int i = 0; i < RequestQueue.Count; ++i) + if (FindOrCreateFreeConnection(RequestQueue[i]) != null) + return true; + + return false; + } + + private static void RecycleConnection(ConnectionBase conn) + { + conn.Recycle(OnConnectionRecylced); + } + + private static void OnConnectionRecylced(ConnectionBase conn) + { + lock (RecycledConnections) + { + RecycledConnections.Add(conn); + } + } + + #endregion + + #region Internal Helper Functions + + /// + /// Will return the ConnectionBase object that processing the given request. + /// + internal static ConnectionBase GetConnectionWith(HTTPRequest request) + { + lock (Locker) + { + for (int i = 0; i < ActiveConnections.Count; ++i) + { + var connection = ActiveConnections[i]; + if (connection.CurrentRequest == request) + return connection; + } + + return null; + } + } + + internal static bool RemoveFromQueue(HTTPRequest request) + { + return RequestQueue.Remove(request); + } + +#if !((BESTHTTP_DISABLE_CACHING && BESTHTTP_DISABLE_COOKIES) || (UNITY_WEBGL && !UNITY_EDITOR)) + /// + /// Will return where the various caches should be saved. + /// + internal static string GetRootCacheFolder() + { + try + { + if (RootCacheFolderProvider != null) + return RootCacheFolderProvider(); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("HTTPManager", "GetRootCacheFolder", ex); + } + +#if NETFX_CORE + return Windows.Storage.ApplicationData.Current.LocalFolder.Path; +#else + return Application.persistentDataPath; +#endif + } +#endif + + #endregion + + #region MonoBehaviour Events (Called from HTTPUpdateDelegator) + + /// + /// Update function that should be called regularly from a Unity event(Update, LateUpdate). Callbacks are dispatched from this function. + /// + public static void OnUpdate() + { + // We will try to acquire a lock. If it fails, we will skip this frame without calling any callback. + if (System.Threading.Monitor.TryEnter(Locker)) + { + try + { + IsCallingCallbacks = true; + try + { + for (int i = 0; i < ActiveConnections.Count; ++i) + { + ConnectionBase conn = ActiveConnections[i]; + + switch (conn.State) + { + case HTTPConnectionStates.Processing: + conn.HandleProgressCallback(); + + if (conn.CurrentRequest.UseStreaming && conn.CurrentRequest.Response != null && conn.CurrentRequest.Response.HasStreamedFragments()) + conn.HandleCallback(); + + try + { + if (((!conn.CurrentRequest.UseStreaming && conn.CurrentRequest.UploadStream == null) || conn.CurrentRequest.EnableTimoutForStreaming) && + DateTime.UtcNow - conn.StartTime > conn.CurrentRequest.Timeout) + conn.Abort(HTTPConnectionStates.TimedOut); + } + catch (OverflowException) + { + HTTPManager.Logger.Warning("HTTPManager", "TimeSpan overflow"); + } + break; + + case HTTPConnectionStates.TimedOut: + // The connection is still in TimedOut state, and if we waited enough time, we will dispatch the + // callback and recycle the connection + try + { + if (DateTime.UtcNow - conn.TimedOutStart > TimeSpan.FromMilliseconds(500)) + { + HTTPManager.Logger.Information("HTTPManager", "Hard aborting connection because of a long waiting TimedOut state"); + + conn.CurrentRequest.Response = null; + conn.CurrentRequest.State = HTTPRequestStates.TimedOut; + conn.HandleCallback(); + + // this will set the connection's CurrentRequest to null + RecycleConnection(conn); + } + } + catch(OverflowException) + { + HTTPManager.Logger.Warning("HTTPManager", "TimeSpan overflow"); + } + break; + + case HTTPConnectionStates.Redirected: + // If the server redirected us, we need to find or create a connection to the new server and send out the request again. + SendRequest(conn.CurrentRequest); + + RecycleConnection(conn); + break; + + case HTTPConnectionStates.WaitForRecycle: + // If it's a streamed request, it's finished now + conn.CurrentRequest.FinishStreaming(); + + // Call the callback + conn.HandleCallback(); + + // Then recycle the connection + RecycleConnection(conn); + break; + + case HTTPConnectionStates.Upgraded: + // The connection upgraded to an other protocol + conn.HandleCallback(); + break; + + case HTTPConnectionStates.WaitForProtocolShutdown: + var ws = conn.CurrentRequest.Response as IProtocol; + if (ws != null) + ws.HandleEvents(); + + if (ws == null || ws.IsClosed) + { + conn.HandleCallback(); + + // After both sending and receiving a Close message, an endpoint considers the WebSocket connection closed and MUST close the underlying TCP connection. + conn.Dispose(); + RecycleConnection(conn); + } + break; + + case HTTPConnectionStates.AbortRequested: + // Corner case: we aborted a WebSocket connection + { + ws = conn.CurrentRequest.Response as IProtocol; + if (ws != null) + { + ws.HandleEvents(); + + if (ws.IsClosed) + { + conn.HandleCallback(); + conn.Dispose(); + + RecycleConnection(conn); + } + } + } + break; + + case HTTPConnectionStates.Closed: + // If it's a streamed request, it's finished now + conn.CurrentRequest.FinishStreaming(); + + // Call the callback + conn.HandleCallback(); + + // It will remove from the ActiveConnections + RecycleConnection(conn); + break; + + case HTTPConnectionStates.Free: + RecycleConnection(conn); + break; + } + } + } + finally + { + IsCallingCallbacks = false; + } + + // Just try to grab the lock, if we can't have it we can wait another turn because it isn't + // critical to do it right now. + if (System.Threading.Monitor.TryEnter(RecycledConnections)) + try + { + if (RecycledConnections.Count > 0) + { + for (int i = 0; i < RecycledConnections.Count; ++i) + { + var connection = RecycledConnections[i]; + // If in a callback made a request that acquired this connection, then we will not remove it from the + // active connections. + if (connection.IsFree) + { + ActiveConnections.Remove(connection); + FreeConnections.Add(connection); + } + } + RecycledConnections.Clear(); + } + } + finally + { + System.Threading.Monitor.Exit(RecycledConnections); + } + + if (FreeConnections.Count > 0) + for (int i = 0; i < FreeConnections.Count; i++) + { + var connection = FreeConnections[i]; + + if (connection.IsRemovable) + { + // Remove the connection from the connection reference table + List connections = null; + if (Connections.TryGetValue(connection.ServerAddress, out connections)) + connections.Remove(connection); + + // Dispose the connection + connection.Dispose(); + + FreeConnections.RemoveAt(i); + i--; + } + } + + + if (CanProcessFromQueue()) + { + // Sort the queue by priority, only if we have to + if (RequestQueue.Find((req) => req.Priority != 0) != null) + RequestQueue.Sort((req1, req2) => req1.Priority - req2.Priority); + + // Create an array from the queue and clear it. When we call the SendRequest while still no room for new connections, the same queue will be rebuilt. + + var queue = RequestQueue.ToArray(); + RequestQueue.Clear(); + + for (int i = 0; i < queue.Length; ++i) + SendRequest(queue[i]); + } + } + finally + { + System.Threading.Monitor.Exit(Locker); + } + } + + if (heartbeats != null) + heartbeats.Update(); + } + + public static void OnQuit() + { + lock (Locker) + { + IsQuitting = true; + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + Caching.HTTPCacheService.SaveLibrary(); +#endif + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + Cookies.CookieJar.Persist(); +#endif + + AbortAll(true); + + OnUpdate(); + } + } + + public static void AbortAll(bool allowCallbacks = false) + { + lock (Locker) + { + var queue = RequestQueue.ToArray(); + RequestQueue.Clear(); + foreach (var req in queue) + { + // Swallow any exceptions, we are quitting anyway. + try + { + if (!allowCallbacks) + req.Callback = null; + req.Abort(); + } + catch { } + } + + // Close all TCP connections when the application is terminating. + foreach (var kvp in Connections) + { + foreach (var conn in kvp.Value) + { + // Swallow any exceptions, we are quitting anyway. + try + { + if (conn.CurrentRequest != null) + { + if (!allowCallbacks) + conn.CurrentRequest.Callback = null; + conn.CurrentRequest.State = HTTPRequestStates.Aborted; + } + conn.Abort(HTTPConnectionStates.Closed); + conn.Dispose(); + } + catch { } + } + kvp.Value.Clear(); + } + Connections.Clear(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs.meta new file mode 100644 index 0000000..22e9749 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPManager.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8598bf6546f50e64197d043a215a5897 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs new file mode 100644 index 0000000..8a4a48d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs @@ -0,0 +1,76 @@ +namespace BestHTTP +{ + /// + /// Some supported methods described in the rfc: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9 + /// + public enum HTTPMethods : byte + { + /// + /// The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. + /// If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the + /// entity in the response and not the source text of the process, unless that text happens to be the output of the process. + /// + Get, + + /// + /// The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. + /// The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. + /// This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. + /// This method is often used for testing hypertext links for validity, accessibility, and recent modification. + /// + Head, + + /// + /// The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. + /// POST is designed to allow a uniform method to cover the following functions: + /// + /// Annotation of existing resources; + /// Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles; + /// Providing a block of data, such as the result of submitting a form, to a data-handling process; + /// Extending a database through an append operation. + /// + /// The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. + /// The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, + /// a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database. + /// The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, + /// either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result. + /// + Post, + + /// + /// The PUT method requests that the enclosed entity be stored under the supplied Request-URI. + /// If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. + /// If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, + /// the origin server can create the resource with that URI. If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. + /// If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. + /// If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. + /// The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases. + /// + Put, + + /// + /// The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. + /// The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. + /// However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location. + /// A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) + /// if the action has been enacted but the response does not include an entity. + /// + Delete, + + /// + /// http://tools.ietf.org/html/rfc5789 + /// The PATCH method requests that a set of changes described in the request entity be applied to the resource identified by the Request-URI. + /// The set of changes is represented in a format called a "patchdocument" identified by a media type. If the Request-URI does not point to an existing resource, + /// the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc. + /// + Patch, + + /// + /// The HTTP methods PATCH can be used to update partial resources. For instance, when you only need to update one field of the resource, PUTting a complete resource representation might be cumbersome and utilizes more bandwidth. + /// + /// + Merge, + + Options + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs.meta new file mode 100644 index 0000000..d60a3c2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPMethods.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: faf468f5056a1614da3acf7f571cc6bb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs new file mode 100644 index 0000000..1049fba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace BestHTTP +{ + public enum SupportedProtocols + { + Unknown, + HTTP, + +#if !BESTHTTP_DISABLE_WEBSOCKET + WebSocket, +#endif + +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + ServerSentEvents +#endif + } + + internal static class HTTPProtocolFactory + { + public static HTTPResponse Get(SupportedProtocols protocol, HTTPRequest request, Stream stream, bool isStreamed, bool isFromCache) + { + switch (protocol) + { +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + case SupportedProtocols.WebSocket: return new WebSocket.WebSocketResponse(request, stream, isStreamed, isFromCache); +#endif + +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS && (!UNITY_WEBGL || UNITY_EDITOR) + case SupportedProtocols.ServerSentEvents: return new ServerSentEvents.EventSourceResponse(request, stream, isStreamed, isFromCache); +#endif + default: return new HTTPResponse(request, stream, isStreamed, isFromCache); + } + } + + public static SupportedProtocols GetProtocolFromUri(Uri uri) + { + if (uri == null || uri.Scheme == null) + throw new Exception("Malformed URI in GetProtocolFromUri"); + + string scheme = uri.Scheme.ToLowerInvariant(); + switch (scheme) + { +#if !BESTHTTP_DISABLE_WEBSOCKET + case "ws": + case "wss": + return SupportedProtocols.WebSocket; +#endif + + default: + return SupportedProtocols.HTTP; + } + } + + public static bool IsSecureProtocol(Uri uri) + { + if (uri == null || uri.Scheme == null) + throw new Exception("Malformed URI in IsSecureProtocol"); + + string scheme = uri.Scheme.ToLowerInvariant(); + switch (scheme) + { + // http + case "https": + +#if !BESTHTTP_DISABLE_WEBSOCKET + // WebSocket + case "wss": +#endif + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs.meta new file mode 100644 index 0000000..96dfe0b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProtocolFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 42fc2aaed5d783a48b2d61c1d7db8f23 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs new file mode 100644 index 0000000..d0d973b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs @@ -0,0 +1,62 @@ +#if !BESTHTTP_DISABLE_PROXY + +using System; +using BestHTTP.Authentication; + +namespace BestHTTP +{ + public sealed class HTTPProxy + { + /// + /// Address of the proxy server. It has to be in the http://proxyaddress:port form. + /// + public Uri Address { get; set; } + + /// + /// Credentials of the proxy + /// + public Credentials Credentials { get; set; } + + /// + /// True if the proxy can act as a transparent proxy + /// + public bool IsTransparent { get; set; } + + /// + /// Some non-transparent proxies are except only the path and query of the request uri. Default value is true + /// + public bool SendWholeUri { get; set; } + + /// + /// Regardless of the value of IsTransparent, for secure protocols(HTTPS://, WSS://) the plugin will use the proxy as an explicit proxy(will issue a CONNECT request to the proxy) + /// + public bool NonTransparentForHTTPS { get; set; } + + public HTTPProxy(Uri address) + :this(address, null, false) + {} + + public HTTPProxy(Uri address, Credentials credentials) + :this(address, credentials, false) + {} + + public HTTPProxy(Uri address, Credentials credentials, bool isTransparent) + :this(address, credentials, isTransparent, true) + { } + + public HTTPProxy(Uri address, Credentials credentials, bool isTransparent, bool sendWholeUri) + : this(address, credentials, isTransparent, true, true) + { } + + public HTTPProxy(Uri address, Credentials credentials, bool isTransparent, bool sendWholeUri, bool nonTransparentForHTTPS) + { + this.Address = address; + this.Credentials = credentials; + this.IsTransparent = isTransparent; + this.SendWholeUri = sendWholeUri; + this.NonTransparentForHTTPS = nonTransparentForHTTPS; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs.meta new file mode 100644 index 0000000..632889c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPProxy.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9e3868a6f38c2cc42bbb8c562caba79a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs new file mode 100644 index 0000000..aa03249 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs @@ -0,0 +1,57 @@ +using System; + +namespace BestHTTP +{ + /// + /// + /// + public sealed class HTTPRange + { + /// + /// The first byte's position that the server sent. + /// + public int FirstBytePos { get; private set; } + + /// + /// The last byte's position that the server sent. + /// + public int LastBytePos { get; private set; } + + /// + /// Indicates the total length of the full entity-body on the server, -1 if this length is unknown or difficult to determine. + /// + public int ContentLength { get; private set; } + + /// + /// + /// + public bool IsValid { get; private set; } + + internal HTTPRange() + { + this.ContentLength = -1; + this.IsValid = false; + } + + internal HTTPRange(int contentLength) + { + this.ContentLength = contentLength; + this.IsValid = false; + } + + internal HTTPRange(int firstBytePosition, int lastBytePosition, int contentLength) + { + this.FirstBytePos = firstBytePosition; + this.LastBytePos = lastBytePosition; + this.ContentLength = contentLength; + + // A byte-content-range-spec with a byte-range-resp-spec whose last-byte-pos value is less than its first-byte-pos value, or whose instance-length value is less than or equal to its last-byte-pos value, is invalid. + this.IsValid = this.FirstBytePos <= this.LastBytePos && this.ContentLength > this.LastBytePos; + } + + public override string ToString() + { + return string.Format("{0}-{1}/{2} (valid: {3})", FirstBytePos, LastBytePos, ContentLength, IsValid); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs.meta new file mode 100644 index 0000000..b9bf1e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 874904f9618b97045b510c161f498030 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs new file mode 100644 index 0000000..308222c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs @@ -0,0 +1,1434 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace BestHTTP +{ + using BestHTTP.Authentication; + using BestHTTP.Extensions; + using BestHTTP.Forms; + + #if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + using BestHTTP.Cookies; + #endif + + /// + /// Possible logical states of a HTTTPRequest object. + /// + public enum HTTPRequestStates + { + /// + /// Initial status of a request. No callback will be called with this status. + /// + Initial, + + /// + /// Waiting in a queue to be processed. No callback will be called with this status. + /// + Queued, + + /// + /// Processing of the request started. In this state the client will send the request, and parse the response. No callback will be called with this status. + /// + Processing, + + /// + /// The request finished without problem. Parsing the response done, the result can be used. The user defined callback will be called with a valid response object. The request’s Exception property will be null. + /// + Finished, + + /// + /// The request finished with an unexpected error. The user defined callback will be called with a null response object. The request's Exception property may contain more info about the error, but it can be null. + /// + Error, + + /// + /// The request aborted by the client(HTTPRequest’s Abort() function). The user defined callback will be called with a null response. The request’s Exception property will be null. + /// + Aborted, + + /// + /// Connecting to the server timed out. The user defined callback will be called with a null response. The request’s Exception property will be null. + /// + ConnectionTimedOut, + + /// + /// The request didn't finished in the given time. The user defined callback will be called with a null response. The request’s Exception property will be null. + /// + TimedOut + } + + public delegate void OnRequestFinishedDelegate(HTTPRequest originalRequest, HTTPResponse response); + public delegate void OnDownloadProgressDelegate(HTTPRequest originalRequest, long downloaded, long downloadLength); + public delegate void OnUploadProgressDelegate(HTTPRequest originalRequest, long uploaded, long uploadLength); + public delegate bool OnBeforeRedirectionDelegate(HTTPRequest originalRequest, HTTPResponse response, Uri redirectUri); + public delegate void OnHeaderEnumerationDelegate(string header, List values); + public delegate void OnBeforeHeaderSendDelegate(HTTPRequest req); + + /// + /// + /// + public sealed class HTTPRequest : IEnumerator, IEnumerator + { + #region Statics + + public static readonly byte[] EOL = { HTTPResponse.CR, HTTPResponse.LF }; + + /// + /// Cached uppercase values to save some cpu cycles and GC alloc per request. + /// + public static readonly string[] MethodNames = { + HTTPMethods.Get.ToString().ToUpper(), + HTTPMethods.Head.ToString().ToUpper(), + HTTPMethods.Post.ToString().ToUpper(), + HTTPMethods.Put.ToString().ToUpper(), + HTTPMethods.Delete.ToString().ToUpper(), + HTTPMethods.Patch.ToString().ToUpper(), + HTTPMethods.Merge.ToString().ToUpper(), + HTTPMethods.Options.ToString().ToUpper() + }; + + /// + /// Size of the internal buffer, and upload progress will be fired when this size of data sent to the wire. It's default value is 2 KiB. + /// + public static int UploadChunkSize = 2 * 1024; + + #endregion + + #region Properties + + /// + /// The original request's Uri. + /// + public Uri Uri { get; private set; } + + /// + /// The method that how we want to process our request the server. + /// + public HTTPMethods MethodType { get; set; } + + /// + /// The raw data to send in a POST request. If it set all other fields that added to this request will be ignored. + /// + public byte[] RawData { get; set; } + + /// + /// The stream that the plugin will use to get the data to send out the server. When this property is set, no forms or the RawData property will be used + /// + public Stream UploadStream { get; set; } + + /// + /// When set to true(its default value) the plugin will call the UploadStream's Dispose() function when finished uploading the data from it. Default value is true. + /// + public bool DisposeUploadStream { get; set; } + + /// + /// If it's true, the plugin will use the Stream's Length property. Otherwise the plugin will send the data chunked. Default value is true. + /// + public bool UseUploadStreamLength { get; set; } + + /// + /// Called after data sent out to the wire. + /// + public OnUploadProgressDelegate OnUploadProgress; + + /// + /// Indicates that the connection should be open after the response received. If its true, then the internal TCP connections will be reused if it's possible. Default value is true. + /// The default value can be changed in the HTTPManager class. If you make rare request to the server it's should be changed to false. + /// + public bool IsKeepAlive + { + get { return isKeepAlive; } + set + { + if (State == HTTPRequestStates.Processing) + throw new NotSupportedException("Changing the IsKeepAlive property while processing the request is not supported."); + isKeepAlive = value; + } + } + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// With this property caching can be enabled/disabled on a per-request basis. + /// + public bool DisableCache + { + get { return disableCache; } + set + { + if (State == HTTPRequestStates.Processing) + throw new NotSupportedException("Changing the DisableCache property while processing the request is not supported."); + disableCache = value; + } + } + + public bool CacheOnly + { + get { return cacheOnly; } + set + { + if (State == HTTPRequestStates.Processing) + throw new NotSupportedException("Changing the CacheOnly property while processing the request is not supported."); + cacheOnly = value; + } + } +#endif + + /// + /// If it's true, the Callback will be called every time if we can send out at least one fragment. + /// + public bool UseStreaming + { + get { return useStreaming; } + set + { + if (State == HTTPRequestStates.Processing) + throw new NotSupportedException("Changing the UseStreaming property while processing the request is not supported."); + useStreaming = value; + } + } + + /// + /// Maximum size of a data chunk that we want to receive when streaming is set. + /// + public int StreamFragmentSize + { + get{ return streamFragmentSize; } + set + { + if (State == HTTPRequestStates.Processing) + throw new NotSupportedException("Changing the StreamFragmentSize property while processing the request is not supported."); + + if (value < 1) + throw new System.ArgumentException("StreamFragmentSize must be at least 1."); + + streamFragmentSize = value; + } + } + + public int MaxFragmentQueueLength { get; set; } + + /// + /// The callback function that will be called when a request is fully processed or when any downloaded fragment is available if UseStreaming is true. Can be null for fire-and-forget requests. + /// + public OnRequestFinishedDelegate Callback { get; set; } + + /// + /// Called when new data downloaded from the server. + /// The first parameter is the original HTTTPRequest object itself, the second parameter is the downloaded bytes while the third parameter is the content length. + /// There are download modes where we can't figure out the exact length of the final content. In these cases we just guarantee that the third parameter will be at least the size of the second one. + /// + public OnDownloadProgressDelegate OnProgress; + + /// + /// Called when the current protocol is upgraded to an other. (HTTP => WebSocket for example) + /// + public OnRequestFinishedDelegate OnUpgraded; + + /// + /// With this option if reading back the server's response fails, the request will fail and any exceptions can be checked through the Exception property. The default value is True for POST requests, otherwise false. + /// + public bool DisableRetry { get; set; } + + /// + /// Indicates that the request is redirected. If a request is redirected, the connection that served it will be closed regardless of the value of IsKeepAlive. + /// + public bool IsRedirected { get; internal set; } + + /// + /// The Uri that the request redirected to. + /// + public Uri RedirectUri { get; internal set; } + + /// + /// If redirected it contains the RedirectUri. + /// + public Uri CurrentUri { get { return IsRedirected ? RedirectUri : Uri; } } + + /// + /// The response to the query. + /// If an exception occurred during reading of the response stream or can't connect to the server, this will be null! + /// + public HTTPResponse Response { get; internal set; } + +#if !BESTHTTP_DISABLE_PROXY + /// + /// Response from the Proxy server. It's null with transparent proxies. + /// + public HTTPResponse ProxyResponse { get; internal set; } +#endif + + /// + /// It there is an exception while processing the request or response the Response property will be null, and the Exception will be stored in this property. + /// + public Exception Exception { get; internal set; } + + /// + /// Any object can be passed with the request with this property. (eq. it can be identified, etc.) + /// + public object Tag { get; set; } + + /// + /// The UserName, Password pair that the plugin will use to authenticate to the remote server. + /// + public Credentials Credentials { get; set; } + +#if !BESTHTTP_DISABLE_PROXY + /// + /// True, if there is a Proxy object. + /// + public bool HasProxy { get { return Proxy != null; } } + + /// + /// A web proxy's properties where the request must pass through. + /// + public HTTPProxy Proxy { get; set; } +#endif + + /// + /// How many redirection supported for this request. The default is int.MaxValue. 0 or a negative value means no redirection supported. + /// + public int MaxRedirects { get; set; } + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Use Bouncy Castle's code to handle the secure protocol instead of Mono's. You can try to set it true if you receive a "System.Security.Cryptography.CryptographicException: Unsupported hash algorithm" exception. + /// + public bool UseAlternateSSL { get; set; } +#endif + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + + /// + /// If true cookies will be added to the headers (if any), and parsed from the response. If false, all cookie operations will be ignored. It's default value is HTTPManager's IsCookiesEnabled. + /// + public bool IsCookiesEnabled { get; set; } + + /// + /// Cookies that are added to this list will be sent to the server alongside withe the server sent ones. If cookies are disabled only these cookies will be sent. + /// + public List Cookies + { + get + { + if (customCookies == null) + customCookies = new List(); + return customCookies; + } + set { customCookies = value; } + } + + private List customCookies; +#endif + + /// + /// What form should used. Default to Automatic. + /// + public HTTPFormUsage FormUsage { get; set; } + + /// + /// Current state of this request. + /// + public HTTPRequestStates State { get; internal set; } + + /// + /// How many times redirected. + /// + public int RedirectCount { get; internal set; } + +#if !NETFX_CORE && !UNITY_WP8 + /// + /// Custom validator for an SslStream. This event will receive the original HTTPRequest, an X509Certificate and an X509Chain objects. It must return true if the certificate valid, false otherwise. + /// It's called in a thread! Not available on Windows Phone! + /// + public event System.Func CustomCertificationValidator; +#endif + + /// + /// Maximum time we wait to establish the connection to the target server. If set to TimeSpan.Zero or lower, no connect timeout logic is executed. Default value is 20 seconds. + /// + public TimeSpan ConnectTimeout { get; set; } + + /// + /// Maximum time we want to wait to the request to finish after the connection is established. Default value is 60 seconds. + /// It's disabled for streaming requests! See . + /// + public TimeSpan Timeout { get; set; } + + /// + /// Set to true to enable Timeouts on streaming request. Default value is false. + /// + public bool EnableTimoutForStreaming { get; set; } + + /// + /// Enables safe read method when the response's length of the content is unknown. Its default value is enabled (true). + /// + public bool EnableSafeReadOnUnknownContentLength { get; set; } + + /// + /// The priority of the request. Higher priority requests will be picked from the request queue sooner than lower priority ones. + /// + public int Priority { get; set; } + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// The ICertificateVerifyer implementation that the plugin will use to verify the server certificates when the request's UseAlternateSSL property is set to true. + /// + public Org.BouncyCastle.Crypto.Tls.ICertificateVerifyer CustomCertificateVerifyer { get; set; } + + /// + /// The IClientCredentialsProvider implementation that the plugin will use to send client certificates when the request's UseAlternateSSL property is set to true. + /// + public Org.BouncyCastle.Crypto.Tls.IClientCredentialsProvider CustomClientCredentialsProvider { get; set; } + + /// + /// With this property custom Server Name Indication entries can be sent to the server while negotiating TLS. + /// All added entries must conform to the rules defined in the RFC (https://tools.ietf.org/html/rfc3546#section-3.1), the plugin will not check the entries' validity! + /// This list will be sent to every server that the plugin must connect to while it tries to finish the request. + /// So for example if redirected to an another server, that new server will receive this list too! + /// + public List CustomTLSServerNameList { get; set; } +#endif + + /// + /// + /// + public SupportedProtocols ProtocolHandler { get; set; } + + /// + /// It's called before the plugin will do a new request to the new uri. The return value of this function will control the redirection: if it's false the redirection is aborted. + /// This function is called on a thread other than the main Unity thread! + /// + public event OnBeforeRedirectionDelegate OnBeforeRedirection + { + add { onBeforeRedirection += value; } + remove { onBeforeRedirection -= value; } + } + private OnBeforeRedirectionDelegate onBeforeRedirection; + + /// + /// This event will be fired before the plugin will write headers to the wire. New headers can be added in this callback. This event is called on a non-Unity thread! + /// + public event OnBeforeHeaderSendDelegate OnBeforeHeaderSend + { + add { _onBeforeHeaderSend += value; } + remove { _onBeforeHeaderSend -= value; } + } + private OnBeforeHeaderSendDelegate _onBeforeHeaderSend; + + /// + /// Setting this option to true, the processing connection will set the TCP NoDelay option to send out data as soon as it can. + /// + public bool TryToMinimizeTCPLatency { get; set; } + + #region Internal Properties For Progress Report Support + + /// + /// How many bytes downloaded so far. + /// + internal long Downloaded { get; set; } + + /// + /// The length of the content that we are currently downloading. + /// If chunked encoding is used, then it is the size of the sum of all previous chunks plus the current one. + /// When no Content-Length present and no chunked encoding is used then its size is the currently downloaded size. + /// + internal long DownloadLength { get; set; } + + /// + /// Set to true when the downloaded bytes are changed, and set to false when the OnProgress event called. + /// + internal bool DownloadProgressChanged { get; set; } + + /// + /// Will return the length of the UploadStream, or -1 if it's not supported. + /// + internal long UploadStreamLength + { + get + { + if (UploadStream == null || !UseUploadStreamLength) + return -1; + + try + { + // This may will throw a NotSupportedException + return UploadStream.Length; + } + catch + { + // We will fall back to chunked + return -1; + } + } + } + + /// + /// How many bytes are sent to the wire + /// + internal long Uploaded { get; set; } + + /// + /// How many bytes are expected we are sending. If we are don't know, then it will be -1. + /// + internal long UploadLength { get; set; } + + /// + /// Set to true when the uploaded bytes are changed, and set to false when the OnUploadProgress event called. + /// + internal bool UploadProgressChanged { get; set; } + + #endregion + + #endregion + + #region Privates + + private bool isKeepAlive; +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + private bool disableCache; + private bool cacheOnly; +#endif + private int streamFragmentSize; + private bool useStreaming; + + private Dictionary> Headers { get; set; } + + /// + /// We will collect the fields and values to the FieldCollector through the AddField and AddBinaryData functions. + /// + private HTTPFormBase FieldCollector; + + /// + /// When the request about to send the request we will create a specialized form implementation(url-encoded, multipart, or the legacy WWWForm based). + /// And we will use this instance to create the data that we will send to the server. + /// + private HTTPFormBase FormImpl; + + #endregion + + #region Constructors + + #region Default Get Constructors + + public HTTPRequest(Uri uri) + : this(uri, HTTPMethods.Get, HTTPManager.KeepAliveDefaultValue, +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPManager.IsCachingDisabled +#else + true +#endif + , null) + { + } + + public HTTPRequest(Uri uri, OnRequestFinishedDelegate callback) + : this(uri, HTTPMethods.Get, HTTPManager.KeepAliveDefaultValue, +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPManager.IsCachingDisabled +#else + true +#endif + , callback) + { + } + + public HTTPRequest(Uri uri, bool isKeepAlive, OnRequestFinishedDelegate callback) + : this(uri, HTTPMethods.Get, isKeepAlive, +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPManager.IsCachingDisabled +#else + true +#endif + + , callback) + { + } + public HTTPRequest(Uri uri, bool isKeepAlive, bool disableCache, OnRequestFinishedDelegate callback) + : this(uri, HTTPMethods.Get, isKeepAlive, disableCache, callback) + { + } + + #endregion + + public HTTPRequest(Uri uri, HTTPMethods methodType) + : this(uri, methodType, HTTPManager.KeepAliveDefaultValue, +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPManager.IsCachingDisabled || methodType != HTTPMethods.Get +#else + true +#endif + , null) + { + } + + public HTTPRequest(Uri uri, HTTPMethods methodType, OnRequestFinishedDelegate callback) + : this(uri, methodType, HTTPManager.KeepAliveDefaultValue, +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPManager.IsCachingDisabled || methodType != HTTPMethods.Get +#else + true +#endif + , callback) + { + } + + public HTTPRequest(Uri uri, HTTPMethods methodType, bool isKeepAlive, OnRequestFinishedDelegate callback) + : this(uri, methodType, isKeepAlive, +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + HTTPManager.IsCachingDisabled || methodType != HTTPMethods.Get +#else + true +#endif + , callback) + { + } + + public HTTPRequest(Uri uri, HTTPMethods methodType, bool isKeepAlive, bool disableCache, OnRequestFinishedDelegate callback) + { + this.Uri = uri; + this.MethodType = methodType; + this.IsKeepAlive = isKeepAlive; +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + this.DisableCache = disableCache; +#endif + this.Callback = callback; + this.StreamFragmentSize = 4 * 1024; + this.MaxFragmentQueueLength = 10; + + this.DisableRetry = !(methodType == HTTPMethods.Get); + this.MaxRedirects = int.MaxValue; + this.RedirectCount = 0; +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + this.IsCookiesEnabled = HTTPManager.IsCookiesEnabled; +#endif + + this.Downloaded = DownloadLength = 0; + this.DownloadProgressChanged = false; + + this.State = HTTPRequestStates.Initial; + + this.ConnectTimeout = HTTPManager.ConnectTimeout; + this.Timeout = HTTPManager.RequestTimeout; + this.EnableTimoutForStreaming = false; + + this.EnableSafeReadOnUnknownContentLength = true; + +#if !BESTHTTP_DISABLE_PROXY + this.Proxy = HTTPManager.Proxy; +#endif + + this.UseUploadStreamLength = true; + this.DisposeUploadStream = true; + +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + this.CustomCertificateVerifyer = HTTPManager.DefaultCertificateVerifyer; + this.CustomClientCredentialsProvider = HTTPManager.DefaultClientCredentialsProvider; + this.UseAlternateSSL = HTTPManager.UseAlternateSSLDefaultValue; +#endif + +#if !NETFX_CORE && !UNITY_WP8 + this.CustomCertificationValidator += HTTPManager.DefaultCertificationValidator; +#endif + this.TryToMinimizeTCPLatency = HTTPManager.TryToMinimizeTCPLatency; + } + + #endregion + + #region Public Field Functions + + /// + /// Add a field with a given string value. + /// + public void AddField(string fieldName, string value) + { + AddField(fieldName, value, System.Text.Encoding.UTF8); + } + + /// + /// Add a field with a given string value. + /// + public void AddField(string fieldName, string value, System.Text.Encoding e) + { + if (FieldCollector == null) + FieldCollector = new HTTPFormBase(); + + FieldCollector.AddField(fieldName, value, e); + } + + /// + /// Add a field with binary content to the form. + /// + public void AddBinaryData(string fieldName, byte[] content) + { + AddBinaryData(fieldName, content, null, null); + } + + /// + /// Add a field with binary content to the form. + /// + public void AddBinaryData(string fieldName, byte[] content, string fileName) + { + AddBinaryData(fieldName, content, fileName, null); + } + + /// + /// Add a field with binary content to the form. + /// + public void AddBinaryData(string fieldName, byte[] content, string fileName, string mimeType) + { + if (FieldCollector == null) + FieldCollector = new HTTPFormBase(); + + FieldCollector.AddBinaryData(fieldName, content, fileName, mimeType); + } + +#if !BESTHTTP_DISABLE_UNITY_FORM + /// + /// Set or overwrite the internal form. Remarks: on WP8 it doesn't supported! + /// + public void SetFields(UnityEngine.WWWForm wwwForm) + { + FormUsage = HTTPFormUsage.Unity; + FormImpl = new UnityForm(wwwForm); + } +#endif + + /// + /// Manually set a HTTP Form. + /// + public void SetForm(HTTPFormBase form) + { + FormImpl = form; + } + + /// + /// Returns with the added form-fields or null if no one added. + /// + public List GetFormFields() + { + if (this.FieldCollector == null || this.FieldCollector.IsEmpty) + return null; + + return new List(this.FieldCollector.Fields); + } + + /// + /// Clears all data from the form. + /// + public void ClearForm() + { + FormImpl = null; + FieldCollector = null; + } + + /// + /// Will create the form implementation based on the value of the FormUsage property. + /// + private HTTPFormBase SelectFormImplementation() + { + // Our form already created with a previous + if (FormImpl != null) + return FormImpl; + + // No field added to this request yet + if (FieldCollector == null) + return null; + + switch (FormUsage) + { + case HTTPFormUsage.Automatic: + // A really simple decision making: if there are at least one field with binary data, or a 'long' string value then we will choose a Multipart form. + // Otherwise Url Encoded form will be used. + if (FieldCollector.HasBinary || FieldCollector.HasLongValue) + goto case HTTPFormUsage.Multipart; + else + goto case HTTPFormUsage.UrlEncoded; + + case HTTPFormUsage.UrlEncoded: FormImpl = new HTTPUrlEncodedForm(); break; + case HTTPFormUsage.Multipart: FormImpl = new HTTPMultiPartForm(); break; + case HTTPFormUsage.RawJSon: FormImpl = new RawJsonForm(); break; +#if !BESTHTTP_DISABLE_UNITY_FORM + case HTTPFormUsage.Unity: FormImpl = new UnityForm(); break; +#endif + } + + // Copy the fields, and other properties to the new implementation + FormImpl.CopyFrom(FieldCollector); + + return FormImpl; + } + + #endregion + + #region Header Management + + #region General Management + + /// + /// Adds a header and value pair to the Headers. Use it to add custom headers to the request. + /// + /// AddHeader("User-Agent', "FooBar 1.0") + public void AddHeader(string name, string value) + { + if (Headers == null) + Headers = new Dictionary>(); + + List values; + if (!Headers.TryGetValue(name, out values)) + Headers.Add(name, values = new List(1)); + + values.Add(value); + } + + /// + /// Removes any previously added values, and sets the given one. + /// + public void SetHeader(string name, string value) + { + if (Headers == null) + Headers = new Dictionary>(); + + List values; + if (!Headers.TryGetValue(name, out values)) + Headers.Add(name, values = new List(1)); + + values.Clear(); + values.Add(value); + } + + /// + /// Removes the specified header. Returns true, if the header found and succesfully removed. + /// + /// + /// + public bool RemoveHeader(string name) + { + if (Headers == null) + return false; + + return Headers.Remove(name); + } + + /// + /// Returns true if the given head name is already in the Headers. + /// + public bool HasHeader(string name) + { + return Headers != null && Headers.ContainsKey(name); + } + + /// + /// Returns the first header or null for the given header name. + /// + public string GetFirstHeaderValue(string name) + { + if (Headers == null) + return null; + + List headers = null; + if (Headers.TryGetValue(name, out headers) && headers.Count > 0) + return headers[0]; + + return null; + } + + /// + /// Returns all header values for the given header or null. + /// + public List GetHeaderValues(string name) + { + if (Headers == null) + return null; + + List headers = null; + if (Headers.TryGetValue(name, out headers) && headers.Count > 0) + return headers; + + return null; + } + + public void RemoveHeaders() + { + if (Headers == null) + return; + + Headers.Clear(); + } + + #endregion + + #region Range Headers + + /// + /// Sets the Range header to download the content from the given byte position. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 + /// + /// Start position of the download. + public void SetRangeHeader(int firstBytePos) + { + SetHeader("Range", string.Format("bytes={0}-", firstBytePos)); + } + + /// + /// Sets the Range header to download the content from the given byte position to the given last position. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 + /// + /// Start position of the download. + /// The end position of the download. + public void SetRangeHeader(int firstBytePos, int lastBytePos) + { + SetHeader("Range", string.Format("bytes={0}-{1}", firstBytePos, lastBytePos)); + } + + #endregion + + public void EnumerateHeaders(OnHeaderEnumerationDelegate callback) + { + EnumerateHeaders(callback, false); + } + + public void EnumerateHeaders(OnHeaderEnumerationDelegate callback, bool callBeforeSendCallback) + { +#if !UNITY_WEBGL || UNITY_EDITOR + if (!HasHeader("Host")) + SetHeader("Host", CurrentUri.Authority); + + if (IsRedirected && !HasHeader("Referer")) + AddHeader("Referer", Uri.ToString()); + + if (!HasHeader("Accept-Encoding")) +#if BESTHTTP_DISABLE_GZIP + AddHeader("Accept-Encoding", "identity"); +#else + AddHeader("Accept-Encoding", "gzip, identity"); +#endif + + #if !BESTHTTP_DISABLE_PROXY + if (HasProxy && !HasHeader("Proxy-Connection")) + AddHeader("Proxy-Connection", IsKeepAlive ? "Keep-Alive" : "Close"); + #endif + + if (!HasHeader("Connection")) + AddHeader("Connection", IsKeepAlive ? "Keep-Alive, TE" : "Close, TE"); + + if (!HasHeader("TE")) + AddHeader("TE", "identity"); + + if (!HasHeader("User-Agent")) + AddHeader("User-Agent", "BestHTTP"); +#endif + long contentLength = -1; + + if (UploadStream == null) + { + byte[] entityBody = GetEntityBody(); + contentLength = entityBody != null ? entityBody.Length : 0; + + if (RawData == null && (FormImpl != null || (FieldCollector != null && !FieldCollector.IsEmpty))) + { + SelectFormImplementation(); + if (FormImpl != null) + FormImpl.PrepareRequest(this); + } + } + else + { + contentLength = UploadStreamLength; + + if (contentLength == -1) + SetHeader("Transfer-Encoding", "Chunked"); + + if (!HasHeader("Content-Type")) + SetHeader("Content-Type", "application/octet-stream"); + } + + // Always set the Content-Length header if possible + // http://tools.ietf.org/html/rfc2616#section-4.4 : For compatibility with HTTP/1.0 applications, HTTP/1.1 requests containing a message-body MUST include a valid Content-Length header field unless the server is known to be HTTP/1.1 compliant. + // 2018.06.03: Changed the condition so that content-length header will be included for zero length too. + if ( +#if !UNITY_WEBGL || UNITY_EDITOR + contentLength >= 0 +#else + contentLength != -1 +#endif + && !HasHeader("Content-Length")) + SetHeader("Content-Length", contentLength.ToString()); + +#if !UNITY_WEBGL || UNITY_EDITOR + #if !BESTHTTP_DISABLE_PROXY + // Proxy Authentication + if (HasProxy && Proxy.Credentials != null) + { + switch (Proxy.Credentials.Type) + { + case AuthenticationTypes.Basic: + // With Basic authentication we don't want to wait for a challenge, we will send the hash with the first request + SetHeader("Proxy-Authorization", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))); + break; + + case AuthenticationTypes.Unknown: + case AuthenticationTypes.Digest: + var digest = DigestStore.Get(Proxy.Address); + if (digest != null) + { + string authentication = digest.GenerateResponseHeader(this, Proxy.Credentials); + if (!string.IsNullOrEmpty(authentication)) + SetHeader("Proxy-Authorization", authentication); + } + + break; + } + } + #endif + +#endif + + // Server authentication + if (Credentials != null) + { + switch (Credentials.Type) + { + case AuthenticationTypes.Basic: + // With Basic authentication we don't want to wait for a challenge, we will send the hash with the first request + SetHeader("Authorization", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Credentials.UserName + ":" + Credentials.Password)))); + break; + + case AuthenticationTypes.Unknown: + case AuthenticationTypes.Digest: + var digest = DigestStore.Get(this.CurrentUri); + if (digest != null) + { + string authentication = digest.GenerateResponseHeader(this, Credentials); + if (!string.IsNullOrEmpty(authentication)) + SetHeader("Authorization", authentication); + } + + break; + } + } + + // Cookies. +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + // User added cookies are sent even when IsCookiesEnabled is set to false + List cookies = IsCookiesEnabled ? CookieJar.Get(CurrentUri) : null; + + // Merge server sent cookies with user-set cookies + if (cookies == null || cookies.Count == 0) + cookies = this.customCookies; + else if (this.customCookies != null) + { + // Merge + int idx = 0; + while (idx < this.customCookies.Count) + { + Cookie customCookie = customCookies[idx]; + + int foundIdx = cookies.FindIndex(c => c.Name.Equals(customCookie.Name)); + if (foundIdx >= 0) + cookies[foundIdx] = customCookie; + else + cookies.Add(customCookie); + + idx++; + } + } + + // http://tools.ietf.org/html/rfc6265#section-5.4 + // -When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field. + if (cookies != null && cookies.Count > 0) + { + // TODO: + // 2. The user agent SHOULD sort the cookie-list in the following order: + // * Cookies with longer paths are listed before cookies with shorter paths. + // * Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times. + + bool first = true; + string cookieStr = string.Empty; + + bool isSecureProtocolInUse = HTTPProtocolFactory.IsSecureProtocol(CurrentUri); + + foreach (var cookie in cookies) + if (!cookie.IsSecure || (cookie.IsSecure && isSecureProtocolInUse)) + { + if (!first) + cookieStr += "; "; + else + first = false; + + cookieStr += cookie.ToString(); + + // 3. Update the last-access-time of each cookie in the cookie-list to the current date and time. + cookie.LastAccess = DateTime.UtcNow; + } + + if (!string.IsNullOrEmpty(cookieStr)) + SetHeader("Cookie", cookieStr); + } +#endif + + if (callBeforeSendCallback && _onBeforeHeaderSend != null) + { + try + { + _onBeforeHeaderSend(this); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("HTTPRequest", "OnBeforeHeaderSend", ex); + } + } + + // Write out the headers to the stream + if (callback != null && Headers != null) + foreach (var kvp in Headers) + callback(kvp.Key, kvp.Value); + } + + /// + /// Writes out the Headers to the stream. + /// + private void SendHeaders(Stream stream) + { + EnumerateHeaders((header, values) => + { + if (string.IsNullOrEmpty(header) || values == null) + return; + + byte[] headerName = string.Concat(header, ": ").GetASCIIBytes(); + + for (int i = 0; i < values.Count; ++i) + { + if (string.IsNullOrEmpty(values[i])) + { + HTTPManager.Logger.Warning("HTTPRequest", string.Format("Null/empty value for header: {0}", header)); + continue; + } + + if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) + VerboseLogging("Header - '" + header + "': '" + values[i] + "'"); + + stream.WriteArray(headerName); + stream.WriteArray(values[i].GetASCIIBytes()); + stream.WriteArray(EOL); + } + }, /*callBeforeSendCallback:*/ true); + } + + /// + /// Returns a string representation of the headers. + /// + public string DumpHeaders() + { + using (var ms = new MemoryStream()) + { + SendHeaders(ms); + return ms.ToArray().AsciiToString(); + } + } + + /// + /// Returns with the bytes that will be sent to the server as the request's payload. + /// + /// Call this only after all form-fields are added! + public byte[] GetEntityBody() + { + if (RawData != null) + return RawData; + + if (FormImpl != null || (FieldCollector != null && !FieldCollector.IsEmpty)) + { + SelectFormImplementation(); + if (FormImpl != null) + return FormImpl.GetData(); + } + + return null; + } + + #endregion + + #region Internal Helper Functions + + internal void SendOutTo(Stream stream) + { + // Under WEBGL EnumerateHeaders and GetEntityBody are used instead of this function. +#if !UNITY_WEBGL || UNITY_EDITOR + try + { + string requestPathAndQuery = + #if !BESTHTTP_DISABLE_PROXY + HasProxy && Proxy.SendWholeUri ? CurrentUri.OriginalString : + #endif + CurrentUri.GetRequestPathAndQueryURL(); + + string requestLine = string.Format("{0} {1} HTTP/1.1", MethodNames[(byte)MethodType], requestPathAndQuery); + + if (HTTPManager.Logger.Level <= Logger.Loglevels.Information) + HTTPManager.Logger.Information("HTTPRequest", string.Format("Sending request: '{0}'", requestLine)); + + // Create a buffer stream that will not close 'stream' when disposed or closed. + // buffersize should be larger than UploadChunkSize as it might be used for uploading user data and + // it should have enough room for UploadChunkSize data and additional chunk information. + WriteOnlyBufferedStream bufferStream = new WriteOnlyBufferedStream(stream, (int)(UploadChunkSize * 1.5f)); + + bufferStream.WriteArray(requestLine.GetASCIIBytes()); + bufferStream.WriteArray(EOL); + + // Write headers to the buffer + SendHeaders(bufferStream); + bufferStream.WriteArray(EOL); + + // Send remaining data to the wire + bufferStream.Flush(); + + byte[] data = RawData; + + // We are sending forms? Then convert the form to a byte array + if (data == null && FormImpl != null) + data = FormImpl.GetData(); + + if (data != null || UploadStream != null) + { + // Make a new reference, as we will check the UploadStream property in the HTTPManager + Stream uploadStream = UploadStream; + + if (uploadStream == null) + { + // Make stream from the data + uploadStream = new MemoryStream(data, 0, data.Length); + + // Initialize progress report variable + UploadLength = data.Length; + } + else + UploadLength = UseUploadStreamLength ? UploadStreamLength : -1; + + // Initialize the progress report variables + Uploaded = 0; + + // Upload buffer. First we will read the data into this buffer from the UploadStream, then write this buffer to our outStream + byte[] buffer = new byte[UploadChunkSize]; + + // How many bytes was read from the UploadStream + int count = 0; + while ((count = uploadStream.Read(buffer, 0, buffer.Length)) > 0) + { + // If we don't know the size, send as chunked + if (!UseUploadStreamLength) + { + bufferStream.WriteArray(count.ToString("X").GetASCIIBytes()); + bufferStream.WriteArray(EOL); + } + + // write out the buffer to the wire + bufferStream.Write(buffer, 0, count); + + // chunk trailing EOL + if (!UseUploadStreamLength) + bufferStream.WriteArray(EOL); + + // update how many bytes are uploaded + Uploaded += count; + + // Write to the wire + bufferStream.Flush(); + + // let the callback fire + UploadProgressChanged = true; + } + + // All data from the stream are sent, write the 'end' chunk if necessary + if (!UseUploadStreamLength) + { + bufferStream.WriteArray("0".GetASCIIBytes()); + bufferStream.WriteArray(EOL); + bufferStream.WriteArray(EOL); + } + + // Make sure all remaining data will be on the wire + bufferStream.Flush(); + + // Dispose the MemoryStream + if (UploadStream == null && uploadStream != null) + uploadStream.Dispose(); + } + else + bufferStream.Flush(); + + HTTPManager.Logger.Information("HTTPRequest", "'" + requestLine + "' sent out"); + } + finally + { + if (UploadStream != null && DisposeUploadStream) + UploadStream.Dispose(); + } +#endif + } + + internal void UpgradeCallback() + { + if (Response == null || !Response.IsUpgraded) + return; + + try + { + if (OnUpgraded != null) + OnUpgraded(this, Response); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HTTPRequest", "UpgradeCallback", ex); + } + } + + internal void CallCallback() + { + try + { + if (this.Callback != null) + this.Callback(this, Response); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HTTPRequest", "CallCallback", ex); + } + } + + internal bool CallOnBeforeRedirection(Uri redirectUri) + { + if (onBeforeRedirection != null) + return onBeforeRedirection(this, this.Response, redirectUri); + + return true; + } + + internal void FinishStreaming() + { + if (Response != null && UseStreaming) + Response.FinishStreaming(); + } + + /// + /// Called on Unity's main thread just before processing it. + /// + internal void Prepare() + { +#if !BESTHTTP_DISABLE_UNITY_FORM + if (FormUsage == HTTPFormUsage.Unity) + SelectFormImplementation(); +#endif + } + +#if !NETFX_CORE && !UNITY_WP8 + internal bool CallCustomCertificationValidator(System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain) + { + if (CustomCertificationValidator != null) + return CustomCertificationValidator(this, cert, chain); + return true; + } +#endif + +#endregion + + /// + /// Starts processing the request. + /// + public HTTPRequest Send() + { + return HTTPManager.SendRequest(this); + } + + /// + /// Aborts an already established connection, so no further download or upload are done. + /// + public void Abort() + { + if (System.Threading.Monitor.TryEnter(HTTPManager.Locker, TimeSpan.FromMilliseconds(100))) + { + try + { + if (this.State >= HTTPRequestStates.Finished) + { + HTTPManager.Logger.Warning("HTTPRequest", string.Format("Abort - Already in a state({0}) where no Abort required!", this.State.ToString())); + + return; + } + + // Get the parent connection + var connection = HTTPManager.GetConnectionWith(this); + + // No Connection found for this request, maybe not even started + if (connection == null) + { + // so try to remove from the request queue + if (!HTTPManager.RemoveFromQueue(this)) + HTTPManager.Logger.Warning("HTTPRequest", "Abort - No active connection found with this request! (The request may already finished?)"); + + this.State = HTTPRequestStates.Aborted; + this.CallCallback(); + } + else + { + // destroy the incomplete response + if (Response != null && Response.IsStreamed) + Response.Dispose(); + + // send an abort request to the connection + connection.Abort(HTTPConnectionStates.AbortRequested); + } + } + finally + { + System.Threading.Monitor.Exit(HTTPManager.Locker); + } + } + else + throw new Exception("Wasn't able to acquire a thread lock. Abort failed!"); + } + + /// + /// Resets the request for a state where switching MethodType is possible. + /// + public void Clear() + { + ClearForm(); + RemoveHeaders(); + + this.IsRedirected = false; + this.RedirectCount = 0; + this.Downloaded = this.DownloadLength = 0; + } + + private void VerboseLogging(string str) + { + HTTPManager.Logger.Verbose("HTTPRequest", "'" + this.CurrentUri.ToString() + "' - " + str); + } + + #region System.Collections.IEnumerator implementation + + public object Current { get { return null; } } + + public bool MoveNext() + { + return this.State < HTTPRequestStates.Finished; + } + + public void Reset() + { + throw new NotImplementedException(); + } + +#endregion + + HTTPRequest IEnumerator.Current + { + get { return this; } + } + + public void Dispose() + { + + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs.meta new file mode 100644 index 0000000..5ad5cae --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPRequest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bb4a0cfc508761746bb8e11d32d4c8e0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs new file mode 100644 index 0000000..eaa2bfb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs @@ -0,0 +1,1161 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +#if !NETFX_CORE || UNITY_EDITOR + using System.Net.Sockets; +#endif + +using UnityEngine; + +namespace BestHTTP +{ + #if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + using BestHTTP.Caching; + #endif + + using BestHTTP.Extensions; + + #if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + using BestHTTP.Cookies; + #endif + + public interface IProtocol + { + bool IsClosed { get; } + void HandleEvents(); + } + + /// + /// + /// + public class HTTPResponse : IDisposable + { + internal const byte CR = 13; + internal const byte LF = 10; + + public const int MinBufferSize = 4 * 1024; + + #region Public Properties + + public int VersionMajor { get; protected set; } + public int VersionMinor { get; protected set; } + + /// + /// The status code that sent from the server. + /// + public int StatusCode { get; protected set; } + + /// + /// Returns true if the status code is in the range of [200..300[ or 304 (Not Modified) + /// + public bool IsSuccess { get { return (this.StatusCode >= 200 && this.StatusCode < 300) || this.StatusCode == 304; } } + + /// + /// The message that sent along with the StatusCode from the server. You can check it for errors from the server. + /// + public string Message { get; protected set; } + + /// + /// True if it's a streamed response. + /// + public bool IsStreamed { get; protected set; } + + /// + /// True if the streaming is finished, and no more fragments are coming. + /// + public bool IsStreamingFinished { get; internal set; } + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Indicates that the response body is read from the cache. + /// + public bool IsFromCache { get; internal set; } + + /// + /// Provides information about the file used for caching the request. + /// + public HTTPCacheFileInfo CacheFileInfo { get; internal set; } + + /// + /// Determines if this response is only stored to cache. + /// If both IsCacheOnly and IsStreamed are true, GetStreamedFragments should not be called. + /// + public bool IsCacheOnly { get; private set; } +#endif + + /// + /// The headers that sent from the server. + /// + public Dictionary> Headers { get; protected set; } + + /// + /// The data that downloaded from the server. All Transfer and Content encodings decoded if any(eg. chunked, gzip, deflate). + /// + public byte[] Data { get; internal set; } + + /// + /// The normal HTTP protocol is upgraded to an other. + /// + public bool IsUpgraded { get; protected set; } + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// The cookies that the server sent to the client. + /// + public List Cookies { get; internal set; } +#endif + + /// + /// Cached, converted data. + /// + protected string dataAsText; + + /// + /// The data converted to an UTF8 string. + /// + public string DataAsText + { + get + { + if (Data == null) + return string.Empty; + + if (!string.IsNullOrEmpty(dataAsText)) + return dataAsText; + + return dataAsText = Encoding.UTF8.GetString(Data, 0, Data.Length); + } + } + + /// + /// Cached converted data. + /// + protected Texture2D texture; + + /// + /// The data loaded to a Texture2D. + /// + public Texture2D DataAsTexture2D + { + get + { + if (Data == null) + return null; + + if (texture != null) + return texture; + + texture = new Texture2D(0, 0, TextureFormat.ARGB32, false); + texture.LoadImage(Data); + + return texture; + } + } + + /// + /// True if the connection's stream will be closed manually. Used in custom protocols (WebSocket, EventSource). + /// + public bool IsClosedManually { get; protected set; } + + #endregion + + #region Internal Fields + + internal HTTPRequest baseRequest; + + #endregion + + #region Protected Properties And Fields + + protected Stream Stream; + + protected List streamedFragments; + protected object SyncRoot = new object(); + + protected byte[] fragmentBuffer; + protected int fragmentBufferDataLength; +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + protected Stream cacheStream; +#endif + protected int allFragmentSize; + + #endregion + + public HTTPResponse(HTTPRequest request, Stream stream, bool isStreamed, bool isFromCache) + { + this.baseRequest = request; + this.Stream = stream; + this.IsStreamed = isStreamed; +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + this.IsFromCache = isFromCache; + this.IsCacheOnly = request.CacheOnly; +#endif + this.IsClosedManually = false; + } + + public virtual bool Receive(int forceReadRawContentLength = -1, bool readPayloadData = true) + { + string statusLine = string.Empty; + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("Receive. forceReadRawContentLength: '{0:N0}', readPayloadData: '{1:N0}'", forceReadRawContentLength, readPayloadData)); + + // On WP platform we aren't able to determined sure enough whether the tcp connection is closed or not. + // So if we get an exception here, we need to recreate the connection. + try + { + // Read out 'HTTP/1.1' from the "HTTP/1.1 {StatusCode} {Message}" + statusLine = ReadTo(Stream, (byte)' '); + } + catch + { + if (!baseRequest.DisableRetry) + { + HTTPManager.Logger.Warning("HTTPResponse", string.Format("{0} - Failed to read Status Line! Retry is enabled, returning with false.", this.baseRequest.CurrentUri.ToString())); + return false; + } + + HTTPManager.Logger.Warning("HTTPResponse", string.Format("{0} - Failed to read Status Line! Retry is disabled, re-throwing exception.", this.baseRequest.CurrentUri.ToString())); + throw; + } + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("Status Line: '{0}'", statusLine)); + + if (string.IsNullOrEmpty(statusLine)) + { + if (!baseRequest.DisableRetry) + return false; + + throw new Exception("Remote server closed the connection before sending response header!"); + } + + string[] versions = statusLine.Split(new char[] { '/', '.' }); + this.VersionMajor = int.Parse(versions[1]); + this.VersionMinor = int.Parse(versions[2]); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("HTTP Version: '{0}.{1}'", this.VersionMajor.ToString(), this.VersionMinor.ToString())); + + int statusCode; + string statusCodeStr = NoTrimReadTo(Stream, (byte)' ', LF); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("Status Code: '{0}'", statusCodeStr)); + + if (baseRequest.DisableRetry) + statusCode = int.Parse(statusCodeStr); + else if (!int.TryParse(statusCodeStr, out statusCode)) + return false; + + this.StatusCode = statusCode; + + if (statusCodeStr.Length > 0 && (byte)statusCodeStr[statusCodeStr.Length - 1] != LF && (byte)statusCodeStr[statusCodeStr.Length - 1] != CR) + { + this.Message = ReadTo(Stream, LF); + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("Status Message: '{0}'", this.Message)); + } + else + { + HTTPManager.Logger.Warning("HTTPResponse", string.Format("{0} - Skipping Status Message reading!", this.baseRequest.CurrentUri.ToString())); + + this.Message = string.Empty; + } + + //Read Headers + ReadHeaders(Stream); + + IsUpgraded = StatusCode == 101 && (HasHeaderWithValue("connection", "upgrade") || HasHeader("upgrade")); + + if (IsUpgraded && HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging("Request Upgraded!"); + + if (!readPayloadData) + return true; + + return ReadPayload(forceReadRawContentLength); + } + + protected bool ReadPayload(int forceReadRawContentLength) + { + // Reading from an already unpacked stream (eq. From a file cache) + if (forceReadRawContentLength != -1) + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + this.IsFromCache = true; +#endif + ReadRaw(Stream, forceReadRawContentLength); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging("ReadPayload Finished!"); + return true; + } + + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 + // 1.Any response message which "MUST NOT" include a message-body (such as the 1xx, 204, and 304 responses and any response to a HEAD request) + // is always terminated by the first empty line after the header fields, regardless of the entity-header fields present in the message. + if ((StatusCode >= 100 && StatusCode < 200) || StatusCode == 204 || StatusCode == 304 || baseRequest.MethodType == HTTPMethods.Head) + return true; + +#if (!UNITY_WEBGL || UNITY_EDITOR) + if (HasHeaderWithValue("transfer-encoding", "chunked")) + ReadChunked(Stream); + else +#endif + { + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 + // Case 3 in the above link. + List contentLengthHeaders = GetHeaderValues("content-length"); + var contentRangeHeaders = GetHeaderValues("content-range"); + if (contentLengthHeaders != null && contentRangeHeaders == null) + ReadRaw(Stream, long.Parse(contentLengthHeaders[0])); + else if (contentRangeHeaders != null) + { + if (contentLengthHeaders != null) + ReadRaw(Stream, long.Parse(contentLengthHeaders[0])); + else + { + HTTPRange range = GetRange(); + ReadRaw(Stream, (range.LastBytePos - range.FirstBytePos) + 1); + } + } + else + ReadUnknownSize(Stream); + } + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging("ReadPayload Finished!"); + + return true; + } + + #region Header Management + + protected void ReadHeaders(Stream stream) + { + string headerName = ReadTo(stream, (byte)':', LF).Trim(); + while (headerName != string.Empty) + { + string value = ReadTo(stream, LF); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("Header - '{0}': '{1}'", headerName, value)); + + AddHeader(headerName, value); + + headerName = ReadTo(stream, (byte)':', LF); + } + } + + protected void AddHeader(string name, string value) + { + name = name.ToLower(); + + if (Headers == null) + Headers = new Dictionary>(); + + List values; + if (!Headers.TryGetValue(name, out values)) + Headers.Add(name, values = new List(1)); + + values.Add(value); + } + + /// + /// Returns the list of values that received from the server for the given header name. + /// Remarks: All headers converted to lowercase while reading the response. + /// + /// Name of the header + /// If no header found with the given name or there are no values in the list (eg. Count == 0) returns null. + public List GetHeaderValues(string name) + { + if (Headers == null) + return null; + + name = name.ToLower(); + + List values; + if (!Headers.TryGetValue(name, out values) || values.Count == 0) + return null; + + return values; + } + + /// + /// Returns the first value in the header list or null if there are no header or value. + /// + /// Name of the header + /// If no header found with the given name or there are no values in the list (eg. Count == 0) returns null. + public string GetFirstHeaderValue(string name) + { + if (Headers == null) + return null; + + name = name.ToLower(); + + List values; + if (!Headers.TryGetValue(name, out values) || values.Count == 0) + return null; + + return values[0]; + } + + /// + /// Checks if there is a header with the given name and value. + /// + /// Name of the header. + /// + /// Returns true if there is a header with the given name and value. + public bool HasHeaderWithValue(string headerName, string value) + { + var values = GetHeaderValues(headerName); + if (values == null) + return false; + + for (int i = 0; i < values.Count; ++i) + if (string.Compare(values[i], value, StringComparison.OrdinalIgnoreCase) == 0) + return true; + + return false; + } + + /// + /// Checks if there is a header with the given name. + /// + /// Name of the header. + /// Returns true if there is a header with the given name. + public bool HasHeader(string headerName) + { + var values = GetHeaderValues(headerName); + if (values == null) + return false; + + return true; + } + + /// + /// Parses the 'Content-Range' header's value and returns a HTTPRange object. + /// + /// If the server ignores a byte-range-spec because it is syntactically invalid, the server SHOULD treat the request as if the invalid Range header field did not exist. + /// (Normally, this means return a 200 response containing the full entity). In this case because of there are no 'Content-Range' header, this function will return null! + /// Returns null if no 'Content-Range' header found. + public HTTPRange GetRange() + { + var rangeHeaders = GetHeaderValues("content-range"); + if (rangeHeaders == null) + return null; + + // A byte-content-range-spec with a byte-range-resp-spec whose last- byte-pos value is less than its first-byte-pos value, + // or whose instance-length value is less than or equal to its last-byte-pos value, is invalid. + // The recipient of an invalid byte-content-range- spec MUST ignore it and any content transferred along with it. + + // A valid content-range sample: "bytes 500-1233/1234" + var ranges = rangeHeaders[0].Split(new char[] { ' ', '-', '/' }, StringSplitOptions.RemoveEmptyEntries); + + // A server sending a response with status code 416 (Requested range not satisfiable) SHOULD include a Content-Range field with a byte-range-resp-spec of "*". + // The instance-length specifies the current length of the selected resource. + // "bytes */1234" + if (ranges[1] == "*") + return new HTTPRange(int.Parse(ranges[2])); + + return new HTTPRange(int.Parse(ranges[1]), int.Parse(ranges[2]), ranges[3] != "*" ? int.Parse(ranges[3]) : -1); + } + + #endregion + + #region Static Stream Management Helper Functions + + public static string ReadTo(Stream stream, byte blocker) + { + using (var ms = new MemoryStream()) + { + int ch = stream.ReadByte(); + while (ch != blocker && ch != -1) + { + ms.WriteByte((byte)ch); + ch = stream.ReadByte(); + } + + return ms.ToArray().AsciiToString().Trim(); + } + } + + public static string ReadTo(Stream stream, byte blocker1, byte blocker2) + { + using (var ms = new MemoryStream()) + { + int ch = stream.ReadByte(); + while (ch != blocker1 && ch != blocker2 && ch != -1) + { + ms.WriteByte((byte)ch); + ch = stream.ReadByte(); + } + + return ms.ToArray().AsciiToString().Trim(); + } + } + + public static string NoTrimReadTo(Stream stream, byte blocker1, byte blocker2) + { + using (var ms = new MemoryStream()) + { + int ch = stream.ReadByte(); + while (ch != blocker1 && ch != blocker2 && ch != -1) + { + ms.WriteByte((byte)ch); + ch = stream.ReadByte(); + } + + return ms.ToArray().AsciiToString(); + } + } + + #endregion + + #region Read Chunked Body + + protected int ReadChunkLength(Stream stream) + { + // Read until the end of line, then split the string so we will discard any optional chunk extensions + string line = ReadTo(stream, LF); + string[] splits = line.Split(';'); + string num = splits[0]; + + int result; + if (int.TryParse(num, System.Globalization.NumberStyles.AllowHexSpecifier, null, out result)) + return result; + + throw new Exception(string.Format("Can't parse '{0}' as a hex number!", num)); + } + + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 + protected void ReadChunked(Stream stream) + { + BeginReceiveStreamFragments(); + + string contentLengthHeader = GetFirstHeaderValue("Content-Length"); + bool hasContentLengthHeader = !string.IsNullOrEmpty(contentLengthHeader); + int realLength = 0; + if (hasContentLengthHeader) + hasContentLengthHeader = int.TryParse(contentLengthHeader, out realLength); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("ReadChunked - hasContentLengthHeader: {0}, contentLengthHeader: {1} realLength: {2:N0}", hasContentLengthHeader.ToString(), contentLengthHeader, realLength)); + + using (var output = new MemoryStream()) + { + int chunkLength = ReadChunkLength(stream); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("chunkLength: {0:N0}", chunkLength)); + + byte[] buffer = new byte[chunkLength]; + + int contentLength = 0; + + // Progress report: + baseRequest.DownloadLength = hasContentLengthHeader ? realLength : chunkLength; + baseRequest.DownloadProgressChanged = this.IsSuccess +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + || this.IsFromCache +#endif + ; + + string encoding = +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + IsFromCache ? null : +#endif + GetFirstHeaderValue("content-encoding"); + bool gzipped = !string.IsNullOrEmpty(encoding) && encoding == "gzip"; + + while (chunkLength != 0) + { + // To avoid more GC garbage we use only one buffer, and resize only if the next chunk doesn't fit. + if (buffer.Length < chunkLength) + Array.Resize(ref buffer, chunkLength); + + int readBytes = 0; + + // Fill up the buffer + do + { + int bytes = stream.Read(buffer, readBytes, chunkLength - readBytes); + if (bytes <= 0) + throw ExceptionHelper.ServerClosedTCPStream(); + + readBytes += bytes; + + // Progress report: + // Placing reporting inside this cycle will report progress much more frequent + baseRequest.Downloaded += bytes; + baseRequest.DownloadProgressChanged = this.IsSuccess +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + || this.IsFromCache +#endif + ; + + } while (readBytes < chunkLength); + + if (baseRequest.UseStreaming) + { + // If reading from cache, we don't want to read too much data to memory. So we will wait until the loaded fragment processed. + WaitWhileHasFragments(); + + if (gzipped) + { + var decompressed = Decompress(buffer, 0, readBytes); + if (decompressed != null) + FeedStreamFragment(decompressed, 0, decompressed.Length); + } + else + FeedStreamFragment(buffer, 0, readBytes); + } + else + output.Write(buffer, 0, readBytes); + + // Every chunk data has a trailing CRLF + ReadTo(stream, LF); + + contentLength += readBytes; + + // read the next chunk's length + chunkLength = ReadChunkLength(stream); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("chunkLength: {0:N0}", chunkLength)); + + if (!hasContentLengthHeader) + baseRequest.DownloadLength += chunkLength; + baseRequest.DownloadProgressChanged = this.IsSuccess +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + || this.IsFromCache +#endif + ; + } + + if (baseRequest.UseStreaming) + { + if (gzipped) + { + var decompressed = Decompress(null, 0, 0, true); + if (decompressed != null) + FeedStreamFragment(decompressed, 0, decompressed.Length); + } + + FlushRemainingFragmentBuffer(); + } + + // Read the trailing headers or the CRLF + ReadHeaders(stream); + + // HTTP servers sometimes use compression (gzip) or deflate methods to optimize transmission. + // How both chunked and gzip encoding interact is dictated by the two-staged encoding of HTTP: + // first the content stream is encoded as (Content-Encoding: gzip), after which the resulting byte stream is encoded for transfer using another encoder (Transfer-Encoding: chunked). + // This means that in case both compression and chunked encoding are enabled, the chunk encoding itself is not compressed, and the data in each chunk should not be compressed individually. + // The remote endpoint can decode the incoming stream by first decoding it with the Transfer-Encoding, followed by the specified Content-Encoding. + // It would be a better implementation when the chunk would be decododed on-the-fly. Becouse now the whole stream must be downloaded, and then decoded. It needs more memory. + if (!baseRequest.UseStreaming) + this.Data = DecodeStream(output); + } + } + + #endregion + + #region Read Raw Body + + // No transfer-encoding just raw bytes. + internal void ReadRaw(Stream stream, long contentLength) + { + BeginReceiveStreamFragments(); + + // Progress report: + baseRequest.DownloadLength = contentLength; + baseRequest.DownloadProgressChanged = this.IsSuccess +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + || this.IsFromCache +#endif + ; + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("ReadRaw - contentLength: {0:N0}", contentLength)); + + string encoding = +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + IsFromCache ? null : +#endif + GetFirstHeaderValue("content-encoding"); + bool gzipped = !string.IsNullOrEmpty(encoding) && encoding == "gzip"; + if(!baseRequest.UseStreaming && contentLength > 2147483646) + { + throw new OverflowException("You have to use STREAMING to download files bigger than 2GB!"); + } + + using (var output = new MemoryStream(baseRequest.UseStreaming ? 0 : (int)contentLength)) + { + byte[] buffer = new byte[Math.Max(baseRequest.StreamFragmentSize, MinBufferSize)]; + int readBytes = 0; + + while (contentLength > 0) + { + readBytes = 0; + + do + { + int readbuffer = (int)Math.Min(2147483646, (uint)contentLength); + int bytes = stream.Read(buffer, readBytes, Math.Min(readbuffer, buffer.Length - readBytes)); + + if (bytes <= 0) + throw ExceptionHelper.ServerClosedTCPStream(); + + readBytes += bytes; + contentLength -= bytes; + + // Progress report: + baseRequest.Downloaded += bytes; + baseRequest.DownloadProgressChanged = this.IsSuccess +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + || this.IsFromCache +#endif + ; + + } while (readBytes < buffer.Length && contentLength > 0); + + if (baseRequest.UseStreaming) + { + // If reading from cache, we don't want to read too much data to memory. So we will wait until the loaded fragment processed. + WaitWhileHasFragments(); + + if (gzipped) + { + var decompressed = Decompress(buffer, 0, readBytes); + if (decompressed != null) + FeedStreamFragment(decompressed, 0, decompressed.Length); + } + else + FeedStreamFragment(buffer, 0, readBytes); + } + else + output.Write(buffer, 0, readBytes); + }; + + if (baseRequest.UseStreaming) + { + if (gzipped) + { + var decompressed = Decompress(null, 0, 0, true); + if (decompressed != null) + FeedStreamFragment(decompressed, 0, decompressed.Length); + } + + FlushRemainingFragmentBuffer(); + } + + if (!baseRequest.UseStreaming) + this.Data = DecodeStream(output); + } + } + + #endregion + + #region Read Unknown Size + + protected void ReadUnknownSize(Stream stream) + { + string encoding = +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + IsFromCache ? null : +#endif + GetFirstHeaderValue("content-encoding"); + bool gzipped = !string.IsNullOrEmpty(encoding) && encoding == "gzip"; + + using (var output = new MemoryStream()) + { + byte[] buffer = new byte[Math.Max(baseRequest.StreamFragmentSize, MinBufferSize)]; + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("ReadUnknownSize - buffer size: {0:N0}", buffer.Length)); + + int readBytes = 0; + int bytes = 0; + do + { + readBytes = 0; + + do + { + bytes = 0; + +#if (!NETFX_CORE && !UNITY_WP8) || UNITY_EDITOR + NetworkStream networkStream = stream as NetworkStream; + // If we have the good-old NetworkStream, than we can use the DataAvailable property. On WP8 platforms, these are omitted... :/ + if (networkStream != null && baseRequest.EnableSafeReadOnUnknownContentLength) + { + for (int i = readBytes; i < buffer.Length && networkStream.DataAvailable; ++i) + { + int read = stream.ReadByte(); + if (read >= 0) + { + buffer[i] = (byte)read; + bytes++; + } + else + break; + } + } + else // This will be good anyway, but a little slower. +#endif + { + bytes = stream.Read(buffer, readBytes, buffer.Length - readBytes); + } + + readBytes += bytes; + + // Progress report: + baseRequest.Downloaded += bytes; + baseRequest.DownloadLength = baseRequest.Downloaded; + baseRequest.DownloadProgressChanged = this.IsSuccess +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + || this.IsFromCache +#endif + ; + + } while (readBytes < buffer.Length && bytes > 0); + + if (baseRequest.UseStreaming) + { + // If reading from cache, we don't want to read too much data to memory. So we will wait until the loaded fragment processed. + WaitWhileHasFragments(); + + if (gzipped) + { + var decompressed = Decompress(buffer, 0, readBytes); + if (decompressed != null) + FeedStreamFragment(decompressed, 0, decompressed.Length); + } + else + FeedStreamFragment(buffer, 0, readBytes); + } + else + output.Write(buffer, 0, readBytes); + + } while (bytes > 0); + + if (baseRequest.UseStreaming) + { + if (gzipped) + { + var decompressed = Decompress(null, 0, 0, true); + if (decompressed != null) + FeedStreamFragment(decompressed, 0, decompressed.Length); + } + + FlushRemainingFragmentBuffer(); + } + + if (!baseRequest.UseStreaming) + this.Data = DecodeStream(output); + } + } + + #endregion + + #region Stream Decoding + + protected byte[] DecodeStream(MemoryStream streamToDecode) + { + streamToDecode.Seek(0, SeekOrigin.Begin); + + // The cache stores the decoded data + var encoding = +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + IsFromCache ? null : +#endif + GetHeaderValues("content-encoding"); + +#if !UNITY_WEBGL || UNITY_EDITOR + Stream decoderStream = null; +#endif + + // Return early if there are no encoding used. + if (encoding == null) + return streamToDecode.ToArray(); + else + { + switch (encoding[0]) + { +#if !UNITY_WEBGL || UNITY_EDITOR + case "gzip": decoderStream = new Decompression.Zlib.GZipStream(streamToDecode, Decompression.Zlib.CompressionMode.Decompress); break; + case "deflate": decoderStream = new Decompression.Zlib.DeflateStream(streamToDecode, Decompression.Zlib.CompressionMode.Decompress); break; +#endif + //identity, utf-8, etc. + default: + // Do not copy from one stream to an other, just return with the raw bytes + return streamToDecode.ToArray(); + } + } + +#if !UNITY_WEBGL || UNITY_EDITOR + using (var ms = new MemoryStream((int)streamToDecode.Length)) + { + var buf = new byte[1024]; + int byteCount = 0; + + while ((byteCount = decoderStream.Read(buf, 0, buf.Length)) > 0) + ms.Write(buf, 0, byteCount); + + return ms.ToArray(); + } +#endif + } + + #endregion + + #region Streaming Fragments Support + + private System.IO.MemoryStream decompressorInputStream; + private System.IO.MemoryStream decompressorOutputStream; + private Decompression.Zlib.GZipStream decompressorGZipStream; + private byte[] copyBuffer; + + const int MinLengthToDecompress = 256; + + private byte[] Decompress(byte[] data, int offset, int count, bool forceDecompress = false) + { + if (decompressorInputStream == null) + decompressorInputStream = new MemoryStream(count); + + if (data != null) + decompressorInputStream.Write(data, offset, count); + + if (!forceDecompress && decompressorInputStream.Length < MinLengthToDecompress) + return null; + + decompressorInputStream.Position = 0; + + if (decompressorGZipStream == null) + { + decompressorGZipStream = new Decompression.Zlib.GZipStream(decompressorInputStream, + Decompression.Zlib.CompressionMode.Decompress, + Decompression.Zlib.CompressionLevel.Default, + true); + decompressorGZipStream.FlushMode = Decompression.Zlib.FlushType.Sync; + } + + if (decompressorOutputStream == null) + decompressorOutputStream = new System.IO.MemoryStream(); + decompressorOutputStream.SetLength(0); + + if (copyBuffer == null) + copyBuffer = new byte[1024]; + + int readCount; + while ((readCount = decompressorGZipStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0) + decompressorOutputStream.Write(copyBuffer, 0, readCount); + + decompressorGZipStream.SetLength(0); + + byte[] result = decompressorOutputStream.ToArray(); + + return result; + } + + protected void BeginReceiveStreamFragments() + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (!baseRequest.DisableCache && baseRequest.UseStreaming) + { + // If caching is enabled and the response not from cache and it's cacheble we will cache the downloaded data. + if (!IsFromCache && HTTPCacheService.IsCacheble(baseRequest.CurrentUri, baseRequest.MethodType, this)) + cacheStream = HTTPCacheService.PrepareStreamed(baseRequest.CurrentUri, this); + } +#endif + allFragmentSize = 0; + } + + /// + /// Add data to the fragments list. + /// + /// The buffer to be added. + /// The position where we start copy the data. + /// How many data we want to copy. + protected void FeedStreamFragment(byte[] buffer, int pos, int length) + { + if (buffer == null || length == 0) + return; + + if (fragmentBuffer == null) + { + fragmentBuffer = new byte[baseRequest.StreamFragmentSize]; + fragmentBufferDataLength = 0; + } + + if (fragmentBufferDataLength + length <= baseRequest.StreamFragmentSize) + { + Array.Copy(buffer, pos, fragmentBuffer, fragmentBufferDataLength, length); + fragmentBufferDataLength += length; + + if (fragmentBufferDataLength == baseRequest.StreamFragmentSize) + { + AddStreamedFragment(fragmentBuffer); + fragmentBuffer = null; + fragmentBufferDataLength = 0; + } + } + else + { + int remaining = baseRequest.StreamFragmentSize - fragmentBufferDataLength; + + FeedStreamFragment(buffer, pos, remaining); + FeedStreamFragment(buffer, pos + remaining, length - remaining); + } + } + + protected void FlushRemainingFragmentBuffer() + { + if (fragmentBuffer != null) + { + Array.Resize(ref fragmentBuffer, fragmentBufferDataLength); + + AddStreamedFragment(fragmentBuffer); + fragmentBuffer = null; + fragmentBufferDataLength = 0; + } + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (cacheStream != null) + { + cacheStream.Dispose(); + cacheStream = null; + + HTTPCacheService.SetBodyLength(baseRequest.CurrentUri, allFragmentSize); + } +#endif + } + + protected void AddStreamedFragment(byte[] buffer) + { + lock (SyncRoot) + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (!IsCacheOnly) +#endif + { + if (streamedFragments == null) + streamedFragments = new List(); + + streamedFragments.Add(buffer); + } + + + if (HTTPManager.Logger.Level == Logger.Loglevels.All && buffer != null && streamedFragments != null) + VerboseLogging(string.Format("AddStreamedFragment buffer length: {0:N0} streamedFragments: {1:N0}", buffer.Length, streamedFragments.Count)); + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (cacheStream != null) + { + cacheStream.Write(buffer, 0, buffer.Length); + allFragmentSize += buffer.Length; + } +#endif + } + } + + protected +#if NETFX_CORE + async +#endif + void WaitWhileHasFragments() + { + VerboseLogging("WaitWhileHasFragments"); + +#if !UNITY_WEBGL || UNITY_EDITOR + while (baseRequest.UseStreaming && HasFragmentsInQueue()) + { + #if NETFX_CORE + await System.Threading.Tasks.Task.Delay(16); + #else + System.Threading.Thread.Sleep(16); + #endif + } +#endif + } + + bool HasFragmentsInQueue() + { + lock (SyncRoot) + { + bool result = streamedFragments != null && streamedFragments.Count >= baseRequest.MaxFragmentQueueLength; + if (result && HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("HasFragmentsInQueue - {0} / {1}", streamedFragments.Count, baseRequest.MaxFragmentQueueLength)); + + return result; + } + } + + /// + /// If streaming is used, then every time this callback function called we can use this function to + /// retrieve the downloaded and buffered data. The returned list can be null, if there is no data yet. + /// + /// + public List GetStreamedFragments() + { + lock (SyncRoot) + { + if (streamedFragments == null || streamedFragments.Count == 0) + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging("GetStreamedFragments - no fragments, returning with null"); + return null; + } + + var result = new List(streamedFragments); + streamedFragments.Clear(); + + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging(string.Format("GetStreamedFragments - returning with {0:N0} fragments", result.Count.ToString())); + + return result; + } + } + + internal bool HasStreamedFragments() + { + lock (SyncRoot) + return streamedFragments != null && streamedFragments.Count >= baseRequest.MaxFragmentQueueLength; + } + + internal void FinishStreaming() + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + VerboseLogging("FinishStreaming"); + + IsStreamingFinished = true; + Dispose(); + } + + #endregion + + void VerboseLogging(string str) + { + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + HTTPManager.Logger.Verbose("HTTPResponse", "'" + this.baseRequest.CurrentUri.ToString() + "' - " + str); + } + + /// + /// IDisposable implementation. + /// + public void Dispose() + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + if (cacheStream != null) + { + cacheStream.Dispose(); + cacheStream = null; + } +#endif + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs.meta new file mode 100644 index 0000000..7792ad9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPResponse.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 555ceb051cbef0648b81ad42a853d672 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs b/Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs new file mode 100644 index 0000000..3c9d637 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs @@ -0,0 +1,257 @@ +using UnityEngine; + +#if NETFX_CORE || BUILD_FOR_WP8 + using System.Threading.Tasks; +#endif + +namespace BestHTTP +{ + /// + /// Will route some U3D calls to the HTTPManager. + /// + [ExecuteInEditMode] + public sealed class HTTPUpdateDelegator : MonoBehaviour + { + #region Public Properties + + /// + /// The singleton instance of the HTTPUpdateDelegator + /// + public static HTTPUpdateDelegator Instance { get; private set; } + + /// + /// True, if the Instance property should hold a valid value. + /// + public static bool IsCreated { get; private set; } + + /// + /// Set it true before any CheckInstance() call, or before any request sent to dispatch callbacks on another thread. + /// + public static bool IsThreaded { get; set; } + + /// + /// It's true if the dispatch thread running. + /// + public static bool IsThreadRunning { get; private set; } + + /// + /// How much time the plugin should wait between two update call. Its default value 100 ms. + /// + public static int ThreadFrequencyInMS { get; set; } + + /// + /// Called in the OnApplicationQuit function. If this function returns False, the plugin will not start to + /// shut down itself. + /// + public static System.Func OnBeforeApplicationQuit; + + public static System.Action OnApplicationForegroundStateChanged; + + #endregion + + private static bool IsSetupCalled; + + static HTTPUpdateDelegator() + { + ThreadFrequencyInMS = 100; + } + + /// + /// Will create the HTTPUpdateDelegator instance and set it up. + /// + public static void CheckInstance() + { + try + { + if (!IsCreated) + { + GameObject go = GameObject.Find("HTTP Update Delegator"); + + if (go != null) + Instance = go.GetComponent(); + + if (Instance == null) + { + go = new GameObject("HTTP Update Delegator"); + go.hideFlags = HideFlags.DontSave; + + Instance = go.AddComponent(); + } + IsCreated = true; + +#if UNITY_EDITOR + if (!UnityEditor.EditorApplication.isPlaying) + { + UnityEditor.EditorApplication.update -= Instance.Update; + UnityEditor.EditorApplication.update += Instance.Update; + } + +#if UNITY_2017_2_OR_NEWER + UnityEditor.EditorApplication.playModeStateChanged -= Instance.OnPlayModeStateChanged; + UnityEditor.EditorApplication.playModeStateChanged += Instance.OnPlayModeStateChanged; +#else + UnityEditor.EditorApplication.playmodeStateChanged -= Instance.OnPlayModeStateChanged; + UnityEditor.EditorApplication.playmodeStateChanged += Instance.OnPlayModeStateChanged; +#endif +#endif + HTTPManager.Logger.Information("HTTPUpdateDelegator", "Instance Created!"); + } + } + catch + { + HTTPManager.Logger.Error("HTTPUpdateDelegator", "Please call the BestHTTP.HTTPManager.Setup() from one of Unity's event(eg. awake, start) before you send any request!"); + } + } + + private void Setup() + { +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + Caching.HTTPCacheService.SetupCacheFolder(); +#endif + +#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR) + Cookies.CookieJar.SetupFolder(); + Cookies.CookieJar.Load(); +#endif + +#if UNITY_WEBGL && !UNITY_EDITOR + // Threads are not implemented in WEBGL builds, disable it for now. + IsThreaded = false; +#endif + if (IsThreaded) + { +#if NETFX_CORE +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(ThreadFunc); +#pragma warning restore 4014 +#else + System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ThreadFunc)); +#endif + } + + IsSetupCalled = true; + + // Unity doesn't tolerate well if the DontDestroyOnLoad called when purely in editor mode. So, we will set the flag + // only when we are playing, or not in the editor. + if (!Application.isEditor || Application.isPlaying) + GameObject.DontDestroyOnLoad(this.gameObject); + + HTTPManager.Logger.Information("HTTPUpdateDelegator", "Setup done!"); + } + +#if NETFX_CORE + async +#endif + void ThreadFunc(object obj) + { + HTTPManager.Logger.Information ("HTTPUpdateDelegator", "Update Thread Started"); + + try + { + IsThreadRunning = true; + while (IsThreadRunning) + { + HTTPManager.OnUpdate(); + +#if NETFX_CORE + await Task.Delay(ThreadFrequencyInMS); +#else + System.Threading.Thread.Sleep(ThreadFrequencyInMS); +#endif + } + } + finally + { + HTTPManager.Logger.Information("HTTPUpdateDelegator", "Update Thread Ended"); + } + } + + void Update() + { + if (!IsSetupCalled) + { + IsSetupCalled = true; + Setup(); + } + + if (!IsThreaded) + HTTPManager.OnUpdate(); + } + +#if UNITY_EDITOR +#if UNITY_2017_2_OR_NEWER + void OnPlayModeStateChanged(UnityEditor.PlayModeStateChange playMode) + { + if (playMode == UnityEditor.PlayModeStateChange.EnteredPlayMode) + UnityEditor.EditorApplication.update -= Update; + else if (playMode == UnityEditor.PlayModeStateChange.ExitingPlayMode) + UnityEditor.EditorApplication.update += Update; + } +#else + void OnPlayModeStateChanged() + { + if (UnityEditor.EditorApplication.isPlaying) + UnityEditor.EditorApplication.update -= Update; + else if (!UnityEditor.EditorApplication.isPlaying) + UnityEditor.EditorApplication.update += Update; + } + +#endif +#endif + + void OnDisable() + { + HTTPManager.Logger.Information("HTTPUpdateDelegator", "OnDisable Called!"); + +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isPlaying) +#endif + OnApplicationQuit(); + } + + void OnApplicationPause(bool isPaused) + { + if (HTTPUpdateDelegator.OnApplicationForegroundStateChanged != null) + HTTPUpdateDelegator.OnApplicationForegroundStateChanged(isPaused); + } + + void OnApplicationQuit() + { + HTTPManager.Logger.Information("HTTPUpdateDelegator", "OnApplicationQuit Called!"); + + if (OnBeforeApplicationQuit != null) + { + try + { + if (!OnBeforeApplicationQuit()) + { + HTTPManager.Logger.Information("HTTPUpdateDelegator", "OnBeforeApplicationQuit call returned false, postponing plugin shutdown."); + return; + } + } + catch(System.Exception ex) + { + HTTPManager.Logger.Exception("HTTPUpdateDelegator", string.Empty, ex); + } + } + + IsThreadRunning = false; + + if (!IsCreated) + return; + + IsCreated = false; + + HTTPManager.OnQuit(); + +#if UNITY_EDITOR + UnityEditor.EditorApplication.update -= Update; +#if UNITY_2017_2_OR_NEWER + UnityEditor.EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; +#else + UnityEditor.EditorApplication.playmodeStateChanged -= OnPlayModeStateChanged; +#endif +#endif + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs.meta new file mode 100644 index 0000000..0ea1921 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/HTTPUpdateDelegator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 232e901bb55e034408a6e54c43880ed6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/JSON.meta b/Assets/Best HTTP (Pro)/BestHTTP/JSON.meta new file mode 100644 index 0000000..e2b1bb5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/JSON.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e64190d0765d2dc4597de64694e99b53 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs b/Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs new file mode 100644 index 0000000..ccfef9e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs @@ -0,0 +1,487 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace BestHTTP.JSON +{ + /// + /// Based on the download from http://techblog.procurios.nl/k/news/view/14605/14863/how-do-i-write-my-own-parser-%28for-json%29.html + /// This class encodes and decodes JSON strings. + /// Spec. details, see http://www.json.org/ + /// + /// JSON uses Arrays and Objects. These correspond here to the datatypes List and Dictionary. + /// All numbers are parsed to doubles. + /// + public class Json + { + private const int TOKEN_NONE = 0; + private const int TOKEN_CURLY_OPEN = 1; + private const int TOKEN_CURLY_CLOSE = 2; + private const int TOKEN_SQUARED_OPEN = 3; + private const int TOKEN_SQUARED_CLOSE = 4; + private const int TOKEN_COLON = 5; + private const int TOKEN_COMMA = 6; + private const int TOKEN_STRING = 7; + private const int TOKEN_NUMBER = 8; + private const int TOKEN_TRUE = 9; + private const int TOKEN_FALSE = 10; + private const int TOKEN_NULL = 11; + + private const int BUILDER_CAPACITY = 2000; + + /// + /// Parses the string json into a value + /// + /// A JSON string. + /// A List, a Dictionary, a double, a string, null, true, or false + public static object Decode(string json) + { + bool success = true; + + return Decode(json, ref success); + } + + /// + /// Parses the string json into a value; and fills 'success' with the successfullness of the parse. + /// + /// A JSON string. + /// Successful parse? + /// A List, a Dictionary, a double, a string, null, true, or false + public static object Decode(string json, ref bool success) + { + success = true; + if (json != null) { + char[] charArray = json.ToCharArray(); + int index = 0; + object value = ParseValue(charArray, ref index, ref success); + return value; + } else { + return null; + } + } + + /// + /// Converts a Dictionary / List object into a JSON string + /// + /// A Dictionary / List + /// A JSON encoded string, or null if object 'json' is not serializable + public static string Encode(object json) + { + StringBuilder builder = new StringBuilder(BUILDER_CAPACITY); + bool success = SerializeValue(json, builder); + return (success ? builder.ToString() : null); + } + + protected static Dictionary ParseObject(char[] json, ref int index, ref bool success) + { + Dictionary table = new Dictionary(); + int token; + + // { + NextToken(json, ref index); + + bool done = false; + while (!done) { + token = LookAhead(json, index); + if (token == Json.TOKEN_NONE) { + success = false; + return null; + } else if (token == Json.TOKEN_COMMA) { + NextToken(json, ref index); + } else if (token == Json.TOKEN_CURLY_CLOSE) { + NextToken(json, ref index); + return table; + } else { + + // name + string name = ParseString(json, ref index, ref success); + if (!success) { + success = false; + return null; + } + + // : + token = NextToken(json, ref index); + if (token != Json.TOKEN_COLON) { + success = false; + return null; + } + + // value + object value = ParseValue(json, ref index, ref success); + if (!success) { + success = false; + return null; + } + + table[name] = value; + } + } + + return table; + } + + protected static List ParseArray(char[] json, ref int index, ref bool success) + { + List array = new List(); + + // [ + NextToken(json, ref index); + + bool done = false; + while (!done) { + int token = LookAhead(json, index); + if (token == Json.TOKEN_NONE) { + success = false; + return null; + } else if (token == Json.TOKEN_COMMA) { + NextToken(json, ref index); + } else if (token == Json.TOKEN_SQUARED_CLOSE) { + NextToken(json, ref index); + break; + } else { + object value = ParseValue(json, ref index, ref success); + if (!success) { + return null; + } + + array.Add(value); + } + } + + return array; + } + + protected static object ParseValue(char[] json, ref int index, ref bool success) + { + switch (LookAhead(json, index)) { + case Json.TOKEN_STRING: + return ParseString(json, ref index, ref success); + case Json.TOKEN_NUMBER: + return ParseNumber(json, ref index, ref success); + case Json.TOKEN_CURLY_OPEN: + return ParseObject(json, ref index, ref success); + case Json.TOKEN_SQUARED_OPEN: + return ParseArray(json, ref index, ref success); + case Json.TOKEN_TRUE: + NextToken(json, ref index); + return true; + case Json.TOKEN_FALSE: + NextToken(json, ref index); + return false; + case Json.TOKEN_NULL: + NextToken(json, ref index); + return null; + case Json.TOKEN_NONE: + break; + } + + success = false; + return null; + } + + protected static string ParseString(char[] json, ref int index, ref bool success) + { + StringBuilder s = new StringBuilder(BUILDER_CAPACITY); + char c; + + EatWhitespace(json, ref index); + + // " + c = json[index++]; + + bool complete = false; + while (!complete) { + + if (index == json.Length) { + break; + } + + c = json[index++]; + if (c == '"') { + complete = true; + break; + } else if (c == '\\') { + + if (index == json.Length) { + break; + } + c = json[index++]; + if (c == '"') { + s.Append('"'); + } else if (c == '\\') { + s.Append('\\'); + } else if (c == '/') { + s.Append('/'); + } else if (c == 'b') { + s.Append('\b'); + } else if (c == 'f') { + s.Append('\f'); + } else if (c == 'n') { + s.Append('\n'); + } else if (c == 'r') { + s.Append('\r'); + } else if (c == 't') { + s.Append('\t'); + } else if (c == 'u') { + int remainingLength = json.Length - index; + if (remainingLength >= 4) { + // parse the 32 bit hex into an integer codepoint + uint codePoint; + if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) { + return ""; + } + // convert the integer codepoint to a unicode char and add to string + s.Append(Char.ConvertFromUtf32((int)codePoint)); + // skip 4 chars + index += 4; + } else { + break; + } + } + + } else { + s.Append(c); + } + + } + + if (!complete) { + success = false; + return null; + } + + return s.ToString(); + } + + protected static double ParseNumber(char[] json, ref int index, ref bool success) + { + EatWhitespace(json, ref index); + + int lastIndex = GetLastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + + double number; + success = Double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + + index = lastIndex + 1; + return number; + } + + protected static int GetLastIndexOfNumber(char[] json, int index) + { + int lastIndex; + + for (lastIndex = index; lastIndex < json.Length; lastIndex++) { + if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) { + break; + } + } + return lastIndex - 1; + } + + protected static void EatWhitespace(char[] json, ref int index) + { + for (; index < json.Length; index++) { + if (" \t\n\r".IndexOf(json[index]) == -1) { + break; + } + } + } + + protected static int LookAhead(char[] json, int index) + { + int saveIndex = index; + return NextToken(json, ref saveIndex); + } + + protected static int NextToken(char[] json, ref int index) + { + EatWhitespace(json, ref index); + + if (index == json.Length) { + return Json.TOKEN_NONE; + } + + char c = json[index]; + index++; + switch (c) { + case '{': + return Json.TOKEN_CURLY_OPEN; + case '}': + return Json.TOKEN_CURLY_CLOSE; + case '[': + return Json.TOKEN_SQUARED_OPEN; + case ']': + return Json.TOKEN_SQUARED_CLOSE; + case ',': + return Json.TOKEN_COMMA; + case '"': + return Json.TOKEN_STRING; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': + return Json.TOKEN_NUMBER; + case ':': + return Json.TOKEN_COLON; + } + index--; + + int remainingLength = json.Length - index; + + // false + if (remainingLength >= 5) { + if (json[index] == 'f' && + json[index + 1] == 'a' && + json[index + 2] == 'l' && + json[index + 3] == 's' && + json[index + 4] == 'e') { + index += 5; + return Json.TOKEN_FALSE; + } + } + + // true + if (remainingLength >= 4) { + if (json[index] == 't' && + json[index + 1] == 'r' && + json[index + 2] == 'u' && + json[index + 3] == 'e') { + index += 4; + return Json.TOKEN_TRUE; + } + } + + // null + if (remainingLength >= 4) { + if (json[index] == 'n' && + json[index + 1] == 'u' && + json[index + 2] == 'l' && + json[index + 3] == 'l') { + index += 4; + return Json.TOKEN_NULL; + } + } + + return Json.TOKEN_NONE; + } + + protected static bool SerializeValue(object value, StringBuilder builder) + { + bool success = true; + + if (value is string) { + success = SerializeString((string)value, builder); + } else if (value is IDictionary) { + success = SerializeObject((IDictionary)value, builder); + } else if (value is IList) { + success = SerializeArray(value as IList, builder); + } else if ((value is Boolean) && ((Boolean)value == true)) { + builder.Append("true"); + } else if ((value is Boolean) && ((Boolean)value == false)) { + builder.Append("false"); + } else if (value is ValueType) { + // thanks to ritchie for pointing out ValueType to me + success = SerializeNumber(Convert.ToDouble(value), builder); + } else if (value == null) { + builder.Append("null"); + } else { + success = false; + } + return success; + } + + protected static bool SerializeObject(IDictionary anObject, StringBuilder builder) + { + builder.Append("{"); + + IDictionaryEnumerator e = anObject.GetEnumerator(); + bool first = true; + while (e.MoveNext()) { + string key = e.Key.ToString(); + object value = e.Value; + + if (!first) { + builder.Append(", "); + } + + SerializeString(key, builder); + builder.Append(":"); + if (!SerializeValue(value, builder)) { + return false; + } + + first = false; + } + + builder.Append("}"); + return true; + } + + protected static bool SerializeArray(IList anArray, StringBuilder builder) + { + builder.Append("["); + + bool first = true; + for (int i = 0; i < anArray.Count; i++) { + object value = anArray[i]; + + if (!first) { + builder.Append(", "); + } + + if (!SerializeValue(value, builder)) { + return false; + } + + first = false; + } + + builder.Append("]"); + return true; + } + + protected static bool SerializeString(string aString, StringBuilder builder) + { + builder.Append("\""); + + char[] charArray = aString.ToCharArray(); + for (int i = 0; i < charArray.Length; i++) { + char c = charArray[i]; + if (c == '"') { + builder.Append("\\\""); + } else if (c == '\\') { + builder.Append("\\\\"); + } else if (c == '\b') { + builder.Append("\\b"); + } else if (c == '\f') { + builder.Append("\\f"); + } else if (c == '\n') { + builder.Append("\\n"); + } else if (c == '\r') { + builder.Append("\\r"); + } else if (c == '\t') { + builder.Append("\\t"); + } else { + int codepoint = Convert.ToInt32(c); + if ((codepoint >= 32) && (codepoint <= 126)) { + builder.Append(c); + } else { + builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0')); + } + } + } + + builder.Append("\""); + return true; + } + + protected static bool SerializeNumber(double number, StringBuilder builder) + { + builder.Append(Convert.ToString(number, CultureInfo.InvariantCulture)); + return true; + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs.meta new file mode 100644 index 0000000..ae55178 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/JSON/JSON.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 60c48240ba404f04db57f061215d0f36 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Logger.meta b/Assets/Best HTTP (Pro)/BestHTTP/Logger.meta new file mode 100644 index 0000000..812d097 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Logger.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 603b8a5653cd7d84ab97cc7367e95682 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs b/Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs new file mode 100644 index 0000000..24f5888 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Logger +{ + /// + /// A basic logger implementation to be able to log intelligently additional informations about the plugin's internal mechanism. + /// + public class DefaultLogger : BestHTTP.Logger.ILogger + { + public Loglevels Level { get; set; } + public string FormatVerbose { get; set; } + public string FormatInfo { get; set; } + public string FormatWarn { get; set; } + public string FormatErr { get; set; } + public string FormatEx { get; set; } + + public DefaultLogger() + { + FormatVerbose = "[{0}] D [{1}]: {2}"; + FormatInfo = "[{0}] I [{1}]: {2}"; + FormatWarn = "[{0}] W [{1}]: {2}"; + FormatErr = "[{0}] Err [{1}]: {2}"; + FormatEx = "[{0}] Ex [{1}]: {2} - Message: {3} StackTrace: {4}"; + + Level = UnityEngine.Debug.isDebugBuild ? Loglevels.Warning : Loglevels.Error; + } + + public void Verbose(string division, string verb) + { + if (Level <= Loglevels.All) + { + try + { + UnityEngine.Debug.Log(string.Format(FormatVerbose, GetFormattedTime(), division, verb)); + } + catch + { } + } + } + + public void Information(string division, string info) + { + if (Level <= Loglevels.Information) + { + try + { + UnityEngine.Debug.Log(string.Format(FormatInfo, GetFormattedTime(), division, info)); + } + catch + { } + } + } + + public void Warning(string division, string warn) + { + if (Level <= Loglevels.Warning) + { + try + { + UnityEngine.Debug.LogWarning(string.Format(FormatWarn, GetFormattedTime(), division, warn)); + } + catch + { } + } + } + + public void Error(string division, string err) + { + if (Level <= Loglevels.Error) + { + try + { + UnityEngine.Debug.LogError(string.Format(FormatErr, GetFormattedTime(), division, err)); + } + catch + { } + } + } + + public void Exception(string division, string msg, Exception ex) + { + if (Level <= Loglevels.Exception) + { + try + { + string exceptionMessage = string.Empty; + if (ex == null) + exceptionMessage = "null"; + else + { + StringBuilder sb = new StringBuilder(); + + Exception exception = ex; + int counter = 1; + while (exception != null) + { + sb.AppendFormat("{0}: {1} {2}", counter++.ToString(), exception.Message, exception.StackTrace); + + exception = exception.InnerException; + + if (exception != null) + sb.AppendLine(); + } + + exceptionMessage = sb.ToString(); + } + + UnityEngine.Debug.LogError(string.Format(FormatEx, + GetFormattedTime(), + division, + msg, + exceptionMessage, + ex != null ? ex.StackTrace : "null")); + } + catch + { } + } + } + + private string GetFormattedTime() + { + return DateTime.Now.Ticks.ToString(); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs.meta new file mode 100644 index 0000000..6138af6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Logger/DefaultLogger.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f0c6097670314f141ad42c8060f64ecb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs b/Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs new file mode 100644 index 0000000..841b041 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.Logger +{ + /// + /// Available logging levels. + /// + public enum Loglevels : byte + { + /// + /// All message will be logged. + /// + All, + + /// + /// Only Informations and above will be logged. + /// + Information, + + /// + /// Only Warnings and above will be logged. + /// + Warning, + + /// + /// Only Errors and above will be logged. + /// + Error, + + /// + /// Only Exceptions will be logged. + /// + Exception, + + /// + /// No logging will occur. + /// + None + } + + public interface ILogger + { + /// + /// The minimum severity to log + /// + Loglevels Level { get; set; } + string FormatVerbose { get; set; } + string FormatInfo { get; set; } + string FormatWarn { get; set; } + string FormatErr { get; set; } + string FormatEx { get; set; } + + void Verbose(string division, string verb); + void Information(string division, string info); + void Warning(string division, string warn); + void Error(string division, string err); + void Exception(string division, string msg, Exception ex); + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs.meta new file mode 100644 index 0000000..b093394 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Logger/ILogger.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 41bbbfdb18d1d6f479d52229e8e4e827 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport.meta new file mode 100644 index 0000000..49315e3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 164dda27bfff2e7449444d94e5c7de32 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections.meta new file mode 100644 index 0000000..672d046 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f8b56237e32291c40859f2f1660759d9 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel.meta new file mode 100644 index 0000000..d2085d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e58ef16077b4b374b806509cec119484 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs new file mode 100644 index 0000000..5cfdd72 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs @@ -0,0 +1,263 @@ +using System; +using System.Linq; +using System.ComponentModel; +using System.Collections.Generic; +using System.Collections; + +#if NETFX_CORE + using specialized = System.Collections.Specialized; +#else + using specialized = PlatformSupport.Collections.Specialized; +#endif + +namespace PlatformSupport.Collections.ObjectModel +{ + public class ObservableDictionary : IDictionary, specialized.INotifyCollectionChanged, INotifyPropertyChanged + { + private const string CountString = "Count"; + private const string IndexerName = "Item[]"; + private const string KeysName = "Keys"; + private const string ValuesName = "Values"; + + private IDictionary _Dictionary; + protected IDictionary Dictionary + { + get { return _Dictionary; } + } + +#region Constructors + public ObservableDictionary() + { + _Dictionary = new Dictionary(); + } + public ObservableDictionary(IDictionary dictionary) + { + _Dictionary = new Dictionary(dictionary); + } + public ObservableDictionary(IEqualityComparer comparer) + { + _Dictionary = new Dictionary(comparer); + } + public ObservableDictionary(int capacity) + { + _Dictionary = new Dictionary(capacity); + } + public ObservableDictionary(IDictionary dictionary, IEqualityComparer comparer) + { + _Dictionary = new Dictionary(dictionary, comparer); + } + public ObservableDictionary(int capacity, IEqualityComparer comparer) + { + _Dictionary = new Dictionary(capacity, comparer); + } +#endregion + +#region IDictionary Members + + public void Add(TKey key, TValue value) + { + Insert(key, value, true); + } + + public bool ContainsKey(TKey key) + { + return Dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return Dictionary.Keys; } + } + + public bool Remove(TKey key) + { + if (key == null) throw new ArgumentNullException("key"); + + TValue value; + Dictionary.TryGetValue(key, out value); + var removed = Dictionary.Remove(key); + if (removed) + + //OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair(key, value)); + OnCollectionChanged(); + + + return removed; + } + + public bool TryGetValue(TKey key, out TValue value) + { + return Dictionary.TryGetValue(key, out value); + } + + public ICollection Values + { + get { return Dictionary.Values; } + } + + public TValue this[TKey key] + { + get + { + return Dictionary[key]; + } + set + { + Insert(key, value, false); + } + } + +#endregion + +#region ICollection> Members + + public void Add(KeyValuePair item) + { + Insert(item.Key, item.Value, true); + } + + public void Clear() + { + if (Dictionary.Count > 0) + { + Dictionary.Clear(); + OnCollectionChanged(); + } + } + + public bool Contains(KeyValuePair item) + { + return Dictionary.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + Dictionary.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return Dictionary.Count; } + } + + public bool IsReadOnly + { + get { return Dictionary.IsReadOnly; } + } + + public bool Remove(KeyValuePair item) + { + return Remove(item.Key); + } + +#endregion + +#region IEnumerable> Members + + public IEnumerator> GetEnumerator() + { + return Dictionary.GetEnumerator(); + } + +#endregion + +#region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)Dictionary).GetEnumerator(); + } + +#endregion + +#region INotifyCollectionChanged Members + + public event specialized.NotifyCollectionChangedEventHandler CollectionChanged; + +#endregion + +#region INotifyPropertyChanged Members + + public event PropertyChangedEventHandler PropertyChanged; + +#endregion + + public void AddRange(IDictionary items) + { + if (items == null) throw new ArgumentNullException("items"); + + if (items.Count > 0) + { + if (Dictionary.Count > 0) + { + if (items.Keys.Any((k) => Dictionary.ContainsKey(k))) + throw new ArgumentException("An item with the same key has already been added."); + else + foreach (var item in items) Dictionary.Add(item); + } + else + _Dictionary = new Dictionary(items); + + OnCollectionChanged(specialized.NotifyCollectionChangedAction.Add, items.ToArray()); + } + } + + private void Insert(TKey key, TValue value, bool add) + { + if (key == null) throw new ArgumentNullException("key"); + + TValue item; + if (Dictionary.TryGetValue(key, out item)) + { + if (add) throw new ArgumentException("An item with the same key has already been added."); + if (Equals(item, value)) return; + Dictionary[key] = value; + + OnCollectionChanged(specialized.NotifyCollectionChangedAction.Replace, new KeyValuePair(key, value), new KeyValuePair(key, item)); + } + else + { + Dictionary[key] = value; + + OnCollectionChanged(specialized.NotifyCollectionChangedAction.Add, new KeyValuePair(key, value)); + } + } + + private void OnPropertyChanged() + { + OnPropertyChanged(CountString); + OnPropertyChanged(IndexerName); + OnPropertyChanged(KeysName); + OnPropertyChanged(ValuesName); + } + + protected virtual void OnPropertyChanged(string propertyName) + { + if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + private void OnCollectionChanged() + { + OnPropertyChanged(); + if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(specialized.NotifyCollectionChangedAction.Reset)); + } + + private void OnCollectionChanged(specialized.NotifyCollectionChangedAction action, KeyValuePair changedItem) + { + OnPropertyChanged(); + if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(action, changedItem)); + } + + private void OnCollectionChanged(specialized.NotifyCollectionChangedAction action, KeyValuePair newItem, KeyValuePair oldItem) + { + OnPropertyChanged(); + if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(action, newItem, oldItem)); + } + + private void OnCollectionChanged(specialized.NotifyCollectionChangedAction action, IList newItems) + { + OnPropertyChanged(); + if (CollectionChanged != null) CollectionChanged(this, new specialized.NotifyCollectionChangedEventArgs(action, newItems)); + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs.meta new file mode 100644 index 0000000..2fa1dc4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/ObjectModel/ObservableDictionary.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b5467f7e4679aea4bbadc541e674c23d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized.meta new file mode 100644 index 0000000..2815645 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ed08c64055c2bad49888497192d9980b +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs new file mode 100644 index 0000000..79df06b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs @@ -0,0 +1,467 @@ +#if !NETFX_CORE +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections; +using System.Diagnostics; + +namespace PlatformSupport.Collections.Specialized +{ + public delegate void NotifyCollectionChangedEventHandler(object sender, PlatformSupport.Collections.Specialized.NotifyCollectionChangedEventArgs e); + + public interface INotifyCollectionChanged + { + event NotifyCollectionChangedEventHandler CollectionChanged; + } + + /// + /// This enum describes the action that caused a CollectionChanged event. + /// + public enum NotifyCollectionChangedAction + { + /// One or more items were added to the collection. + Add, + /// One or more items were removed from the collection. + Remove, + /// One or more items were replaced in the collection. + Replace, + /// One or more items were moved within the collection. + Move, + /// The contents of the collection changed dramatically. + Reset, + } + + /// + /// Arguments for the CollectionChanged event. + /// A collection that supports INotifyCollectionChangedThis raises this event + /// whenever an item is added or removed, or when the contents of the collection + /// changes dramatically. + /// + public class NotifyCollectionChangedEventArgs : EventArgs + { + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a reset change. + /// + /// The action that caused the event (must be Reset). + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset) + throw new ArgumentException("action"); + + InitializeAdd(action, null, -1); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item change. + /// + /// The action that caused the event; can only be Reset, Add or Remove action. + /// The item affected by the change. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, object changedItem) + { + if ((action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Add) && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Remove) + && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset)) + throw new ArgumentException("action"); + + if (action == PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + throw new ArgumentException("action"); + + InitializeAdd(action, null, -1); + } + else + { + InitializeAddOrRemove(action, new object[] { changedItem }, -1); + } + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item change. + /// + /// The action that caused the event. + /// The item affected by the change. + /// The index where the change occurred. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, object changedItem, int index) + { + if ((action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Add) && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Remove) + && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset)) + throw new ArgumentException("action"); + + if (action == PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset) + { + if (changedItem != null) + throw new ArgumentException("action"); + if (index != -1) + throw new ArgumentException("action"); + + InitializeAdd(action, null, -1); + } + else + { + InitializeAddOrRemove(action, new object[] { changedItem }, index); + } + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item change. + /// + /// The action that caused the event. + /// The items affected by the change. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList changedItems) + { + if ((action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Add) && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Remove) + && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset)) + throw new ArgumentException("action"); + + if (action == PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + throw new ArgumentException("action"); + + InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + throw new ArgumentNullException("changedItems"); + + InitializeAddOrRemove(action, changedItems, -1); + } + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item change (or a reset). + /// + /// The action that caused the event. + /// The items affected by the change. + /// The index where the change occurred. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + if ((action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Add) && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Remove) + && (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset)) + throw new ArgumentException("action"); + + if (action == PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Reset) + { + if (changedItems != null) + throw new ArgumentException("action"); + if (startingIndex != -1) + throw new ArgumentException("action"); + + InitializeAdd(action, null, -1); + } + else + { + if (changedItems == null) + throw new ArgumentNullException("changedItems"); + if (startingIndex < -1) + throw new ArgumentException("startingIndex"); + + InitializeAddOrRemove(action, changedItems, startingIndex); + } + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item Replace event. + /// + /// Can only be a Replace action. + /// The new item replacing the original item. + /// The original item that is replaced. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, object newItem, object oldItem) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Replace) + throw new ArgumentException("action"); + + InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, -1, -1); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item Replace event. + /// + /// Can only be a Replace action. + /// The new item replacing the original item. + /// The original item that is replaced. + /// The index of the item being replaced. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, object newItem, object oldItem, int index) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Replace) + throw new ArgumentException("action"); + + InitializeMoveOrReplace(action, new object[] { newItem }, new object[] { oldItem }, index, index); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Replace event. + /// + /// Can only be a Replace action. + /// The new items replacing the original items. + /// The original items that are replaced. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList newItems, IList oldItems) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Replace) + throw new ArgumentException("action"); + if (newItems == null) + throw new ArgumentNullException("newItems"); + if (oldItems == null) + throw new ArgumentNullException("oldItems"); + + InitializeMoveOrReplace(action, newItems, oldItems, -1, -1); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Replace event. + /// + /// Can only be a Replace action. + /// The new items replacing the original items. + /// The original items that are replaced. + /// The starting index of the items being replaced. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Replace) + throw new ArgumentException("action"); + if (newItems == null) + throw new ArgumentNullException("newItems"); + if (oldItems == null) + throw new ArgumentNullException("oldItems"); + + InitializeMoveOrReplace(action, newItems, oldItems, startingIndex, startingIndex); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a one-item Move event. + /// + /// Can only be a Move action. + /// The item affected by the change. + /// The new index for the changed item. + /// The old index for the changed item. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, object changedItem, int index, int oldIndex) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Move) + throw new ArgumentException("action"); + if (index < 0) + throw new ArgumentException("index"); + + object[] changedItems = new object[] { changedItem }; + InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs that describes a multi-item Move event. + /// + /// The action that caused the event. + /// The items affected by the change. + /// The new index for the changed items. + /// The old index for the changed items. + public NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList changedItems, int index, int oldIndex) + { + if (action != PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Move) + throw new ArgumentException("action"); + if (index < 0) + throw new ArgumentException("index"); + + InitializeMoveOrReplace(action, changedItems, changedItems, index, oldIndex); + } + + /// + /// Construct a NotifyCollectionChangedEventArgs with given fields (no validation). Used by WinRT marshaling. + /// + internal NotifyCollectionChangedEventArgs(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList newItems, IList oldItems, int newIndex, int oldIndex) + { + _action = action; + _newItems = (newItems == null) ? null : new ReadOnlyList(newItems); + _oldItems = (oldItems == null) ? null : new ReadOnlyList(oldItems); + _newStartingIndex = newIndex; + _oldStartingIndex = oldIndex; + } + + private void InitializeAddOrRemove(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList changedItems, int startingIndex) + { + if (action == PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Add) + InitializeAdd(action, changedItems, startingIndex); + else if (action == PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction.Remove) + InitializeRemove(action, changedItems, startingIndex); + else + Debug.Assert(false, String.Format("Unsupported action: {0}", action.ToString())); + } + + private void InitializeAdd(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList newItems, int newStartingIndex) + { + _action = action; + _newItems = (newItems == null) ? null : new ReadOnlyList(newItems); + _newStartingIndex = newStartingIndex; + } + + private void InitializeRemove(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList oldItems, int oldStartingIndex) + { + _action = action; + _oldItems = (oldItems == null) ? null : new ReadOnlyList(oldItems); + _oldStartingIndex = oldStartingIndex; + } + + private void InitializeMoveOrReplace(PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction action, IList newItems, IList oldItems, int startingIndex, int oldStartingIndex) + { + InitializeAdd(action, newItems, startingIndex); + InitializeRemove(action, oldItems, oldStartingIndex); + } + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + /// + /// The action that caused the event. + /// + public PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction Action + { + get { return _action; } + } + + /// + /// The items affected by the change. + /// + public IList NewItems + { + get { return _newItems; } + } + + /// + /// The old items affected by the change (for Replace events). + /// + public IList OldItems + { + get { return _oldItems; } + } + + /// + /// The index where the change occurred. + /// + public int NewStartingIndex + { + get { return _newStartingIndex; } + } + + /// + /// The old index where the change occurred (for Move events). + /// + public int OldStartingIndex + { + get { return _oldStartingIndex; } + } + + //------------------------------------------------------ + // + // Private Fields + // + //------------------------------------------------------ + + private PlatformSupport.Collections.Specialized.NotifyCollectionChangedAction _action; + private IList _newItems, _oldItems; + private int _newStartingIndex = -1; + private int _oldStartingIndex = -1; + } + + internal sealed class ReadOnlyList : IList + { + private readonly IList _list; + + internal ReadOnlyList(IList list) + { + Debug.Assert(list != null); + + _list = list; + } + + public int Count + { + get { return _list.Count; } + } + + public bool IsReadOnly + { + get { return true; } + } + + public bool IsFixedSize + { + get { return true; } + } + + public bool IsSynchronized + { + get { return _list.IsSynchronized; } + } + + public object this[int index] + { + get + { + return _list[index]; + } + set + { + throw new NotSupportedException(); + } + } + + public object SyncRoot + { + get { return _list.SyncRoot; } + } + + public int Add(object value) + { + throw new NotSupportedException(); + } + + public void Clear() + { + throw new NotSupportedException(); + } + + public bool Contains(object value) + { + return _list.Contains(value); + } + + public void CopyTo(Array array, int index) + { + _list.CopyTo(array, index); + } + + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + public int IndexOf(object value) + { + return _list.IndexOf(value); + } + + public void Insert(int index, object value) + { + throw new NotSupportedException(); + } + + public void Remove(object value) + { + throw new NotSupportedException(); + } + + public void RemoveAt(int index) + { + throw new NotSupportedException(); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs.meta new file mode 100644 index 0000000..eb73999 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Collections/Specialized/NotifyCollectionChangedEventArgs.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7578ac65ac9a66a4f920882f3e04ea5f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography.meta new file mode 100644 index 0000000..10a7a50 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 94c20f1dcf3252c438635d61509046f2 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs new file mode 100644 index 0000000..78db3b3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs @@ -0,0 +1,510 @@ +#if UNITY_WP8 +// +// System.Security.Cryptography.MD5CryptoServiceProvider.cs +// +// Authors: +// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu) +// Sebastien Pouliot (sebastien@ximian.com) +// +// Copyright 2001 by Matthew S. Ford. +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Runtime.InteropServices; + +namespace BestHTTP.PlatformSupport.Cryptography +{ + using System.Runtime.InteropServices; + using System.Security.Cryptography; + + [ComVisible(true)] + public abstract class MD5 : HashAlgorithm + { + + // Why is it protected when others abstract hash classes are public ? + protected MD5() + { + HashSizeValue = 128; + } + + public static new MD5 Create() + { + return new BestHTTP.PlatformSupport.Cryptography.MD5CryptoServiceProvider(); + } + } + + [ComVisible (true)] + public sealed class MD5CryptoServiceProvider : MD5 { + private const int BLOCK_SIZE_BYTES = 64; + private uint[] _H; + private uint[] buff; + private ulong count; + private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth. + private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed. + + public MD5CryptoServiceProvider () + { + _H = new uint[4]; + buff = new uint[16]; + _ProcessingBuffer = new byte [BLOCK_SIZE_BYTES]; + + Initialize(); + } + + ~MD5CryptoServiceProvider () + { + Dispose (false); + } + + protected override void Dispose (bool disposing) + { + if (_ProcessingBuffer != null) { + Array.Clear (_ProcessingBuffer, 0, _ProcessingBuffer.Length); + _ProcessingBuffer = null; + } + if (_H != null) { + Array.Clear (_H, 0, _H.Length); + _H = null; + } + if (buff != null) { + Array.Clear (buff, 0, buff.Length); + buff = null; + } + } + + protected override void HashCore (byte[] rgb, int ibStart, int cbSize) + { + int i; + State = 1; + + if (_ProcessingBufferCount != 0) { + if (cbSize < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) { + System.Buffer.BlockCopy (rgb, ibStart, _ProcessingBuffer, _ProcessingBufferCount, cbSize); + _ProcessingBufferCount += cbSize; + return; + } + else { + i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount); + System.Buffer.BlockCopy (rgb, ibStart, _ProcessingBuffer, _ProcessingBufferCount, i); + ProcessBlock (_ProcessingBuffer, 0); + _ProcessingBufferCount = 0; + ibStart += i; + cbSize -= i; + } + } + + for (i = 0; i < cbSize - cbSize % BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) { + ProcessBlock (rgb, ibStart + i); + } + + if (cbSize % BLOCK_SIZE_BYTES != 0) { + System.Buffer.BlockCopy (rgb, cbSize - cbSize % BLOCK_SIZE_BYTES + ibStart, _ProcessingBuffer, 0, cbSize % BLOCK_SIZE_BYTES); + _ProcessingBufferCount = cbSize % BLOCK_SIZE_BYTES; + } + } + + protected override byte[] HashFinal () + { + byte[] hash = new byte[16]; + int i, j; + + ProcessFinalBlock (_ProcessingBuffer, 0, _ProcessingBufferCount); + + for (i=0; i<4; i++) { + for (j=0; j<4; j++) { + hash[i*4+j] = (byte)(_H[i] >> j*8); + } + } + + return hash; + } + + public override void Initialize () + { + count = 0; + _ProcessingBufferCount = 0; + + _H[0] = 0x67452301; + _H[1] = 0xefcdab89; + _H[2] = 0x98badcfe; + _H[3] = 0x10325476; + } + + private void ProcessBlock (byte[] inputBuffer, int inputOffset) + { + uint a, b, c, d; + int i; + + count += BLOCK_SIZE_BYTES; + + for (i=0; i<16; i++) { + buff[i] = (uint)(inputBuffer[inputOffset+4*i]) + | (((uint)(inputBuffer[inputOffset+4*i+1])) << 8) + | (((uint)(inputBuffer[inputOffset+4*i+2])) << 16) + | (((uint)(inputBuffer[inputOffset+4*i+3])) << 24); + } + + a = _H[0]; + b = _H[1]; + c = _H[2]; + d = _H[3]; + + // This function was unrolled because it seems to be doubling our performance with current compiler/VM. + // Possibly roll up if this changes. + + // ---- Round 1 -------- + + a += (((c ^ d) & b) ^ d) + (uint) K [0] + buff [0]; + a = (a << 7) | (a >> 25); + a += b; + + d += (((b ^ c) & a) ^ c) + (uint) K [1] + buff [1]; + d = (d << 12) | (d >> 20); + d += a; + + c += (((a ^ b) & d) ^ b) + (uint) K [2] + buff [2]; + c = (c << 17) | (c >> 15); + c += d; + + b += (((d ^ a) & c) ^ a) + (uint) K [3] + buff [3]; + b = (b << 22) | (b >> 10); + b += c; + + a += (((c ^ d) & b) ^ d) + (uint) K [4] + buff [4]; + a = (a << 7) | (a >> 25); + a += b; + + d += (((b ^ c) & a) ^ c) + (uint) K [5] + buff [5]; + d = (d << 12) | (d >> 20); + d += a; + + c += (((a ^ b) & d) ^ b) + (uint) K [6] + buff [6]; + c = (c << 17) | (c >> 15); + c += d; + + b += (((d ^ a) & c) ^ a) + (uint) K [7] + buff [7]; + b = (b << 22) | (b >> 10); + b += c; + + a += (((c ^ d) & b) ^ d) + (uint) K [8] + buff [8]; + a = (a << 7) | (a >> 25); + a += b; + + d += (((b ^ c) & a) ^ c) + (uint) K [9] + buff [9]; + d = (d << 12) | (d >> 20); + d += a; + + c += (((a ^ b) & d) ^ b) + (uint) K [10] + buff [10]; + c = (c << 17) | (c >> 15); + c += d; + + b += (((d ^ a) & c) ^ a) + (uint) K [11] + buff [11]; + b = (b << 22) | (b >> 10); + b += c; + + a += (((c ^ d) & b) ^ d) + (uint) K [12] + buff [12]; + a = (a << 7) | (a >> 25); + a += b; + + d += (((b ^ c) & a) ^ c) + (uint) K [13] + buff [13]; + d = (d << 12) | (d >> 20); + d += a; + + c += (((a ^ b) & d) ^ b) + (uint) K [14] + buff [14]; + c = (c << 17) | (c >> 15); + c += d; + + b += (((d ^ a) & c) ^ a) + (uint) K [15] + buff [15]; + b = (b << 22) | (b >> 10); + b += c; + + + // ---- Round 2 -------- + + a += (((b ^ c) & d) ^ c) + (uint) K [16] + buff [1]; + a = (a << 5) | (a >> 27); + a += b; + + d += (((a ^ b) & c) ^ b) + (uint) K [17] + buff [6]; + d = (d << 9) | (d >> 23); + d += a; + + c += (((d ^ a) & b) ^ a) + (uint) K [18] + buff [11]; + c = (c << 14) | (c >> 18); + c += d; + + b += (((c ^ d) & a) ^ d) + (uint) K [19] + buff [0]; + b = (b << 20) | (b >> 12); + b += c; + + a += (((b ^ c) & d) ^ c) + (uint) K [20] + buff [5]; + a = (a << 5) | (a >> 27); + a += b; + + d += (((a ^ b) & c) ^ b) + (uint) K [21] + buff [10]; + d = (d << 9) | (d >> 23); + d += a; + + c += (((d ^ a) & b) ^ a) + (uint) K [22] + buff [15]; + c = (c << 14) | (c >> 18); + c += d; + + b += (((c ^ d) & a) ^ d) + (uint) K [23] + buff [4]; + b = (b << 20) | (b >> 12); + b += c; + + a += (((b ^ c) & d) ^ c) + (uint) K [24] + buff [9]; + a = (a << 5) | (a >> 27); + a += b; + + d += (((a ^ b) & c) ^ b) + (uint) K [25] + buff [14]; + d = (d << 9) | (d >> 23); + d += a; + + c += (((d ^ a) & b) ^ a) + (uint) K [26] + buff [3]; + c = (c << 14) | (c >> 18); + c += d; + + b += (((c ^ d) & a) ^ d) + (uint) K [27] + buff [8]; + b = (b << 20) | (b >> 12); + b += c; + + a += (((b ^ c) & d) ^ c) + (uint) K [28] + buff [13]; + a = (a << 5) | (a >> 27); + a += b; + + d += (((a ^ b) & c) ^ b) + (uint) K [29] + buff [2]; + d = (d << 9) | (d >> 23); + d += a; + + c += (((d ^ a) & b) ^ a) + (uint) K [30] + buff [7]; + c = (c << 14) | (c >> 18); + c += d; + + b += (((c ^ d) & a) ^ d) + (uint) K [31] + buff [12]; + b = (b << 20) | (b >> 12); + b += c; + + + // ---- Round 3 -------- + + a += (b ^ c ^ d) + (uint) K [32] + buff [5]; + a = (a << 4) | (a >> 28); + a += b; + + d += (a ^ b ^ c) + (uint) K [33] + buff [8]; + d = (d << 11) | (d >> 21); + d += a; + + c += (d ^ a ^ b) + (uint) K [34] + buff [11]; + c = (c << 16) | (c >> 16); + c += d; + + b += (c ^ d ^ a) + (uint) K [35] + buff [14]; + b = (b << 23) | (b >> 9); + b += c; + + a += (b ^ c ^ d) + (uint) K [36] + buff [1]; + a = (a << 4) | (a >> 28); + a += b; + + d += (a ^ b ^ c) + (uint) K [37] + buff [4]; + d = (d << 11) | (d >> 21); + d += a; + + c += (d ^ a ^ b) + (uint) K [38] + buff [7]; + c = (c << 16) | (c >> 16); + c += d; + + b += (c ^ d ^ a) + (uint) K [39] + buff [10]; + b = (b << 23) | (b >> 9); + b += c; + + a += (b ^ c ^ d) + (uint) K [40] + buff [13]; + a = (a << 4) | (a >> 28); + a += b; + + d += (a ^ b ^ c) + (uint) K [41] + buff [0]; + d = (d << 11) | (d >> 21); + d += a; + + c += (d ^ a ^ b) + (uint) K [42] + buff [3]; + c = (c << 16) | (c >> 16); + c += d; + + b += (c ^ d ^ a) + (uint) K [43] + buff [6]; + b = (b << 23) | (b >> 9); + b += c; + + a += (b ^ c ^ d) + (uint) K [44] + buff [9]; + a = (a << 4) | (a >> 28); + a += b; + + d += (a ^ b ^ c) + (uint) K [45] + buff [12]; + d = (d << 11) | (d >> 21); + d += a; + + c += (d ^ a ^ b) + (uint) K [46] + buff [15]; + c = (c << 16) | (c >> 16); + c += d; + + b += (c ^ d ^ a) + (uint) K [47] + buff [2]; + b = (b << 23) | (b >> 9); + b += c; + + + // ---- Round 4 -------- + + a += (((~d) | b) ^ c) + (uint) K [48] + buff [0]; + a = (a << 6) | (a >> 26); + a += b; + + d += (((~c) | a) ^ b) + (uint) K [49] + buff [7]; + d = (d << 10) | (d >> 22); + d += a; + + c += (((~b) | d) ^ a) + (uint) K [50] + buff [14]; + c = (c << 15) | (c >> 17); + c += d; + + b += (((~a) | c) ^ d) + (uint) K [51] + buff [5]; + b = (b << 21) | (b >> 11); + b += c; + + a += (((~d) | b) ^ c) + (uint) K [52] + buff [12]; + a = (a << 6) | (a >> 26); + a += b; + + d += (((~c) | a) ^ b) + (uint) K [53] + buff [3]; + d = (d << 10) | (d >> 22); + d += a; + + c += (((~b) | d) ^ a) + (uint) K [54] + buff [10]; + c = (c << 15) | (c >> 17); + c += d; + + b += (((~a) | c) ^ d) + (uint) K [55] + buff [1]; + b = (b << 21) | (b >> 11); + b += c; + + a += (((~d) | b) ^ c) + (uint) K [56] + buff [8]; + a = (a << 6) | (a >> 26); + a += b; + + d += (((~c) | a) ^ b) + (uint) K [57] + buff [15]; + d = (d << 10) | (d >> 22); + d += a; + + c += (((~b) | d) ^ a) + (uint) K [58] + buff [6]; + c = (c << 15) | (c >> 17); + c += d; + + b += (((~a) | c) ^ d) + (uint) K [59] + buff [13]; + b = (b << 21) | (b >> 11); + b += c; + + a += (((~d) | b) ^ c) + (uint) K [60] + buff [4]; + a = (a << 6) | (a >> 26); + a += b; + + d += (((~c) | a) ^ b) + (uint) K [61] + buff [11]; + d = (d << 10) | (d >> 22); + d += a; + + c += (((~b) | d) ^ a) + (uint) K [62] + buff [2]; + c = (c << 15) | (c >> 17); + c += d; + + b += (((~a) | c) ^ d) + (uint) K [63] + buff [9]; + b = (b << 21) | (b >> 11); + b += c; + + _H [0] += a; + _H [1] += b; + _H [2] += c; + _H [3] += d; + } + + private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) + { + ulong total = count + (ulong)inputCount; + int paddingSize = (int)(56 - total % BLOCK_SIZE_BYTES); + + if (paddingSize < 1) + paddingSize += BLOCK_SIZE_BYTES; + + byte[] fooBuffer = new byte [inputCount+paddingSize+8]; + + for (int i=0; i> 8); + buffer [position++] = (byte)(length >> 16); + buffer [position++] = (byte)(length >> 24); + buffer [position++] = (byte)(length >> 32); + buffer [position++] = (byte)(length >> 40); + buffer [position++] = (byte)(length >> 48); + buffer [position] = (byte)(length >> 56); + } + + private readonly static uint[] K = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }; + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs.meta new file mode 100644 index 0000000..ea9d308 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/Cryptography/MD5CryptoServiceProvider.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0fe40887a92052c4ebc5ac3febeabb15 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO.meta new file mode 100644 index 0000000..3bcdbe8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f887fb4426c85f74b9874f0790e203ec +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs new file mode 100644 index 0000000..e449aa2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs @@ -0,0 +1,270 @@ +#if NETFX_CORE +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.IO; +using System.Linq; +using System.Text; +using Windows.Storage; +using Windows.Storage.Streams; +using Windows.Foundation; + +namespace BestHTTP.PlatformSupport.IO +{ + public static class Directory + { + private static StorageFolder GetDirectoryForPath(string path) + { + IAsyncOperation folderFromPathAsync = StorageFolder.GetFolderFromPathAsync(path); + WindowsRuntimeSystemExtensions.AsTask(folderFromPathAsync).Wait(); + return folderFromPathAsync.GetResults(); + } + + public static DirectoryInfo CreateDirectory(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException("Path is empty"); + StorageFolder folder = (StorageFolder)null; + path = path.Replace('/', '\\'); + string path1 = path; + Stack stack = new Stack(); + do + { + try + { + folder = Directory.GetDirectoryForPath(path1); + break; + } + catch + { + int length = path1.LastIndexOf('\\'); + if (length < 0) + { + path1 = (string)null; + } + else + { + stack.Push(path1.Substring(length + 1)); + path1 = path1.Substring(0, length); + } + } + } + while (path1 != null); + if (path1 == null) + { + System.Diagnostics.Debug.WriteLine("Directory.CreateDirectory: Could not find any part of the path: " + path); + throw new IOException("Could not find any part of the path: " + path); + } + try + { + while (stack.Count > 0) + { + string desiredName = stack.Pop(); + if (string.IsNullOrWhiteSpace(desiredName) && stack.Count > 0) + throw new ArgumentNullException("Empty directory name in the path"); + IAsyncOperation folderAsync = folder.CreateFolderAsync(desiredName); + WindowsRuntimeSystemExtensions.AsTask(folderAsync).Wait(); + folder = folderAsync.GetResults(); + } + return new DirectoryInfo(path, folder); + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("Directory.CreateDirectory: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Directory.CreateDirectory: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public static void Delete(string path) + { + Directory.Delete(path, false); + } + + public static void Delete(string path, bool recursive) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path is empty"); + try + { + StorageFolder directoryForPath = Directory.GetDirectoryForPath(path); + if (!recursive) + { + IAsyncOperation> foldersAsync = directoryForPath.GetFoldersAsync(); + WindowsRuntimeSystemExtensions.AsTask>(foldersAsync).Wait(); + if (Enumerable.Count((IEnumerable)foldersAsync.GetResults()) > 0) + { + System.Diagnostics.Debug.WriteLine("Directory.Delete: Directory not empty"); + throw new IOException("Directory not empty"); + } + IAsyncOperation> filesAsync = directoryForPath.GetFilesAsync(); + WindowsRuntimeSystemExtensions.AsTask>(filesAsync).Wait(); + if (Enumerable.Count((IEnumerable)filesAsync.GetResults()) > 0) + { + System.Diagnostics.Debug.WriteLine("Directory.Delete: Directory not empty"); + throw new IOException("Directory not empty"); + } + } + WindowsRuntimeSystemExtensions.AsTask(directoryForPath.DeleteAsync()).Wait(); + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("Directory.Delete: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Directory.Delete: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public static IEnumerable EnumerateDirectories(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path is empty"); + try + { + IAsyncOperation> foldersAsync = Directory.GetDirectoryForPath(path).GetFoldersAsync(); + WindowsRuntimeSystemExtensions.AsTask>(foldersAsync).Wait(); + IReadOnlyList results = foldersAsync.GetResults(); + List list = new List(Enumerable.Count((IEnumerable)results)); + foreach (StorageFolder storageFolder in (IEnumerable)results) + list.Add(storageFolder.Path); + return (IEnumerable)list; + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("Directory.EnumerateDirectories: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Directory.EnumerateDirectories: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public static IEnumerable EnumerateFiles(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path is empty"); + try + { + IAsyncOperation> filesAsync = Directory.GetDirectoryForPath(path).GetFilesAsync(); + WindowsRuntimeSystemExtensions.AsTask>(filesAsync).Wait(); + IReadOnlyList results = filesAsync.GetResults(); + List list = new List(Enumerable.Count((IEnumerable)results)); + foreach (StorageFile storageFile in (IEnumerable)results) + list.Add(storageFile.Path); + return (IEnumerable)list; + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("Directory.EnumerateFiles: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Directory.EnumerateFiles: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public static IEnumerable EnumerateFileSystemEntries(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path is empty"); + try + { + List list = (List)Directory.EnumerateDirectories(path); + list.AddRange(Directory.EnumerateFiles(path)); + return (IEnumerable)list; + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("Directory.EnumerateFileSystemEntries: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Directory.EnumerateFileSystemEntries: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public static bool Exists(string path) + { + try + { + return Directory.GetDirectoryForPath(path) != null; + } + catch + { + return false; + } + } + + private static DateTimeOffset GetFolderCreationTime(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("Path is empty"); + try + { + return Directory.GetDirectoryForPath(path).DateCreated; + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("Directory.GetFolderCreationTime: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("Directory.GetFolderCreationTime: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public static System.DateTime GetCreationTime(string path) + { + return Directory.GetFolderCreationTime(path).DateTime; + } + + public static System.DateTime GetCreationTimeUtc(string path) + { + return Directory.GetFolderCreationTime(path).ToUniversalTime().DateTime; + } + + public static string[] GetDirectories(string path) + { + return Enumerable.ToArray(Directory.EnumerateDirectories(path)); + } + + public static string[] GetFiles(string path) + { + return Enumerable.ToArray(Directory.EnumerateFiles(path)); + } + + public static string[] GetFileSystemEntries(string path) + { + return Enumerable.ToArray(Directory.EnumerateFileSystemEntries(path)); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs.meta new file mode 100644 index 0000000..7b0914e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Directory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32e14ace0c4c59645bedb1bf56f76355 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs new file mode 100644 index 0000000..80a20cf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs @@ -0,0 +1,491 @@ +#if NETFX_CORE +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.IO; +using System.Linq; +using System.Text; +using Windows.Storage; +using Windows.Storage.Streams; +using Windows.Foundation; + +namespace BestHTTP.PlatformSupport.IO +{ + public static class File + { + public static void AppendAllLines(string path, IEnumerable contents) + { + File.AppendAllLines(path, contents, (Encoding)null); + } + + public static void AppendAllLines(string path, IEnumerable contents, Encoding encoding) + { + try + { + IEnumerator enumerator = contents.GetEnumerator(); + if (!enumerator.MoveNext()) + return; + using (StreamWriter streamWriter = File.AppendText(path, encoding)) + { + string current = enumerator.Current; + while (enumerator.MoveNext()) + { + streamWriter.WriteLine(current); + current = enumerator.Current; + } + streamWriter.Write(current); + } + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static void AppendAllText(string path, string contents) + { + File.AppendAllText(path, contents, (Encoding)null); + } + + public static void AppendAllText(string path, string contents, Encoding encoding) + { + try + { + using (StreamWriter streamWriter = File.AppendText(path, encoding)) + streamWriter.Write(contents); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static StreamWriter AppendText(string path, Encoding encoding) + { + try + { + IAsyncOperation fileAsync = FileHelper.GetFolderForPathOrURI(path).CreateFileAsync(Path.GetFileName(path), CreationCollisionOption.OpenIfExists); + WindowsRuntimeSystemExtensions.AsTask(fileAsync).Wait(); + IAsyncOperation source = fileAsync.GetResults().OpenAsync(FileAccessMode.ReadWrite); + WindowsRuntimeSystemExtensions.AsTask(source).Wait(); + FileRandomAccessStream randomAccessStream = (FileRandomAccessStream)source.GetResults(); + randomAccessStream.Seek(randomAccessStream.Size); + return encoding == null ? new StreamWriter(WindowsRuntimeStreamExtensions.AsStream((IRandomAccessStream)randomAccessStream)) : new StreamWriter(WindowsRuntimeStreamExtensions.AsStream((IRandomAccessStream)randomAccessStream), encoding); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + private static Exception GetRethrowException(Exception ex) + { + System.Diagnostics.Debug.WriteLine("File.GetRethrowException: " + ex.Message + "\n" + ex.StackTrace); + if (ex.GetType() == typeof(IOException)) + return ex; + else + return (Exception)new IOException(ex.Message, ex); + } + + public static void Copy(string sourceFileName, string destFileName) + { + File.Copy(sourceFileName, destFileName, false); + } + + public static void Copy(string sourceFileName, string destFileName, bool overwrite) + { + try + { + StorageFile fileForPathOrUri = FileHelper.GetFileForPathOrURI(sourceFileName); + if (overwrite) + { + StorageFile storageFile = (StorageFile)null; + try + { + storageFile = FileHelper.GetFileForPathOrURI(destFileName); + } + catch + { + } + if (storageFile != null) + { + WindowsRuntimeSystemExtensions.AsTask(fileForPathOrUri.CopyAndReplaceAsync((IStorageFile)storageFile)).Wait(); + return; + } + } + WindowsRuntimeSystemExtensions.AsTask(fileForPathOrUri.CopyAsync((IStorageFolder)FileHelper.GetFolderForPathOrURI(destFileName), Path.GetFileName(destFileName))).Wait(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static FileStream Create(string path) + { + return new FileStream(path, FileMode.Create, FileAccess.ReadWrite); + } + + public static FileStream Create(string path, int bufferSize) + { + return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize); + } + + public static StreamWriter CreateText(string path) + { + return new StreamWriter((Stream)File.Create(path)); + } + + public static void Delete(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (path.Trim() == "") + throw new ArgumentException(); + try + { + WindowsRuntimeSystemExtensions.AsTask(FileHelper.GetFileForPathOrURI(path).DeleteAsync()).Wait(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static bool Exists(string path) + { + try + { + return FileHelper.GetFileForPathOrURI(path) != null; + } + catch + { + return false; + } + } + + public static FileAttributes GetAttributes(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + return File.WinAttributesToSysAttributes(FileHelper.GetFileForPathOrURI(path).Attributes); + } + catch (Exception ex) + { + throw new FileNotFoundException(ex.Message, ex); + } + } + + internal static FileAttributes WinAttributesToSysAttributes(Windows.Storage.FileAttributes atts) + { + FileAttributes fileAttributes = (FileAttributes)0; + if ((Windows.Storage.FileAttributes.ReadOnly & atts) != Windows.Storage.FileAttributes.Normal) + fileAttributes |= FileAttributes.ReadOnly; + if ((Windows.Storage.FileAttributes.Directory & atts) != Windows.Storage.FileAttributes.Normal) + fileAttributes |= FileAttributes.Directory; + if ((Windows.Storage.FileAttributes.Archive & atts) != Windows.Storage.FileAttributes.Normal) + fileAttributes |= FileAttributes.Archive; + if ((Windows.Storage.FileAttributes.Temporary & atts) != Windows.Storage.FileAttributes.Normal) + fileAttributes |= FileAttributes.Temporary; + if (fileAttributes == (FileAttributes)0) + fileAttributes = FileAttributes.Normal; + return fileAttributes; + } + + public static System.DateTime GetCreationTime(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + return FileHelper.GetFileForPathOrURI(path).DateCreated.DateTime; + } + catch (Exception ex) + { + throw new FileNotFoundException(ex.Message, ex); + } + } + + public static System.DateTime GetCreationTimeUtc(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + return FileHelper.GetFileForPathOrURI(path).DateCreated.ToUniversalTime().DateTime; + } + catch (Exception ex) + { + throw new FileNotFoundException(ex.Message, ex); + } + } + + public static void Move(string sourceFileName, string destFileName) + { + try + { + WindowsRuntimeSystemExtensions.AsTask(FileHelper.GetFileForPathOrURI(sourceFileName).MoveAsync((IStorageFolder)FileHelper.GetFolderForPathOrURI(destFileName), Path.GetFileName(destFileName))).Wait(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static FileStream Open(string path, FileMode mode) + { + return new FileStream(path, mode); + } + + public static FileStream Open(string path, FileMode mode, FileAccess access) + { + return new FileStream(path, mode, access); + } + + public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share) + { + return new FileStream(path, mode, access, share); + } + + public static FileStream OpenRead(string path) + { + return File.Open(path, FileMode.Open, FileAccess.Read); + } + + public static StreamReader OpenText(string path) + { + return new StreamReader((Stream)File.OpenRead(path)); + } + + public static FileStream OpenWrite(string path) + { + return File.Open(path, FileMode.Create, FileAccess.Write); + } + + public static byte[] ReadAllBytes(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + return FileHelper.ReadEntireFile(FileHelper.GetFileForPathOrURI(path)); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static string[] ReadAllLines(string path) + { + return Enumerable.ToArray(File.ReadLines(path)); + } + + public static string[] ReadAllLines(string path, Encoding encoding) + { + return File.ReadAllLines(path); + } + + public static string ReadAllText(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + IAsyncOperation source = FileHelper.GetFileForPathOrURI(path).OpenAsync(FileAccessMode.Read); + WindowsRuntimeSystemExtensions.AsTask(source).Wait(); + using (FileRandomAccessStream randomAccessStream = (FileRandomAccessStream)source.GetResults()) + return new StreamReader(WindowsRuntimeStreamExtensions.AsStreamForRead((IInputStream)randomAccessStream)).ReadToEnd(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static string ReadAllText(string path, Encoding encoding) + { + return File.ReadAllText(path); + } + + public static IEnumerable ReadLines(string path) + { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + IAsyncOperation source = FileHelper.GetFileForPathOrURI(path).OpenAsync(FileAccessMode.Read); + WindowsRuntimeSystemExtensions.AsTask(source).Wait(); + using (FileRandomAccessStream randomAccessStream = (FileRandomAccessStream)source.GetResults()) + { + StreamReader streamReader = new StreamReader(WindowsRuntimeStreamExtensions.AsStreamForRead((IInputStream)randomAccessStream)); + List list = new List(); + while (true) + { + string str = streamReader.ReadLine(); + if (str != null) + list.Add(str); + else + break; + } + return (IEnumerable)list; + } + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static IEnumerable ReadLines(string path, Encoding encoding) + { + return File.ReadLines(path); + } + + public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName) + { + if (destinationFileName == null) + throw new ArgumentNullException(); + if (!string.IsNullOrWhiteSpace(sourceFileName) && !string.IsNullOrWhiteSpace(destinationFileName)) + { + if (!string.IsNullOrWhiteSpace(destinationBackupFileName)) + { + try + { + StorageFile fileForPathOrUri1 = FileHelper.GetFileForPathOrURI(sourceFileName); + string fileName1 = Path.GetFileName(destinationFileName); + StorageFile fileForPathOrUri2; + if (fileName1.ToLower() == destinationFileName.ToLower()) + { + if (Path.GetFileName(sourceFileName).ToLower() == fileName1.ToLower()) + { + System.Diagnostics.Debug.WriteLine("File.Replace: Source and destination is the same file"); + throw new IOException("Source and destination is the same file"); + } + fileForPathOrUri2 = FileHelper.GetFileForPathOrURI(Path.Combine(Path.GetDirectoryName(fileForPathOrUri1.Path), fileName1)); + } + else + { + fileForPathOrUri2 = FileHelper.GetFileForPathOrURI(destinationFileName); + if (fileForPathOrUri1.Equals((object)fileForPathOrUri2)) + { + System.Diagnostics.Debug.WriteLine("File.Replace: Source and destination is the same file"); + throw new IOException("Source and destination is the same file"); + } + } + string fileName2 = Path.GetFileName(destinationBackupFileName); + if (fileName2.ToLower() == destinationBackupFileName.ToLower()) + { + WindowsRuntimeSystemExtensions.AsTask(fileForPathOrUri2.RenameAsync(destinationBackupFileName)).Wait(); + } + else + { + StorageFolder folderForPathOrUri = FileHelper.GetFolderForPathOrURI(destinationBackupFileName); + WindowsRuntimeSystemExtensions.AsTask(fileForPathOrUri2.MoveAsync((IStorageFolder)folderForPathOrUri, fileName2)).Wait(); + } + if (fileName1.ToLower() == destinationFileName.ToLower()) + { + WindowsRuntimeSystemExtensions.AsTask(fileForPathOrUri1.RenameAsync(destinationFileName)).Wait(); + return; + } + else + { + StorageFolder folderForPathOrUri = FileHelper.GetFolderForPathOrURI(destinationFileName); + WindowsRuntimeSystemExtensions.AsTask(fileForPathOrUri1.MoveAsync((IStorageFolder)folderForPathOrUri, fileName1)).Wait(); + return; + } + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + } + throw new ArgumentException(); + } + + public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors) + { + File.Replace(sourceFileName, destinationFileName, destinationBackupFileName); + } + + private static StorageFile CreateOrReplaceFile(string path) + { + IAsyncOperation fileAsync = FileHelper.GetFolderForPathOrURI(path).CreateFileAsync(Path.GetFileName(path), CreationCollisionOption.ReplaceExisting); + WindowsRuntimeSystemExtensions.AsTask(fileAsync).Wait(); + return fileAsync.GetResults(); + } + + public static void WriteAllBytes(string path, byte[] bytes) + { + if (path == null || bytes == null || bytes.Length == 0) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + WindowsRuntimeSystemExtensions.AsTask(FileIO.WriteBytesAsync((IStorageFile)File.CreateOrReplaceFile(path), bytes)).Wait(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static void WriteAllLines(string path, IEnumerable contents) + { + if (path == null || contents == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + WindowsRuntimeSystemExtensions.AsTask(FileIO.WriteLinesAsync((IStorageFile)File.CreateOrReplaceFile(path), contents)).Wait(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static void WriteAllLines(string path, string[] contents) + { + IEnumerable contents1 = (IEnumerable)contents; + File.WriteAllLines(path, contents1); + } + + public static void WriteAllLines(string path, IEnumerable contents, Encoding encoding) + { + File.WriteAllLines(path, contents); + } + + public static void WriteAllLines(string path, string[] contents, Encoding encoding) + { + File.WriteAllLines(path, contents); + } + + public static void WriteAllText(string path, string contents) + { + if (path == null || string.IsNullOrEmpty(contents)) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + WindowsRuntimeSystemExtensions.AsTask(FileIO.WriteTextAsync((IStorageFile)File.CreateOrReplaceFile(path), contents)).Wait(); + } + catch (Exception ex) + { + throw File.GetRethrowException(ex); + } + } + + public static void WriteAllText(string path, string contents, Encoding encoding) + { + File.WriteAllText(path, contents); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs.meta new file mode 100644 index 0000000..46eada0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/File.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a4bc1887a1674ae4eb836a53c61d8069 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs new file mode 100644 index 0000000..cff3420 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs @@ -0,0 +1,69 @@ +#if NETFX_CORE +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BestHTTP.PlatformSupport.IO +{ + [Flags] + public enum FileAccess + { + Read = 1, + Write = 2, + ReadWrite = Write | Read, + } + + [Flags] + public enum FileAttributes + { + Archive = 32, + Compressed = 2048, + Device = 64, + Directory = 16, + Encrypted = 16384, + Hidden = 2, + Normal = 128, + NotContentIndexed = 8192, + Offline = 4096, + ReadOnly = 1, + ReparsePoint = 1024, + SparseFile = 512, + System = 4, + Temporary = 256, + } + + public enum FileMode + { + CreateNew = 1, + Create = 2, + Open = 3, + OpenOrCreate = 4, + Truncate = 5, + Append = 6, + } + + [Flags] + public enum FileOptions + { + None = 0, + Encrypted = 16384, + DeleteOnClose = 67108864, + SequentialScan = 134217728, + RandomAccess = 268435456, + Asynchronous = 1073741824, + WriteThrough = -2147483648, + } + + [Flags] + public enum FileShare + { + None = 0, + Read = 1, + Write = 2, + ReadWrite = Write | Read, + Delete = 4, + Inheritable = 16, + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs.meta new file mode 100644 index 0000000..da3545a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileEnums.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 78373321983343443805a7608720fd74 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs new file mode 100644 index 0000000..2dbfd80 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs @@ -0,0 +1,140 @@ +#if NETFX_CORE +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.IO; +using System.Linq; +using System.Text; +using Windows.Storage; +using Windows.Storage.Streams; +using Windows.Foundation; + +namespace BestHTTP.PlatformSupport.IO +{ + public static class FileHelper + { + internal const string LOCAL_FOLDER = "ms-appdata:///local/"; + internal const string ROAMING_FOLDER = "ms-appdata:///roaming/"; + internal const string TEMP_FOLDER = "ms-appdata:///temp/"; + internal const string STORE_FOLDER = "isostore:/"; + + public static Stream OpenFileForReading(string uri) + { + return FileHelper.OpenFileForReading(FileHelper.GetFileForPathOrURI(uri)); + } + + public static Stream OpenFileForReading(System.Uri uri) + { + Task task = WindowsRuntimeSystemExtensions.AsTask(StorageFile.GetFileFromApplicationUriAsync(uri)); + task.Wait(); + if (task.Status != TaskStatus.RanToCompletion) + throw new Exception("Filed to open file " + uri.ToString()); + else + return FileHelper.OpenFileForReading(task.Result); + } + + public static Stream OpenFileForWriting(string uri) + { + string fileName = Path.GetFileName(uri); + Task task1 = WindowsRuntimeSystemExtensions.AsTask(FileHelper.GetFolderForPathOrURI(uri).CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting)); + task1.Wait(); + if (task1.Status != TaskStatus.RanToCompletion) + throw new Exception("Failed to open the file"); + Task task2 = WindowsRuntimeSystemExtensions.AsTask(task1.Result.OpenAsync(FileAccessMode.ReadWrite)); + task2.Wait(); + if (task2.Status != TaskStatus.RanToCompletion) + throw new Exception("Failed to open the file"); + else + return WindowsRuntimeStreamExtensions.AsStreamForWrite((IOutputStream)task2.Result); + } + + internal static StorageFolder GetFolderForURI(string uri) + { + uri = uri.ToLower(); + StorageFolder storageFolder1; + if (uri.StartsWith("ms-appdata:///local/")) + { + storageFolder1 = ApplicationData.Current.LocalFolder; + uri = uri.Replace("ms-appdata:///local/", ""); + } + else if (uri.StartsWith("ms-appdata:///roaming/")) + { + storageFolder1 = ApplicationData.Current.RoamingFolder; + uri = uri.Replace("ms-appdata:///roaming/", ""); + } + else + { + if (!uri.StartsWith("ms-appdata:///temp/")) + throw new Exception("Unsupported URI: " + uri); + storageFolder1 = ApplicationData.Current.TemporaryFolder; + uri = uri.Replace("ms-appdata:///temp/", ""); + } + string[] strArray = uri.Split(new char[1] + { + '/' + }); + for (int index = 0; index < strArray.Length - 1; ++index) + { + Task> task = WindowsRuntimeSystemExtensions.AsTask>(storageFolder1.CreateFolderQuery().GetFoldersAsync()); + task.Wait(); + if (task.Status != TaskStatus.RanToCompletion) + throw new Exception("Failed to find folder: " + strArray[index]); + IReadOnlyList result = task.Result; + bool flag = false; + foreach (StorageFolder storageFolder2 in (IEnumerable)result) + { + if (storageFolder2.Name == strArray[index]) + { + storageFolder1 = storageFolder2; + flag = true; + break; + } + } + if (!flag) + throw new Exception("Folder not found: " + strArray[index]); + } + return storageFolder1; + } + + internal static StorageFolder GetFolderForPathOrURI(string path) + { + if (System.Uri.IsWellFormedUriString(path, UriKind.RelativeOrAbsolute)) + return FileHelper.GetFolderForURI(path); + IAsyncOperation folderFromPathAsync = StorageFolder.GetFolderFromPathAsync(Path.GetDirectoryName(path)); + WindowsRuntimeSystemExtensions.AsTask(folderFromPathAsync).Wait(); + return folderFromPathAsync.GetResults(); + } + + internal static StorageFile GetFileForPathOrURI(string path) + { + IAsyncOperation source = !System.Uri.IsWellFormedUriString(path, UriKind.RelativeOrAbsolute) ? StorageFile.GetFileFromPathAsync(path) : StorageFile.GetFileFromApplicationUriAsync(new System.Uri(path)); + WindowsRuntimeSystemExtensions.AsTask(source).Wait(); + return source.GetResults(); + } + + internal static Stream OpenFileForReading(StorageFile file) + { + Task task = WindowsRuntimeSystemExtensions.AsTask(file.OpenAsync(FileAccessMode.Read)); + task.Wait(); + if (task.Status != TaskStatus.RanToCompletion) + throw new Exception("Failed to open file!"); + else + return WindowsRuntimeStreamExtensions.AsStreamForRead((IInputStream)task.Result); + } + + internal static byte[] ReadEntireFile(StorageFile file) + { + Task task = WindowsRuntimeSystemExtensions.AsTask(FileIO.ReadBufferAsync((IStorageFile)file)); + task.Wait(); + if (task.Status != TaskStatus.RanToCompletion) + throw new Exception("Failed to read file"); + IBuffer result = task.Result; + DataReader dataReader = DataReader.FromBuffer(result); + byte[] numArray = new byte[result.Length]; + dataReader.ReadBytes(numArray); + return numArray; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs.meta new file mode 100644 index 0000000..fc86f73 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileHelper.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fd9462d46d0b7fb4ba58fc3368304fe2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs new file mode 100644 index 0000000..2638880 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs @@ -0,0 +1,338 @@ +#if NETFX_CORE + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.IO; +using System.Linq; +using System.Text; + +using Windows.Storage; +using Windows.Storage.Streams; +using Windows.Foundation; + +namespace BestHTTP.PlatformSupport.IO +{ + public class FileStream : Stream + { + private int readTimeout = -1; + private int writeTimeout = 1000; + internal const int DefaultBufferSize = 8192; + private FileRandomAccessStream backend; + private FileOptions fileOptions; + private string name; + + public override bool CanRead { get { return this.backend.CanRead; } } + public override bool CanSeek { get { return true; } } + public override bool CanWrite { get { return this.backend.CanWrite; } } + public virtual bool IsAsync { get { return (this.fileOptions & FileOptions.Asynchronous) > FileOptions.None; } } + public override long Length { get { return (long)this.backend.Size; } } + public override int ReadTimeout { get { return this.readTimeout; } set { this.readTimeout = value; } } + public override int WriteTimeout { get { return this.writeTimeout; } set { this.writeTimeout = value; } } + + public string Name { get { return this.name; } } + + public override long Position + { + get { return (long)this.backend.Position; } + set + { + try + { + this.backend.Seek((ulong)value); + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + } + + public FileStream(string file, FileMode mode) + : this(file, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.Read, 8192, FileOptions.None) + { + } + + public FileStream(string file, FileMode mode, FileAccess access) + : this(file, mode, access, FileShare.Read, 8192, FileOptions.None) + { + } + + public FileStream(string file, FileMode mode, FileAccess access, FileShare share) + : this(file, mode, access, share, 8192, FileOptions.None) + { + } + + public FileStream(string file, FileMode mode, FileAccess access, FileShare share, int bufferSize) + : this(file, mode, access, share, bufferSize, FileOptions.None) + { + } + + public FileStream(string file, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) + : this(file, mode, access, share, bufferSize, useAsync ? FileOptions.Asynchronous : FileOptions.None) + { + } + + public FileStream(string file, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) + { + try + { + this.fileOptions = options; + this.name = file; + this.CheckAccess(mode, access); + StorageFile storageFile; + switch (mode) + { + case FileMode.CreateNew: + case FileMode.Create: + case FileMode.OpenOrCreate: + case FileMode.Append: + storageFile = FileStream.CreateFile(file, mode, access); + break; + case FileMode.Open: + case FileMode.Truncate: + storageFile = FileStream.OpenFile(file, mode, access); + break; + default: + throw new ArgumentException("Unknown file mode"); + } + IAsyncOperation source = storageFile.OpenAsync(FileStream.GetAccessMode(access)); + WindowsRuntimeSystemExtensions.AsTask(source).Wait(); + this.backend = (FileRandomAccessStream)source.GetResults(); + if (mode == FileMode.Truncate) + { + this.backend.Size = 0UL; + } + else + { + if (mode != FileMode.Append) + return; + this.backend.Seek(this.backend.Size); + } + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + + private void CheckAccess(FileMode mode, FileAccess access) + { + switch (mode) + { + case FileMode.CreateNew: + break; + case FileMode.Create: + break; + case FileMode.Open: + break; + case FileMode.OpenOrCreate: + break; + case FileMode.Truncate: + break; + case FileMode.Append: + if (access == FileAccess.Write) + break; + else + { + System.Diagnostics.Debug.WriteLine("FileStream.CheckAccess: Bad access mode for Append"); + throw new IOException("Bad access mode for Append"); + } + default: + throw new ArgumentException("Unknown file mode"); + } + } + + private static StorageFile OpenFile(string file, FileMode mode, FileAccess access) + { + return FileHelper.GetFileForPathOrURI(file); + } + + private static StorageFile CreateFile(string file, FileMode mode, FileAccess access) + { + IAsyncOperation fileAsync = FileHelper.GetFolderForPathOrURI(file).CreateFileAsync(Path.GetFileName(file), FileStream.GetCollisionOption(mode, access)); + WindowsRuntimeSystemExtensions.AsTask(fileAsync).Wait(); + if (fileAsync.Status != AsyncStatus.Completed) + { + System.Diagnostics.Debug.WriteLine("FileStream.CheckAccess: Failed to create file " + file); + throw new IOException("Failed to create file " + file); + } + else + return fileAsync.GetResults(); + } + + public override void Flush() + { + try + { + WindowsRuntimeSystemExtensions.AsTask(this.backend.FlushAsync()).Wait(); + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + + public void Flush(bool flushToDisc) + { + Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + try + { + Windows.Storage.Streams.Buffer buffer1 = new Windows.Storage.Streams.Buffer((uint)count); + WindowsRuntimeSystemExtensions.AsTask(this.backend.ReadAsync((IBuffer)buffer1, (uint)count, InputStreamOptions.ReadAhead)).Wait(this.readTimeout); + int length = (int)buffer1.Length; + DataReader dataReader = DataReader.FromBuffer((IBuffer)buffer1); + bool flag = offset == 0 && buffer.Length == count && length == count; + byte[] numArray = flag ? buffer : new byte[length]; + dataReader.ReadBytes(numArray); + if (!flag) + Array.Copy((Array)numArray, 0, (Array)buffer, offset, numArray.Length); + return length; + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + + public override long Seek(long offset, SeekOrigin origin) + { + try + { + switch (origin) + { + case SeekOrigin.Begin: + if (offset > (long)this.backend.Size) + { + offset = (long)this.backend.Size; + break; + } + else + break; + case SeekOrigin.Current: + if ((long)this.backend.Position + offset > (long)this.backend.Size) + { + offset = (long)this.backend.Position + offset; + break; + } + else + break; + case SeekOrigin.End: + if (offset >= 0L) + { + offset = (long)this.backend.Size; + break; + } + else + { + offset += (long)this.backend.Size; + break; + } + } + if (offset < 0L) + offset = 0L; + this.backend.Seek((ulong)offset); + return offset; + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + + public override void SetLength(long value) + { + try + { + this.backend.Size = (ulong)value; + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + + public override void Write(byte[] buffer, int offset, int count) + { + try + { + Windows.Storage.Streams.Buffer buffer1 = new Windows.Storage.Streams.Buffer((uint)count); + byte[] numArray; + if (offset == 0 && count == buffer.Length) + { + numArray = buffer; + } + else + { + numArray = new byte[count]; + Array.Copy((Array)buffer, offset, (Array)numArray, 0, count); + } + DataWriter dataWriter = new DataWriter(); + dataWriter.WriteBytes(numArray); + WindowsRuntimeSystemExtensions.AsTask(this.backend.WriteAsync(dataWriter.DetachBuffer())).Wait(this.writeTimeout); + } + catch (Exception ex) + { + throw FileStream.RethrowException(ex); + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + this.backend.Dispose(); + } + + public void Close() + { + base.Dispose(); + } + + private static Exception RethrowException(Exception e) + { + System.Diagnostics.Debug.WriteLine("FileStream.RethrowException: " + e.Message + "\n" + e.StackTrace); + if (e.GetType() == typeof(IOException)) + return e; + else + return (Exception)new IOException(e.Message, e); + } + + private static CreationCollisionOption GetCollisionOption(FileMode mode, FileAccess access) + { + CreationCollisionOption creationCollisionOption = CreationCollisionOption.GenerateUniqueName; + switch (mode) + { + case FileMode.CreateNew: + creationCollisionOption = CreationCollisionOption.FailIfExists; + break; + case FileMode.Create: + case FileMode.Truncate: + creationCollisionOption = CreationCollisionOption.ReplaceExisting; + break; + case FileMode.Open: + case FileMode.OpenOrCreate: + case FileMode.Append: + creationCollisionOption = CreationCollisionOption.OpenIfExists; + break; + } + return creationCollisionOption; + } + + private static FileAccessMode GetAccessMode(FileAccess access) + { + switch (access) + { + case FileAccess.Read: + return FileAccessMode.Read; + default: + return FileAccessMode.ReadWrite; + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs.meta new file mode 100644 index 0000000..43a1394 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/FileStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e83c057a0be3389429bd8bd82f4dc612 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs new file mode 100644 index 0000000..4676b5c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs @@ -0,0 +1,217 @@ +#if NETFX_CORE +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.IO; +using System.Linq; +using System.Text; +using Windows.Storage; +using Windows.Storage.Streams; +using Windows.Foundation; + +namespace BestHTTP.PlatformSupport.IO +{ + public abstract class FileSystemInfo + { + public FileAttributes Attributes + { + get + { + return this.GetAttributes(); + } + } + + public DateTime CreationTime + { + get + { + return this.GetCreationTime().DateTime; + } + } + + public DateTime CreationTimeUtc + { + get + { + return this.GetCreationTime().ToUniversalTime().DateTime; + } + } + + public abstract bool Exists { get; } + + public string Extention + { + get + { + return Path.GetExtension(this.FullName); + } + } + + public abstract string FullName { get; } + + public abstract string Name { get; } + + internal abstract FileAttributes GetAttributes(); + + internal abstract DateTimeOffset GetCreationTime(); + + public abstract void Delete(); + + public void Refresh() + { + this.RefreshInternal(); + } + + internal abstract void RefreshInternal(); + } + + public sealed class DirectoryInfo : FileSystemInfo + { + private string path; + private StorageFolder folder; + + public override bool Exists + { + get + { + try + { + this.RefreshInternal(); + return true; + } + catch + { + return false; + } + } + } + + public override string FullName + { + get + { + return this.folder.Path; + } + } + + public override string Name + { + get + { + return this.folder.Name; + } + } + + public DirectoryInfo(string path) + { + if (path == null) + throw new ArgumentNullException(); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException(); + try + { + this.path = path; + this.folder = FileHelper.GetFolderForPathOrURI(path); + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + internal DirectoryInfo(string path, StorageFolder folder) + { + this.path = path; + this.folder = folder; + } + + internal override FileAttributes GetAttributes() + { + try + { + return File.WinAttributesToSysAttributes(this.folder.Attributes); + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.GetAttributes: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.GetAttributes: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + internal override DateTimeOffset GetCreationTime() + { + try + { + return this.folder.DateCreated; + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.GetCreationTime: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.GetCreationTime: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public override void Delete() + { + try + { + WindowsRuntimeSystemExtensions.AsTask(this.folder.DeleteAsync()).Wait(); + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.Delete: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.Delete: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + internal override void RefreshInternal() + { + try + { + this.folder = FileHelper.GetFolderForPathOrURI(this.path); + } + catch (IOException ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.RefreshInternal: " + ex.Message + "\n" + ex.StackTrace); + throw; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine("DirectoryInfo.RefreshInternal: " + ex.Message + "\n" + ex.StackTrace); + throw new IOException(ex.Message, ex); + } + } + + public override string ToString() + { + return this.path; + } + + public override int GetHashCode() + { + return this.path.GetHashCode(); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs.meta new file mode 100644 index 0000000..65dc053 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/IO/Infos.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 65147cd559a8ee44bae33bf013e68463 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient.meta new file mode 100644 index 0000000..9060705 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2b874ed66c4deeb4f9a5f68d9de30628 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs new file mode 100644 index 0000000..d4ac9d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs @@ -0,0 +1,630 @@ +#if (!NETFX_CORE && !UNITY_WP8) || UNITY_EDITOR + +// TcpClient.cs +// +// Author: +// Phillip Pearson (pp@myelin.co.nz) +// Gonzalo Paniagua Javier (gonzalo@novell.com) +// Sridhar Kulkarni (sridharkulkarni@gmail.com) +// Marek Safar (marek.safar@gmail.com) +// +// Copyright (C) 2001, Phillip Pearson http://www.myelin.co.nz +// Copyright (c) 2006 Novell, Inc. (http://www.novell.com) +// Copyright 2011 Xamarin Inc. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; + +namespace BestHTTP.PlatformSupport.TcpClient.General +{ + // This is a little modified TcpClient class from the Mono src tree. + public class TcpClient : IDisposable + { + enum Properties : uint + { + LingerState = 1, + NoDelay = 2, + ReceiveBufferSize = 4, + ReceiveTimeout = 8, + SendBufferSize = 16, + SendTimeout = 32 + } + + // private data + NetworkStream stream; + bool active; + Socket client; + bool disposed; + Properties values; + int recv_timeout, send_timeout; + int recv_buffer_size, send_buffer_size; + LingerOption linger_state; + bool no_delay; + + private void Init(AddressFamily family) + { + active = false; + + if (client != null) + { + client.Close(); + client = null; + } + + client = new Socket(family, SocketType.Stream, ProtocolType.Tcp); + } + + public TcpClient() + { + Init(AddressFamily.InterNetwork); + //client.Bind(new IPEndPoint(IPAddress.Any, 0)); + + ConnectTimeout = TimeSpan.FromSeconds(2); + } + + public TcpClient(AddressFamily family) + { + if (family != AddressFamily.InterNetwork && + family != AddressFamily.InterNetworkV6) + { + throw new ArgumentException("Family must be InterNetwork or InterNetworkV6", "family"); + } + + Init(family); + /*IPAddress any = IPAddress.Any; + if (family == AddressFamily.InterNetworkV6) + any = IPAddress.IPv6Any; + client.Bind(new IPEndPoint(any, 0));*/ + + ConnectTimeout = TimeSpan.FromSeconds(2); + } + + public TcpClient(IPEndPoint localEP) + { + Init(localEP.AddressFamily); + //client.Bind(localEP); + + ConnectTimeout = TimeSpan.FromSeconds(2); + } + + public TcpClient(string hostname, int port) + { + ConnectTimeout = TimeSpan.FromSeconds(2); + + Connect(hostname, port); + } + + protected bool Active + { + get { return active; } + set { active = value; } + } + + public Socket Client + { + get { return client; } + set + { + client = value; + stream = null; + } + } + + public int Available + { + get { return client.Available; } + } + + public bool Connected + { + get { return client.Connected; } + } + + + public bool IsConnected() + { + try + { + return !(Client.Poll(1, SelectMode.SelectRead) && Client.Available == 0); + } + catch (Exception) { return false; } + } + + public bool ExclusiveAddressUse + { + get + { + return (client.ExclusiveAddressUse); + } + set + { + client.ExclusiveAddressUse = value; + } + } + + internal void SetTcpClient(Socket s) + { + Client = s; + } + + public LingerOption LingerState + { + get + { + if ((values & Properties.LingerState) != 0) + return linger_state; + + return (LingerOption)client.GetSocketOption(SocketOptionLevel.Socket, + SocketOptionName.Linger); + } + set + { + if (!client.Connected) + { + linger_state = value; + values |= Properties.LingerState; + return; + } + client.SetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.Linger, value); + } + } + + public bool NoDelay + { + get + { + if ((values & Properties.NoDelay) != 0) + return no_delay; + + return (bool)client.GetSocketOption( + SocketOptionLevel.Tcp, + SocketOptionName.NoDelay); + } + set + { + if (!client.Connected) + { + no_delay = value; + values |= Properties.NoDelay; + return; + } + client.SetSocketOption( + SocketOptionLevel.Tcp, + SocketOptionName.NoDelay, value ? 1 : 0); + } + } + + public int ReceiveBufferSize + { + get + { + if ((values & Properties.ReceiveBufferSize) != 0) + return recv_buffer_size; + + return (int)client.GetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.ReceiveBuffer); + } + set + { + if (!client.Connected) + { + recv_buffer_size = value; + values |= Properties.ReceiveBufferSize; + return; + } + client.SetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.ReceiveBuffer, value); + } + } + + public int ReceiveTimeout + { + get + { + if ((values & Properties.ReceiveTimeout) != 0) + return recv_timeout; + + return (int)client.GetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.ReceiveTimeout); + } + set + { + if (!client.Connected) + { + recv_timeout = value; + values |= Properties.ReceiveTimeout; + return; + } + client.SetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.ReceiveTimeout, value); + } + } + + public int SendBufferSize + { + get + { + if ((values & Properties.SendBufferSize) != 0) + return send_buffer_size; + + return (int)client.GetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.SendBuffer); + } + set + { + if (!client.Connected) + { + send_buffer_size = value; + values |= Properties.SendBufferSize; + return; + } + client.SetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.SendBuffer, value); + } + } + + public int SendTimeout + { + get + { + if ((values & Properties.SendTimeout) != 0) + return send_timeout; + + return (int)client.GetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.SendTimeout); + } + set + { + if (!client.Connected) + { + send_timeout = value; + values |= Properties.SendTimeout; + return; + } + client.SetSocketOption( + SocketOptionLevel.Socket, + SocketOptionName.SendTimeout, value); + } + } + + public TimeSpan ConnectTimeout { get; set; } + + // methods + + public void Close() + { + ((IDisposable)this).Dispose(); + } + + public void Connect(IPEndPoint remoteEP) + { + try + { + if (ConnectTimeout > TimeSpan.Zero) + { + // Third version, works in WebPlayer + System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false); + IAsyncResult result = client.BeginConnect(remoteEP, (res) => mre.Set(), null); + active = mre.WaitOne(ConnectTimeout); + if (active) + client.EndConnect(result); + else + { + try + { + client.Close(); + } + catch + { } + + throw new TimeoutException("Connection timed out!"); + } + + // Second version with timeout, in WebPlayer can't connect: + // Attempt to access a private/protected method failed. at System.Security.SecurityManager.ThrowException (System.Exception ex) [0x00000] in :0 + /*IAsyncResult result = client.BeginConnect(remoteEP, null, null); + Active = result.AsyncWaitHandle.WaitOne(ConnectTimeout, true); + if (active) + { + client.EndConnect(result); + } + else + { + client.Close(); + //throw new SocketException(10060); + throw new TimeoutException("Connection timed out!"); + }*/ + } + else + { + // First(old) version, no timeout + client.Connect(remoteEP); + active = true; + } + } + finally + { + CheckDisposed(); + } + } + + public void Connect(IPAddress address, int port) + { + Connect(new IPEndPoint(address, port)); + } + + void SetOptions() + { + Properties props = values; + values = 0; + + if ((props & Properties.LingerState) != 0) + LingerState = linger_state; + if ((props & Properties.NoDelay) != 0) + NoDelay = no_delay; + if ((props & Properties.ReceiveBufferSize) != 0) + ReceiveBufferSize = recv_buffer_size; + if ((props & Properties.ReceiveTimeout) != 0) + ReceiveTimeout = recv_timeout; + if ((props & Properties.SendBufferSize) != 0) + SendBufferSize = send_buffer_size; + if ((props & Properties.SendTimeout) != 0) + SendTimeout = send_timeout; + } + + public void Connect(string hostname, int port) + { + if (ConnectTimeout > TimeSpan.Zero) + { + // https://forum.unity3d.com/threads/best-http-released.200006/page-37#post-3150972 + System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false); + IAsyncResult result = Dns.BeginGetHostAddresses(hostname, (res) => mre.Set(), null); + bool success = mre.WaitOne(ConnectTimeout); + if (success) + { + IPAddress[] addresses = Dns.EndGetHostAddresses(result); + Connect(addresses, port); + } + else + { + throw new TimeoutException("DNS resolve timed out!"); + } + } + else + { + IPAddress[] addresses = Dns.GetHostAddresses(hostname); + Connect(addresses, port); + } + } + + public void Connect(IPAddress[] ipAddresses, int port) + { + CheckDisposed(); + + if (ipAddresses == null) + { + throw new ArgumentNullException("ipAddresses"); + } + + for (int i = 0; i < ipAddresses.Length; i++) + { + try + { + IPAddress address = ipAddresses[i]; + + if (address.Equals(IPAddress.Any) || + address.Equals(IPAddress.IPv6Any)) + { + throw new SocketException((int)SocketError.AddressNotAvailable); + } + + Init(address.AddressFamily); + + if (address.AddressFamily == AddressFamily.InterNetwork) + { + //client.Bind(new IPEndPoint(IPAddress.Any, 0)); + } + else if (address.AddressFamily == AddressFamily.InterNetworkV6) + { + //client.Bind(new IPEndPoint(IPAddress.IPv6Any, 0)); + } + else + { + throw new NotSupportedException("This method is only valid for sockets in the InterNetwork and InterNetworkV6 families"); + } + + Connect(new IPEndPoint(address, port)); + + if (values != 0) + { + SetOptions(); + } + + // Enable Keep-Alive packets + client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); + + try + { + /* + TCP_KEEPIDLE 4 // Start keeplives after this period + TCP_KEEPINTVL 5 // Interval between keepalives + TCP_KEEPCNT 6 // Number of keepalives before death + */ + + //client.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)4, 30); + //client.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)5, 10); + } + catch { } + + +#if UNITY_WINDOWS || UNITY_EDITOR + // Set the keep-alive time and interval on windows + + // https://msdn.microsoft.com/en-us/library/windows/desktop/dd877220%28v=vs.85%29.aspx + // https://msdn.microsoft.com/en-us/library/windows/desktop/ee470551%28v=vs.85%29.aspx + try + { + //SetKeepAlive(true, 30000, 1000); + } + catch{ } +#endif + + HTTPManager.Logger.Information("TcpClient", string.Format("Connected to {0}:{1}", address.ToString(), port.ToString())); + + break; + } + catch (Exception e) + { + /* Reinitialise the socket so + * other properties still work + * (see no-arg constructor) + */ + Init(AddressFamily.InterNetwork); + + /* This is the last known + * address, so re-throw the + * exception + */ + if (i == ipAddresses.Length - 1) + { + throw e; + } + } + } + } + + public void EndConnect(IAsyncResult asyncResult) + { + client.EndConnect(asyncResult); + } + + public IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback requestCallback, object state) + { + return client.BeginConnect(address, port, requestCallback, state); + } + + public IAsyncResult BeginConnect(IPAddress[] addresses, int port, AsyncCallback requestCallback, object state) + { + return client.BeginConnect(addresses, port, requestCallback, state); + } + + public IAsyncResult BeginConnect(string host, int port, AsyncCallback requestCallback, object state) + { + return client.BeginConnect(host, port, requestCallback, state); + } + + void IDisposable.Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposed) + return; + disposed = true; + + if (disposing) + { + // release managed resources + NetworkStream s = stream; + stream = null; + if (s != null) + { + // This closes the socket as well, as the NetworkStream + // owns the socket. + s.Close(); + active = false; + s = null; + } + else if (client != null) + { + client.Close(); + client = null; + } + } + } + + ~TcpClient() + { + Dispose(false); + } + + public Stream GetStream() + { + try + { + if (stream == null) + stream = new NetworkStream(client, true); + return stream; + } + finally { CheckDisposed(); } + } + + private void CheckDisposed() + { + if (disposed) + throw new ObjectDisposedException(GetType().FullName); + } + +#if UNITY_WINDOWS || UNITY_EDITOR + public void SetKeepAlive(bool on, uint keepAliveTime, uint keepAliveInterval) + { + int size = System.Runtime.InteropServices.Marshal.SizeOf(new uint()); + + var inOptionValues = new byte[size * 3]; + + BitConverter.GetBytes((uint)(on ? 1 : 0)).CopyTo(inOptionValues, 0); + BitConverter.GetBytes((uint)keepAliveTime).CopyTo(inOptionValues, size); + BitConverter.GetBytes((uint)keepAliveInterval).CopyTo(inOptionValues, size * 2); + + //client.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); + int dwBytesRet = 0; + WSAIoctl(client.Handle, /*SIO_KEEPALIVE_VALS*/ System.Net.Sockets.IOControlCode.KeepAliveValues, inOptionValues, inOptionValues.Length, /*NULL*/IntPtr.Zero, 0, ref dwBytesRet, /*NULL*/IntPtr.Zero, /*NULL*/IntPtr.Zero); + } + + [System.Runtime.InteropServices.DllImport("Ws2_32.dll")] + public static extern int WSAIoctl( + /* Socket, Mode */ IntPtr s, System.Net.Sockets.IOControlCode dwIoControlCode, + /* Optional Or IntPtr.Zero, 0 */ byte[] lpvInBuffer, int cbInBuffer, + /* Optional Or IntPtr.Zero, 0 */ IntPtr lpvOutBuffer, int cbOutBuffer, + /* reference to receive Size */ ref int lpcbBytesReturned, + /* IntPtr.Zero, IntPtr.Zero */ IntPtr lpOverlapped, IntPtr lpCompletionRoutine); +#endif + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs.meta new file mode 100644 index 0000000..fb6f20b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/TcpClient.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e8000d20829121a4aa2466c39057835e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT.meta new file mode 100644 index 0000000..dd22bf7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1d6092b0b312e184b8d45e66dba37d60 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs new file mode 100644 index 0000000..8e5e02f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs @@ -0,0 +1,148 @@ +#if (UNITY_WSA || BUILD_FOR_WP8) && !UNITY_EDITOR && !ENABLE_IL2CPP + +using System; + +using Windows.Storage.Streams; + +namespace BestHTTP.PlatformSupport.TcpClient.WinRT +{ + public sealed class DataReaderWriterStream : System.IO.Stream + { + private TcpClient Client { get; set; } + private DataReader Reader { get; set; } + private DataWriter Writer { get; set; } + + public DataReaderWriterStream(TcpClient socket) + { + this.Client = socket; + this.Reader = new DataReader(Client.Socket.InputStream); + this.Writer = new DataWriter(Client.Socket.OutputStream); + } + +#region Stream interface + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override void Flush() + { + Writer.StoreAsync().AsTask().Wait(); + } + + public override long Length + { + get { throw new NotImplementedException(); } + } + + public override long Position + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + + public bool DataAvailable + { + get + { + return Reader.UnconsumedBufferLength > 0; + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + Windows.Storage.Streams.Buffer tmpBuffer = new Windows.Storage.Streams.Buffer((uint)count); + + try + { + var task = Client.Socket.InputStream.ReadAsync(tmpBuffer, (uint)count, InputStreamOptions.None); + task.AsTask().Wait(); + } + catch(AggregateException ex) + { + if (ex.InnerException != null) + throw ex.InnerException; + else + throw ex; + } + + /*byte[] tmpBuff = tmpBuffer.ToArray(); + int length = Math.Min(tmpBuff.Length, count); + + Array.Copy(tmpBuff, 0, buffer, offset, length); + + return length;*/ + + DataReader buf = DataReader.FromBuffer(tmpBuffer); + int length = (int)buf.UnconsumedBufferLength; + for (int i = 0; i < length; ++i) + buffer[offset + i] = buf.ReadByte(); + return length; + } + + public override void Write(byte[] buffer, int offset, int count) + { + for (int i = 0; i < count; ++i) + Writer.WriteByte(buffer[offset + i]); + } + + public override long Seek(long offset, System.IO.SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + +#endregion + +#region Dispose + + private bool disposed = false; + protected override void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + if (Reader != null) + { + Reader.Dispose(); + Reader = null; + } + + if (Writer != null) + { + Writer.Dispose(); + Writer = null; + } + } + disposed = true; + } + base.Dispose(disposing); + } + +#endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs.meta new file mode 100644 index 0000000..0ccf26b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/DataReaderWriterStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 427d34e18e3b2874bb249aea978feba8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs new file mode 100644 index 0000000..5c17226 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs @@ -0,0 +1,133 @@ +#if (NETFX_CORE || BUILD_FOR_WP8) && !UNITY_EDITOR && !ENABLE_IL2CPP + +using System; +using Windows.Networking; +using Windows.Networking.Sockets; + +namespace BestHTTP.PlatformSupport.TcpClient.WinRT +{ + public sealed class TcpClient : IDisposable + { +#region Public Properties + + public bool Connected { get; private set; } + public TimeSpan ConnectTimeout { get; set; } + + public bool UseHTTPSProtocol { get; set; } + +#endregion + +#region Private Properties + + internal StreamSocket Socket { get; set; } + private System.IO.Stream Stream { get; set; } + +#endregion + + public TcpClient() + { + ConnectTimeout = TimeSpan.FromSeconds(2); + } + + public void Connect(string hostName, int port) + { + //How to secure socket connections with TLS/SSL: + //http://msdn.microsoft.com/en-us/library/windows/apps/jj150597.aspx + + //Networking in Windows 8 Apps - Using StreamSocket for TCP Communication + //http://blogs.msdn.com/b/metulev/archive/2012/10/22/networking-in-windows-8-apps-using-streamsocket-for-tcp-communication.aspx + + Socket = new StreamSocket(); + Socket.Control.KeepAlive = true; + + var host = new HostName(hostName); + + SocketProtectionLevel spl = SocketProtectionLevel.PlainSocket; + if (UseHTTPSProtocol) + spl = SocketProtectionLevel. +#if UNITY_WSA_8_0 || BUILD_FOR_WP8 + Ssl; +#else + Tls12; +#endif + + // https://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj710176.aspx#content + try + { + var result = Socket.ConnectAsync(host, UseHTTPSProtocol ? "https" : port.ToString(), spl); + + if (ConnectTimeout > TimeSpan.Zero) + Connected = result.AsTask().Wait(ConnectTimeout); + else + Connected = result.AsTask().Wait(TimeSpan.FromMilliseconds(-1)); + } + catch(AggregateException ex) + { + if (ex.InnerException != null) + //throw ex.InnerException; + { + if ( ex.Message.Contains("No such host is known") || ex.Message.Contains("unreachable host") ) + throw new Exception("Socket Exception"); + else + throw ex.InnerException; + } + else + throw ex; + } + + if (!Connected) + throw new TimeoutException("Connection timed out!"); + } + + public bool IsConnected() + { + return true; + } + + public System.IO.Stream GetStream() + { + if (Stream == null) + Stream = new DataReaderWriterStream(this); + return Stream; + } + + public void Close() + { + Dispose(); + } + +#region IDisposeble + + private bool disposed = false; + + private void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + if (Stream != null) + Stream.Dispose(); + Stream = null; + Connected = false; + } + disposed = true; + } + } + + ~TcpClient() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + +#endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs.meta new file mode 100644 index 0000000..44682dd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/PlatformSupport/TcpClient/WinRT/TcpClient.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f655ab9e34dc51541b1d220a7ba46446 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol.meta new file mode 100644 index 0000000..3d21f30 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 97fdcd3872eb99b47b5b13fc86176ca5 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt new file mode 100644 index 0000000..96e67d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt @@ -0,0 +1,7 @@ +Copyright (c) 2000 - 2017 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt.meta new file mode 100644 index 0000000..4db4e3b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/License.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc7453f14fee55347b287df5490f3c4d +timeCreated: 1490202077 +licenseType: Free +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs new file mode 100644 index 0000000..2b9991b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs @@ -0,0 +1,112 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; + + +namespace System.TypeFix +{ + public static class ReflectionHelpers + { + /// + /// Determines whether the specified object is an instance of the current Type. + /// + /// The type. + /// The object to compare with the current type. + /// true if the current Type is in the inheritance hierarchy of the + /// object represented by o, or if the current Type is an interface that o + /// supports. false if neither of these conditions is the case, or if o is + /// null, or if the current Type is an open generic type (that is, + /// ContainsGenericParameters returns true). + public static bool IsInstanceOfType(this Type type, object o) + { + return o != null && type.IsAssignableFrom(o.GetType()); + } + + + internal static bool ImplementInterface(this Type type, Type ifaceType) + { + while (type != null) + { + Type[] interfaces = type.GetTypeInfo().ImplementedInterfaces.ToArray(); // .GetInterfaces(); + if (interfaces != null) + { + for (int i = 0; i < interfaces.Length; i++) + { + if (interfaces[i] == ifaceType || (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType))) + { + return true; + } + } + } + type = type.GetTypeInfo().BaseType; + // type = type.BaseType; + } + return false; + } + + + public static bool IsAssignableFrom(this Type type, Type c) + { + if (c == null) + { + return false; + } + if (type == c) + { + return true; + } + + + //RuntimeType runtimeType = type.UnderlyingSystemType as RuntimeType; + //if (runtimeType != null) + //{ + // return runtimeType.IsAssignableFrom(c); + //} + + + //if (c.IsSubclassOf(type)) + if (c.GetTypeInfo().IsSubclassOf(c)) + { + return true; + } + + + //if (type.IsInterface) + if (type.GetTypeInfo().IsInterface) + { + return c.ImplementInterface(type); + } + + + if (type.IsGenericParameter) + { + Type[] genericParameterConstraints = type.GetTypeInfo().GetGenericParameterConstraints(); + for (int i = 0; i < genericParameterConstraints.Length; i++) + { + if (!genericParameterConstraints[i].IsAssignableFrom(c)) + { + return false; + } + } + return true; + } + return false; + } + + public static bool IsEnum(this Type type) + { + return type.GetTypeInfo().IsEnum; + } + + + } +} + +#endif +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs.meta new file mode 100644 index 0000000..2a430ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/ReflectionHelpers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 82817667b4e18d64c917ad3fab2a38f4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1.meta new file mode 100644 index 0000000..c4943d1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bedc740ef99712e40b82c0c7de92cf9c +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs new file mode 100644 index 0000000..8d117f5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs @@ -0,0 +1,30 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Generator + { + private Stream _out; + + protected Asn1Generator( + Stream outStream) + { + _out = outStream; + } + + protected Stream Out + { + get { return _out; } + } + + public abstract void AddObject(Asn1Encodable obj); + + public abstract Stream GetRawOutputStream(); + + public abstract void Close(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs.meta new file mode 100644 index 0000000..e18d3f6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1Generator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bdc81b96ab45ff94098a67c1dcf27e23 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs new file mode 100644 index 0000000..46a9b2e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1OctetStringParser + : IAsn1Convertible + { + Stream GetOctetStream(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs.meta new file mode 100644 index 0000000..f11f80f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1OctetStringParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cc7b00883ebe075438a06d46defe0b35 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs new file mode 100644 index 0000000..f27d882 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs @@ -0,0 +1,11 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1SequenceParser + : IAsn1Convertible + { + IAsn1Convertible ReadObject(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs.meta new file mode 100644 index 0000000..29ad679 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SequenceParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 945f35756f280754580483acdd35d1f3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs new file mode 100644 index 0000000..98aaa35 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs @@ -0,0 +1,11 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1SetParser + : IAsn1Convertible + { + IAsn1Convertible ReadObject(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs.meta new file mode 100644 index 0000000..6d92519 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1SetParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e5c4059ebe7ac0240878ec76e191d1ad +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs new file mode 100644 index 0000000..edf6b82 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs @@ -0,0 +1,237 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1StreamParser + { + private readonly Stream _in; + private readonly int _limit; + + private readonly byte[][] tmpBuffers; + + public Asn1StreamParser( + Stream inStream) + : this(inStream, Asn1InputStream.FindLimit(inStream)) + { + } + + public Asn1StreamParser( + Stream inStream, + int limit) + { + if (!inStream.CanRead) + throw new ArgumentException("Expected stream to be readable", "inStream"); + + this._in = inStream; + this._limit = limit; + this.tmpBuffers = new byte[16][]; + } + + public Asn1StreamParser( + byte[] encoding) + : this(new MemoryStream(encoding, false), encoding.Length) + { + } + + internal IAsn1Convertible ReadIndef(int tagValue) + { + // Note: INDEF => CONSTRUCTED + + // TODO There are other tags that may be constructed (e.g. BIT_STRING) + switch (tagValue) + { + case Asn1Tags.External: + return new DerExternalParser(this); + case Asn1Tags.OctetString: + return new BerOctetStringParser(this); + case Asn1Tags.Sequence: + return new BerSequenceParser(this); + case Asn1Tags.Set: + return new BerSetParser(this); + default: + throw new Asn1Exception("unknown BER object encountered: 0x" + tagValue.ToString("X")); + } + } + + internal IAsn1Convertible ReadImplicit(bool constructed, int tag) + { + if (_in is IndefiniteLengthInputStream) + { + if (!constructed) + throw new IOException("indefinite length primitive encoding encountered"); + + return ReadIndef(tag); + } + + if (constructed) + { + switch (tag) + { + case Asn1Tags.Set: + return new DerSetParser(this); + case Asn1Tags.Sequence: + return new DerSequenceParser(this); + case Asn1Tags.OctetString: + return new BerOctetStringParser(this); + } + } + else + { + switch (tag) + { + case Asn1Tags.Set: + throw new Asn1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)"); + case Asn1Tags.Sequence: + throw new Asn1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)"); + case Asn1Tags.OctetString: + return new DerOctetStringParser((DefiniteLengthInputStream)_in); + } + } + + throw new Asn1Exception("implicit tagging not implemented"); + } + + internal Asn1Object ReadTaggedObject(bool constructed, int tag) + { + if (!constructed) + { + // Note: !CONSTRUCTED => IMPLICIT + DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; + return new DerTaggedObject(false, tag, new DerOctetString(defIn.ToArray())); + } + + Asn1EncodableVector v = ReadVector(); + + if (_in is IndefiniteLengthInputStream) + { + return v.Count == 1 + ? new BerTaggedObject(true, tag, v[0]) + : new BerTaggedObject(false, tag, BerSequence.FromVector(v)); + } + + return v.Count == 1 + ? new DerTaggedObject(true, tag, v[0]) + : new DerTaggedObject(false, tag, DerSequence.FromVector(v)); + } + + public virtual IAsn1Convertible ReadObject() + { + int tag = _in.ReadByte(); + if (tag == -1) + return null; + + // turn of looking for "00" while we resolve the tag + Set00Check(false); + + // + // calculate tag number + // + int tagNo = Asn1InputStream.ReadTagNumber(_in, tag); + + bool isConstructed = (tag & Asn1Tags.Constructed) != 0; + + // + // calculate length + // + int length = Asn1InputStream.ReadLength(_in, _limit); + + if (length < 0) // indefinite length method + { + if (!isConstructed) + throw new IOException("indefinite length primitive encoding encountered"); + + IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); + Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit); + + if ((tag & Asn1Tags.Application) != 0) + { + return new BerApplicationSpecificParser(tagNo, sp); + } + + if ((tag & Asn1Tags.Tagged) != 0) + { + return new BerTaggedObjectParser(true, tagNo, sp); + } + + return sp.ReadIndef(tagNo); + } + else + { + DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length); + + if ((tag & Asn1Tags.Application) != 0) + { + return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray()); + } + + if ((tag & Asn1Tags.Tagged) != 0) + { + return new BerTaggedObjectParser(isConstructed, tagNo, new Asn1StreamParser(defIn)); + } + + if (isConstructed) + { + // TODO There are other tags that may be constructed (e.g. BitString) + switch (tagNo) + { + case Asn1Tags.OctetString: + // + // yes, people actually do this... + // + return new BerOctetStringParser(new Asn1StreamParser(defIn)); + case Asn1Tags.Sequence: + return new DerSequenceParser(new Asn1StreamParser(defIn)); + case Asn1Tags.Set: + return new DerSetParser(new Asn1StreamParser(defIn)); + case Asn1Tags.External: + return new DerExternalParser(new Asn1StreamParser(defIn)); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } + } + + // Some primitive encodings can be handled by parsers too... + switch (tagNo) + { + case Asn1Tags.OctetString: + return new DerOctetStringParser(defIn); + } + + try + { + return Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); + } + catch (ArgumentException e) + { + throw new Asn1Exception("corrupted stream detected", e); + } + } + } + + private void Set00Check( + bool enabled) + { + if (_in is IndefiniteLengthInputStream) + { + ((IndefiniteLengthInputStream) _in).SetEofOn00(enabled); + } + } + + internal Asn1EncodableVector ReadVector() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + IAsn1Convertible obj; + while ((obj = ReadObject()) != null) + { + v.Add(obj.ToAsn1Object()); + } + + return v; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs.meta new file mode 100644 index 0000000..4391f71 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1StreamParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 12d648f2463b0b34a8a0756dbb9d6bfb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs new file mode 100644 index 0000000..ba5b6da --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1TaggedObjectParser + : IAsn1Convertible + { + int TagNo { get; } + + IAsn1Convertible GetObjectParser(int tag, bool isExplicit); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs.meta new file mode 100644 index 0000000..c5f9e59 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ASN1TaggedObjectParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e183ed6c26f0fac4caebd14e56080e86 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs new file mode 100644 index 0000000..2e8c52e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Encodable + : IAsn1Convertible + { + public const string Der = "DER"; + public const string Ber = "BER"; + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + Asn1OutputStream aOut = new Asn1OutputStream(bOut); + + aOut.WriteObject(this); + + return bOut.ToArray(); + } + + public byte[] GetEncoded( + string encoding) + { + if (encoding.Equals(Der)) + { + MemoryStream bOut = new MemoryStream(); + DerOutputStream dOut = new DerOutputStream(bOut); + + dOut.WriteObject(this); + + return bOut.ToArray(); + } + + return GetEncoded(); + } + + /** + * Return the DER encoding of the object, null if the DER encoding can not be made. + * + * @return a DER byte array, null otherwise. + */ + public byte[] GetDerEncoded() + { + try + { + return GetEncoded(Der); + } + catch (IOException) + { + return null; + } + } + + public sealed override int GetHashCode() + { + return ToAsn1Object().CallAsn1GetHashCode(); + } + + public sealed override bool Equals( + object obj) + { + if (obj == this) + return true; + + IAsn1Convertible other = obj as IAsn1Convertible; + + if (other == null) + return false; + + Asn1Object o1 = ToAsn1Object(); + Asn1Object o2 = other.ToAsn1Object(); + + return o1 == o2 || o1.CallAsn1Equals(o2); + } + + public abstract Asn1Object ToAsn1Object(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs.meta new file mode 100644 index 0000000..932d4f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Encodable.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1b69b682df6ac1845b77ec1b6bf0427d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs new file mode 100644 index 0000000..6eec05d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs @@ -0,0 +1,96 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1EncodableVector + : IEnumerable + { + private IList v = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + public static Asn1EncodableVector FromEnumerable( + IEnumerable e) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + foreach (Asn1Encodable obj in e) + { + v.Add(obj); + } + return v; + } + +// public Asn1EncodableVector() +// { +// } + + public Asn1EncodableVector( + params Asn1Encodable[] v) + { + Add(v); + } + +// public void Add( +// Asn1Encodable obj) +// { +// v.Add(obj); +// } + + public void Add( + params Asn1Encodable[] objs) + { + foreach (Asn1Encodable obj in objs) + { + v.Add(obj); + } + } + + public void AddOptional( + params Asn1Encodable[] objs) + { + if (objs != null) + { + foreach (Asn1Encodable obj in objs) + { + if (obj != null) + { + v.Add(obj); + } + } + } + } + + public Asn1Encodable this[ + int index] + { + get { return (Asn1Encodable) v[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public Asn1Encodable Get( + int index) + { + return this[index]; + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return v.Count; } + } + + public int Count + { + get { return v.Count; } + } + + public IEnumerator GetEnumerator() + { + return v.GetEnumerator(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs.meta new file mode 100644 index 0000000..564586d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1EncodableVector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e3245f80405a56e41ad1c7af42022aea +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs new file mode 100644 index 0000000..de49f05 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class Asn1Exception + : IOException + { + public Asn1Exception() + : base() + { + } + + public Asn1Exception( + string message) + : base(message) + { + } + + public Asn1Exception( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs.meta new file mode 100644 index 0000000..e69a0f8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Exception.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bbd822b3cbfd4b643a313c46df1ee0a7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs new file mode 100644 index 0000000..5ccf0a5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs @@ -0,0 +1,374 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * a general purpose ASN.1 decoder - note: this class differs from the + * others in that it returns null after it has read the last object in + * the stream. If an ASN.1 Null is encountered a Der/BER Null object is + * returned. + */ + public class Asn1InputStream + : FilterStream + { + private readonly int limit; + + private readonly byte[][] tmpBuffers; + + internal static int FindLimit(Stream input) + { + if (input is LimitedInputStream) + { + return ((LimitedInputStream)input).GetRemaining(); + } + else if (input is MemoryStream) + { + MemoryStream mem = (MemoryStream)input; + return (int)(mem.Length - mem.Position); + } + + return int.MaxValue; + } + + public Asn1InputStream( + Stream inputStream) + : this(inputStream, FindLimit(inputStream)) + { + } + + /** + * Create an ASN1InputStream where no DER object will be longer than limit. + * + * @param input stream containing ASN.1 encoded data. + * @param limit maximum size of a DER encoded object. + */ + public Asn1InputStream( + Stream inputStream, + int limit) + : base(inputStream) + { + this.limit = limit; + this.tmpBuffers = new byte[16][]; + } + + /** + * Create an ASN1InputStream based on the input byte array. The length of DER objects in + * the stream is automatically limited to the length of the input array. + * + * @param input array containing ASN.1 encoded data. + */ + public Asn1InputStream( + byte[] input) + : this(new MemoryStream(input, false), input.Length) + { + } + + /** + * build an object given its tag and the number of bytes to construct it from. + */ + private Asn1Object BuildObject( + int tag, + int tagNo, + int length) + { + bool isConstructed = (tag & Asn1Tags.Constructed) != 0; + + DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this.s, length); + + if ((tag & Asn1Tags.Application) != 0) + { + return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray()); + } + + if ((tag & Asn1Tags.Tagged) != 0) + { + return new Asn1StreamParser(defIn).ReadTaggedObject(isConstructed, tagNo); + } + + if (isConstructed) + { + // TODO There are other tags that may be constructed (e.g. BitString) + switch (tagNo) + { + case Asn1Tags.OctetString: + // + // yes, people actually do this... + // + return new BerOctetString(BuildDerEncodableVector(defIn)); + case Asn1Tags.Sequence: + return CreateDerSequence(defIn); + case Asn1Tags.Set: + return CreateDerSet(defIn); + case Asn1Tags.External: + return new DerExternal(BuildDerEncodableVector(defIn)); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } + } + + return CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); + } + + internal Asn1EncodableVector BuildEncodableVector() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + Asn1Object o; + while ((o = ReadObject()) != null) + { + v.Add(o); + } + + return v; + } + + internal virtual Asn1EncodableVector BuildDerEncodableVector( + DefiniteLengthInputStream dIn) + { + return new Asn1InputStream(dIn).BuildEncodableVector(); + } + + internal virtual DerSequence CreateDerSequence( + DefiniteLengthInputStream dIn) + { + return DerSequence.FromVector(BuildDerEncodableVector(dIn)); + } + + internal virtual DerSet CreateDerSet( + DefiniteLengthInputStream dIn) + { + return DerSet.FromVector(BuildDerEncodableVector(dIn), false); + } + + public Asn1Object ReadObject() + { + int tag = ReadByte(); + if (tag <= 0) + { + if (tag == 0) + throw new IOException("unexpected end-of-contents marker"); + + return null; + } + + // + // calculate tag number + // + int tagNo = ReadTagNumber(this.s, tag); + + bool isConstructed = (tag & Asn1Tags.Constructed) != 0; + + // + // calculate length + // + int length = ReadLength(this.s, limit); + + if (length < 0) // indefinite length method + { + if (!isConstructed) + throw new IOException("indefinite length primitive encoding encountered"); + + IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this.s, limit); + Asn1StreamParser sp = new Asn1StreamParser(indIn, limit); + + if ((tag & Asn1Tags.Application) != 0) + { + return new BerApplicationSpecificParser(tagNo, sp).ToAsn1Object(); + } + + if ((tag & Asn1Tags.Tagged) != 0) + { + return new BerTaggedObjectParser(true, tagNo, sp).ToAsn1Object(); + } + + // TODO There are other tags that may be constructed (e.g. BitString) + switch (tagNo) + { + case Asn1Tags.OctetString: + return new BerOctetStringParser(sp).ToAsn1Object(); + case Asn1Tags.Sequence: + return new BerSequenceParser(sp).ToAsn1Object(); + case Asn1Tags.Set: + return new BerSetParser(sp).ToAsn1Object(); + case Asn1Tags.External: + return new DerExternalParser(sp).ToAsn1Object(); + default: + throw new IOException("unknown BER object encountered"); + } + } + else + { + try + { + return BuildObject(tag, tagNo, length); + } + catch (ArgumentException e) + { + throw new Asn1Exception("corrupted stream detected", e); + } + } + } + + internal static int ReadTagNumber( + Stream s, + int tag) + { + int tagNo = tag & 0x1f; + + // + // with tagged object tag number is bottom 5 bits, or stored at the start of the content + // + if (tagNo == 0x1f) + { + tagNo = 0; + + int b = s.ReadByte(); + + // X.690-0207 8.1.2.4.2 + // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." + if ((b & 0x7f) == 0) // Note: -1 will pass + { + throw new IOException("Corrupted stream - invalid high tag number found"); + } + + while ((b >= 0) && ((b & 0x80) != 0)) + { + tagNo |= (b & 0x7f); + tagNo <<= 7; + b = s.ReadByte(); + } + + if (b < 0) + throw new EndOfStreamException("EOF found inside tag value."); + + tagNo |= (b & 0x7f); + } + + return tagNo; + } + + internal static int ReadLength( + Stream s, + int limit) + { + int length = s.ReadByte(); + if (length < 0) + throw new EndOfStreamException("EOF found when length expected"); + + if (length == 0x80) + return -1; // indefinite-length encoding + + if (length > 127) + { + int size = length & 0x7f; + + // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here + if (size > 4) + throw new IOException("DER length more than 4 bytes: " + size); + + length = 0; + for (int i = 0; i < size; i++) + { + int next = s.ReadByte(); + + if (next < 0) + throw new EndOfStreamException("EOF found reading length"); + + length = (length << 8) + next; + } + + if (length < 0) + throw new IOException("Corrupted stream - negative length found"); + + if (length >= limit) // after all we must have read at least 1 byte + throw new IOException("Corrupted stream - out of bounds length found"); + } + + return length; + } + + internal static byte[] GetBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) + { + int len = defIn.GetRemaining(); + if (len >= tmpBuffers.Length) + { + return defIn.ToArray(); + } + + byte[] buf = tmpBuffers[len]; + if (buf == null) + { + buf = tmpBuffers[len] = new byte[len]; + } + + defIn.ReadAllIntoByteArray(buf); + + return buf; + } + + internal static Asn1Object CreatePrimitiveDerObject( + int tagNo, + DefiniteLengthInputStream defIn, + byte[][] tmpBuffers) + { + switch (tagNo) + { + case Asn1Tags.Boolean: + return DerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers)); + case Asn1Tags.Enumerated: + return DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers)); + case Asn1Tags.ObjectIdentifier: + return DerObjectIdentifier.FromOctetString(GetBuffer(defIn, tmpBuffers)); + } + + byte[] bytes = defIn.ToArray(); + + switch (tagNo) + { + case Asn1Tags.BitString: + return DerBitString.FromAsn1Octets(bytes); + case Asn1Tags.BmpString: + return new DerBmpString(bytes); + case Asn1Tags.GeneralizedTime: + return new DerGeneralizedTime(bytes); + case Asn1Tags.GeneralString: + return new DerGeneralString(bytes); + case Asn1Tags.GraphicString: + return new DerGraphicString(bytes); + case Asn1Tags.IA5String: + return new DerIA5String(bytes); + case Asn1Tags.Integer: + return new DerInteger(bytes); + case Asn1Tags.Null: + return DerNull.Instance; // actual content is ignored (enforce 0 length?) + case Asn1Tags.NumericString: + return new DerNumericString(bytes); + case Asn1Tags.OctetString: + return new DerOctetString(bytes); + case Asn1Tags.PrintableString: + return new DerPrintableString(bytes); + case Asn1Tags.T61String: + return new DerT61String(bytes); + case Asn1Tags.UniversalString: + return new DerUniversalString(bytes); + case Asn1Tags.UtcTime: + return new DerUtcTime(bytes); + case Asn1Tags.Utf8String: + return new DerUtf8String(bytes); + case Asn1Tags.VideotexString: + return new DerVideotexString(bytes); + case Asn1Tags.VisibleString: + return new DerVisibleString(bytes); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs.meta new file mode 100644 index 0000000..5b52f9c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1InputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e252ac704e464264d8409a56a0bb3eb3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs new file mode 100644 index 0000000..cd96f38 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + /** + * A Null object. + */ + public abstract class Asn1Null + : Asn1Object + { + internal Asn1Null() + { + } + + public override string ToString() + { + return "NULL"; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs.meta new file mode 100644 index 0000000..d949309 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Null.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2b6ffeb7c543040429c96c7fa0041261 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs new file mode 100644 index 0000000..2b549a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs @@ -0,0 +1,71 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Object + : Asn1Encodable + { + /// Create a base ASN.1 object from a byte array. + /// The byte array to parse. + /// The base ASN.1 object represented by the byte array. + /// If there is a problem parsing the data. + public static Asn1Object FromByteArray( + byte[] data) + { + try + { + MemoryStream input = new MemoryStream(data, false); + Asn1InputStream asn1 = new Asn1InputStream(input, data.Length); + Asn1Object result = asn1.ReadObject(); + if (input.Position != input.Length) + throw new IOException("extra data found after object"); + return result; + } + catch (InvalidCastException) + { + throw new IOException("cannot recognise object in byte array"); + } + } + + /// Read a base ASN.1 object from a stream. + /// The stream to parse. + /// The base ASN.1 object represented by the byte array. + /// If there is a problem parsing the data. + public static Asn1Object FromStream( + Stream inStr) + { + try + { + return new Asn1InputStream(inStr).ReadObject(); + } + catch (InvalidCastException) + { + throw new IOException("cannot recognise object in stream"); + } + } + + public sealed override Asn1Object ToAsn1Object() + { + return this; + } + + internal abstract void Encode(DerOutputStream derOut); + + protected abstract bool Asn1Equals(Asn1Object asn1Object); + protected abstract int Asn1GetHashCode(); + + internal bool CallAsn1Equals(Asn1Object obj) + { + return Asn1Equals(obj); + } + + internal int CallAsn1GetHashCode() + { + return Asn1GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs.meta new file mode 100644 index 0000000..711c891 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Object.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 86b4801bceb05f54ab0490784feb75c1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs new file mode 100644 index 0000000..5d80117 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs @@ -0,0 +1,122 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1OctetString + : Asn1Object, Asn1OctetStringParser + { + internal byte[] str; + + /** + * return an Octet string from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1OctetString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is Asn1OctetString) + { + return GetInstance(o); + } + + return BerOctetString.FromSequence(Asn1Sequence.GetInstance(o)); + } + + /** + * return an Octet string from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1OctetString GetInstance(object obj) + { + if (obj == null || obj is Asn1OctetString) + { + return (Asn1OctetString)obj; + } + + // TODO: this needs to be deleted in V2 + if (obj is Asn1TaggedObject) + return GetInstance(((Asn1TaggedObject)obj).GetObject()); + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * @param string the octets making up the octet string. + */ + internal Asn1OctetString( + byte[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + internal Asn1OctetString( + Asn1Encodable obj) + { + try + { + this.str = obj.GetEncoded(Asn1Encodable.Der); + } + catch (IOException e) + { + throw new ArgumentException("Error processing object : " + e.ToString()); + } + } + + public Stream GetOctetStream() + { + return new MemoryStream(str, false); + } + + public Asn1OctetStringParser Parser + { + get { return this; } + } + + public virtual byte[] GetOctets() + { + return str; + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerOctetString other = asn1Object as DerOctetString; + + if (other == null) + return false; + + return Arrays.AreEqual(GetOctets(), other.GetOctets()); + } + + public override string ToString() + { + return "#" + Hex.ToHexString(str); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs.meta new file mode 100644 index 0000000..58a6662 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OctetString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 605a6b277ffde7640a895840c2243816 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs new file mode 100644 index 0000000..7edf8cc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs @@ -0,0 +1,38 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1OutputStream + : DerOutputStream + { + public Asn1OutputStream(Stream os) : base(os) + { + } + + [Obsolete("Use version taking an Asn1Encodable arg instead")] + public override void WriteObject( + object obj) + { + if (obj == null) + { + WriteNull(); + } + else if (obj is Asn1Object) + { + ((Asn1Object)obj).Encode(this); + } + else if (obj is Asn1Encodable) + { + ((Asn1Encodable)obj).ToAsn1Object().Encode(this); + } + else + { + throw new IOException("object not Asn1Encodable"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs.meta new file mode 100644 index 0000000..7cf85e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1OutputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ca2e340a1bd44254cac396effbb16cda +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs new file mode 100644 index 0000000..3d82dd8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs @@ -0,0 +1,32 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1 +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class Asn1ParsingException + : InvalidOperationException + { + public Asn1ParsingException() + : base() + { + } + + public Asn1ParsingException( + string message) + : base(message) + { + } + + public Asn1ParsingException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs.meta new file mode 100644 index 0000000..a1aaf07 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1ParsingException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e565a5f2f13a702468596b17c248ac68 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs new file mode 100644 index 0000000..6cfcf31 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs @@ -0,0 +1,271 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Sequence + : Asn1Object, IEnumerable + { + private readonly IList seq; + + /** + * return an Asn1Sequence from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1Sequence GetInstance( + object obj) + { + if (obj == null || obj is Asn1Sequence) + { + return (Asn1Sequence)obj; + } + else if (obj is Asn1SequenceParser) + { + return Asn1Sequence.GetInstance(((Asn1SequenceParser)obj).ToAsn1Object()); + } + else if (obj is byte[]) + { + try + { + return Asn1Sequence.GetInstance(FromByteArray((byte[])obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message); + } + } + else if (obj is Asn1Encodable) + { + Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); + + if (primitive is Asn1Sequence) + { + return (Asn1Sequence)primitive; + } + } + + throw new ArgumentException("Unknown object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * Return an ASN1 sequence from a tagged object. There is a special + * case here, if an object appears to have been explicitly tagged on + * reading but we were expecting it to be implicitly tagged in the + * normal course of events it indicates that we lost the surrounding + * sequence - so we need to add it back (this will happen if the tagged + * object is a sequence that contains other sequences). If you are + * dealing with implicitly tagged sequences you really should + * be using this method. + * + * @param obj the tagged object. + * @param explicitly true if the object is meant to be explicitly tagged, + * false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1Sequence GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + Asn1Object inner = obj.GetObject(); + + if (explicitly) + { + if (!obj.IsExplicit()) + throw new ArgumentException("object implicit - explicit expected."); + + return (Asn1Sequence) inner; + } + + // + // constructed object which appears to be explicitly tagged + // when it should be implicit means we have to add the + // surrounding sequence. + // + if (obj.IsExplicit()) + { + if (obj is BerTaggedObject) + { + return new BerSequence(inner); + } + + return new DerSequence(inner); + } + + if (inner is Asn1Sequence) + { + return (Asn1Sequence) inner; + } + + throw new ArgumentException("Unknown object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + protected internal Asn1Sequence( + int capacity) + { + seq = Org.BouncyCastle.Utilities.Platform.CreateArrayList(capacity); + } + + public virtual IEnumerator GetEnumerator() + { + return seq.GetEnumerator(); + } + + [Obsolete("Use GetEnumerator() instead")] + public IEnumerator GetObjects() + { + return GetEnumerator(); + } + + private class Asn1SequenceParserImpl + : Asn1SequenceParser + { + private readonly Asn1Sequence outer; + private readonly int max; + private int index; + + public Asn1SequenceParserImpl( + Asn1Sequence outer) + { + this.outer = outer; + this.max = outer.Count; + } + + public IAsn1Convertible ReadObject() + { + if (index == max) + return null; + + Asn1Encodable obj = outer[index++]; + + if (obj is Asn1Sequence) + return ((Asn1Sequence)obj).Parser; + + if (obj is Asn1Set) + return ((Asn1Set)obj).Parser; + + // NB: Asn1OctetString implements Asn1OctetStringParser directly +// if (obj is Asn1OctetString) +// return ((Asn1OctetString)obj).Parser; + + return obj; + } + + public Asn1Object ToAsn1Object() + { + return outer; + } + } + + public virtual Asn1SequenceParser Parser + { + get { return new Asn1SequenceParserImpl(this); } + } + + /** + * return the object at the sequence position indicated by index. + * + * @param index the sequence number (starting at zero) of the object + * @return the object at the sequence position indicated by index. + */ + public virtual Asn1Encodable this[int index] + { + get { return (Asn1Encodable) seq[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public Asn1Encodable GetObjectAt( + int index) + { + return this[index]; + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return Count; } + } + + public virtual int Count + { + get { return seq.Count; } + } + + protected override int Asn1GetHashCode() + { + int hc = Count; + + foreach (object o in this) + { + hc *= 17; + if (o == null) + { + hc ^= DerNull.Instance.GetHashCode(); + } + else + { + hc ^= o.GetHashCode(); + } + } + + return hc; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + Asn1Sequence other = asn1Object as Asn1Sequence; + + if (other == null) + return false; + + if (Count != other.Count) + return false; + + IEnumerator s1 = GetEnumerator(); + IEnumerator s2 = other.GetEnumerator(); + + while (s1.MoveNext() && s2.MoveNext()) + { + Asn1Object o1 = GetCurrent(s1).ToAsn1Object(); + Asn1Object o2 = GetCurrent(s2).ToAsn1Object(); + + if (!o1.Equals(o2)) + return false; + } + + return true; + } + + private Asn1Encodable GetCurrent(IEnumerator e) + { + Asn1Encodable encObj = (Asn1Encodable)e.Current; + + // unfortunately null was allowed as a substitute for DER null + if (encObj == null) + return DerNull.Instance; + + return encObj; + } + + protected internal void AddObject( + Asn1Encodable obj) + { + seq.Add(obj); + } + + public override string ToString() + { + return CollectionUtilities.ToString(seq); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs.meta new file mode 100644 index 0000000..bdd1f16 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Sequence.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 251efabb5e3250d49ad3fb7b45d68d01 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs new file mode 100644 index 0000000..e9f8f55 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs @@ -0,0 +1,375 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; + +#if PORTABLE || NETFX_CORE +using System.Collections.Generic; +using System.Linq; +#endif + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + abstract public class Asn1Set + : Asn1Object, IEnumerable + { + private readonly IList _set; + + /** + * return an ASN1Set from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1Set GetInstance( + object obj) + { + if (obj == null || obj is Asn1Set) + { + return (Asn1Set)obj; + } + else if (obj is Asn1SetParser) + { + return Asn1Set.GetInstance(((Asn1SetParser)obj).ToAsn1Object()); + } + else if (obj is byte[]) + { + try + { + return Asn1Set.GetInstance(FromByteArray((byte[])obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct set from byte[]: " + e.Message); + } + } + else if (obj is Asn1Encodable) + { + Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); + + if (primitive is Asn1Set) + { + return (Asn1Set)primitive; + } + } + + throw new ArgumentException("Unknown object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * Return an ASN1 set from a tagged object. There is a special + * case here, if an object appears to have been explicitly tagged on + * reading but we were expecting it to be implicitly tagged in the + * normal course of events it indicates that we lost the surrounding + * set - so we need to add it back (this will happen if the tagged + * object is a sequence that contains other sequences). If you are + * dealing with implicitly tagged sets you really should + * be using this method. + * + * @param obj the tagged object. + * @param explicitly true if the object is meant to be explicitly tagged + * false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1Set GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + Asn1Object inner = obj.GetObject(); + + if (explicitly) + { + if (!obj.IsExplicit()) + throw new ArgumentException("object implicit - explicit expected."); + + return (Asn1Set) inner; + } + + // + // constructed object which appears to be explicitly tagged + // and it's really implicit means we have to add the + // surrounding sequence. + // + if (obj.IsExplicit()) + { + return new DerSet(inner); + } + + if (inner is Asn1Set) + { + return (Asn1Set) inner; + } + + // + // in this case the parser returns a sequence, convert it + // into a set. + // + if (inner is Asn1Sequence) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1Sequence s = (Asn1Sequence) inner; + + foreach (Asn1Encodable ae in s) + { + v.Add(ae); + } + + // TODO Should be able to construct set directly from sequence? + return new DerSet(v, false); + } + + throw new ArgumentException("Unknown object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + protected internal Asn1Set( + int capacity) + { + _set = Org.BouncyCastle.Utilities.Platform.CreateArrayList(capacity); + } + + public virtual IEnumerator GetEnumerator() + { + return _set.GetEnumerator(); + } + + [Obsolete("Use GetEnumerator() instead")] + public IEnumerator GetObjects() + { + return GetEnumerator(); + } + + /** + * return the object at the set position indicated by index. + * + * @param index the set number (starting at zero) of the object + * @return the object at the set position indicated by index. + */ + public virtual Asn1Encodable this[int index] + { + get { return (Asn1Encodable) _set[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public Asn1Encodable GetObjectAt( + int index) + { + return this[index]; + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return Count; } + } + + public virtual int Count + { + get { return _set.Count; } + } + + public virtual Asn1Encodable[] ToArray() + { + Asn1Encodable[] values = new Asn1Encodable[this.Count]; + for (int i = 0; i < this.Count; ++i) + { + values[i] = this[i]; + } + return values; + } + + private class Asn1SetParserImpl + : Asn1SetParser + { + private readonly Asn1Set outer; + private readonly int max; + private int index; + + public Asn1SetParserImpl( + Asn1Set outer) + { + this.outer = outer; + this.max = outer.Count; + } + + public IAsn1Convertible ReadObject() + { + if (index == max) + return null; + + Asn1Encodable obj = outer[index++]; + if (obj is Asn1Sequence) + return ((Asn1Sequence)obj).Parser; + + if (obj is Asn1Set) + return ((Asn1Set)obj).Parser; + + // NB: Asn1OctetString implements Asn1OctetStringParser directly +// if (obj is Asn1OctetString) +// return ((Asn1OctetString)obj).Parser; + + return obj; + } + + public virtual Asn1Object ToAsn1Object() + { + return outer; + } + } + + public Asn1SetParser Parser + { + get { return new Asn1SetParserImpl(this); } + } + + protected override int Asn1GetHashCode() + { + int hc = Count; + + foreach (object o in this) + { + hc *= 17; + if (o == null) + { + hc ^= DerNull.Instance.GetHashCode(); + } + else + { + hc ^= o.GetHashCode(); + } + } + + return hc; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + Asn1Set other = asn1Object as Asn1Set; + + if (other == null) + return false; + + if (Count != other.Count) + { + return false; + } + + IEnumerator s1 = GetEnumerator(); + IEnumerator s2 = other.GetEnumerator(); + + while (s1.MoveNext() && s2.MoveNext()) + { + Asn1Object o1 = GetCurrent(s1).ToAsn1Object(); + Asn1Object o2 = GetCurrent(s2).ToAsn1Object(); + + if (!o1.Equals(o2)) + return false; + } + + return true; + } + + private Asn1Encodable GetCurrent(IEnumerator e) + { + Asn1Encodable encObj = (Asn1Encodable)e.Current; + + // unfortunately null was allowed as a substitute for DER null + if (encObj == null) + return DerNull.Instance; + + return encObj; + } + + protected internal void Sort() + { + if (_set.Count < 2) + return; + +#if PORTABLE || NETFX_CORE + var sorted = _set.Cast() + .Select(a => new { Item = a, Key = a.GetEncoded(Asn1Encodable.Der) }) + .OrderBy(t => t.Key, new DerComparer()) + .Select(t => t.Item) + .ToList(); + + for (int i = 0; i < _set.Count; ++i) + { + _set[i] = sorted[i]; + } +#else + Asn1Encodable[] items = new Asn1Encodable[_set.Count]; + byte[][] keys = new byte[_set.Count][]; + + for (int i = 0; i < _set.Count; ++i) + { + Asn1Encodable item = (Asn1Encodable)_set[i]; + items[i] = item; + keys[i] = item.GetEncoded(Asn1Encodable.Der); + } + + Array.Sort(keys, items, new DerComparer()); + + for (int i = 0; i < _set.Count; ++i) + { + _set[i] = items[i]; + } +#endif + } + + protected internal void AddObject(Asn1Encodable obj) + { + _set.Add(obj); + } + + public override string ToString() + { + return CollectionUtilities.ToString(_set); + } + +#if PORTABLE || NETFX_CORE + private class DerComparer + : IComparer + { + public int Compare(byte[] x, byte[] y) + { + byte[] a = x, b = y; +#else + private class DerComparer + : IComparer + { + public int Compare(object x, object y) + { + byte[] a = (byte[])x, b = (byte[])y; +#endif + int len = System.Math.Min(a.Length, b.Length); + for (int i = 0; i != len; ++i) + { + byte ai = a[i], bi = b[i]; + if (ai != bi) + return ai < bi ? -1 : 1; + } + if (a.Length > b.Length) + return AllZeroesFrom(a, len) ? 0 : 1; + if (a.Length < b.Length) + return AllZeroesFrom(b, len) ? 0 : -1; + return 0; + } + + private bool AllZeroesFrom(byte[] bs, int pos) + { + while (pos < bs.Length) + { + if (bs[pos++] != 0) + return false; + } + return true; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs.meta new file mode 100644 index 0000000..5557985 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Set.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: db687a85bbc7c7240b1b2f57359d0c46 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs new file mode 100644 index 0000000..aa30ec4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs @@ -0,0 +1,191 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ + public abstract class Asn1TaggedObject + : Asn1Object, Asn1TaggedObjectParser + { + internal static bool IsConstructed(bool isExplicit, Asn1Object obj) + { + if (isExplicit || obj is Asn1Sequence || obj is Asn1Set) + return true; + Asn1TaggedObject tagged = obj as Asn1TaggedObject; + if (tagged == null) + return false; + return IsConstructed(tagged.IsExplicit(), tagged.GetObject()); + } + + internal int tagNo; +// internal bool empty; + internal bool explicitly = true; + internal Asn1Encodable obj; + + static public Asn1TaggedObject GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + if (explicitly) + { + return (Asn1TaggedObject) obj.GetObject(); + } + + throw new ArgumentException("implicitly tagged tagged object"); + } + + static public Asn1TaggedObject GetInstance( + object obj) + { + if (obj == null || obj is Asn1TaggedObject) + { + return (Asn1TaggedObject) obj; + } + + throw new ArgumentException("Unknown object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + protected Asn1TaggedObject( + int tagNo, + Asn1Encodable obj) + { + this.explicitly = true; + this.tagNo = tagNo; + this.obj = obj; + } + + /** + * @param explicitly true if the object is explicitly tagged. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + protected Asn1TaggedObject( + bool explicitly, + int tagNo, + Asn1Encodable obj) + { + // IAsn1Choice marker interface 'insists' on explicit tagging + this.explicitly = explicitly || (obj is IAsn1Choice); + this.tagNo = tagNo; + this.obj = obj; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + Asn1TaggedObject other = asn1Object as Asn1TaggedObject; + + if (other == null) + return false; + + return this.tagNo == other.tagNo +// && this.empty == other.empty + && this.explicitly == other.explicitly // TODO Should this be part of equality? + && Org.BouncyCastle.Utilities.Platform.Equals(GetObject(), other.GetObject()); + } + + protected override int Asn1GetHashCode() + { + int code = tagNo.GetHashCode(); + + // TODO: actually this is wrong - the problem is that a re-encoded + // object may end up with a different hashCode due to implicit + // tagging. As implicit tagging is ambiguous if a sequence is involved + // it seems the only correct method for both equals and hashCode is to + // compare the encodings... +// code ^= explicitly.GetHashCode(); + + if (obj != null) + { + code ^= obj.GetHashCode(); + } + + return code; + } + + public int TagNo + { + get { return tagNo; } + } + + /** + * return whether or not the object may be explicitly tagged. + *

+ * Note: if the object has been read from an input stream, the only + * time you can be sure if isExplicit is returning the true state of + * affairs is if it returns false. An implicitly tagged object may appear + * to be explicitly tagged, so you need to understand the context under + * which the reading was done as well, see GetObject below.

+ */ + public bool IsExplicit() + { + return explicitly; + } + + public bool IsEmpty() + { + return false; //empty; + } + + /** + * return whatever was following the tag. + *

+ * Note: tagged objects are generally context dependent if you're + * trying to extract a tagged object you should be going via the + * appropriate GetInstance method.

+ */ + public Asn1Object GetObject() + { + if (obj != null) + { + return obj.ToAsn1Object(); + } + + return null; + } + + /** + * Return the object held in this tagged object as a parser assuming it has + * the type of the passed in tag. If the object doesn't have a parser + * associated with it, the base object is returned. + */ + public IAsn1Convertible GetObjectParser( + int tag, + bool isExplicit) + { + switch (tag) + { + case Asn1Tags.Set: + return Asn1Set.GetInstance(this, isExplicit).Parser; + case Asn1Tags.Sequence: + return Asn1Sequence.GetInstance(this, isExplicit).Parser; + case Asn1Tags.OctetString: + return Asn1OctetString.GetInstance(this, isExplicit).Parser; + } + + if (isExplicit) + { + return GetObject(); + } + + throw Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("implicit tagging for tag: " + tag); + } + + public override string ToString() + { + return "[" + tagNo + "]" + obj; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs.meta new file mode 100644 index 0000000..f79ac35 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1TaggedObject.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8dc761d7a5e48814998a495824555f3a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs new file mode 100644 index 0000000..c8aaccf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs @@ -0,0 +1,39 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1Tags + { + public const int Boolean = 0x01; + public const int Integer = 0x02; + public const int BitString = 0x03; + public const int OctetString = 0x04; + public const int Null = 0x05; + public const int ObjectIdentifier = 0x06; + public const int External = 0x08; + public const int Enumerated = 0x0a; + public const int Sequence = 0x10; + public const int SequenceOf = 0x10; // for completeness + public const int Set = 0x11; + public const int SetOf = 0x11; // for completeness + + public const int NumericString = 0x12; + public const int PrintableString = 0x13; + public const int T61String = 0x14; + public const int VideotexString = 0x15; + public const int IA5String = 0x16; + public const int UtcTime = 0x17; + public const int GeneralizedTime = 0x18; + public const int GraphicString = 0x19; + public const int VisibleString = 0x1a; + public const int GeneralString = 0x1b; + public const int UniversalString = 0x1c; + public const int BmpString = 0x1e; + public const int Utf8String = 0x0c; + + public const int Constructed = 0x20; + public const int Application = 0x40; + public const int Tagged = 0x80; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs.meta new file mode 100644 index 0000000..d8ad88f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/Asn1Tags.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1d609f8d10b0a5c469fd85eb4b389e30 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs new file mode 100644 index 0000000..f93ea4c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs @@ -0,0 +1,46 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerBitString + : DerBitString + { + public BerBitString(byte[] data, int padBits) + : base(data, padBits) + { + } + + public BerBitString(byte[] data) + : base(data) + { + } + + public BerBitString(int namedBits) + : base(namedBits) + { + } + + public BerBitString(Asn1Encodable obj) + : base(obj) + { + } + + internal override void Encode( + DerOutputStream derOut) + { + if (derOut is Asn1OutputStream || derOut is BerOutputStream) + { + derOut.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData); + } + else + { + base.Encode(derOut); + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs.meta new file mode 100644 index 0000000..509f2c7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERBitString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2e6d38188b772c2409c7dad9240d601a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs new file mode 100644 index 0000000..07c0dac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerGenerator + : Asn1Generator + { + private bool _tagged = false; + private bool _isExplicit; + private int _tagNo; + + protected BerGenerator( + Stream outStream) + : base(outStream) + { + } + + public BerGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream) + { + _tagged = true; + _isExplicit = isExplicit; + _tagNo = tagNo; + } + + public override void AddObject( + Asn1Encodable obj) + { + new BerOutputStream(Out).WriteObject(obj); + } + + public override Stream GetRawOutputStream() + { + return Out; + } + + public override void Close() + { + WriteBerEnd(); + } + + private void WriteHdr( + int tag) + { + Out.WriteByte((byte) tag); + Out.WriteByte(0x80); + } + + protected void WriteBerHeader( + int tag) + { + if (_tagged) + { + int tagNum = _tagNo | Asn1Tags.Tagged; + + if (_isExplicit) + { + WriteHdr(tagNum | Asn1Tags.Constructed); + WriteHdr(tag); + } + else + { + if ((tag & Asn1Tags.Constructed) != 0) + { + WriteHdr(tagNum | Asn1Tags.Constructed); + } + else + { + WriteHdr(tagNum); + } + } + } + else + { + WriteHdr(tag); + } + } + + protected void WriteBerBody( + Stream contentStream) + { + Streams.PipeAll(contentStream, Out); + } + + protected void WriteBerEnd() + { + Out.WriteByte(0x00); + Out.WriteByte(0x00); + + if (_tagged && _isExplicit) // write extra end for tag header + { + Out.WriteByte(0x00); + Out.WriteByte(0x00); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs.meta new file mode 100644 index 0000000..a535beb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ebf471a1d43735f4aa2425eda406c2d7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs new file mode 100644 index 0000000..b65d708 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs @@ -0,0 +1,39 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerOctetStringParser + : Asn1OctetStringParser + { + private readonly Asn1StreamParser _parser; + + internal BerOctetStringParser( + Asn1StreamParser parser) + { + _parser = parser; + } + + public Stream GetOctetStream() + { + return new ConstructedOctetStream(_parser); + } + + public Asn1Object ToAsn1Object() + { + try + { + return new BerOctetString(Streams.ReadAll(GetOctetStream())); + } + catch (IOException e) + { + throw new Asn1ParsingException("IOException converting stream to byte array: " + e.Message, e); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs.meta new file mode 100644 index 0000000..7df8231 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BEROctetStringParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f349002b9962c3f449219681235b114a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs new file mode 100644 index 0000000..94b225e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSequenceGenerator + : BerGenerator + { + public BerSequenceGenerator( + Stream outStream) + : base(outStream) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence); + } + + public BerSequenceGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs.meta new file mode 100644 index 0000000..e8983a8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 39e69b682926f0348a2f183f3d1c8913 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs new file mode 100644 index 0000000..d9240f9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class BerSequenceParser + : Asn1SequenceParser + { + private readonly Asn1StreamParser _parser; + + internal BerSequenceParser( + Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new BerSequence(_parser.ReadVector()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs.meta new file mode 100644 index 0000000..f9678b5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSequenceParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6d593cc0e2b63d14a8aeed9ce0369876 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs new file mode 100644 index 0000000..fca37aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSetGenerator + : BerGenerator + { + public BerSetGenerator( + Stream outStream) + : base(outStream) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set); + } + + public BerSetGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs.meta new file mode 100644 index 0000000..eff3d24 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0fbdbc3f5ccf9f446b5a5b30159adca1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs new file mode 100644 index 0000000..1449c83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class BerSetParser + : Asn1SetParser + { + private readonly Asn1StreamParser _parser; + + internal BerSetParser( + Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new BerSet(_parser.ReadVector(), false); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs.meta new file mode 100644 index 0000000..98b7c63 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERSetParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0260d4642cd5cf94c965eb9cd0ea9635 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs new file mode 100644 index 0000000..0db0f17 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs @@ -0,0 +1,74 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerTaggedObjectParser + : Asn1TaggedObjectParser + { + private bool _constructed; + private int _tagNumber; + private Asn1StreamParser _parser; + + [Obsolete] + internal BerTaggedObjectParser( + int baseTag, + int tagNumber, + Stream contentStream) + : this((baseTag & Asn1Tags.Constructed) != 0, tagNumber, new Asn1StreamParser(contentStream)) + { + } + + internal BerTaggedObjectParser( + bool constructed, + int tagNumber, + Asn1StreamParser parser) + { + _constructed = constructed; + _tagNumber = tagNumber; + _parser = parser; + } + + public bool IsConstructed + { + get { return _constructed; } + } + + public int TagNo + { + get { return _tagNumber; } + } + + public IAsn1Convertible GetObjectParser( + int tag, + bool isExplicit) + { + if (isExplicit) + { + if (!_constructed) + throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); + + return _parser.ReadObject(); + } + + return _parser.ReadImplicit(_constructed, tag); + } + + public Asn1Object ToAsn1Object() + { + try + { + return _parser.ReadTaggedObject(_constructed, _tagNumber); + } + catch (IOException e) + { + throw new Asn1ParsingException(e.Message); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs.meta new file mode 100644 index 0000000..16e3a72 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BERTaggedObjectParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 59190053596d8924a9902581e3b94f46 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs new file mode 100644 index 0000000..c6baa10 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerApplicationSpecific + : DerApplicationSpecific + { + public BerApplicationSpecific( + int tagNo, + Asn1EncodableVector vec) + : base(tagNo, vec) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs.meta new file mode 100644 index 0000000..2554e80 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecific.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e34e4ccb03d83c34393d6d2588965d04 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs new file mode 100644 index 0000000..a06a24e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs @@ -0,0 +1,32 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerApplicationSpecificParser + : IAsn1ApplicationSpecificParser + { + private readonly int tag; + private readonly Asn1StreamParser parser; + + internal BerApplicationSpecificParser( + int tag, + Asn1StreamParser parser) + { + this.tag = tag; + this.parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new BerApplicationSpecific(tag, parser.ReadVector()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs.meta new file mode 100644 index 0000000..ff56763 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerApplicationSpecificParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 584fba93d29d0d84da6c0b7606076a8a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs new file mode 100644 index 0000000..3b79bd6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs @@ -0,0 +1,138 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerOctetString + : DerOctetString, IEnumerable + { + public static BerOctetString FromSequence(Asn1Sequence seq) + { + IList v = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + foreach (Asn1Encodable obj in seq) + { + v.Add(obj); + } + + return new BerOctetString(v); + } + + private const int MaxLength = 1000; + + /** + * convert a vector of octet strings into a single byte string + */ + private static byte[] ToBytes( + IEnumerable octs) + { + MemoryStream bOut = new MemoryStream(); + foreach (DerOctetString o in octs) + { + byte[] octets = o.GetOctets(); + bOut.Write(octets, 0, octets.Length); + } + return bOut.ToArray(); + } + + private readonly IEnumerable octs; + + /// The octets making up the octet string. + public BerOctetString( + byte[] str) + : base(str) + { + } + + public BerOctetString( + IEnumerable octets) + : base(ToBytes(octets)) + { + this.octs = octets; + } + + public BerOctetString( + Asn1Object obj) + : base(obj) + { + } + + public BerOctetString( + Asn1Encodable obj) + : base(obj.ToAsn1Object()) + { + } + + public override byte[] GetOctets() + { + return str; + } + + /** + * return the DER octets that make up this string. + */ + public IEnumerator GetEnumerator() + { + if (octs == null) + { + return GenerateOcts().GetEnumerator(); + } + + return octs.GetEnumerator(); + } + + [Obsolete("Use GetEnumerator() instead")] + public IEnumerator GetObjects() + { + return GetEnumerator(); + } + + private IList GenerateOcts() + { + IList vec = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + for (int i = 0; i < str.Length; i += MaxLength) + { + int end = System.Math.Min(str.Length, i + MaxLength); + + byte[] nStr = new byte[end - i]; + + Array.Copy(str, i, nStr, 0, nStr.Length); + + vec.Add(new DerOctetString(nStr)); + } + return vec; + } + + internal override void Encode( + DerOutputStream derOut) + { + if (derOut is Asn1OutputStream || derOut is BerOutputStream) + { + derOut.WriteByte(Asn1Tags.Constructed | Asn1Tags.OctetString); + + derOut.WriteByte(0x80); + + // + // write out the octet array + // + foreach (DerOctetString oct in this) + { + derOut.WriteObject(oct); + } + + derOut.WriteByte(0x00); + derOut.WriteByte(0x00); + } + else + { + base.Encode(derOut); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs.meta new file mode 100644 index 0000000..644b45b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOctetString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d06a07cbd3b71a74f8cb664efab20cd0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs new file mode 100644 index 0000000..9bf5bb6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs @@ -0,0 +1,39 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + // TODO Make Obsolete in favour of Asn1OutputStream? + public class BerOutputStream + : DerOutputStream + { + public BerOutputStream(Stream os) : base(os) + { + } + + [Obsolete("Use version taking an Asn1Encodable arg instead")] + public override void WriteObject( + object obj) + { + if (obj == null) + { + WriteNull(); + } + else if (obj is Asn1Object) + { + ((Asn1Object)obj).Encode(this); + } + else if (obj is Asn1Encodable) + { + ((Asn1Encodable)obj).ToAsn1Object().Encode(this); + } + else + { + throw new IOException("object not BerEncodable"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs.meta new file mode 100644 index 0000000..2f4306a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerOutputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2fda066304739a7438fe6eedca01a7a7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs new file mode 100644 index 0000000..db8b9cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs @@ -0,0 +1,72 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class BerSequence + : DerSequence + { + public static new readonly BerSequence Empty = new BerSequence(); + + public static new BerSequence FromVector( + Asn1EncodableVector v) + { + return v.Count < 1 ? Empty : new BerSequence(v); + } + + /** + * create an empty sequence + */ + public BerSequence() + { + } + + /** + * create a sequence containing one object + */ + public BerSequence( + Asn1Encodable obj) + : base(obj) + { + } + + public BerSequence( + params Asn1Encodable[] v) + : base(v) + { + } + + /** + * create a sequence containing a vector of objects. + */ + public BerSequence( + Asn1EncodableVector v) + : base(v) + { + } + + /* + */ + internal override void Encode( + DerOutputStream derOut) + { + if (derOut is Asn1OutputStream || derOut is BerOutputStream) + { + derOut.WriteByte(Asn1Tags.Sequence | Asn1Tags.Constructed); + derOut.WriteByte(0x80); + + foreach (Asn1Encodable o in this) + { + derOut.WriteObject(o); + } + + derOut.WriteByte(0x00); + derOut.WriteByte(0x00); + } + else + { + base.Encode(derOut); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs.meta new file mode 100644 index 0000000..6e4eff1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSequence.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c5bc0026174da4a4e878a4914a50457b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs new file mode 100644 index 0000000..637d66e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs @@ -0,0 +1,73 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class BerSet + : DerSet + { + public static new readonly BerSet Empty = new BerSet(); + + public static new BerSet FromVector( + Asn1EncodableVector v) + { + return v.Count < 1 ? Empty : new BerSet(v); + } + + internal static new BerSet FromVector( + Asn1EncodableVector v, + bool needsSorting) + { + return v.Count < 1 ? Empty : new BerSet(v, needsSorting); + } + + /** + * create an empty sequence + */ + public BerSet() + { + } + + /** + * create a set containing one object + */ + public BerSet(Asn1Encodable obj) : base(obj) + { + } + + /** + * create a set containing a vector of objects. + */ + public BerSet(Asn1EncodableVector v) : base(v, false) + { + } + + internal BerSet(Asn1EncodableVector v, bool needsSorting) : base(v, needsSorting) + { + } + + /* + */ + internal override void Encode( + DerOutputStream derOut) + { + if (derOut is Asn1OutputStream || derOut is BerOutputStream) + { + derOut.WriteByte(Asn1Tags.Set | Asn1Tags.Constructed); + derOut.WriteByte(0x80); + + foreach (Asn1Encodable o in this) + { + derOut.WriteObject(o); + } + + derOut.WriteByte(0x00); + derOut.WriteByte(0x00); + } + else + { + base.Encode(derOut); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs.meta new file mode 100644 index 0000000..5cf05ff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerSet.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 01890d0dd345cff48bdbba411a658317 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs new file mode 100644 index 0000000..d1a2427 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs @@ -0,0 +1,111 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * BER TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ + public class BerTaggedObject + : DerTaggedObject + { + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public BerTaggedObject( + int tagNo, + Asn1Encodable obj) + : base(tagNo, obj) + { + } + + /** + * @param explicitly true if an explicitly tagged object. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public BerTaggedObject( + bool explicitly, + int tagNo, + Asn1Encodable obj) + : base(explicitly, tagNo, obj) + { + } + + /** + * create an implicitly tagged object that contains a zero + * length sequence. + */ + public BerTaggedObject( + int tagNo) + : base(false, tagNo, BerSequence.Empty) + { + } + + internal override void Encode( + DerOutputStream derOut) + { + if (derOut is Asn1OutputStream || derOut is BerOutputStream) + { + derOut.WriteTag((byte)(Asn1Tags.Constructed | Asn1Tags.Tagged), tagNo); + derOut.WriteByte(0x80); + + if (!IsEmpty()) + { + if (!explicitly) + { + IEnumerable eObj; + if (obj is Asn1OctetString) + { + if (obj is BerOctetString) + { + eObj = (BerOctetString) obj; + } + else + { + Asn1OctetString octs = (Asn1OctetString)obj; + eObj = new BerOctetString(octs.GetOctets()); + } + } + else if (obj is Asn1Sequence) + { + eObj = (Asn1Sequence) obj; + } + else if (obj is Asn1Set) + { + eObj = (Asn1Set) obj; + } + else + { + throw Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException(Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + foreach (Asn1Encodable o in eObj) + { + derOut.WriteObject(o); + } + } + else + { + derOut.WriteObject(obj); + } + } + + derOut.WriteByte(0x00); + derOut.WriteByte(0x00); + } + else + { + base.Encode(derOut); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs.meta new file mode 100644 index 0000000..2e2d64a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/BerTaggedObject.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cb57ca2d9225e0340bc7c9ef54c0bd13 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs new file mode 100644 index 0000000..84bb61c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + internal class ConstructedOctetStream + : BaseInputStream + { + private readonly Asn1StreamParser _parser; + + private bool _first = true; + private Stream _currentStream; + + internal ConstructedOctetStream( + Asn1StreamParser parser) + { + _parser = parser; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (_currentStream == null) + { + if (!_first) + return 0; + + Asn1OctetStringParser s = (Asn1OctetStringParser)_parser.ReadObject(); + + if (s == null) + return 0; + + _first = false; + _currentStream = s.GetOctetStream(); + } + + int totalRead = 0; + + for (;;) + { + int numRead = _currentStream.Read(buffer, offset + totalRead, count - totalRead); + + if (numRead > 0) + { + totalRead += numRead; + + if (totalRead == count) + return totalRead; + } + else + { + Asn1OctetStringParser aos = (Asn1OctetStringParser)_parser.ReadObject(); + + if (aos == null) + { + _currentStream = null; + return totalRead; + } + + _currentStream = aos.GetOctetStream(); + } + } + } + + public override int ReadByte() + { + if (_currentStream == null) + { + if (!_first) + return 0; + + Asn1OctetStringParser s = (Asn1OctetStringParser)_parser.ReadObject(); + + if (s == null) + return 0; + + _first = false; + _currentStream = s.GetOctetStream(); + } + + for (;;) + { + int b = _currentStream.ReadByte(); + + if (b >= 0) + { + return b; + } + + Asn1OctetStringParser aos = (Asn1OctetStringParser)_parser.ReadObject(); + + if (aos == null) + { + _currentStream = null; + return -1; + } + + _currentStream = aos.GetOctetStream(); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs.meta new file mode 100644 index 0000000..175c368 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ConstructedOctetStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1b0993a20facfcf478ecec624bad7b88 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs new file mode 100644 index 0000000..b680891 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs @@ -0,0 +1,205 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Class representing the DER-type External + */ + public class DerExternal + : Asn1Object + { + private DerObjectIdentifier directReference; + private DerInteger indirectReference; + private Asn1Object dataValueDescriptor; + private int encoding; + private Asn1Object externalContent; + + public DerExternal( + Asn1EncodableVector vector) + { + int offset = 0; + Asn1Object enc = GetObjFromVector(vector, offset); + if (enc is DerObjectIdentifier) + { + directReference = (DerObjectIdentifier)enc; + offset++; + enc = GetObjFromVector(vector, offset); + } + if (enc is DerInteger) + { + indirectReference = (DerInteger) enc; + offset++; + enc = GetObjFromVector(vector, offset); + } + if (!(enc is Asn1TaggedObject)) + { + dataValueDescriptor = enc; + offset++; + enc = GetObjFromVector(vector, offset); + } + + if (vector.Count != offset + 1) + throw new ArgumentException("input vector too large", "vector"); + + if (!(enc is Asn1TaggedObject)) + throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector"); + + Asn1TaggedObject obj = (Asn1TaggedObject)enc; + + // Use property accessor to include check on value + Encoding = obj.TagNo; + + if (encoding < 0 || encoding > 2) + throw new InvalidOperationException("invalid encoding value"); + + externalContent = obj.GetObject(); + } + + /** + * Creates a new instance of DerExternal + * See X.690 for more informations about the meaning of these parameters + * @param directReference The direct reference or null if not set. + * @param indirectReference The indirect reference or null if not set. + * @param dataValueDescriptor The data value descriptor or null if not set. + * @param externalData The external data in its encoded form. + */ + public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, DerTaggedObject externalData) + : this(directReference, indirectReference, dataValueDescriptor, externalData.TagNo, externalData.ToAsn1Object()) + { + } + + /** + * Creates a new instance of DerExternal. + * See X.690 for more informations about the meaning of these parameters + * @param directReference The direct reference or null if not set. + * @param indirectReference The indirect reference or null if not set. + * @param dataValueDescriptor The data value descriptor or null if not set. + * @param encoding The encoding to be used for the external data + * @param externalData The external data + */ + public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, int encoding, Asn1Object externalData) + { + DirectReference = directReference; + IndirectReference = indirectReference; + DataValueDescriptor = dataValueDescriptor; + Encoding = encoding; + ExternalContent = externalData.ToAsn1Object(); + } + + internal override void Encode(DerOutputStream derOut) + { + MemoryStream ms = new MemoryStream(); + WriteEncodable(ms, directReference); + WriteEncodable(ms, indirectReference); + WriteEncodable(ms, dataValueDescriptor); + WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent)); + + derOut.WriteEncoded(Asn1Tags.Constructed, Asn1Tags.External, ms.ToArray()); + } + + protected override int Asn1GetHashCode() + { + int ret = externalContent.GetHashCode(); + if (directReference != null) + { + ret ^= directReference.GetHashCode(); + } + if (indirectReference != null) + { + ret ^= indirectReference.GetHashCode(); + } + if (dataValueDescriptor != null) + { + ret ^= dataValueDescriptor.GetHashCode(); + } + return ret; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + if (this == asn1Object) + return true; + + DerExternal other = asn1Object as DerExternal; + + if (other == null) + return false; + + return Org.BouncyCastle.Utilities.Platform.Equals(directReference, other.directReference) + && Org.BouncyCastle.Utilities.Platform.Equals(indirectReference, other.indirectReference) + && Org.BouncyCastle.Utilities.Platform.Equals(dataValueDescriptor, other.dataValueDescriptor) + && externalContent.Equals(other.externalContent); + } + + public Asn1Object DataValueDescriptor + { + get { return dataValueDescriptor; } + set { this.dataValueDescriptor = value; } + } + + public DerObjectIdentifier DirectReference + { + get { return directReference; } + set { this.directReference = value; } + } + + /** + * The encoding of the content. Valid values are + *
    + *
  • 0 single-ASN1-type
  • + *
  • 1 OCTET STRING
  • + *
  • 2 BIT STRING
  • + *
+ */ + public int Encoding + { + get + { + return encoding; + } + set + { + if (encoding < 0 || encoding > 2) + throw new InvalidOperationException("invalid encoding value: " + encoding); + + this.encoding = value; + } + } + + public Asn1Object ExternalContent + { + get { return externalContent; } + set { this.externalContent = value; } + } + + public DerInteger IndirectReference + { + get { return indirectReference; } + set { this.indirectReference = value; } + } + + private static Asn1Object GetObjFromVector(Asn1EncodableVector v, int index) + { + if (v.Count <= index) + throw new ArgumentException("too few objects in input vector", "v"); + + return v[index].ToAsn1Object(); + } + + private static void WriteEncodable(MemoryStream ms, Asn1Encodable e) + { + if (e != null) + { + byte[] bs = e.GetDerEncoded(); + ms.Write(bs, 0, bs.Length); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs.meta new file mode 100644 index 0000000..8039dde --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternal.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 935fe2462b03f3d428919bf7cefbb60b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs new file mode 100644 index 0000000..88b7312 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs @@ -0,0 +1,29 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerExternalParser + : Asn1Encodable + { + private readonly Asn1StreamParser _parser; + + public DerExternalParser(Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerExternal(_parser.ReadVector()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs.meta new file mode 100644 index 0000000..b3e4069 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERExternalParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 31eecbd25b910414fa16a090b4665272 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs new file mode 100644 index 0000000..b22a22a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs @@ -0,0 +1,110 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class DerGenerator + : Asn1Generator + { + private bool _tagged = false; + private bool _isExplicit; + private int _tagNo; + + protected DerGenerator( + Stream outStream) + : base(outStream) + { + } + + protected DerGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream) + { + _tagged = true; + _isExplicit = isExplicit; + _tagNo = tagNo; + } + + private static void WriteLength( + Stream outStr, + int length) + { + if (length > 127) + { + int size = 1; + int val = length; + + while ((val >>= 8) != 0) + { + size++; + } + + outStr.WriteByte((byte)(size | 0x80)); + + for (int i = (size - 1) * 8; i >= 0; i -= 8) + { + outStr.WriteByte((byte)(length >> i)); + } + } + else + { + outStr.WriteByte((byte)length); + } + } + + internal static void WriteDerEncoded( + Stream outStream, + int tag, + byte[] bytes) + { + outStream.WriteByte((byte) tag); + WriteLength(outStream, bytes.Length); + outStream.Write(bytes, 0, bytes.Length); + } + + internal void WriteDerEncoded( + int tag, + byte[] bytes) + { + if (_tagged) + { + int tagNum = _tagNo | Asn1Tags.Tagged; + + if (_isExplicit) + { + int newTag = _tagNo | Asn1Tags.Constructed | Asn1Tags.Tagged; + MemoryStream bOut = new MemoryStream(); + WriteDerEncoded(bOut, tag, bytes); + WriteDerEncoded(Out, newTag, bOut.ToArray()); + } + else + { + if ((tag & Asn1Tags.Constructed) != 0) + { + tagNum |= Asn1Tags.Constructed; + } + + WriteDerEncoded(Out, tagNum, bytes); + } + } + else + { + WriteDerEncoded(Out, tag, bytes); + } + } + + internal static void WriteDerEncoded( + Stream outStr, + int tag, + Stream inStr) + { + WriteDerEncoded(outStr, tag, Streams.ReadAll(inStr)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs.meta new file mode 100644 index 0000000..9a5e55a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 86052d0b423f7dd4e812736107d50f9c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs new file mode 100644 index 0000000..4ca2651 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs @@ -0,0 +1,39 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerOctetStringParser + : Asn1OctetStringParser + { + private readonly DefiniteLengthInputStream stream; + + internal DerOctetStringParser( + DefiniteLengthInputStream stream) + { + this.stream = stream; + } + + public Stream GetOctetStream() + { + return stream; + } + + public Asn1Object ToAsn1Object() + { + try + { + return new DerOctetString(stream.ToArray()); + } + catch (IOException e) + { + throw new InvalidOperationException("IOException converting stream to byte array: " + e.Message, e); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs.meta new file mode 100644 index 0000000..9ed9b52 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DEROctetStringParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d08d17989b4e0584ba0cd58d1293e26f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs new file mode 100644 index 0000000..b804f98 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class DerSequenceParser + : Asn1SequenceParser + { + private readonly Asn1StreamParser _parser; + + internal DerSequenceParser( + Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new DerSequence(_parser.ReadVector()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs.meta new file mode 100644 index 0000000..4243f93 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSequenceParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 78a54d52c5aa20746a40a83ecd7dcf8c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs new file mode 100644 index 0000000..f2e7a10 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs @@ -0,0 +1,43 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerSetGenerator + : DerGenerator + { + private readonly MemoryStream _bOut = new MemoryStream(); + + public DerSetGenerator( + Stream outStream) + : base(outStream) + { + } + + public DerSetGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + } + + public override void AddObject( + Asn1Encodable obj) + { + new DerOutputStream(_bOut).WriteObject(obj); + } + + public override Stream GetRawOutputStream() + { + return _bOut; + } + + public override void Close() + { + WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Set, _bOut.ToArray()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs.meta new file mode 100644 index 0000000..0a1dae4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d1f54b39d3b0bb24a932046d612bdac3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs new file mode 100644 index 0000000..99c9cff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class DerSetParser + : Asn1SetParser + { + private readonly Asn1StreamParser _parser; + + internal DerSetParser( + Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new DerSet(_parser.ReadVector(), false); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs.meta new file mode 100644 index 0000000..e24af04 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DERSetParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e88a6ff513bc2d0438d22d47ace8fe6f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs new file mode 100644 index 0000000..c57f0f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs @@ -0,0 +1,103 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + class DefiniteLengthInputStream + : LimitedInputStream + { + private static readonly byte[] EmptyBytes = new byte[0]; + + private readonly int _originalLength; + private int _remaining; + + internal DefiniteLengthInputStream( + Stream inStream, + int length) + : base(inStream, length) + { + if (length < 0) + throw new ArgumentException("negative lengths not allowed", "length"); + + this._originalLength = length; + this._remaining = length; + + if (length == 0) + { + SetParentEofDetect(true); + } + } + + internal int Remaining + { + get { return _remaining; } + } + + public override int ReadByte() + { + if (_remaining == 0) + return -1; + + int b = _in.ReadByte(); + + if (b < 0) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + + if (--_remaining == 0) + { + SetParentEofDetect(true); + } + + return b; + } + + public override int Read( + byte[] buf, + int off, + int len) + { + if (_remaining == 0) + return 0; + + int toRead = System.Math.Min(len, _remaining); + int numRead = _in.Read(buf, off, toRead); + + if (numRead < 1) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + + if ((_remaining -= numRead) == 0) + { + SetParentEofDetect(true); + } + + return numRead; + } + + internal void ReadAllIntoByteArray(byte[] buf) + { + if (_remaining != buf.Length) + throw new ArgumentException("buffer length not right for data"); + + if ((_remaining -= Streams.ReadFully(_in, buf)) != 0) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + SetParentEofDetect(true); + } + + internal byte[] ToArray() + { + if (_remaining == 0) + return EmptyBytes; + + byte[] bytes = new byte[_remaining]; + if ((_remaining -= Streams.ReadFully(_in, bytes)) != 0) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + SetParentEofDetect(true); + return bytes; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs.meta new file mode 100644 index 0000000..270da12 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DefiniteLengthInputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 062975b128b005345a6d1502412231dd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs new file mode 100644 index 0000000..be1c1d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs @@ -0,0 +1,240 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Base class for an application specific object + */ + public class DerApplicationSpecific + : Asn1Object + { + private readonly bool isConstructed; + private readonly int tag; + private readonly byte[] octets; + + internal DerApplicationSpecific( + bool isConstructed, + int tag, + byte[] octets) + { + this.isConstructed = isConstructed; + this.tag = tag; + this.octets = octets; + } + + public DerApplicationSpecific( + int tag, + byte[] octets) + : this(false, tag, octets) + { + } + + public DerApplicationSpecific( + int tag, + Asn1Encodable obj) + : this(true, tag, obj) + { + } + + public DerApplicationSpecific( + bool isExplicit, + int tag, + Asn1Encodable obj) + { + Asn1Object asn1Obj = obj.ToAsn1Object(); + + byte[] data = asn1Obj.GetDerEncoded(); + + this.isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Obj); + this.tag = tag; + + if (isExplicit) + { + this.octets = data; + } + else + { + int lenBytes = GetLengthOfHeader(data); + byte[] tmp = new byte[data.Length - lenBytes]; + Array.Copy(data, lenBytes, tmp, 0, tmp.Length); + this.octets = tmp; + } + } + + public DerApplicationSpecific( + int tagNo, + Asn1EncodableVector vec) + { + this.tag = tagNo; + this.isConstructed = true; + MemoryStream bOut = new MemoryStream(); + + for (int i = 0; i != vec.Count; i++) + { + try + { + byte[] bs = vec[i].GetDerEncoded(); + bOut.Write(bs, 0, bs.Length); + } + catch (IOException e) + { + throw new InvalidOperationException("malformed object", e); + } + } + this.octets = bOut.ToArray(); + } + + private int GetLengthOfHeader( + byte[] data) + { + int length = data[1]; // TODO: assumes 1 byte tag + + if (length == 0x80) + { + return 2; // indefinite-length encoding + } + + if (length > 127) + { + int size = length & 0x7f; + + // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here + if (size > 4) + { + throw new InvalidOperationException("DER length more than 4 bytes: " + size); + } + + return size + 2; + } + + return 2; + } + + public bool IsConstructed() + { + return isConstructed; + } + + public byte[] GetContents() + { + return octets; + } + + public int ApplicationTag + { + get { return tag; } + } + + /** + * Return the enclosed object assuming explicit tagging. + * + * @return the resulting object + * @throws IOException if reconstruction fails. + */ + public Asn1Object GetObject() + { + return FromByteArray(GetContents()); + } + + /** + * Return the enclosed object assuming implicit tagging. + * + * @param derTagNo the type tag that should be applied to the object's contents. + * @return the resulting object + * @throws IOException if reconstruction fails. + */ + public Asn1Object GetObject( + int derTagNo) + { + if (derTagNo >= 0x1f) + throw new IOException("unsupported tag number"); + + byte[] orig = this.GetEncoded(); + byte[] tmp = ReplaceTagNumber(derTagNo, orig); + + if ((orig[0] & Asn1Tags.Constructed) != 0) + { + tmp[0] |= Asn1Tags.Constructed; + } + + return FromByteArray(tmp); + } + + internal override void Encode( + DerOutputStream derOut) + { + int classBits = Asn1Tags.Application; + if (isConstructed) + { + classBits |= Asn1Tags.Constructed; + } + + derOut.WriteEncoded(classBits, tag, octets); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerApplicationSpecific other = asn1Object as DerApplicationSpecific; + + if (other == null) + return false; + + return this.isConstructed == other.isConstructed + && this.tag == other.tag + && Arrays.AreEqual(this.octets, other.octets); + } + + protected override int Asn1GetHashCode() + { + return isConstructed.GetHashCode() ^ tag.GetHashCode() ^ Arrays.GetHashCode(octets); + } + + private byte[] ReplaceTagNumber( + int newTag, + byte[] input) + { + int tagNo = input[0] & 0x1f; + int index = 1; + // + // with tagged object tag number is bottom 5 bits, or stored at the start of the content + // + if (tagNo == 0x1f) + { + tagNo = 0; + + int b = input[index++] & 0xff; + + // X.690-0207 8.1.2.4.2 + // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." + if ((b & 0x7f) == 0) // Note: -1 will pass + { + throw new InvalidOperationException("corrupted stream - invalid high tag number found"); + } + + while ((b >= 0) && ((b & 0x80) != 0)) + { + tagNo |= (b & 0x7f); + tagNo <<= 7; + b = input[index++] & 0xff; + } + + tagNo |= (b & 0x7f); + } + + byte[] tmp = new byte[input.Length - index + 1]; + + Array.Copy(input, index, tmp, 1, tmp.Length - 1); + + tmp[0] = (byte)newTag; + + return tmp; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs.meta new file mode 100644 index 0000000..4f16e49 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerApplicationSpecific.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 788472ee00a6d10478a465572f1ffddb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs new file mode 100644 index 0000000..4351299 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs @@ -0,0 +1,120 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der BMPString object. + */ + public class DerBmpString + : DerStringBase + { + private readonly string str; + + /** + * return a BMP string from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static DerBmpString GetInstance( + object obj) + { + if (obj == null || obj is DerBmpString) + { + return (DerBmpString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return a BMP string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerBmpString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerBmpString) + { + return GetInstance(o); + } + + return new DerBmpString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerBmpString( + byte[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + char[] cs = new char[str.Length / 2]; + + for (int i = 0; i != cs.Length; i++) + { + cs[i] = (char)((str[2 * i] << 8) | (str[2 * i + 1] & 0xff)); + } + + this.str = new string(cs); + } + + /** + * basic constructor + */ + public DerBmpString( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerBmpString other = asn1Object as DerBmpString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + internal override void Encode( + DerOutputStream derOut) + { + char[] c = str.ToCharArray(); + byte[] b = new byte[c.Length * 2]; + + for (int i = 0; i != c.Length; i++) + { + b[2 * i] = (byte)(c[i] >> 8); + b[2 * i + 1] = (byte)c[i]; + } + + derOut.WriteEncoded(Asn1Tags.BmpString, b); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs.meta new file mode 100644 index 0000000..daca612 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBMPString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1237842c248008f47ae09b2fc3d95cb2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs new file mode 100644 index 0000000..c60f7a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs @@ -0,0 +1,279 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Diagnostics; +using System.Text; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerBitString + : DerStringBase + { + private static readonly char[] table + = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + protected readonly byte[] mData; + protected readonly int mPadBits; + + /** + * return a Bit string from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerBitString GetInstance( + object obj) + { + if (obj == null || obj is DerBitString) + { + return (DerBitString) obj; + } + if (obj is byte[]) + { + try + { + return (DerBitString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString()); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return a Bit string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerBitString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerBitString) + { + return GetInstance(o); + } + + return FromAsn1Octets(((Asn1OctetString)o).GetOctets()); + } + + /** + * @param data the octets making up the bit string. + * @param padBits the number of extra bits at the end of the string. + */ + public DerBitString( + byte[] data, + int padBits) + { + if (data == null) + throw new ArgumentNullException("data"); + if (padBits < 0 || padBits > 7) + throw new ArgumentException("must be in the range 0 to 7", "padBits"); + if (data.Length == 0 && padBits != 0) + throw new ArgumentException("if 'data' is empty, 'padBits' must be 0"); + + this.mData = Arrays.Clone(data); + this.mPadBits = padBits; + } + + public DerBitString( + byte[] data) + : this(data, 0) + { + } + + public DerBitString( + int namedBits) + { + if (namedBits == 0) + { + this.mData = new byte[0]; + this.mPadBits = 0; + return; + } + + int bits = BigInteger.BitLen(namedBits); + int bytes = (bits + 7) / 8; + + Debug.Assert(0 < bytes && bytes <= 4); + + byte[] data = new byte[bytes]; + --bytes; + + for (int i = 0; i < bytes; i++) + { + data[i] = (byte)namedBits; + namedBits >>= 8; + } + + Debug.Assert((namedBits & 0xFF) != 0); + + data[bytes] = (byte)namedBits; + + int padBits = 0; + while ((namedBits & (1 << padBits)) == 0) + { + ++padBits; + } + + Debug.Assert(padBits < 8); + + this.mData = data; + this.mPadBits = padBits; + } + + public DerBitString( + Asn1Encodable obj) + : this(obj.GetDerEncoded()) + { + } + + /** + * Return the octets contained in this BIT STRING, checking that this BIT STRING really + * does represent an octet aligned string. Only use this method when the standard you are + * following dictates that the BIT STRING will be octet aligned. + * + * @return a copy of the octet aligned data. + */ + public virtual byte[] GetOctets() + { + if (mPadBits != 0) + throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING"); + + return Arrays.Clone(mData); + } + + public virtual byte[] GetBytes() + { + byte[] data = Arrays.Clone(mData); + + // DER requires pad bits be zero + if (mPadBits > 0) + { + data[data.Length - 1] &= (byte)(0xFF << mPadBits); + } + + return data; + } + + public virtual int PadBits + { + get { return mPadBits; } + } + + /** + * @return the value of the bit string as an int (truncating if necessary) + */ + public virtual int IntValue + { + get + { + int value = 0, length = System.Math.Min(4, mData.Length); + for (int i = 0; i < length; ++i) + { + value |= (int)mData[i] << (8 * i); + } + if (mPadBits > 0 && length == mData.Length) + { + int mask = (1 << mPadBits) - 1; + value &= ~(mask << (8 * (length - 1))); + } + return value; + } + } + + internal override void Encode( + DerOutputStream derOut) + { + if (mPadBits > 0) + { + int last = mData[mData.Length - 1]; + int mask = (1 << mPadBits) - 1; + int unusedBits = last & mask; + + if (unusedBits != 0) + { + byte[] contents = Arrays.Prepend(mData, (byte)mPadBits); + + /* + * X.690-0207 11.2.1: Each unused bit in the final octet of the encoding of a bit string value shall be set to zero. + */ + contents[contents.Length - 1] = (byte)(last ^ unusedBits); + + derOut.WriteEncoded(Asn1Tags.BitString, contents); + return; + } + } + + derOut.WriteEncoded(Asn1Tags.BitString, (byte)mPadBits, mData); + } + + protected override int Asn1GetHashCode() + { + return mPadBits.GetHashCode() ^ Arrays.GetHashCode(mData); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerBitString other = asn1Object as DerBitString; + + if (other == null) + return false; + + return this.mPadBits == other.mPadBits + && Arrays.AreEqual(this.mData, other.mData); + } + + public override string GetString() + { + StringBuilder buffer = new StringBuilder("#"); + + byte[] str = GetDerEncoded(); + + for (int i = 0; i != str.Length; i++) + { + uint ubyte = str[i]; + buffer.Append(table[(ubyte >> 4) & 0xf]); + buffer.Append(table[str[i] & 0xf]); + } + + return buffer.ToString(); + } + + internal static DerBitString FromAsn1Octets(byte[] octets) + { + if (octets.Length < 1) + throw new ArgumentException("truncated BIT STRING detected", "octets"); + + int padBits = octets[0]; + byte[] data = Arrays.CopyOfRange(octets, 1, octets.Length); + + if (padBits > 0 && padBits < 8 && data.Length > 0) + { + int last = data[data.Length - 1]; + int mask = (1 << padBits) - 1; + + if ((last & mask) != 0) + { + return new BerBitString(data, padBits); + } + } + + return new DerBitString(data, padBits); + } + } +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs.meta new file mode 100644 index 0000000..06d1894 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBitString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3267bb6b435ba4a4a90fa383aa2c3bde +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs new file mode 100644 index 0000000..86af5ca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs @@ -0,0 +1,127 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerBoolean + : Asn1Object + { + private readonly byte value; + + public static readonly DerBoolean False = new DerBoolean(false); + public static readonly DerBoolean True = new DerBoolean(true); + + /** + * return a bool from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerBoolean GetInstance( + object obj) + { + if (obj == null || obj is DerBoolean) + { + return (DerBoolean) obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return a DerBoolean from the passed in bool. + */ + public static DerBoolean GetInstance( + bool value) + { + return value ? True : False; + } + + /** + * return a Boolean from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerBoolean GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerBoolean) + { + return GetInstance(o); + } + + return FromOctetString(((Asn1OctetString)o).GetOctets()); + } + + public DerBoolean( + byte[] val) + { + if (val.Length != 1) + throw new ArgumentException("byte value should have 1 byte in it", "val"); + + // TODO Are there any constraints on the possible byte values? + this.value = val[0]; + } + + private DerBoolean( + bool value) + { + this.value = value ? (byte)0xff : (byte)0; + } + + public bool IsTrue + { + get { return value != 0; } + } + + internal override void Encode( + DerOutputStream derOut) + { + // TODO Should we make sure the byte value is one of '0' or '0xff' here? + derOut.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value }); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerBoolean other = asn1Object as DerBoolean; + + if (other == null) + return false; + + return IsTrue == other.IsTrue; + } + + protected override int Asn1GetHashCode() + { + return IsTrue.GetHashCode(); + } + + public override string ToString() + { + return IsTrue ? "TRUE" : "FALSE"; + } + + internal static DerBoolean FromOctetString(byte[] value) + { + if (value.Length != 1) + { + throw new ArgumentException("BOOLEAN value should have 1 byte in it", "value"); + } + + byte b = value[0]; + + return b == 0 ? False : b == 0xFF ? True : new DerBoolean(value); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs.meta new file mode 100644 index 0000000..98ab935 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerBoolean.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 720c28a719a95734a88eab4e5bfce644 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs new file mode 100644 index 0000000..b9ec140 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs @@ -0,0 +1,127 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerEnumerated + : Asn1Object + { + private readonly byte[] bytes; + + /** + * return an integer from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerEnumerated GetInstance( + object obj) + { + if (obj == null || obj is DerEnumerated) + { + return (DerEnumerated)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an Enumerated from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerEnumerated GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerEnumerated) + { + return GetInstance(o); + } + + return FromOctetString(((Asn1OctetString)o).GetOctets()); + } + + public DerEnumerated( + int val) + { + bytes = BigInteger.ValueOf(val).ToByteArray(); + } + + public DerEnumerated( + BigInteger val) + { + bytes = val.ToByteArray(); + } + + public DerEnumerated( + byte[] bytes) + { + this.bytes = bytes; + } + + public BigInteger Value + { + get { return new BigInteger(bytes); } + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.Enumerated, bytes); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerEnumerated other = asn1Object as DerEnumerated; + + if (other == null) + return false; + + return Arrays.AreEqual(this.bytes, other.bytes); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(bytes); + } + + private static readonly DerEnumerated[] cache = new DerEnumerated[12]; + + internal static DerEnumerated FromOctetString(byte[] enc) + { + if (enc.Length == 0) + { + throw new ArgumentException("ENUMERATED has zero length", "enc"); + } + + if (enc.Length == 1) + { + int value = enc[0]; + if (value < cache.Length) + { + DerEnumerated cached = cache[value]; + if (cached != null) + { + return cached; + } + + return cache[value] = new DerEnumerated(Arrays.Clone(enc)); + } + } + + return new DerEnumerated(Arrays.Clone(enc)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs.meta new file mode 100644 index 0000000..57a7e10 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerEnumerated.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 061d704d9da7baf4a98aaad06e96b37c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs new file mode 100644 index 0000000..f82cff6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs @@ -0,0 +1,84 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerGeneralString + : DerStringBase + { + private readonly string str; + + public static DerGeneralString GetInstance( + object obj) + { + if (obj == null || obj is DerGeneralString) + { + return (DerGeneralString) obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + public static DerGeneralString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGeneralString) + { + return GetInstance(o); + } + + return new DerGeneralString(((Asn1OctetString)o).GetOctets()); + } + + public DerGeneralString( + byte[] str) + : this(Strings.FromAsciiByteArray(str)) + { + } + + public DerGeneralString( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.GeneralString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGeneralString other = asn1Object as DerGeneralString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs.meta new file mode 100644 index 0000000..bc9dfee --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f83195af35e42dd42900ea19ea491dda +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs new file mode 100644 index 0000000..b9c99ab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs @@ -0,0 +1,323 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Globalization; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Generalized time object. + */ + public class DerGeneralizedTime + : Asn1Object + { + private readonly string time; + + /** + * return a generalized time from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerGeneralizedTime GetInstance( + object obj) + { + if (obj == null || obj is DerGeneralizedTime) + { + return (DerGeneralizedTime)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Generalized Time object from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerGeneralizedTime GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGeneralizedTime) + { + return GetInstance(o); + } + + return new DerGeneralizedTime(((Asn1OctetString)o).GetOctets()); + } + + /** + * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z + * for local time, or Z+-HHMM on the end, for difference between local + * time and UTC time. The fractional second amount f must consist of at + * least one number with trailing zeroes removed. + * + * @param time the time string. + * @exception ArgumentException if string is an illegal format. + */ + public DerGeneralizedTime( + string time) + { + this.time = time; + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + /** + * base constructor from a local time object + */ + public DerGeneralizedTime( + DateTime time) + { +#if PORTABLE || NETFX_CORE + this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z"); +#else + this.time = time.ToString(@"yyyyMMddHHmmss\Z"); +#endif + } + + internal DerGeneralizedTime( + byte[] bytes) + { + // + // explicitly convert to characters + // + this.time = Strings.FromAsciiByteArray(bytes); + } + + /** + * Return the time. + * @return The time string as it appeared in the encoded object. + */ + public string TimeString + { + get { return time; } + } + + /** + * return the time - always in the form of + * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). + *

+ * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + *

+         *     dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+         * 
+ * To read in the time and Get a date which is compatible with our local + * time zone.

+ */ + public string GetTime() + { + // + // standardise the format. + // + if (time[time.Length - 1] == 'Z') + { + return time.Substring(0, time.Length - 1) + "GMT+00:00"; + } + else + { + int signPos = time.Length - 5; + char sign = time[signPos]; + if (sign == '-' || sign == '+') + { + return time.Substring(0, signPos) + + "GMT" + + time.Substring(signPos, 3) + + ":" + + time.Substring(signPos + 3); + } + else + { + signPos = time.Length - 3; + sign = time[signPos]; + if (sign == '-' || sign == '+') + { + return time.Substring(0, signPos) + + "GMT" + + time.Substring(signPos) + + ":00"; + } + } + } + + return time + CalculateGmtOffset(); + } + + private string CalculateGmtOffset() + { + char sign = '+'; + DateTime time = ToDateTime(); + +#if true //SILVERLIGHT || PORTABLE || NETFX_CORE + long offset = time.Ticks - time.ToUniversalTime().Ticks; + if (offset < 0) + { + sign = '-'; + offset = -offset; + } + int hours = (int)(offset / TimeSpan.TicksPerHour); + int minutes = (int)(offset / TimeSpan.TicksPerMinute) % 60; +#else + // Note: GetUtcOffset incorporates Daylight Savings offset + TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time); + if (offset.CompareTo(TimeSpan.Zero) < 0) + { + sign = '-'; + offset = offset.Duration(); + } + int hours = offset.Hours; + int minutes = offset.Minutes; +#endif + + return "GMT" + sign + Convert(hours) + ":" + Convert(minutes); + } + + private static string Convert( + int time) + { + if (time < 10) + { + return "0" + time; + } + + return time.ToString(); + } + + public DateTime ToDateTime() + { + string formatStr; + string d = time; + bool makeUniversal = false; + + if (Org.BouncyCastle.Utilities.Platform.EndsWith(d, "Z")) + { + if (HasFractionalSeconds) + { + int fCount = d.Length - d.IndexOf('.') - 2; + formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z"; + } + else + { + formatStr = @"yyyyMMddHHmmss\Z"; + } + } + else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0) + { + d = GetTime(); + makeUniversal = true; + + if (HasFractionalSeconds) + { + int fCount = Org.BouncyCastle.Utilities.Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.'); + formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz"; + } + else + { + formatStr = @"yyyyMMddHHmmss'GMT'zzz"; + } + } + else + { + if (HasFractionalSeconds) + { + int fCount = d.Length - 1 - d.IndexOf('.'); + formatStr = @"yyyyMMddHHmmss." + FString(fCount); + } + else + { + formatStr = @"yyyyMMddHHmmss"; + } + + // TODO? +// dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID())); + } + + return ParseDateString(d, formatStr, makeUniversal); + } + + private string FString( + int count) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; ++i) + { + sb.Append('f'); + } + return sb.ToString(); + } + + private DateTime ParseDateString(string s, string format, bool makeUniversal) + { + /* + * NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1 + */ + DateTimeStyles style = DateTimeStyles.None; + if (Org.BouncyCastle.Utilities.Platform.EndsWith(format, "Z")) + { + try + { + style = (DateTimeStyles)Enums.GetEnumValue(typeof(DateTimeStyles), "AssumeUniversal"); + } + catch (Exception) + { + } + + style |= DateTimeStyles.AdjustToUniversal; + } + + DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, style); + + return makeUniversal ? dt.ToUniversalTime() : dt; + } + + private bool HasFractionalSeconds + { + get { return time.IndexOf('.') == 14; } + } + + private byte[] GetOctets() + { + return Strings.ToAsciiByteArray(time); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.GeneralizedTime, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGeneralizedTime other = asn1Object as DerGeneralizedTime; + + if (other == null) + return false; + + return this.time.Equals(other.time); + } + + protected override int Asn1GetHashCode() + { + return time.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs.meta new file mode 100644 index 0000000..3b87b51 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGeneralizedTime.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1ebcc047ba1daf04db5d2ebd9c124a28 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs new file mode 100644 index 0000000..73eb333 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs @@ -0,0 +1,106 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerGraphicString + : DerStringBase + { + private readonly byte[] mString; + + /** + * return a Graphic String from the passed in object + * + * @param obj a DerGraphicString or an object that can be converted into one. + * @exception IllegalArgumentException if the object cannot be converted. + * @return a DerGraphicString instance, or null. + */ + public static DerGraphicString GetInstance(object obj) + { + if (obj == null || obj is DerGraphicString) + { + return (DerGraphicString)obj; + } + + if (obj is byte[]) + { + try + { + return (DerGraphicString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Graphic String from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + * @return a DerGraphicString instance, or null. + */ + public static DerGraphicString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGraphicString) + { + return GetInstance(o); + } + + return new DerGraphicString(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + * @param string the byte encoding of the characters making up the string. + */ + public DerGraphicString(byte[] encoding) + { + this.mString = Arrays.Clone(encoding); + } + + public override string GetString() + { + return Strings.FromByteArray(mString); + } + + public byte[] GetOctets() + { + return Arrays.Clone(mString); + } + + internal override void Encode(DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.GraphicString, mString); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(mString); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGraphicString other = asn1Object as DerGraphicString; + + if (other == null) + return false; + + return Arrays.AreEqual(mString, other.mString); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs.meta new file mode 100644 index 0000000..b7e5a11 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerGraphicString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f18e39588618e334c961eec4c763ef13 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs new file mode 100644 index 0000000..ff33a6f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs @@ -0,0 +1,148 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der IA5String object - this is an ascii string. + */ + public class DerIA5String + : DerStringBase + { + private readonly string str; + + /** + * return a IA5 string from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerIA5String GetInstance( + object obj) + { + if (obj == null || obj is DerIA5String) + { + return (DerIA5String)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an IA5 string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerIA5String GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerIA5String) + { + return GetInstance(o); + } + + return new DerIA5String(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + */ + public DerIA5String( + byte[] str) + : this(Strings.FromAsciiByteArray(str), false) + { + } + + /** + * basic constructor - without validation. + */ + public DerIA5String( + string str) + : this(str, false) + { + } + + /** + * Constructor with optional validation. + * + * @param string the base string to wrap. + * @param validate whether or not to check the string. + * @throws ArgumentException if validate is true and the string + * contains characters that should not be in an IA5String. + */ + public DerIA5String( + string str, + bool validate) + { + if (str == null) + throw new ArgumentNullException("str"); + if (validate && !IsIA5String(str)) + throw new ArgumentException("string contains illegal characters", "str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.IA5String, GetOctets()); + } + + protected override int Asn1GetHashCode() + { + return this.str.GetHashCode(); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerIA5String other = asn1Object as DerIA5String; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + /** + * return true if the passed in String can be represented without + * loss as an IA5String, false otherwise. + * + * @return true if in printable set, false otherwise. + */ + public static bool IsIA5String( + string str) + { + foreach (char ch in str) + { + if (ch > 0x007f) + { + return false; + } + } + + return true; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs.meta new file mode 100644 index 0000000..ead9945 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerIA5String.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 92ba1c46247b34d4b83218ac4a011b9e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs new file mode 100644 index 0000000..a22468c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs @@ -0,0 +1,120 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerInteger + : Asn1Object + { + private readonly byte[] bytes; + + /** + * return an integer from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerInteger GetInstance( + object obj) + { + if (obj == null || obj is DerInteger) + { + return (DerInteger)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an Integer from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerInteger GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerInteger) + { + return GetInstance(o); + } + + return new DerInteger(Asn1OctetString.GetInstance(o).GetOctets()); + } + + public DerInteger( + int value) + { + bytes = BigInteger.ValueOf(value).ToByteArray(); + } + + public DerInteger( + BigInteger value) + { + if (value == null) + throw new ArgumentNullException("value"); + + bytes = value.ToByteArray(); + } + + public DerInteger( + byte[] bytes) + { + this.bytes = bytes; + } + + public BigInteger Value + { + get { return new BigInteger(bytes); } + } + + /** + * in some cases positive values Get crammed into a space, + * that's not quite big enough... + */ + public BigInteger PositiveValue + { + get { return new BigInteger(1, bytes); } + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.Integer, bytes); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(bytes); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerInteger other = asn1Object as DerInteger; + + if (other == null) + return false; + + return Arrays.AreEqual(this.bytes, other.bytes); + } + + public override string ToString() + { + return Value.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs.meta new file mode 100644 index 0000000..b580ccd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerInteger.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ae09d83855723bc498fdae7631d51686 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs new file mode 100644 index 0000000..4a89910 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * A Null object. + */ + public class DerNull + : Asn1Null + { + public static readonly DerNull Instance = new DerNull(0); + + byte[] zeroBytes = new byte[0]; + + [Obsolete("Use static Instance object")] + public DerNull() + { + } + + protected internal DerNull(int dummy) + { + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.Null, zeroBytes); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + return asn1Object is DerNull; + } + + protected override int Asn1GetHashCode() + { + return -1; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs.meta new file mode 100644 index 0000000..a2eeacc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNull.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 48eba232a4b25614c941a9adb09edc24 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs new file mode 100644 index 0000000..67cac91 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs @@ -0,0 +1,141 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }. + */ + public class DerNumericString + : DerStringBase + { + private readonly string str; + + /** + * return a Numeric string from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerNumericString GetInstance( + object obj) + { + if (obj == null || obj is DerNumericString) + { + return (DerNumericString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an Numeric string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerNumericString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerNumericString) + { + return GetInstance(o); + } + + return new DerNumericString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - with bytes. + */ + public DerNumericString( + byte[] str) + : this(Strings.FromAsciiByteArray(str), false) + { + } + + /** + * basic constructor - without validation.. + */ + public DerNumericString( + string str) + : this(str, false) + { + } + + /** + * Constructor with optional validation. + * + * @param string the base string to wrap. + * @param validate whether or not to check the string. + * @throws ArgumentException if validate is true and the string + * contains characters that should not be in a NumericString. + */ + public DerNumericString( + string str, + bool validate) + { + if (str == null) + throw new ArgumentNullException("str"); + if (validate && !IsNumericString(str)) + throw new ArgumentException("string contains illegal characters", "str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.NumericString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerNumericString other = asn1Object as DerNumericString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + /** + * Return true if the string can be represented as a NumericString ('0'..'9', ' ') + * + * @param str string to validate. + * @return true if numeric, fale otherwise. + */ + public static bool IsNumericString( + string str) + { + foreach (char ch in str) + { + if (ch > 0x007f || (ch != ' ' && !char.IsDigit(ch))) + return false; + } + + return true; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs.meta new file mode 100644 index 0000000..e935817 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerNumericString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b0707908aca9e6943ba955d46365d37e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs new file mode 100644 index 0000000..ad17b2e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs @@ -0,0 +1,350 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerObjectIdentifier + : Asn1Object + { + private readonly string identifier; + + private byte[] body = null; + + /** + * return an Oid from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerObjectIdentifier GetInstance(object obj) + { + if (obj == null || obj is DerObjectIdentifier) + return (DerObjectIdentifier) obj; + if (obj is byte[]) + return FromOctetString((byte[])obj); + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * return an object Identifier from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerObjectIdentifier GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(obj.GetObject()); + } + + public DerObjectIdentifier( + string identifier) + { + if (identifier == null) + throw new ArgumentNullException("identifier"); + if (!IsValidIdentifier(identifier)) + throw new FormatException("string " + identifier + " not an OID"); + + this.identifier = identifier; + } + + internal DerObjectIdentifier(DerObjectIdentifier oid, string branchID) + { + if (!IsValidBranchID(branchID, 0)) + throw new ArgumentException("string " + branchID + " not a valid OID branch", "branchID"); + + this.identifier = oid.Id + "." + branchID; + } + + // TODO Change to ID? + public string Id + { + get { return identifier; } + } + + public virtual DerObjectIdentifier Branch(string branchID) + { + return new DerObjectIdentifier(this, branchID); + } + + /** + * Return true if this oid is an extension of the passed in branch, stem. + * @param stem the arc or branch that is a possible parent. + * @return true if the branch is on the passed in stem, false otherwise. + */ + public virtual bool On(DerObjectIdentifier stem) + { + string id = Id, stemId = stem.Id; + return id.Length > stemId.Length && id[stemId.Length] == '.' && Org.BouncyCastle.Utilities.Platform.StartsWith(id, stemId); + } + + internal DerObjectIdentifier(byte[] bytes) + { + this.identifier = MakeOidStringFromBytes(bytes); + this.body = Arrays.Clone(bytes); + } + + private void WriteField( + Stream outputStream, + long fieldValue) + { + byte[] result = new byte[9]; + int pos = 8; + result[pos] = (byte)(fieldValue & 0x7f); + while (fieldValue >= (1L << 7)) + { + fieldValue >>= 7; + result[--pos] = (byte)((fieldValue & 0x7f) | 0x80); + } + outputStream.Write(result, pos, 9 - pos); + } + + private void WriteField( + Stream outputStream, + BigInteger fieldValue) + { + int byteCount = (fieldValue.BitLength + 6) / 7; + if (byteCount == 0) + { + outputStream.WriteByte(0); + } + else + { + BigInteger tmpValue = fieldValue; + byte[] tmp = new byte[byteCount]; + for (int i = byteCount-1; i >= 0; i--) + { + tmp[i] = (byte) ((tmpValue.IntValue & 0x7f) | 0x80); + tmpValue = tmpValue.ShiftRight(7); + } + tmp[byteCount-1] &= 0x7f; + outputStream.Write(tmp, 0, tmp.Length); + } + } + + private void DoOutput(MemoryStream bOut) + { + OidTokenizer tok = new OidTokenizer(identifier); + + string token = tok.NextToken(); + int first = int.Parse(token) * 40; + + token = tok.NextToken(); + if (token.Length <= 18) + { + WriteField(bOut, first + Int64.Parse(token)); + } + else + { + WriteField(bOut, new BigInteger(token).Add(BigInteger.ValueOf(first))); + } + + while (tok.HasMoreTokens) + { + token = tok.NextToken(); + if (token.Length <= 18) + { + WriteField(bOut, Int64.Parse(token)); + } + else + { + WriteField(bOut, new BigInteger(token)); + } + } + } + + internal byte[] GetBody() + { + lock (this) + { + if (body == null) + { + MemoryStream bOut = new MemoryStream(); + DoOutput(bOut); + body = bOut.ToArray(); + } + } + + return body; + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.ObjectIdentifier, GetBody()); + } + + protected override int Asn1GetHashCode() + { + return identifier.GetHashCode(); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerObjectIdentifier other = asn1Object as DerObjectIdentifier; + + if (other == null) + return false; + + return this.identifier.Equals(other.identifier); + } + + public override string ToString() + { + return identifier; + } + + private static bool IsValidBranchID( + String branchID, int start) + { + bool periodAllowed = false; + + int pos = branchID.Length; + while (--pos >= start) + { + char ch = branchID[pos]; + + // TODO Leading zeroes? + if ('0' <= ch && ch <= '9') + { + periodAllowed = true; + continue; + } + + if (ch == '.') + { + if (!periodAllowed) + return false; + + periodAllowed = false; + continue; + } + + return false; + } + + return periodAllowed; + } + + private static bool IsValidIdentifier(string identifier) + { + if (identifier.Length < 3 || identifier[1] != '.') + return false; + + char first = identifier[0]; + if (first < '0' || first > '2') + return false; + + return IsValidBranchID(identifier, 2); + } + + private const long LONG_LIMIT = (long.MaxValue >> 7) - 0x7f; + + private static string MakeOidStringFromBytes( + byte[] bytes) + { + StringBuilder objId = new StringBuilder(); + long value = 0; + BigInteger bigValue = null; + bool first = true; + + for (int i = 0; i != bytes.Length; i++) + { + int b = bytes[i]; + + if (value <= LONG_LIMIT) + { + value += (b & 0x7f); + if ((b & 0x80) == 0) // end of number reached + { + if (first) + { + if (value < 40) + { + objId.Append('0'); + } + else if (value < 80) + { + objId.Append('1'); + value -= 40; + } + else + { + objId.Append('2'); + value -= 80; + } + first = false; + } + + objId.Append('.'); + objId.Append(value); + value = 0; + } + else + { + value <<= 7; + } + } + else + { + if (bigValue == null) + { + bigValue = BigInteger.ValueOf(value); + } + bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7f)); + if ((b & 0x80) == 0) + { + if (first) + { + objId.Append('2'); + bigValue = bigValue.Subtract(BigInteger.ValueOf(80)); + first = false; + } + + objId.Append('.'); + objId.Append(bigValue); + bigValue = null; + value = 0; + } + else + { + bigValue = bigValue.ShiftLeft(7); + } + } + } + + return objId.ToString(); + } + + private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024]; + + internal static DerObjectIdentifier FromOctetString(byte[] enc) + { + int hashCode = Arrays.GetHashCode(enc); + int first = hashCode & 1023; + + lock (cache) + { + DerObjectIdentifier entry = cache[first]; + if (entry != null && Arrays.AreEqual(enc, entry.GetBody())) + { + return entry; + } + + return cache[first] = new DerObjectIdentifier(enc); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs.meta new file mode 100644 index 0000000..828365e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerObjectIdentifier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 44d9a2bc67c903f468455f944abaccfc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs new file mode 100644 index 0000000..1be7733 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs @@ -0,0 +1,37 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public class DerOctetString + : Asn1OctetString + { + /// The octets making up the octet string. + public DerOctetString( + byte[] str) + : base(str) + { + } + + public DerOctetString( + Asn1Encodable obj) + : base(obj) + { + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.OctetString, str); + } + + internal static void Encode( + DerOutputStream derOut, + byte[] bytes, + int offset, + int length) + { + derOut.WriteEncoded(Asn1Tags.OctetString, bytes, offset, length); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs.meta new file mode 100644 index 0000000..c2c62d9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOctetString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8d4f36a04b2ccfc478c9e105de48f09f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs new file mode 100644 index 0000000..599590b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs @@ -0,0 +1,174 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerOutputStream + : FilterStream + { + public DerOutputStream(Stream os) + : base(os) + { + } + + private void WriteLength( + int length) + { + if (length > 127) + { + int size = 1; + uint val = (uint)length; + + while ((val >>= 8) != 0) + { + size++; + } + + WriteByte((byte)(size | 0x80)); + + for (int i = (size - 1) * 8; i >= 0; i -= 8) + { + WriteByte((byte)(length >> i)); + } + } + else + { + WriteByte((byte)length); + } + } + + internal void WriteEncoded( + int tag, + byte[] bytes) + { + WriteByte((byte)tag); + WriteLength(bytes.Length); + Write(bytes, 0, bytes.Length); + } + + internal void WriteEncoded( + int tag, + byte first, + byte[] bytes) + { + WriteByte((byte)tag); + WriteLength(bytes.Length + 1); + WriteByte(first); + Write(bytes, 0, bytes.Length); + } + + internal void WriteEncoded( + int tag, + byte[] bytes, + int offset, + int length) + { + WriteByte((byte)tag); + WriteLength(length); + Write(bytes, offset, length); + } + + internal void WriteTag( + int flags, + int tagNo) + { + if (tagNo < 31) + { + WriteByte((byte)(flags | tagNo)); + } + else + { + WriteByte((byte)(flags | 0x1f)); + if (tagNo < 128) + { + WriteByte((byte)tagNo); + } + else + { + byte[] stack = new byte[5]; + int pos = stack.Length; + + stack[--pos] = (byte)(tagNo & 0x7F); + + do + { + tagNo >>= 7; + stack[--pos] = (byte)(tagNo & 0x7F | 0x80); + } + while (tagNo > 127); + + Write(stack, pos, stack.Length - pos); + } + } + } + + internal void WriteEncoded( + int flags, + int tagNo, + byte[] bytes) + { + WriteTag(flags, tagNo); + WriteLength(bytes.Length); + Write(bytes, 0, bytes.Length); + } + + protected void WriteNull() + { + WriteByte(Asn1Tags.Null); + WriteByte(0x00); + } + + [Obsolete("Use version taking an Asn1Encodable arg instead")] + public virtual void WriteObject( + object obj) + { + if (obj == null) + { + WriteNull(); + } + else if (obj is Asn1Object) + { + ((Asn1Object)obj).Encode(this); + } + else if (obj is Asn1Encodable) + { + ((Asn1Encodable)obj).ToAsn1Object().Encode(this); + } + else + { + throw new IOException("object not Asn1Object"); + } + } + + public virtual void WriteObject( + Asn1Encodable obj) + { + if (obj == null) + { + WriteNull(); + } + else + { + obj.ToAsn1Object().Encode(this); + } + } + + public virtual void WriteObject( + Asn1Object obj) + { + if (obj == null) + { + WriteNull(); + } + else + { + obj.Encode(this); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs.meta new file mode 100644 index 0000000..b9a008e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerOutputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b1bb944f8dee86942a8e2fb0c5c9520c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs new file mode 100644 index 0000000..5779141 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs @@ -0,0 +1,166 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der PrintableString object. + */ + public class DerPrintableString + : DerStringBase + { + private readonly string str; + + /** + * return a printable string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerPrintableString GetInstance( + object obj) + { + if (obj == null || obj is DerPrintableString) + { + return (DerPrintableString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return a Printable string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerPrintableString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerPrintableString) + { + return GetInstance(o); + } + + return new DerPrintableString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerPrintableString( + byte[] str) + : this(Strings.FromAsciiByteArray(str), false) + { + } + + /** + * basic constructor - this does not validate the string + */ + public DerPrintableString( + string str) + : this(str, false) + { + } + + /** + * Constructor with optional validation. + * + * @param string the base string to wrap. + * @param validate whether or not to check the string. + * @throws ArgumentException if validate is true and the string + * contains characters that should not be in a PrintableString. + */ + public DerPrintableString( + string str, + bool validate) + { + if (str == null) + throw new ArgumentNullException("str"); + if (validate && !IsPrintableString(str)) + throw new ArgumentException("string contains illegal characters", "str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.PrintableString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerPrintableString other = asn1Object as DerPrintableString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + /** + * return true if the passed in String can be represented without + * loss as a PrintableString, false otherwise. + * + * @return true if in printable set, false otherwise. + */ + public static bool IsPrintableString( + string str) + { + foreach (char ch in str) + { + if (ch > 0x007f) + return false; + + if (char.IsLetterOrDigit(ch)) + continue; + +// if (char.IsPunctuation(ch)) +// continue; + + switch (ch) + { + case ' ': + case '\'': + case '(': + case ')': + case '+': + case '-': + case '.': + case ':': + case '=': + case '?': + case '/': + case ',': + continue; + } + + return false; + } + + return true; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs.meta new file mode 100644 index 0000000..95ebeb6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerPrintableString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1200ec73d3f7fca4aaff102854e1059d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs new file mode 100644 index 0000000..1870e0a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs @@ -0,0 +1,90 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerSequence + : Asn1Sequence + { + public static readonly DerSequence Empty = new DerSequence(); + + public static DerSequence FromVector( + Asn1EncodableVector v) + { + return v.Count < 1 ? Empty : new DerSequence(v); + } + + /** + * create an empty sequence + */ + public DerSequence() + : base(0) + { + } + + /** + * create a sequence containing one object + */ + public DerSequence( + Asn1Encodable obj) + : base(1) + { + AddObject(obj); + } + + public DerSequence( + params Asn1Encodable[] v) + : base(v.Length) + { + foreach (Asn1Encodable ae in v) + { + AddObject(ae); + } + } + + /** + * create a sequence containing a vector of objects. + */ + public DerSequence( + Asn1EncodableVector v) + : base(v.Count) + { + foreach (Asn1Encodable ae in v) + { + AddObject(ae); + } + } + + /* + * A note on the implementation: + *

+ * As Der requires the constructed, definite-length model to + * be used for structured types, this varies slightly from the + * ASN.1 descriptions given. Rather than just outputing Sequence, + * we also have to specify Constructed, and the objects length. + */ + internal override void Encode( + DerOutputStream derOut) + { + // TODO Intermediate buffer could be avoided if we could calculate expected length + MemoryStream bOut = new MemoryStream(); + DerOutputStream dOut = new DerOutputStream(bOut); + + foreach (Asn1Encodable obj in this) + { + dOut.WriteObject(obj); + } + + Org.BouncyCastle.Utilities.Platform.Dispose(dOut); + + byte[] bytes = bOut.ToArray(); + + derOut.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, bytes); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs.meta new file mode 100644 index 0000000..f2929a0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSequence.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1ca9f0cbe9fb5c1489017b4d412573eb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs new file mode 100644 index 0000000..46de070 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs @@ -0,0 +1,113 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * A Der encoded set object + */ + public class DerSet + : Asn1Set + { + public static readonly DerSet Empty = new DerSet(); + + public static DerSet FromVector( + Asn1EncodableVector v) + { + return v.Count < 1 ? Empty : new DerSet(v); + } + + internal static DerSet FromVector( + Asn1EncodableVector v, + bool needsSorting) + { + return v.Count < 1 ? Empty : new DerSet(v, needsSorting); + } + + /** + * create an empty set + */ + public DerSet() + : base(0) + { + } + + /** + * @param obj - a single object that makes up the set. + */ + public DerSet( + Asn1Encodable obj) + : base(1) + { + AddObject(obj); + } + + public DerSet( + params Asn1Encodable[] v) + : base(v.Length) + { + foreach (Asn1Encodable o in v) + { + AddObject(o); + } + + Sort(); + } + + /** + * @param v - a vector of objects making up the set. + */ + public DerSet( + Asn1EncodableVector v) + : this(v, true) + { + } + + internal DerSet( + Asn1EncodableVector v, + bool needsSorting) + : base(v.Count) + { + foreach (Asn1Encodable o in v) + { + AddObject(o); + } + + if (needsSorting) + { + Sort(); + } + } + + /* + * A note on the implementation: + *

+ * As Der requires the constructed, definite-length model to + * be used for structured types, this varies slightly from the + * ASN.1 descriptions given. Rather than just outputing Set, + * we also have to specify Constructed, and the objects length. + */ + internal override void Encode( + DerOutputStream derOut) + { + // TODO Intermediate buffer could be avoided if we could calculate expected length + MemoryStream bOut = new MemoryStream(); + DerOutputStream dOut = new DerOutputStream(bOut); + + foreach (Asn1Encodable obj in this) + { + dOut.WriteObject(obj); + } + + Org.BouncyCastle.Utilities.Platform.Dispose(dOut); + + byte[] bytes = bOut.ToArray(); + + derOut.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, bytes); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs.meta new file mode 100644 index 0000000..c445263 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerSet.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f364dec2c9a290d44970ffd282c606bc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs new file mode 100644 index 0000000..6936c0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs @@ -0,0 +1,25 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public abstract class DerStringBase + : Asn1Object, IAsn1String + { + protected DerStringBase() + { + } + + public abstract string GetString(); + + public override string ToString() + { + return GetString(); + } + + protected override int Asn1GetHashCode() + { + return GetString().GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs.meta new file mode 100644 index 0000000..744c800 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerStringBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4ff347a2eb85434458a6035f9c07cb84 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs new file mode 100644 index 0000000..98cdbf2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der T61String (also the teletex string) - 8-bit characters + */ + public class DerT61String + : DerStringBase + { + private readonly string str; + + /** + * return a T61 string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerT61String GetInstance( + object obj) + { + if (obj == null || obj is DerT61String) + { + return (DerT61String)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an T61 string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerT61String GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerT61String) + { + return GetInstance(o); + } + + return new DerT61String(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - with bytes. + */ + public DerT61String( + byte[] str) + : this(Strings.FromByteArray(str)) + { + } + + /** + * basic constructor - with string. + */ + public DerT61String( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.T61String, GetOctets()); + } + + public byte[] GetOctets() + { + return Strings.ToByteArray(str); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerT61String other = asn1Object as DerT61String; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs.meta new file mode 100644 index 0000000..37a381f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerT61String.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3128101ae52c6af4982834c862464364 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs new file mode 100644 index 0000000..a7460d0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs @@ -0,0 +1,75 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + /** + * DER TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ + public class DerTaggedObject + : Asn1TaggedObject + { + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public DerTaggedObject( + int tagNo, + Asn1Encodable obj) + : base(tagNo, obj) + { + } + + /** + * @param explicitly true if an explicitly tagged object. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public DerTaggedObject( + bool explicitly, + int tagNo, + Asn1Encodable obj) + : base(explicitly, tagNo, obj) + { + } + + /** + * create an implicitly tagged object that contains a zero + * length sequence. + */ + public DerTaggedObject( + int tagNo) + : base(false, tagNo, DerSequence.Empty) + { + } + + internal override void Encode( + DerOutputStream derOut) + { + if (!IsEmpty()) + { + byte[] bytes = obj.GetDerEncoded(); + + if (explicitly) + { + derOut.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, bytes); + } + else + { + // + // need to mark constructed types... (preserve Constructed tag) + // + int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.Tagged; + derOut.WriteTag(flags, tagNo); + derOut.Write(bytes, 1, bytes.Length - 1); + } + } + else + { + derOut.WriteEncoded(Asn1Tags.Constructed | Asn1Tags.Tagged, tagNo, new byte[0]); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs.meta new file mode 100644 index 0000000..f095173 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerTaggedObject.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 09a923adf168ad244bfe61ba31f805bb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs new file mode 100644 index 0000000..b4d914d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs @@ -0,0 +1,270 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Globalization; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * UTC time object. + */ + public class DerUtcTime + : Asn1Object + { + private readonly string time; + + /** + * return an UTC Time from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerUtcTime GetInstance( + object obj) + { + if (obj == null || obj is DerUtcTime) + { + return (DerUtcTime)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an UTC Time from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerUtcTime GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerUtcTime) + { + return GetInstance(o); + } + + return new DerUtcTime(((Asn1OctetString)o).GetOctets()); + } + + /** + * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were + * never encoded. When you're creating one of these objects from scratch, that's + * what you want to use, otherwise we'll try to deal with whatever Gets read from + * the input stream... (this is why the input format is different from the GetTime() + * method output). + *

+ * @param time the time string.

+ */ + public DerUtcTime( + string time) + { + if (time == null) + throw new ArgumentNullException("time"); + + this.time = time; + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + /** + * base constructor from a DateTime object + */ + public DerUtcTime( + DateTime time) + { +#if PORTABLE || NETFX_CORE + this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#else + this.time = time.ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#endif + } + + internal DerUtcTime( + byte[] bytes) + { + // + // explicitly convert to characters + // + this.time = Strings.FromAsciiByteArray(bytes); + } + +// public DateTime ToDateTime() +// { +// string tm = this.AdjustedTimeString; +// +// return new DateTime( +// Int16.Parse(tm.Substring(0, 4)), +// Int16.Parse(tm.Substring(4, 2)), +// Int16.Parse(tm.Substring(6, 2)), +// Int16.Parse(tm.Substring(8, 2)), +// Int16.Parse(tm.Substring(10, 2)), +// Int16.Parse(tm.Substring(12, 2))); +// } + + /** + * return the time as a date based on whatever a 2 digit year will return. For + * standardised processing use ToAdjustedDateTime(). + * + * @return the resulting date + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToDateTime() + { + return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz"); + } + + /** + * return the time as an adjusted date + * in the range of 1950 - 2049. + * + * @return a date in the range of 1950 to 2049. + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToAdjustedDateTime() + { + return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz"); + } + + private DateTime ParseDateString( + string dateStr, + string formatStr) + { + DateTime dt = DateTime.ParseExact( + dateStr, + formatStr, + DateTimeFormatInfo.InvariantInfo); + + return dt.ToUniversalTime(); + } + + /** + * return the time - always in the form of + * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). + *

+ * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + *

+         *     dateF = new SimpleDateFormat("yyMMddHHmmssz");
+         * 
+ * To read in the time and Get a date which is compatible with our local + * time zone.

+ *

+ * Note: In some cases, due to the local date processing, this + * may lead to unexpected results. If you want to stick the normal + * convention of 1950 to 2049 use the GetAdjustedTime() method.

+ */ + public string TimeString + { + get + { + // + // standardise the format. + // + if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0) + { + if (time.Length == 11) + { + return time.Substring(0, 10) + "00GMT+00:00"; + } + else + { + return time.Substring(0, 12) + "GMT+00:00"; + } + } + else + { + int index = time.IndexOf('-'); + if (index < 0) + { + index = time.IndexOf('+'); + } + string d = time; + + if (index == time.Length - 3) + { + d += "00"; + } + + if (index == 10) + { + return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2); + } + else + { + return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2); + } + } + } + } + + [Obsolete("Use 'AdjustedTimeString' property instead")] + public string AdjustedTime + { + get { return AdjustedTimeString; } + } + + /// + /// Return a time string as an adjusted date with a 4 digit year. + /// This goes in the range of 1950 - 2049. + /// + public string AdjustedTimeString + { + get + { + string d = TimeString; + string c = d[0] < '5' ? "20" : "19"; + + return c + d; + } + } + + private byte[] GetOctets() + { + return Strings.ToAsciiByteArray(time); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.UtcTime, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerUtcTime other = asn1Object as DerUtcTime; + + if (other == null) + return false; + + return this.time.Equals(other.time); + } + + protected override int Asn1GetHashCode() + { + return time.GetHashCode(); + } + + public override string ToString() + { + return time; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs.meta new file mode 100644 index 0000000..1dede09 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTCTime.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 974cf3154ca4d22409f3c9f174fd6f5d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs new file mode 100644 index 0000000..25f0aaf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs @@ -0,0 +1,101 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der UTF8String object. + */ + public class DerUtf8String + : DerStringBase + { + private readonly string str; + + /** + * return an UTF8 string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerUtf8String GetInstance( + object obj) + { + if (obj == null || obj is DerUtf8String) + { + return (DerUtf8String)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return an UTF8 string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerUtf8String GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerUtf8String) + { + return GetInstance(o); + } + + return new DerUtf8String(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerUtf8String( + byte[] str) + : this(Encoding.UTF8.GetString(str, 0, str.Length)) + { + } + + /** + * basic constructor + */ + public DerUtf8String( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerUtf8String other = asn1Object as DerUtf8String; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.Utf8String, Encoding.UTF8.GetBytes(str)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs.meta new file mode 100644 index 0000000..f5244a5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUTF8String.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 59793e3c98172f046a238fb0352e1e38 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs new file mode 100644 index 0000000..b9302e1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs @@ -0,0 +1,110 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der UniversalString object. + */ + public class DerUniversalString + : DerStringBase + { + private static readonly char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + private readonly byte[] str; + + /** + * return a Universal string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerUniversalString GetInstance( + object obj) + { + if (obj == null || obj is DerUniversalString) + { + return (DerUniversalString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return a Universal string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerUniversalString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerUniversalString) + { + return GetInstance(o); + } + + return new DerUniversalString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerUniversalString( + byte[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + StringBuilder buffer = new StringBuilder("#"); + byte[] enc = GetDerEncoded(); + + for (int i = 0; i != enc.Length; i++) + { + uint ubyte = enc[i]; + buffer.Append(table[(ubyte >> 4) & 0xf]); + buffer.Append(table[enc[i] & 0xf]); + } + + return buffer.ToString(); + } + + public byte[] GetOctets() + { + return (byte[]) str.Clone(); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.UniversalString, this.str); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerUniversalString other = asn1Object as DerUniversalString; + + if (other == null) + return false; + +// return this.GetString().Equals(other.GetString()); + return Arrays.AreEqual(this.str, other.str); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs.meta new file mode 100644 index 0000000..c8c70a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerUniversalString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9aeab3619d1c4324f9e7968fa71c7ed4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs new file mode 100644 index 0000000..3eb7370 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs @@ -0,0 +1,106 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerVideotexString + : DerStringBase + { + private readonly byte[] mString; + + /** + * return a Videotex String from the passed in object + * + * @param obj a DERVideotexString or an object that can be converted into one. + * @exception IllegalArgumentException if the object cannot be converted. + * @return a DERVideotexString instance, or null. + */ + public static DerVideotexString GetInstance(object obj) + { + if (obj == null || obj is DerVideotexString) + { + return (DerVideotexString)obj; + } + + if (obj is byte[]) + { + try + { + return (DerVideotexString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Videotex String from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + * @return a DERVideotexString instance, or null. + */ + public static DerVideotexString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerVideotexString) + { + return GetInstance(o); + } + + return new DerVideotexString(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + * @param string the byte encoding of the characters making up the string. + */ + public DerVideotexString(byte[] encoding) + { + this.mString = Arrays.Clone(encoding); + } + + public override string GetString() + { + return Strings.FromByteArray(mString); + } + + public byte[] GetOctets() + { + return Arrays.Clone(mString); + } + + internal override void Encode(DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.VideotexString, mString); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(mString); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerVideotexString other = asn1Object as DerVideotexString; + + if (other == null) + return false; + + return Arrays.AreEqual(mString, other.mString); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs.meta new file mode 100644 index 0000000..e89e532 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVideotexString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dd1f8c7688b859b4d990225267b276ec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs new file mode 100644 index 0000000..7f36980 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs @@ -0,0 +1,114 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der VisibleString object. + */ + public class DerVisibleString + : DerStringBase + { + private readonly string str; + + /** + * return a Visible string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerVisibleString GetInstance( + object obj) + { + if (obj == null || obj is DerVisibleString) + { + return (DerVisibleString)obj; + } + + if (obj is Asn1OctetString) + { + return new DerVisibleString(((Asn1OctetString)obj).GetOctets()); + } + + if (obj is Asn1TaggedObject) + { + return GetInstance(((Asn1TaggedObject)obj).GetObject()); + } + + throw new ArgumentException("illegal object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + /** + * return a Visible string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerVisibleString GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(obj.GetObject()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerVisibleString( + byte[] str) + : this(Strings.FromAsciiByteArray(str)) + { + } + + /** + * basic constructor + */ + public DerVisibleString( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override void Encode( + DerOutputStream derOut) + { + derOut.WriteEncoded(Asn1Tags.VisibleString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerVisibleString other = asn1Object as DerVisibleString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + protected override int Asn1GetHashCode() + { + return this.str.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs.meta new file mode 100644 index 0000000..80b05d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/DerVisibleString.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9c45522cf4626c4c81e4e6b8b3fe74b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs new file mode 100644 index 0000000..52afd9a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public interface IAsn1ApplicationSpecificParser + : IAsn1Convertible + { + IAsn1Convertible ReadObject(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs.meta new file mode 100644 index 0000000..04e2c6f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1ApplicationSpecificParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5db852656650b934d8a382f2d26d18b1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs new file mode 100644 index 0000000..cb8dff7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Marker interface for CHOICE objects - if you implement this in a roll-your-own + * object, any attempt to tag the object implicitly will convert the tag to an + * explicit one as the encoding rules require. + *

+ * If you use this interface your class should also implement the getInstance + * pattern which takes a tag object and the tagging mode used. + *

+ */ + public interface IAsn1Choice + { + // marker interface + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs.meta new file mode 100644 index 0000000..27f917d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Choice.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71028704810a2d447920c97d24f875e0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs new file mode 100644 index 0000000..5f73c7e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs @@ -0,0 +1,10 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + public interface IAsn1Convertible + { + Asn1Object ToAsn1Object(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs.meta new file mode 100644 index 0000000..d9a044d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1Convertible.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 07cd5c034ed2a474690fa66bd2118ce9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs new file mode 100644 index 0000000..0a12c57 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + /** + * basic interface for Der string objects. + */ + public interface IAsn1String + { + string GetString(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs.meta new file mode 100644 index 0000000..3d4d157 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IAsn1String.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8f46d890a56de484eb4eef965cc5cb64 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs new file mode 100644 index 0000000..86f06db --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs @@ -0,0 +1,173 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + class IndefiniteLengthInputStream + : LimitedInputStream + { + private int _lookAhead; + private bool _eofOn00 = true; + + internal IndefiniteLengthInputStream( + Stream inStream, + int limit) + : base(inStream, limit) + { + _lookAhead = RequireByte(); + CheckForEof(); + } + + internal void SetEofOn00( + bool eofOn00) + { + _eofOn00 = eofOn00; + if (_eofOn00) + { + CheckForEof(); + } + } + + private bool CheckForEof() + { + if (_lookAhead == 0x00) + { + int extra = RequireByte(); + if (extra != 0) + { + throw new IOException("malformed end-of-contents marker"); + } + + _lookAhead = -1; + SetParentEofDetect(true); + return true; + } + return _lookAhead < 0; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + // Only use this optimisation if we aren't checking for 00 + if (_eofOn00 || count <= 1) + return base.Read(buffer, offset, count); + + if (_lookAhead < 0) + return 0; + + int numRead = _in.Read(buffer, offset + 1, count - 1); + + if (numRead <= 0) + { + // Corrupted stream + throw new EndOfStreamException(); + } + + buffer[offset] = (byte)_lookAhead; + _lookAhead = RequireByte(); + + return numRead + 1; + } + + public override int ReadByte() + { + if (_eofOn00 && CheckForEof()) + return -1; + + int result = _lookAhead; + _lookAhead = RequireByte(); + return result; + } + + private int RequireByte() + { + int b = _in.ReadByte(); + if (b < 0) + { + // Corrupted stream + throw new EndOfStreamException(); + } + return b; + } + } +} + +//using System; +//using System.IO; + +//namespace Org.BouncyCastle.Asn1 +//{ +// class IndefiniteLengthInputStream +// : LimitedInputStream +// { +// private bool _eofReached = false; +// private bool _eofOn00 = true; + +// internal IndefiniteLengthInputStream( +// Stream inStream, +// int limit) +// : base(inStream, limit) +// { +// } + +// internal void SetEofOn00( +// bool eofOn00) +// { +// _eofOn00 = eofOn00; +// } + +// public override int Read( +// byte[] buffer, +// int offset, +// int count) +// { +// if (_eofReached) +// return 0; + +// if (_eofOn00) +// return base.Read(buffer, offset, count); + +// int numRead = _in.Read(buffer, offset, count); + +// if (numRead <= 0) +// throw new EndOfStreamException(); + +// return numRead; +// } + +// public override int ReadByte() +// { +// if (_eofReached) +// return -1; + +// int b1 = _in.ReadByte(); + +// if (b1 < 0) +// throw new EndOfStreamException(); + +// if (b1 == 0 && _eofOn00) +// { +// int b2 = _in.ReadByte(); + +// if (b2 < 0) +// throw new EndOfStreamException(); + +// if (b2 == 0) +// { +// _eofReached = true; +// SetParentEofDetect(true); +// return -1; +// } + +// throw new InvalidDataException(); +// } + +// return b1; +// } +// } +//} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs.meta new file mode 100644 index 0000000..7e3ea52 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/IndefiniteLengthInputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5faa2aff355d23945ae836ec7393a1b9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs new file mode 100644 index 0000000..3643b6a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs @@ -0,0 +1,36 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class LazyAsn1InputStream + : Asn1InputStream + { + public LazyAsn1InputStream( + byte[] input) + : base(input) + { + } + + public LazyAsn1InputStream( + Stream inputStream) + : base(inputStream) + { + } + + internal override DerSequence CreateDerSequence( + DefiniteLengthInputStream dIn) + { + return new LazyDerSequence(dIn.ToArray()); + } + + internal override DerSet CreateDerSet( + DefiniteLengthInputStream dIn) + { + return new LazyDerSet(dIn.ToArray()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs.meta new file mode 100644 index 0000000..79f1e8e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyASN1InputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2b99b4c1a9bb0e04cac3fe4ae55f6cf9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs new file mode 100644 index 0000000..a754807 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs @@ -0,0 +1,83 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.Diagnostics; + +namespace Org.BouncyCastle.Asn1 +{ + internal class LazyDerSequence + : DerSequence + { + private byte[] encoded; + + internal LazyDerSequence( + byte[] encoded) + { + this.encoded = encoded; + } + + private void Parse() + { + lock (this) + { + if (encoded != null) + { + Asn1InputStream e = new LazyAsn1InputStream(encoded); + + Asn1Object o; + while ((o = e.ReadObject()) != null) + { + AddObject(o); + } + + encoded = null; + } + } + } + + public override Asn1Encodable this[int index] + { + get + { + Parse(); + + return base[index]; + } + } + + public override IEnumerator GetEnumerator() + { + Parse(); + + return base.GetEnumerator(); + } + + public override int Count + { + get + { + Parse(); + + return base.Count; + } + } + + internal override void Encode( + DerOutputStream derOut) + { + lock (this) + { + if (encoded == null) + { + base.Encode(derOut); + } + else + { + derOut.WriteEncoded(Asn1Tags.Sequence | Asn1Tags.Constructed, encoded); + } + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs.meta new file mode 100644 index 0000000..7d918c0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSequence.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 05b54ca5e1058684db4f666dfd635913 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs new file mode 100644 index 0000000..e0218af --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs @@ -0,0 +1,83 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.Diagnostics; + +namespace Org.BouncyCastle.Asn1 +{ + internal class LazyDerSet + : DerSet + { + private byte[] encoded; + + internal LazyDerSet( + byte[] encoded) + { + this.encoded = encoded; + } + + private void Parse() + { + lock (this) + { + if (encoded != null) + { + Asn1InputStream e = new LazyAsn1InputStream(encoded); + + Asn1Object o; + while ((o = e.ReadObject()) != null) + { + AddObject(o); + } + + encoded = null; + } + } + } + + public override Asn1Encodable this[int index] + { + get + { + Parse(); + + return base[index]; + } + } + + public override IEnumerator GetEnumerator() + { + Parse(); + + return base.GetEnumerator(); + } + + public override int Count + { + get + { + Parse(); + + return base.Count; + } + } + + internal override void Encode( + DerOutputStream derOut) + { + lock (this) + { + if (encoded == null) + { + base.Encode(derOut); + } + else + { + derOut.WriteEncoded(Asn1Tags.Set | Asn1Tags.Constructed, encoded); + } + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs.meta new file mode 100644 index 0000000..8564bfb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LazyDERSet.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 76bf92893e66b884594d31a9693939d6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs new file mode 100644 index 0000000..e4f7560 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs @@ -0,0 +1,38 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + internal abstract class LimitedInputStream + : BaseInputStream + { + protected readonly Stream _in; + private int _limit; + + internal LimitedInputStream( + Stream inStream, + int limit) + { + this._in = inStream; + this._limit = limit; + } + + internal virtual int GetRemaining() + { + // TODO: maybe one day this can become more accurate + return _limit; + } + + protected virtual void SetParentEofDetect(bool on) + { + if (_in is IndefiniteLengthInputStream) + { + ((IndefiniteLengthInputStream)_in).SetEofOn00(on); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs.meta new file mode 100644 index 0000000..4a62351 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/LimitedInputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2282e5c2e036b444d8ef59d4ca1522dc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs new file mode 100644 index 0000000..c91b408 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1 +{ + /** + * class for breaking up an Oid into it's component tokens, ala + * java.util.StringTokenizer. We need this class as some of the + * lightweight Java environment don't support classes like + * StringTokenizer. + */ + public class OidTokenizer + { + private string oid; + private int index; + + public OidTokenizer( + string oid) + { + this.oid = oid; + } + + public bool HasMoreTokens + { + get { return index != -1; } + } + + public string NextToken() + { + if (index == -1) + { + return null; + } + + int end = oid.IndexOf('.', index); + if (end == -1) + { + string lastToken = oid.Substring(index); + index = -1; + return lastToken; + } + + string nextToken = oid.Substring(index, end - index); + index = end + 1; + return nextToken; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs.meta new file mode 100644 index 0000000..17ed1d7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/OidTokenizer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d6be1ce8f546e0745948e3d162116698 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi.meta new file mode 100644 index 0000000..7103a61 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a78b3d8524e59be4999d414a705d774a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs new file mode 100644 index 0000000..5e8dd2c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs @@ -0,0 +1,126 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Anssi +{ + public class AnssiNamedCurves + { + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.Decode(hex)); + } + + /* + * FRP256v1 + */ + internal class Frp256v1Holder + : X9ECParametersHolder + { + private Frp256v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Frp256v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger p = FromHex("F1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C03"); + BigInteger a = FromHex("F1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C00"); + BigInteger b = FromHex("EE353FCA5428A9300D4ABA754A44C00FDFEC0C9AE4B1A1803075ED967B7BB73F"); + byte[] S = null; + BigInteger n = FromHex("F1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF" + + "6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB")); + + return new X9ECParameters(curve, G, n, h, S); + } + }; + + + private static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary curves = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary names = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static AnssiNamedCurves() + { + DefineCurve("FRP256v1", AnssiObjectIdentifiers.FRP256v1, Frp256v1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs.meta new file mode 100644 index 0000000..44c7fef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSINamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e908adca735a50b4ea4afcceea30542f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs new file mode 100644 index 0000000..04ffa6e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1.Anssi +{ + public sealed class AnssiObjectIdentifiers + { + private AnssiObjectIdentifiers() + { + } + + public static readonly DerObjectIdentifier FRP256v1 = new DerObjectIdentifier("1.2.250.1.223.101.256.1"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs.meta new file mode 100644 index 0000000..440af27 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/anssi/ANSSIObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: edd7ffa2202a9ad4fb1a88ae60f09ea7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro.meta new file mode 100644 index 0000000..df6f551 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e3ca23ca4294d3b4b9a88be14d6cde49 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs new file mode 100644 index 0000000..1a0fe11 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs @@ -0,0 +1,54 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public abstract class CryptoProObjectIdentifiers + { + // GOST Algorithms OBJECT IDENTIFIERS : + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)} + public const string GostID = "1.2.643.2.2"; + + public static readonly DerObjectIdentifier GostR3411 = new DerObjectIdentifier(GostID + ".9"); + public static readonly DerObjectIdentifier GostR3411Hmac = new DerObjectIdentifier(GostID + ".10"); + + public static readonly DerObjectIdentifier GostR28147Cbc = new DerObjectIdentifier(GostID + ".21"); + + public static readonly DerObjectIdentifier ID_Gost28147_89_CryptoPro_A_ParamSet = new DerObjectIdentifier(GostID + ".31.1"); + + public static readonly DerObjectIdentifier GostR3410x94 = new DerObjectIdentifier(GostID + ".20"); + public static readonly DerObjectIdentifier GostR3410x2001 = new DerObjectIdentifier(GostID + ".19"); + public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x94 = new DerObjectIdentifier(GostID + ".4"); + public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x2001 = new DerObjectIdentifier(GostID + ".3"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) hashes(30) } + public static readonly DerObjectIdentifier GostR3411x94CryptoProParamSet = new DerObjectIdentifier(GostID + ".30.1"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) signs(32) } + public static readonly DerObjectIdentifier GostR3410x94CryptoProA = new DerObjectIdentifier(GostID + ".32.2"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProB = new DerObjectIdentifier(GostID + ".32.3"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProC = new DerObjectIdentifier(GostID + ".32.4"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProD = new DerObjectIdentifier(GostID + ".32.5"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) exchanges(33) } + public static readonly DerObjectIdentifier GostR3410x94CryptoProXchA = new DerObjectIdentifier(GostID + ".33.1"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProXchB = new DerObjectIdentifier(GostID + ".33.2"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProXchC = new DerObjectIdentifier(GostID + ".33.3"); + + //{ iso(1) member-body(2)ru(643) rans(2) cryptopro(2) ecc-signs(35) } + public static readonly DerObjectIdentifier GostR3410x2001CryptoProA = new DerObjectIdentifier(GostID + ".35.1"); + public static readonly DerObjectIdentifier GostR3410x2001CryptoProB = new DerObjectIdentifier(GostID + ".35.2"); + public static readonly DerObjectIdentifier GostR3410x2001CryptoProC = new DerObjectIdentifier(GostID + ".35.3"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) ecc-exchanges(36) } + public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchA = new DerObjectIdentifier(GostID + ".36.0"); + public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchB = new DerObjectIdentifier(GostID + ".36.1"); + + public static readonly DerObjectIdentifier GostElSgDH3410Default = new DerObjectIdentifier(GostID + ".36.0"); + public static readonly DerObjectIdentifier GostElSgDH3410x1 = new DerObjectIdentifier(GostID + ".36.1"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta new file mode 100644 index 0000000..4897f57 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: be4c3eced0609684c9f9ffa5a4ddd1c5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs new file mode 100644 index 0000000..52e0686 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs @@ -0,0 +1,187 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + /** + * table of the available named parameters for GOST 3410-2001. + */ + public sealed class ECGost3410NamedCurves + { + private ECGost3410NamedCurves() + { + } + + internal static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + internal static readonly IDictionary parameters = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + internal static readonly IDictionary names = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + static ECGost3410NamedCurves() + { + BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); + BigInteger mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); + + FpCurve curve = new FpCurve( + mod_p, // p + new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a + new BigInteger("166"), // b + mod_q, + BigInteger.One); + + ECDomainParameters ecParams = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("1"), // x + new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y + mod_q); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams; + + mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); + mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); + + curve = new FpCurve( + mod_p, // p + new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), + new BigInteger("166"), + mod_q, + BigInteger.One); + + ecParams = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("1"), // x + new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y + mod_q); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = ecParams; + + mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p + mod_q = new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703"); //q + + curve = new FpCurve( + mod_p, // p + new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a + new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595"), // b + mod_q, + BigInteger.One); + + ecParams = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("1"), // x + new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124")), // y + mod_q); // q + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = ecParams; + + mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); + mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); + + curve = new FpCurve( + mod_p, // p + new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), + new BigInteger("32858"), + mod_q, + BigInteger.One); + + ecParams = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("0"), + new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), + mod_q); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = ecParams; + + mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p + mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); //q + curve = new FpCurve( + mod_p, // p + new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a + new BigInteger("32858"), // b + mod_q, + BigInteger.One); + + ecParams = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("0"), // x + new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y + mod_q); // q + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams; + + objIds["GostR3410-2001-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProA; + objIds["GostR3410-2001-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProB; + objIds["GostR3410-2001-CryptoPro-C"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProC; + objIds["GostR3410-2001-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA; + objIds["GostR3410-2001-CryptoPro-XchB"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB; + + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = "GostR3410-2001-CryptoPro-A"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = "GostR3410-2001-CryptoPro-B"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = "GostR3410-2001-CryptoPro-C"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = "GostR3410-2001-CryptoPro-XchA"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = "GostR3410-2001-CryptoPro-XchB"; + } + + /** + * return the ECDomainParameters object for the given OID, null if it + * isn't present. + * + * @param oid an object identifier representing a named parameters, if present. + */ + public static ECDomainParameters GetByOid( + DerObjectIdentifier oid) + { + return (ECDomainParameters) parameters[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + + public static ECDomainParameters GetByName( + string name) + { + DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name]; + + if (oid != null) + { + return (ECDomainParameters) parameters[oid]; + } + + return null; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string) names[oid]; + } + + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier) objIds[name]; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta new file mode 100644 index 0000000..c9f9ff9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 052c30aad96856e439a9a9ac7651d489 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs new file mode 100644 index 0000000..5e410b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs @@ -0,0 +1,126 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + /** + * table of the available named parameters for GOST 3410-94. + */ + public sealed class Gost3410NamedParameters + { + private Gost3410NamedParameters() + { + } + + private static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary parameters = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + private static readonly Gost3410ParamSetParameters cryptoProA = new Gost3410ParamSetParameters( + 1024, + new BigInteger("127021248288932417465907042777176443525787653508916535812817507265705031260985098497423188333483401180925999995120988934130659205614996724254121049274349357074920312769561451689224110579311248812610229678534638401693520013288995000362260684222750813532307004517341633685004541062586971416883686778842537820383"), + new BigInteger("68363196144955700784444165611827252895102170888761442055095051287550314083023"), + new BigInteger("100997906755055304772081815535925224869841082572053457874823515875577147990529272777244152852699298796483356699682842027972896052747173175480590485607134746852141928680912561502802222185647539190902656116367847270145019066794290930185446216399730872221732889830323194097355403213400972588322876850946740663962") + // validationAlgorithm { + // algorithm + // id-GostR3410-94-bBis, + // parameters + // GostR3410-94-ValidationBisParameters: { + // x0 1376285941, + // c 3996757427 + // } + // } + + ); + + private static readonly Gost3410ParamSetParameters cryptoProB = new Gost3410ParamSetParameters( + 1024, + new BigInteger("139454871199115825601409655107690713107041707059928031797758001454375765357722984094124368522288239833039114681648076688236921220737322672160740747771700911134550432053804647694904686120113087816240740184800477047157336662926249423571248823968542221753660143391485680840520336859458494803187341288580489525163"), + new BigInteger("79885141663410976897627118935756323747307951916507639758300472692338873533959"), + new BigInteger("42941826148615804143873447737955502392672345968607143066798112994089471231420027060385216699563848719957657284814898909770759462613437669456364882730370838934791080835932647976778601915343474400961034231316672578686920482194932878633360203384797092684342247621055760235016132614780652761028509445403338652341") + // validationAlgorithm { + // algorithm + // id-GostR3410-94-bBis, + // parameters + // GostR3410-94-ValidationBisParameters: { + // x0 1536654555, + // c 1855361757, + // d 14408629386140014567655 + //4902939282056547857802241461782996702017713059974755104394739915140 + //6115284791024439062735788342744854120601660303926203867703556828005 + //8957203818114895398976594425537561271800850306 + // } + // } + //} + ); + + private static readonly Gost3410ParamSetParameters cryptoProXchA = new Gost3410ParamSetParameters( + 1024, + new BigInteger("142011741597563481196368286022318089743276138395243738762872573441927459393512718973631166078467600360848946623567625795282774719212241929071046134208380636394084512691828894000571524625445295769349356752728956831541775441763139384457191755096847107846595662547942312293338483924514339614727760681880609734239"), + new BigInteger("91771529896554605945588149018382750217296858393520724172743325725474374979801"), + new BigInteger("133531813272720673433859519948319001217942375967847486899482359599369642528734712461590403327731821410328012529253871914788598993103310567744136196364803064721377826656898686468463277710150809401182608770201615324990468332931294920912776241137878030224355746606283971659376426832674269780880061631528163475887") + ); + + static Gost3410NamedParameters() + { + parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProA] = cryptoProA; + parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProB] = cryptoProB; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProC] = cryptoProC; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProD] = cryptoProD; + parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA] = cryptoProXchA; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchB] = cryptoProXchA; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchC] = cryptoProXchA; + + objIds["GostR3410-94-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProA; + objIds["GostR3410-94-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProB; + objIds["GostR3410-94-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA; + } + + /** + * return the GOST3410ParamSetParameters object for the given OID, null if it + * isn't present. + * + * @param oid an object identifier representing a named parameters, if present. + */ + public static Gost3410ParamSetParameters GetByOid( + DerObjectIdentifier oid) + { + return (Gost3410ParamSetParameters) parameters[oid]; + } + + /** + * returns an enumeration containing the name strings for parameters + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(objIds.Keys); } + } + + public static Gost3410ParamSetParameters GetByName( + string name) + { + DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name]; + + if (oid != null) + { + return (Gost3410ParamSetParameters) parameters[oid]; + } + + return null; + } + + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier) objIds[name]; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs.meta new file mode 100644 index 0000000..2a0147f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410NamedParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b57d96c489c54b94c9770abece1115aa +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs new file mode 100644 index 0000000..515c8e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs @@ -0,0 +1,90 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public class Gost3410ParamSetParameters + : Asn1Encodable + { + private readonly int keySize; + private readonly DerInteger p, q, a; + + public static Gost3410ParamSetParameters GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Gost3410ParamSetParameters GetInstance( + object obj) + { + if (obj == null || obj is Gost3410ParamSetParameters) + { + return (Gost3410ParamSetParameters) obj; + } + + if (obj is Asn1Sequence) + { + return new Gost3410ParamSetParameters((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid GOST3410Parameter: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + public Gost3410ParamSetParameters( + int keySize, + BigInteger p, + BigInteger q, + BigInteger a) + { + this.keySize = keySize; + this.p = new DerInteger(p); + this.q = new DerInteger(q); + this.a = new DerInteger(a); + } + + private Gost3410ParamSetParameters( + Asn1Sequence seq) + { + if (seq.Count != 4) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.keySize = DerInteger.GetInstance(seq[0]).Value.IntValue; + this.p = DerInteger.GetInstance(seq[1]); + this.q = DerInteger.GetInstance(seq[2]); + this.a = DerInteger.GetInstance(seq[3]); + } + + public int KeySize + { + get { return keySize; } + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger Q + { + get { return q.PositiveValue; } + } + + public BigInteger A + { + get { return a.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(new DerInteger(keySize), p, q, a); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta new file mode 100644 index 0000000..863d9e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f3aa39c3f91903543994a83200a235d9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs new file mode 100644 index 0000000..ed934aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public class Gost3410PublicKeyAlgParameters + : Asn1Encodable + { + private DerObjectIdentifier publicKeyParamSet; + private DerObjectIdentifier digestParamSet; + private DerObjectIdentifier encryptionParamSet; + + public static Gost3410PublicKeyAlgParameters GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Gost3410PublicKeyAlgParameters GetInstance( + object obj) + { + if (obj == null || obj is Gost3410PublicKeyAlgParameters) + { + return (Gost3410PublicKeyAlgParameters) obj; + } + + if (obj is Asn1Sequence) + { + return new Gost3410PublicKeyAlgParameters((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid GOST3410Parameter: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + public Gost3410PublicKeyAlgParameters( + DerObjectIdentifier publicKeyParamSet, + DerObjectIdentifier digestParamSet) + : this (publicKeyParamSet, digestParamSet, null) + { + } + + public Gost3410PublicKeyAlgParameters( + DerObjectIdentifier publicKeyParamSet, + DerObjectIdentifier digestParamSet, + DerObjectIdentifier encryptionParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + if (digestParamSet == null) + throw new ArgumentNullException("digestParamSet"); + + this.publicKeyParamSet = publicKeyParamSet; + this.digestParamSet = digestParamSet; + this.encryptionParamSet = encryptionParamSet; + } + + public Gost3410PublicKeyAlgParameters( + Asn1Sequence seq) + { + this.publicKeyParamSet = (DerObjectIdentifier) seq[0]; + this.digestParamSet = (DerObjectIdentifier) seq[1]; + + if (seq.Count > 2) + { + this.encryptionParamSet = (DerObjectIdentifier) seq[2]; + } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + public DerObjectIdentifier DigestParamSet + { + get { return digestParamSet; } + } + + public DerObjectIdentifier EncryptionParamSet + { + get { return encryptionParamSet; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + publicKeyParamSet, digestParamSet); + + if (encryptionParamSet != null) + { + v.Add(encryptionParamSet); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta new file mode 100644 index 0000000..9520ac2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d4780d2370f25ea43972c78a80d65319 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana.meta new file mode 100644 index 0000000..7ba089f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3e16237bf0f5bb14e8475973550804e3 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs new file mode 100644 index 0000000..5d8b751 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.Iana +{ + public abstract class IanaObjectIdentifiers + { + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1)} + // + + public static readonly DerObjectIdentifier IsakmpOakley = new DerObjectIdentifier("1.3.6.1.5.5.8.1"); + + public static readonly DerObjectIdentifier HmacMD5 = new DerObjectIdentifier(IsakmpOakley + ".1"); + public static readonly DerObjectIdentifier HmacSha1 = new DerObjectIdentifier(IsakmpOakley + ".2"); + + public static readonly DerObjectIdentifier HmacTiger = new DerObjectIdentifier(IsakmpOakley + ".3"); + + public static readonly DerObjectIdentifier HmacRipeMD160 = new DerObjectIdentifier(IsakmpOakley + ".4"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs.meta new file mode 100644 index 0000000..c9fcda6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/iana/IANAObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8cd1511c90406684f8d5a303e45a9012 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc.meta new file mode 100644 index 0000000..5cff221 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5ea43e51ea443414cb46f425a92b6a69 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs new file mode 100644 index 0000000..9e3713a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.Misc +{ + public abstract class MiscObjectIdentifiers + { + // + // Netscape + // iso/itu(2) joint-assign(16) us(840) uscompany(1) Netscape(113730) cert-extensions(1) } + // + public static readonly DerObjectIdentifier Netscape = new DerObjectIdentifier("2.16.840.1.113730.1"); + public static readonly DerObjectIdentifier NetscapeCertType = Netscape.Branch("1"); + public static readonly DerObjectIdentifier NetscapeBaseUrl = Netscape.Branch("2"); + public static readonly DerObjectIdentifier NetscapeRevocationUrl = Netscape.Branch("3"); + public static readonly DerObjectIdentifier NetscapeCARevocationUrl = Netscape.Branch("4"); + public static readonly DerObjectIdentifier NetscapeRenewalUrl = Netscape.Branch("7"); + public static readonly DerObjectIdentifier NetscapeCAPolicyUrl = Netscape.Branch("8"); + public static readonly DerObjectIdentifier NetscapeSslServerName = Netscape.Branch("12"); + public static readonly DerObjectIdentifier NetscapeCertComment = Netscape.Branch("13"); + + // + // Verisign + // iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) } + // + public static readonly DerObjectIdentifier Verisign = new DerObjectIdentifier("2.16.840.1.113733.1"); + + // + // CZAG - country, zip, age, and gender + // + public static readonly DerObjectIdentifier VerisignCzagExtension = Verisign.Branch("6.3"); + + public static readonly DerObjectIdentifier VerisignPrivate_6_9 = Verisign.Branch("6.9"); + public static readonly DerObjectIdentifier VerisignOnSiteJurisdictionHash = Verisign.Branch("6.11"); + public static readonly DerObjectIdentifier VerisignBitString_6_13 = Verisign.Branch("6.13"); + + // D&B D-U-N-S number + public static readonly DerObjectIdentifier VerisignDnbDunsNumber = Verisign.Branch("6.15"); + + public static readonly DerObjectIdentifier VerisignIssStrongCrypto = Verisign.Branch("8.1"); + + // + // Novell + // iso/itu(2) country(16) us(840) organization(1) novell(113719) + // + public static readonly string Novell = "2.16.840.1.113719"; + public static readonly DerObjectIdentifier NovellSecurityAttribs = new DerObjectIdentifier(Novell + ".1.9.4.1"); + + // + // Entrust + // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7) + // + public static readonly string Entrust = "1.2.840.113533.7"; + public static readonly DerObjectIdentifier EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0"); + + // + // Ascom + // + public static readonly DerObjectIdentifier as_sys_sec_alg_ideaCBC = new DerObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2"); + + // + // Peter Gutmann's Cryptlib + // + public static readonly DerObjectIdentifier cryptlib = new DerObjectIdentifier("1.3.6.1.4.1.3029"); + + public static readonly DerObjectIdentifier cryptlib_algorithm = cryptlib.Branch("1"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_ECB = cryptlib_algorithm.Branch("1.1"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CBC = cryptlib_algorithm.Branch("1.2"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.Branch("1.3"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.Branch("1.4"); + + // + // Blake2b + // + public static readonly DerObjectIdentifier blake2 = new DerObjectIdentifier("1.3.6.1.4.1.1722.12.2"); + + public static readonly DerObjectIdentifier id_blake2b160 = blake2.Branch("1.5"); + public static readonly DerObjectIdentifier id_blake2b256 = blake2.Branch("1.8"); + public static readonly DerObjectIdentifier id_blake2b384 = blake2.Branch("1.12"); + public static readonly DerObjectIdentifier id_blake2b512 = blake2.Branch("1.16"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs.meta new file mode 100644 index 0000000..81bd12b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/MiscObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ffdbc8830f79f824dba418df238c3d44 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs new file mode 100644 index 0000000..adc41c7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs @@ -0,0 +1,57 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + /** + * The NetscapeCertType object. + *
+     *    NetscapeCertType ::= BIT STRING {
+     *         SSLClient               (0),
+     *         SSLServer               (1),
+     *         S/MIME                  (2),
+     *         Object Signing          (3),
+     *         Reserved                (4),
+     *         SSL CA                  (5),
+     *         S/MIME CA               (6),
+     *         Object Signing CA       (7) }
+     * 
+ */ + public class NetscapeCertType + : DerBitString + { + public const int SslClient = (1 << 7); + public const int SslServer = (1 << 6); + public const int Smime = (1 << 5); + public const int ObjectSigning = (1 << 4); + public const int Reserved = (1 << 3); + public const int SslCA = (1 << 2); + public const int SmimeCA = (1 << 1); + public const int ObjectSigningCA = (1 << 0); + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA) + */ + public NetscapeCertType(int usage) + : base(usage) + { + } + + public NetscapeCertType(DerBitString usage) + : base(usage.GetBytes(), usage.PadBits) + { + } + + public override string ToString() + { + byte[] data = GetBytes(); + return "NetscapeCertType: 0x" + (data[0] & 0xff).ToString("X"); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs.meta new file mode 100644 index 0000000..271ac0f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeCertType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d87f849d29198334ab7d6ede2a794d59 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs new file mode 100644 index 0000000..1aeac59 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + public class NetscapeRevocationUrl + : DerIA5String + { + public NetscapeRevocationUrl(DerIA5String str) + : base(str.GetString()) + { + } + + public override string ToString() + { + return "NetscapeRevocationUrl: " + this.GetString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs.meta new file mode 100644 index 0000000..99cd440 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/NetscapeRevocationURL.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 566e17568a7913148b5dec3061e0c7ec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs new file mode 100644 index 0000000..aa91b34 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + public class VerisignCzagExtension + : DerIA5String + { + public VerisignCzagExtension(DerIA5String str) + : base(str.GetString()) + { + } + + public override string ToString() + { + return "VerisignCzagExtension: " + this.GetString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs.meta new file mode 100644 index 0000000..041d5ab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/misc/VerisignCzagExtension.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ea51add55957484479a5898cc980d7b9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist.meta new file mode 100644 index 0000000..0e90acb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e02e741e81a810c4a82a0730fa1d0d19 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs new file mode 100644 index 0000000..05299ac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Nist +{ + /** + * Utility class for fetching curves using their NIST names as published in FIPS-PUB 186-3 + */ + public sealed class NistNamedCurves + { + private NistNamedCurves() + { + } + + private static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary names = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + private static void DefineCurveAlias( + string name, + DerObjectIdentifier oid) + { + objIds.Add(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + } + + static NistNamedCurves() + { + DefineCurveAlias("B-163", SecObjectIdentifiers.SecT163r2); + DefineCurveAlias("B-233", SecObjectIdentifiers.SecT233r1); + DefineCurveAlias("B-283", SecObjectIdentifiers.SecT283r1); + DefineCurveAlias("B-409", SecObjectIdentifiers.SecT409r1); + DefineCurveAlias("B-571", SecObjectIdentifiers.SecT571r1); + + DefineCurveAlias("K-163", SecObjectIdentifiers.SecT163k1); + DefineCurveAlias("K-233", SecObjectIdentifiers.SecT233k1); + DefineCurveAlias("K-283", SecObjectIdentifiers.SecT283k1); + DefineCurveAlias("K-409", SecObjectIdentifiers.SecT409k1); + DefineCurveAlias("K-571", SecObjectIdentifiers.SecT571k1); + + DefineCurveAlias("P-192", SecObjectIdentifiers.SecP192r1); + DefineCurveAlias("P-224", SecObjectIdentifiers.SecP224r1); + DefineCurveAlias("P-256", SecObjectIdentifiers.SecP256r1); + DefineCurveAlias("P-384", SecObjectIdentifiers.SecP384r1); + DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + return SecNamedCurves.GetByOid(oid); + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier) objIds[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string) names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs.meta new file mode 100644 index 0000000..796fd6e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTNamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9f827e48f3be93842b031d823157cb82 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs new file mode 100644 index 0000000..669a7bc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs @@ -0,0 +1,74 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Nist +{ + public sealed class NistObjectIdentifiers + { + private NistObjectIdentifiers() + { + } + + // + // NIST + // iso/itu(2) joint-assign(16) us(840) organization(1) gov(101) csor(3) + + // + // nistalgorithms(4) + // + public static readonly DerObjectIdentifier NistAlgorithm = new DerObjectIdentifier("2.16.840.1.101.3.4"); + + public static readonly DerObjectIdentifier HashAlgs = NistAlgorithm.Branch("2"); + + public static readonly DerObjectIdentifier IdSha256 = HashAlgs.Branch("1"); + public static readonly DerObjectIdentifier IdSha384 = HashAlgs.Branch("2"); + public static readonly DerObjectIdentifier IdSha512 = HashAlgs.Branch("3"); + public static readonly DerObjectIdentifier IdSha224 = HashAlgs.Branch("4"); + public static readonly DerObjectIdentifier IdSha512_224 = HashAlgs.Branch("5"); + public static readonly DerObjectIdentifier IdSha512_256 = HashAlgs.Branch("6"); + public static readonly DerObjectIdentifier IdSha3_224 = HashAlgs.Branch("7"); + public static readonly DerObjectIdentifier IdSha3_256 = HashAlgs.Branch("8"); + public static readonly DerObjectIdentifier IdSha3_384 = HashAlgs.Branch("9"); + public static readonly DerObjectIdentifier IdSha3_512 = HashAlgs.Branch("10"); + public static readonly DerObjectIdentifier IdShake128 = HashAlgs.Branch("11"); + public static readonly DerObjectIdentifier IdShake256 = HashAlgs.Branch("12"); + + public static readonly DerObjectIdentifier Aes = new DerObjectIdentifier(NistAlgorithm + ".1"); + + public static readonly DerObjectIdentifier IdAes128Ecb = new DerObjectIdentifier(Aes + ".1"); + public static readonly DerObjectIdentifier IdAes128Cbc = new DerObjectIdentifier(Aes + ".2"); + public static readonly DerObjectIdentifier IdAes128Ofb = new DerObjectIdentifier(Aes + ".3"); + public static readonly DerObjectIdentifier IdAes128Cfb = new DerObjectIdentifier(Aes + ".4"); + public static readonly DerObjectIdentifier IdAes128Wrap = new DerObjectIdentifier(Aes + ".5"); + public static readonly DerObjectIdentifier IdAes128Gcm = new DerObjectIdentifier(Aes + ".6"); + public static readonly DerObjectIdentifier IdAes128Ccm = new DerObjectIdentifier(Aes + ".7"); + + public static readonly DerObjectIdentifier IdAes192Ecb = new DerObjectIdentifier(Aes + ".21"); + public static readonly DerObjectIdentifier IdAes192Cbc = new DerObjectIdentifier(Aes + ".22"); + public static readonly DerObjectIdentifier IdAes192Ofb = new DerObjectIdentifier(Aes + ".23"); + public static readonly DerObjectIdentifier IdAes192Cfb = new DerObjectIdentifier(Aes + ".24"); + public static readonly DerObjectIdentifier IdAes192Wrap = new DerObjectIdentifier(Aes + ".25"); + public static readonly DerObjectIdentifier IdAes192Gcm = new DerObjectIdentifier(Aes + ".26"); + public static readonly DerObjectIdentifier IdAes192Ccm = new DerObjectIdentifier(Aes + ".27"); + + public static readonly DerObjectIdentifier IdAes256Ecb = new DerObjectIdentifier(Aes + ".41"); + public static readonly DerObjectIdentifier IdAes256Cbc = new DerObjectIdentifier(Aes + ".42"); + public static readonly DerObjectIdentifier IdAes256Ofb = new DerObjectIdentifier(Aes + ".43"); + public static readonly DerObjectIdentifier IdAes256Cfb = new DerObjectIdentifier(Aes + ".44"); + public static readonly DerObjectIdentifier IdAes256Wrap = new DerObjectIdentifier(Aes + ".45"); + public static readonly DerObjectIdentifier IdAes256Gcm = new DerObjectIdentifier(Aes + ".46"); + public static readonly DerObjectIdentifier IdAes256Ccm = new DerObjectIdentifier(Aes + ".47"); + + // + // signatures + // + public static readonly DerObjectIdentifier IdDsaWithSha2 = new DerObjectIdentifier(NistAlgorithm + ".3"); + + public static readonly DerObjectIdentifier DsaWithSha224 = new DerObjectIdentifier(IdDsaWithSha2 + ".1"); + public static readonly DerObjectIdentifier DsaWithSha256 = new DerObjectIdentifier(IdDsaWithSha2 + ".2"); + public static readonly DerObjectIdentifier DsaWithSha384 = new DerObjectIdentifier(IdDsaWithSha2 + ".3"); + public static readonly DerObjectIdentifier DsaWithSha512 = new DerObjectIdentifier(IdDsaWithSha2 + ".4"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs.meta new file mode 100644 index 0000000..e17808b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/nist/NISTObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 156ecab2f2766c44d9d74760780d0860 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp.meta new file mode 100644 index 0000000..065564c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 44025a17146cfb54bbf85c69cc3fc7d9 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs new file mode 100644 index 0000000..52d7b2a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs @@ -0,0 +1,93 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class OcspResponse + : Asn1Encodable + { + private readonly OcspResponseStatus responseStatus; + private readonly ResponseBytes responseBytes; + + public static OcspResponse GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static OcspResponse GetInstance( + object obj) + { + if (obj == null || obj is OcspResponse) + { + return (OcspResponse)obj; + } + + if (obj is Asn1Sequence) + { + return new OcspResponse((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public OcspResponse( + OcspResponseStatus responseStatus, + ResponseBytes responseBytes) + { + if (responseStatus == null) + throw new ArgumentNullException("responseStatus"); + + this.responseStatus = responseStatus; + this.responseBytes = responseBytes; + } + + private OcspResponse( + Asn1Sequence seq) + { + responseStatus = new OcspResponseStatus( + DerEnumerated.GetInstance(seq[0])); + + if (seq.Count == 2) + { + responseBytes = ResponseBytes.GetInstance( + (Asn1TaggedObject)seq[1], true); + } + } + + public OcspResponseStatus ResponseStatus + { + get { return responseStatus; } + } + + public ResponseBytes ResponseBytes + { + get { return responseBytes; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OcspResponse ::= Sequence {
+         *     responseStatus         OcspResponseStatus,
+         *     responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(responseStatus); + + if (responseBytes != null) + { + v.Add(new DerTaggedObject(true, 0, responseBytes)); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs.meta new file mode 100644 index 0000000..d183aa1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponse.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3b6d3078d2d344f4b937e25054e084ae +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs new file mode 100644 index 0000000..ebadb20 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class OcspResponseStatus + : DerEnumerated + { + public const int Successful = 0; + public const int MalformedRequest = 1; + public const int InternalError = 2; + public const int TryLater = 3; + public const int SignatureRequired = 5; + public const int Unauthorized = 6; + + /** + * The OcspResponseStatus enumeration. + *
+         * OcspResponseStatus ::= Enumerated {
+         *     successful            (0),  --Response has valid confirmations
+         *     malformedRequest      (1),  --Illegal confirmation request
+         *     internalError         (2),  --Internal error in issuer
+         *     tryLater              (3),  --Try again later
+         *                                 --(4) is not used
+         *     sigRequired           (5),  --Must sign the request
+         *     unauthorized          (6)   --Request unauthorized
+         * }
+         * 
+ */ + public OcspResponseStatus(int value) + : base(value) + { + } + + public OcspResponseStatus(DerEnumerated value) + : base(value.Value.IntValue) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs.meta new file mode 100644 index 0000000..1462257 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/OCSPResponseStatus.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 23667b08f22dccd4bbf811e2f210dd74 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs new file mode 100644 index 0000000..faea822 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs @@ -0,0 +1,110 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class ResponderID + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Encodable id; + + public static ResponderID GetInstance( + object obj) + { + if (obj == null || obj is ResponderID) + { + return (ResponderID)obj; + } + + if (obj is DerOctetString) + { + return new ResponderID((DerOctetString)obj); + } + + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject o = (Asn1TaggedObject)obj; + + if (o.TagNo == 1) + { + return new ResponderID(X509Name.GetInstance(o, true)); + } + + return new ResponderID(Asn1OctetString.GetInstance(o, true)); + } + + return new ResponderID(X509Name.GetInstance(obj)); + } + + public ResponderID( + Asn1OctetString id) + { + if (id == null) + throw new ArgumentNullException("id"); + + this.id = id; + } + + public ResponderID( + X509Name id) + { + if (id == null) + throw new ArgumentNullException("id"); + + this.id = id; + } + + public static ResponderID GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(obj.GetObject()); // must be explicitly tagged + } + + public virtual byte[] GetKeyHash() + { + if (id is Asn1OctetString) + { + return ((Asn1OctetString)id).GetOctets(); + } + + return null; + } + + public virtual X509Name Name + { + get + { + if (id is Asn1OctetString) + { + return null; + } + + return X509Name.GetInstance(id); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ResponderID ::= CHOICE {
+         *      byName          [1] Name,
+         *      byKey           [2] KeyHash }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + if (id is Asn1OctetString) + { + return new DerTaggedObject(true, 2, id); + } + + return new DerTaggedObject(true, 1, id); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs.meta new file mode 100644 index 0000000..aeaf1a9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponderID.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1d2f0b66c62702343b6d4d874dab6abe +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs new file mode 100644 index 0000000..c3278fa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs @@ -0,0 +1,85 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class ResponseBytes + : Asn1Encodable + { + private readonly DerObjectIdentifier responseType; + private readonly Asn1OctetString response; + + public static ResponseBytes GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static ResponseBytes GetInstance( + object obj) + { + if (obj == null || obj is ResponseBytes) + { + return (ResponseBytes)obj; + } + + if (obj is Asn1Sequence) + { + return new ResponseBytes((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public ResponseBytes( + DerObjectIdentifier responseType, + Asn1OctetString response) + { + if (responseType == null) + throw new ArgumentNullException("responseType"); + if (response == null) + throw new ArgumentNullException("response"); + + this.responseType = responseType; + this.response = response; + } + + private ResponseBytes( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.responseType = DerObjectIdentifier.GetInstance(seq[0]); + this.response = Asn1OctetString.GetInstance(seq[1]); + } + + public DerObjectIdentifier ResponseType + { + get { return responseType; } + } + + public Asn1OctetString Response + { + get { return response; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ResponseBytes ::=       Sequence {
+         *     responseType   OBJECT IDENTIFIER,
+         *     response       OCTET STRING }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(responseType, response); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs.meta new file mode 100644 index 0000000..7bda45f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/ocsp/ResponseBytes.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c1277fc319921a4ebca46154111d17d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw.meta new file mode 100644 index 0000000..074e4d4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09d1a73b7ec49b046a598def5fc61483 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs new file mode 100644 index 0000000..efae689 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs @@ -0,0 +1,50 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Oiw +{ + public class ElGamalParameter + : Asn1Encodable + { + internal DerInteger p, g; + + public ElGamalParameter( + BigInteger p, + BigInteger g) + { + this.p = new DerInteger(p); + this.g = new DerInteger(g); + } + + public ElGamalParameter( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + p = DerInteger.GetInstance(seq[0]); + g = DerInteger.GetInstance(seq[1]); + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(p, g); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs.meta new file mode 100644 index 0000000..25bf354 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/ElGamalParameter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a50b32b1d8a393a438cb8d7e885202e1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs new file mode 100644 index 0000000..bc8d7ce --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs @@ -0,0 +1,32 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.Oiw +{ + public abstract class OiwObjectIdentifiers + { + public static readonly DerObjectIdentifier MD4WithRsa = new DerObjectIdentifier("1.3.14.3.2.2"); + public static readonly DerObjectIdentifier MD5WithRsa = new DerObjectIdentifier("1.3.14.3.2.3"); + public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier("1.3.14.3.2.4"); + + public static readonly DerObjectIdentifier DesEcb = new DerObjectIdentifier("1.3.14.3.2.6"); + public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7"); + public static readonly DerObjectIdentifier DesOfb = new DerObjectIdentifier("1.3.14.3.2.8"); + public static readonly DerObjectIdentifier DesCfb = new DerObjectIdentifier("1.3.14.3.2.9"); + + public static readonly DerObjectIdentifier DesEde = new DerObjectIdentifier("1.3.14.3.2.17"); + + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } // + public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26"); + + public static readonly DerObjectIdentifier DsaWithSha1 = new DerObjectIdentifier("1.3.14.3.2.27"); + + public static readonly DerObjectIdentifier Sha1WithRsa = new DerObjectIdentifier("1.3.14.3.2.29"); + + // ElGamal Algorithm OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 } + // + public static readonly DerObjectIdentifier ElGamalAlgorithm = new DerObjectIdentifier("1.3.14.7.2.1.1"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs.meta new file mode 100644 index 0000000..e7bad60 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/oiw/OIWObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 869fa662a3f9784479a943f14f0a8915 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs.meta new file mode 100644 index 0000000..f7dd846 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09fcff0d03b2a6c4c8a625ec7c05be96 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs new file mode 100644 index 0000000..c9c5728 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs @@ -0,0 +1,77 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class ContentInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier contentType; + private readonly Asn1Encodable content; + + public static ContentInfo GetInstance(object obj) + { + if (obj == null) + return null; + ContentInfo existing = obj as ContentInfo; + if (existing != null) + return existing; + return new ContentInfo(Asn1Sequence.GetInstance(obj)); + } + + private ContentInfo( + Asn1Sequence seq) + { + contentType = (DerObjectIdentifier) seq[0]; + + if (seq.Count > 1) + { + content = ((Asn1TaggedObject) seq[1]).GetObject(); + } + } + + public ContentInfo( + DerObjectIdentifier contentType, + Asn1Encodable content) + { + this.contentType = contentType; + this.content = content; + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public Asn1Encodable Content + { + get { return content; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ContentInfo ::= Sequence {
+         *          contentType ContentType,
+         *          content
+         *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(contentType); + + if (content != null) + { + v.Add(new BerTaggedObject(0, content)); + } + + return new BerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs.meta new file mode 100644 index 0000000..103712e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/ContentInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5322ed3a7bcf61c4cbb3a9aec4ec97cc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs new file mode 100644 index 0000000..a0ef2ea --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs @@ -0,0 +1,75 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Asn1; +using System; +using System.Collections; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class DHParameter + : Asn1Encodable + { + internal DerInteger p, g, l; + + public DHParameter( + BigInteger p, + BigInteger g, + int l) + { + this.p = new DerInteger(p); + this.g = new DerInteger(g); + + if (l != 0) + { + this.l = new DerInteger(l); + } + } + + public DHParameter( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + p = (DerInteger)e.Current; + + e.MoveNext(); + g = (DerInteger)e.Current; + + if (e.MoveNext()) + { + l = (DerInteger) e.Current; + } + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public BigInteger L + { + get { return l == null ? null : l.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(p, g); + + if (this.l != null) + { + v.Add(l); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs.meta new file mode 100644 index 0000000..686f2b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/DHParameter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 67e3f053ff4865548b157255d290ff7a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs new file mode 100644 index 0000000..d7011de --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -0,0 +1,276 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public abstract class PkcsObjectIdentifiers + { + // + // pkcs-1 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } + // + public const string Pkcs1 = "1.2.840.113549.1.1"; + + public static readonly DerObjectIdentifier RsaEncryption = new DerObjectIdentifier(Pkcs1 + ".1"); + public static readonly DerObjectIdentifier MD2WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".2"); + public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".3"); + public static readonly DerObjectIdentifier MD5WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".4"); + public static readonly DerObjectIdentifier Sha1WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".5"); + public static readonly DerObjectIdentifier SrsaOaepEncryptionSet = new DerObjectIdentifier(Pkcs1 + ".6"); + public static readonly DerObjectIdentifier IdRsaesOaep = new DerObjectIdentifier(Pkcs1 + ".7"); + public static readonly DerObjectIdentifier IdMgf1 = new DerObjectIdentifier(Pkcs1 + ".8"); + public static readonly DerObjectIdentifier IdPSpecified = new DerObjectIdentifier(Pkcs1 + ".9"); + public static readonly DerObjectIdentifier IdRsassaPss = new DerObjectIdentifier(Pkcs1 + ".10"); + public static readonly DerObjectIdentifier Sha256WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".11"); + public static readonly DerObjectIdentifier Sha384WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".12"); + public static readonly DerObjectIdentifier Sha512WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".13"); + public static readonly DerObjectIdentifier Sha224WithRsaEncryption = new DerObjectIdentifier(Pkcs1 + ".14"); + + // + // pkcs-3 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 } + // + public const string Pkcs3 = "1.2.840.113549.1.3"; + + public static readonly DerObjectIdentifier DhKeyAgreement = new DerObjectIdentifier(Pkcs3 + ".1"); + + // + // pkcs-5 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } + // + public const string Pkcs5 = "1.2.840.113549.1.5"; + + public static readonly DerObjectIdentifier PbeWithMD2AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".1"); + public static readonly DerObjectIdentifier PbeWithMD2AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".4"); + public static readonly DerObjectIdentifier PbeWithMD5AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".3"); + public static readonly DerObjectIdentifier PbeWithMD5AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".6"); + public static readonly DerObjectIdentifier PbeWithSha1AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".10"); + public static readonly DerObjectIdentifier PbeWithSha1AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".11"); + + public static readonly DerObjectIdentifier IdPbeS2 = new DerObjectIdentifier(Pkcs5 + ".13"); + public static readonly DerObjectIdentifier IdPbkdf2 = new DerObjectIdentifier(Pkcs5 + ".12"); + + // + // encryptionAlgorithm OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) 3 } + // + public const string EncryptionAlgorithm = "1.2.840.113549.3"; + + public static readonly DerObjectIdentifier DesEde3Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".7"); + public static readonly DerObjectIdentifier RC2Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".2"); + + // + // object identifiers for digests + // + public const string DigestAlgorithm = "1.2.840.113549.2"; + + // + // md2 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2} + // + public static readonly DerObjectIdentifier MD2 = new DerObjectIdentifier(DigestAlgorithm + ".2"); + + // + // md4 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 4} + // + public static readonly DerObjectIdentifier MD4 = new DerObjectIdentifier(DigestAlgorithm + ".4"); + + // + // md5 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 5} + // + public static readonly DerObjectIdentifier MD5 = new DerObjectIdentifier(DigestAlgorithm + ".5"); + + public static readonly DerObjectIdentifier IdHmacWithSha1 = new DerObjectIdentifier(DigestAlgorithm + ".7"); + public static readonly DerObjectIdentifier IdHmacWithSha224 = new DerObjectIdentifier(DigestAlgorithm + ".8"); + public static readonly DerObjectIdentifier IdHmacWithSha256 = new DerObjectIdentifier(DigestAlgorithm + ".9"); + public static readonly DerObjectIdentifier IdHmacWithSha384 = new DerObjectIdentifier(DigestAlgorithm + ".10"); + public static readonly DerObjectIdentifier IdHmacWithSha512 = new DerObjectIdentifier(DigestAlgorithm + ".11"); + + // + // pkcs-7 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } + // + public const string Pkcs7 = "1.2.840.113549.1.7"; + + public static readonly DerObjectIdentifier Data = new DerObjectIdentifier(Pkcs7 + ".1"); + public static readonly DerObjectIdentifier SignedData = new DerObjectIdentifier(Pkcs7 + ".2"); + public static readonly DerObjectIdentifier EnvelopedData = new DerObjectIdentifier(Pkcs7 + ".3"); + public static readonly DerObjectIdentifier SignedAndEnvelopedData = new DerObjectIdentifier(Pkcs7 + ".4"); + public static readonly DerObjectIdentifier DigestedData = new DerObjectIdentifier(Pkcs7 + ".5"); + public static readonly DerObjectIdentifier EncryptedData = new DerObjectIdentifier(Pkcs7 + ".6"); + + // + // pkcs-9 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } + // + public const string Pkcs9 = "1.2.840.113549.1.9"; + + public static readonly DerObjectIdentifier Pkcs9AtEmailAddress = new DerObjectIdentifier(Pkcs9 + ".1"); + public static readonly DerObjectIdentifier Pkcs9AtUnstructuredName = new DerObjectIdentifier(Pkcs9 + ".2"); + public static readonly DerObjectIdentifier Pkcs9AtContentType = new DerObjectIdentifier(Pkcs9 + ".3"); + public static readonly DerObjectIdentifier Pkcs9AtMessageDigest = new DerObjectIdentifier(Pkcs9 + ".4"); + public static readonly DerObjectIdentifier Pkcs9AtSigningTime = new DerObjectIdentifier(Pkcs9 + ".5"); + public static readonly DerObjectIdentifier Pkcs9AtCounterSignature = new DerObjectIdentifier(Pkcs9 + ".6"); + public static readonly DerObjectIdentifier Pkcs9AtChallengePassword = new DerObjectIdentifier(Pkcs9 + ".7"); + public static readonly DerObjectIdentifier Pkcs9AtUnstructuredAddress = new DerObjectIdentifier(Pkcs9 + ".8"); + public static readonly DerObjectIdentifier Pkcs9AtExtendedCertificateAttributes = new DerObjectIdentifier(Pkcs9 + ".9"); + public static readonly DerObjectIdentifier Pkcs9AtSigningDescription = new DerObjectIdentifier(Pkcs9 + ".13"); + public static readonly DerObjectIdentifier Pkcs9AtExtensionRequest = new DerObjectIdentifier(Pkcs9 + ".14"); + public static readonly DerObjectIdentifier Pkcs9AtSmimeCapabilities = new DerObjectIdentifier(Pkcs9 + ".15"); + public static readonly DerObjectIdentifier IdSmime = new DerObjectIdentifier(Pkcs9 + ".16"); + + public static readonly DerObjectIdentifier Pkcs9AtFriendlyName = new DerObjectIdentifier(Pkcs9 + ".20"); + public static readonly DerObjectIdentifier Pkcs9AtLocalKeyID = new DerObjectIdentifier(Pkcs9 + ".21"); + + [Obsolete("Use X509Certificate instead")] + public static readonly DerObjectIdentifier X509CertType = new DerObjectIdentifier(Pkcs9 + ".22.1"); + + public const string CertTypes = Pkcs9 + ".22"; + public static readonly DerObjectIdentifier X509Certificate = new DerObjectIdentifier(CertTypes + ".1"); + public static readonly DerObjectIdentifier SdsiCertificate = new DerObjectIdentifier(CertTypes + ".2"); + + public const string CrlTypes = Pkcs9 + ".23"; + public static readonly DerObjectIdentifier X509Crl = new DerObjectIdentifier(CrlTypes + ".1"); + + public static readonly DerObjectIdentifier IdAlg = IdSmime.Branch("3"); + + public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5"); + public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6"); + public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7"); + public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); + public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); + + /* + *
+         * -- RSA-KEM Key Transport Algorithm
+         *
+         * id-rsa-kem OID ::= {
+         *      iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+         *      pkcs-9(9) smime(16) alg(3) 14
+         *   }
+         * 
+ */ + public static readonly DerObjectIdentifier IdRsaKem = IdAlg.Branch("14"); + + // + // SMIME capability sub oids. + // + public static readonly DerObjectIdentifier PreferSignedData = Pkcs9AtSmimeCapabilities.Branch("1"); + public static readonly DerObjectIdentifier CannotDecryptAny = Pkcs9AtSmimeCapabilities.Branch("2"); + public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = Pkcs9AtSmimeCapabilities.Branch("3"); + + // + // other SMIME attributes + // + public static readonly DerObjectIdentifier IdAAReceiptRequest = IdSmime.Branch("2.1"); + + // + // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)} + // + public const string IdCT = "1.2.840.113549.1.9.16.1"; + + public static readonly DerObjectIdentifier IdCTAuthData = new DerObjectIdentifier(IdCT + ".2"); + public static readonly DerObjectIdentifier IdCTTstInfo = new DerObjectIdentifier(IdCT + ".4"); + public static readonly DerObjectIdentifier IdCTCompressedData = new DerObjectIdentifier(IdCT + ".9"); + public static readonly DerObjectIdentifier IdCTAuthEnvelopedData = new DerObjectIdentifier(IdCT + ".23"); + public static readonly DerObjectIdentifier IdCTTimestampedData = new DerObjectIdentifier(IdCT + ".31"); + + // + // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)} + // + public const string IdCti = "1.2.840.113549.1.9.16.6"; + + public static readonly DerObjectIdentifier IdCtiEtsProofOfOrigin = new DerObjectIdentifier(IdCti + ".1"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfReceipt = new DerObjectIdentifier(IdCti + ".2"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfDelivery = new DerObjectIdentifier(IdCti + ".3"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfSender = new DerObjectIdentifier(IdCti + ".4"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfApproval = new DerObjectIdentifier(IdCti + ".5"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfCreation = new DerObjectIdentifier(IdCti + ".6"); + + // + // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)} + // + public const string IdAA = "1.2.840.113549.1.9.16.2"; + + public static readonly DerObjectIdentifier IdAAContentHint = new DerObjectIdentifier(IdAA + ".4"); // See RFC 2634 + public static readonly DerObjectIdentifier IdAAMsgSigDigest = new DerObjectIdentifier(IdAA + ".5"); + public static readonly DerObjectIdentifier IdAAContentReference = new DerObjectIdentifier(IdAA + ".10"); + + /* + * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11} + * + */ + public static readonly DerObjectIdentifier IdAAEncrypKeyPref = new DerObjectIdentifier(IdAA + ".11"); + public static readonly DerObjectIdentifier IdAASigningCertificate = new DerObjectIdentifier(IdAA + ".12"); + public static readonly DerObjectIdentifier IdAASigningCertificateV2 = new DerObjectIdentifier(IdAA + ".47"); + + public static readonly DerObjectIdentifier IdAAContentIdentifier = new DerObjectIdentifier(IdAA + ".7"); // See RFC 2634 + + /* + * RFC 3126 + */ + public static readonly DerObjectIdentifier IdAASignatureTimeStampToken = new DerObjectIdentifier(IdAA + ".14"); + + public static readonly DerObjectIdentifier IdAAEtsSigPolicyID = new DerObjectIdentifier(IdAA + ".15"); + public static readonly DerObjectIdentifier IdAAEtsCommitmentType = new DerObjectIdentifier(IdAA + ".16"); + public static readonly DerObjectIdentifier IdAAEtsSignerLocation = new DerObjectIdentifier(IdAA + ".17"); + public static readonly DerObjectIdentifier IdAAEtsSignerAttr = new DerObjectIdentifier(IdAA + ".18"); + public static readonly DerObjectIdentifier IdAAEtsOtherSigCert = new DerObjectIdentifier(IdAA + ".19"); + public static readonly DerObjectIdentifier IdAAEtsContentTimestamp = new DerObjectIdentifier(IdAA + ".20"); + public static readonly DerObjectIdentifier IdAAEtsCertificateRefs = new DerObjectIdentifier(IdAA + ".21"); + public static readonly DerObjectIdentifier IdAAEtsRevocationRefs = new DerObjectIdentifier(IdAA + ".22"); + public static readonly DerObjectIdentifier IdAAEtsCertValues = new DerObjectIdentifier(IdAA + ".23"); + public static readonly DerObjectIdentifier IdAAEtsRevocationValues = new DerObjectIdentifier(IdAA + ".24"); + public static readonly DerObjectIdentifier IdAAEtsEscTimeStamp = new DerObjectIdentifier(IdAA + ".25"); + public static readonly DerObjectIdentifier IdAAEtsCertCrlTimestamp = new DerObjectIdentifier(IdAA + ".26"); + public static readonly DerObjectIdentifier IdAAEtsArchiveTimestamp = new DerObjectIdentifier(IdAA + ".27"); + + [Obsolete("Use 'IdAAEtsSigPolicyID' instead")] + public static readonly DerObjectIdentifier IdAASigPolicyID = IdAAEtsSigPolicyID; + [Obsolete("Use 'IdAAEtsCommitmentType' instead")] + public static readonly DerObjectIdentifier IdAACommitmentType = IdAAEtsCommitmentType; + [Obsolete("Use 'IdAAEtsSignerLocation' instead")] + public static readonly DerObjectIdentifier IdAASignerLocation = IdAAEtsSignerLocation; + [Obsolete("Use 'IdAAEtsOtherSigCert' instead")] + public static readonly DerObjectIdentifier IdAAOtherSigCert = IdAAEtsOtherSigCert; + + // + // id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)} + // + public const string IdSpq = "1.2.840.113549.1.9.16.5"; + + public static readonly DerObjectIdentifier IdSpqEtsUri = new DerObjectIdentifier(IdSpq + ".1"); + public static readonly DerObjectIdentifier IdSpqEtsUNotice = new DerObjectIdentifier(IdSpq + ".2"); + + // + // pkcs-12 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } + // + public const string Pkcs12 = "1.2.840.113549.1.12"; + public const string BagTypes = Pkcs12 + ".10.1"; + + public static readonly DerObjectIdentifier KeyBag = new DerObjectIdentifier(BagTypes + ".1"); + public static readonly DerObjectIdentifier Pkcs8ShroudedKeyBag = new DerObjectIdentifier(BagTypes + ".2"); + public static readonly DerObjectIdentifier CertBag = new DerObjectIdentifier(BagTypes + ".3"); + public static readonly DerObjectIdentifier CrlBag = new DerObjectIdentifier(BagTypes + ".4"); + public static readonly DerObjectIdentifier SecretBag = new DerObjectIdentifier(BagTypes + ".5"); + public static readonly DerObjectIdentifier SafeContentsBag = new DerObjectIdentifier(BagTypes + ".6"); + + public const string Pkcs12PbeIds = Pkcs12 + ".1"; + + public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".1"); + public static readonly DerObjectIdentifier PbeWithShaAnd40BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".2"); + public static readonly DerObjectIdentifier PbeWithShaAnd3KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".3"); + public static readonly DerObjectIdentifier PbeWithShaAnd2KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".4"); + public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".5"); + public static readonly DerObjectIdentifier PbewithShaAnd40BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".6"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs.meta new file mode 100644 index 0000000..2963fd1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/PKCSObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 00c35305dafe0c74eb19e23e1f3f8cb1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs new file mode 100644 index 0000000..0c1dac8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs @@ -0,0 +1,169 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsassaPssParameters + : Asn1Encodable + { + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private DerInteger saltLength; + private DerInteger trailerField; + + public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm); + public readonly static DerInteger DefaultSaltLength = new DerInteger(20); + public readonly static DerInteger DefaultTrailerField = new DerInteger(1); + + public static RsassaPssParameters GetInstance( + object obj) + { + if (obj == null || obj is RsassaPssParameters) + { + return (RsassaPssParameters)obj; + } + + if (obj is Asn1Sequence) + { + return new RsassaPssParameters((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * The default version + */ + public RsassaPssParameters() + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + saltLength = DefaultSaltLength; + trailerField = DefaultTrailerField; + } + + public RsassaPssParameters( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + DerInteger saltLength, + DerInteger trailerField) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.saltLength = saltLength; + this.trailerField = trailerField; + } + + public RsassaPssParameters( + Asn1Sequence seq) + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + saltLength = DefaultSaltLength; + trailerField = DefaultTrailerField; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = (Asn1TaggedObject)seq[i]; + + switch (o.TagNo) + { + case 0: + hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 1: + maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 2: + saltLength = DerInteger.GetInstance(o, true); + break; + case 3: + trailerField = DerInteger.GetInstance(o, true); + break; + default: + throw new ArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public AlgorithmIdentifier MaskGenAlgorithm + { + get { return maskGenAlgorithm; } + } + + public DerInteger SaltLength + { + get { return saltLength; } + } + + public DerInteger TrailerField + { + get { return trailerField; } + } + + /** + *
+		 * RSASSA-PSS-params ::= SEQUENCE {
+		 *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
+		 *    maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+		 *    saltLength         [2] INTEGER  DEFAULT 20,
+		 *    trailerField       [3] TrailerField  DEFAULT trailerFieldBC
+		 *  }
+		 *
+		 * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *    { OID id-sha1 PARAMETERS NULL   }|
+		 *    { OID id-sha256 PARAMETERS NULL }|
+		 *    { OID id-sha384 PARAMETERS NULL }|
+		 *    { OID id-sha512 PARAMETERS NULL },
+		 *    ...  -- Allows for future expansion --
+		 * }
+		 *
+		 * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+		 *    ...  -- Allows for future expansion --
+		 * }
+		 *
+		 * TrailerField ::= INTEGER { trailerFieldBC(1) }
+		 * 
+ * @return the asn1 primitive representing the parameters. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (!hashAlgorithm.Equals(DefaultHashAlgorithm)) + { + v.Add(new DerTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction)) + { + v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!saltLength.Equals(DefaultSaltLength)) + { + v.Add(new DerTaggedObject(true, 2, saltLength)); + } + + if (!trailerField.Equals(DefaultTrailerField)) + { + v.Add(new DerTaggedObject(true, 3, trailerField)); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs.meta new file mode 100644 index 0000000..7454e41 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/RSASSAPSSparams.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b2c22d57de73f1d48bae3043e36e6a4e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs new file mode 100644 index 0000000..8960237 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs @@ -0,0 +1,160 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * a Pkcs#7 signed data object. + */ + public class SignedData + : Asn1Encodable + { + private readonly DerInteger version; + private readonly Asn1Set digestAlgorithms; + private readonly ContentInfo contentInfo; + private readonly Asn1Set certificates; + private readonly Asn1Set crls; + private readonly Asn1Set signerInfos; + + public static SignedData GetInstance(object obj) + { + if (obj == null) + return null; + SignedData existing = obj as SignedData; + if (existing != null) + return existing; + return new SignedData(Asn1Sequence.GetInstance(obj)); + } + + public SignedData( + DerInteger _version, + Asn1Set _digestAlgorithms, + ContentInfo _contentInfo, + Asn1Set _certificates, + Asn1Set _crls, + Asn1Set _signerInfos) + { + version = _version; + digestAlgorithms = _digestAlgorithms; + contentInfo = _contentInfo; + certificates = _certificates; + crls = _crls; + signerInfos = _signerInfos; + } + + private SignedData( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger) e.Current; + + e.MoveNext(); + digestAlgorithms = (Asn1Set) e.Current; + + e.MoveNext(); + contentInfo = ContentInfo.GetInstance(e.Current); + + while (e.MoveNext()) + { + Asn1Object o = (Asn1Object) e.Current; + + // + // an interesting feature of SignedData is that there appear to be varying implementations... + // for the moment we ignore anything which doesn't fit. + // + if (o is DerTaggedObject) + { + DerTaggedObject tagged = (DerTaggedObject) o; + + switch (tagged.TagNo) + { + case 0: + certificates = Asn1Set.GetInstance(tagged, false); + break; + case 1: + crls = Asn1Set.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag value " + tagged.TagNo); + } + } + else + { + signerInfos = (Asn1Set) o; + } + } + } + + public DerInteger Version + { + get { return version; } + } + + public Asn1Set DigestAlgorithms + { + get { return digestAlgorithms; } + } + + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + public Asn1Set Certificates + { + get { return certificates; } + } + + public Asn1Set Crls + { + get { return crls; } + } + + public Asn1Set SignerInfos + { + get { return signerInfos; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  SignedData ::= Sequence {
+         *      version Version,
+         *      digestAlgorithms DigestAlgorithmIdentifiers,
+         *      contentInfo ContentInfo,
+         *      certificates
+         *          [0] IMPLICIT ExtendedCertificatesAndCertificates
+         *                   OPTIONAL,
+         *      crls
+         *          [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+         *      signerInfos SignerInfos }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + version, digestAlgorithms, contentInfo); + + if (certificates != null) + { + v.Add(new DerTaggedObject(false, 0, certificates)); + } + + if (crls != null) + { + v.Add(new DerTaggedObject(false, 1, crls)); + } + + v.Add(signerInfos); + + return new BerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs.meta new file mode 100644 index 0000000..cff6f7d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/pkcs/SignedData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1ec29216e5122374bad13557289fe449 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec.meta new file mode 100644 index 0000000..089be61 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 33f43652a7e9789499bdc30289b5bc3e +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs new file mode 100644 index 0000000..f0f79bd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs @@ -0,0 +1,1187 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Sec +{ + public sealed class SecNamedCurves + { + private SecNamedCurves() + { + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p) + { + return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create(); + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.Decode(hex)); + } + + /* + * secp112r1 + */ + internal class Secp112r1Holder + : X9ECParametersHolder + { + private Secp112r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp112r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = (2^128 - 3) / 76439 + BigInteger p = FromHex("DB7C2ABF62E35E668076BEAD208B"); + BigInteger a = FromHex("DB7C2ABF62E35E668076BEAD2088"); + BigInteger b = FromHex("659EF8BA043916EEDE8911702B22"); + byte[] S = Hex.Decode("00F50B028E4D696E676875615175290472783FB1"); + BigInteger n = FromHex("DB7C2ABF62E35E7628DFAC6561C5"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "09487239995A5EE76B55F9C2F098" + + "A89CE5AF8724C0A23E0E0FF77500")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp112r2 + */ + internal class Secp112r2Holder + : X9ECParametersHolder + { + private Secp112r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp112r2Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = (2^128 - 3) / 76439 + BigInteger p = FromHex("DB7C2ABF62E35E668076BEAD208B"); + BigInteger a = FromHex("6127C24C05F38A0AAAF65C0EF02C"); + BigInteger b = FromHex("51DEF1815DB5ED74FCC34C85D709"); + byte[] S = Hex.Decode("002757A1114D696E6768756151755316C05E0BD4"); + BigInteger n = FromHex("36DF0AAFD8B8D7597CA10520D04B"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "4BA30AB5E892B4E1649DD0928643" + + "ADCD46F5882E3747DEF36E956E97")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp128r1 + */ + internal class Secp128r1Holder + : X9ECParametersHolder + { + private Secp128r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp128r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^128 - 2^97 - 1 + BigInteger p = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("E87579C11079F43DD824993C2CEE5ED3"); + byte[] S = Hex.Decode("000E0D4D696E6768756151750CC03A4473D03679"); + BigInteger n = FromHex("FFFFFFFE0000000075A30D1B9038A115"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "161FF7528B899B2D0C28607CA52C5B86" + + "CF5AC8395BAFEB13C02DA292DDED7A83")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp128r2 + */ + internal class Secp128r2Holder + : X9ECParametersHolder + { + private Secp128r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp128r2Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^128 - 2^97 - 1 + BigInteger p = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1"); + BigInteger b = FromHex("5EEEFCA380D02919DC2C6558BB6D8A5D"); + byte[] S = Hex.Decode("004D696E67687561517512D8F03431FCE63B88F4"); + BigInteger n = FromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "7B6AA5D85E572983E6FB32A7CDEBC140" + + "27B6916A894D3AEE7106FE805FC34B44")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp160k1 + */ + internal class Secp160k1Holder + : X9ECParametersHolder + { + private Secp160k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp160k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(7); + byte[] S = null; + BigInteger n = FromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), + new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" + + "938CF935318FDCED6BC28286531733C3F03C4FEE")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp160r1 + */ + internal class Secp160r1Holder + : X9ECParametersHolder + { + private Secp160r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp160r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^160 - 2^31 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); + BigInteger b = FromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); + byte[] S = Hex.Decode("1053CDE42C14D696E67687561517533BF3F83345"); + BigInteger n = FromHex("0100000000000000000001F4C8F927AED3CA752257"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "4A96B5688EF573284664698968C38BB913CBFC82" + + "23A628553168947D59DCC912042351377AC5FB32")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp160r2 + */ + internal class Secp160r2Holder + : X9ECParametersHolder + { + private Secp160r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp160r2Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70"); + BigInteger b = FromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA"); + byte[] S = Hex.Decode("B99B99B099B323E02709A4D696E6768756151751"); + BigInteger n = FromHex("0100000000000000000000351EE786A818F3A1A16B"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "52DCB034293A117E1F4FF11B30F7199D3144CE6D" + + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp192k1 + */ + internal class Secp192k1Holder + : X9ECParametersHolder + { + private Secp192k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp192k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(3); + byte[] S = null; + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), + new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" + + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp192r1 + */ + internal class Secp192r1Holder + : X9ECParametersHolder + { + private Secp192r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp192r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^192 - 2^64 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); + byte[] S = Hex.Decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" + + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp224k1 + */ + internal class Secp224k1Holder + : X9ECParametersHolder + { + private Secp224k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp224k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(5); + byte[] S = null; + BigInteger n = FromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), + new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C" + + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp224r1 + */ + internal class Secp224r1Holder + : X9ECParametersHolder + { + private Secp224r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp224r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^224 - 2^96 + 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); + BigInteger b = FromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); + byte[] S = Hex.Decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" + + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp256k1 + */ + internal class Secp256k1Holder + : X9ECParametersHolder + { + private Secp256k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp256k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(7); + byte[] S = null; + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), + new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp256r1 + */ + internal class Secp256r1Holder + : X9ECParametersHolder + { + private Secp256r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp256r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 + BigInteger p = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); + byte[] S = Hex.Decode("C49D360886E704936A6678E1139D26B7819F7E90"); + BigInteger n = FromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp384r1 + */ + internal class Secp384r1Holder + : X9ECParametersHolder + { + private Secp384r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp384r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^384 - 2^128 - 2^96 + 2^32 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"); + BigInteger b = FromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"); + byte[] S = Hex.Decode("A335926AA319A27A1D00896A6773A4827ACDAC73"); + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" + + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp521r1 + */ + internal class Secp521r1Holder + : X9ECParametersHolder + { + private Secp521r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp521r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^521 - 1 + BigInteger p = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"); + byte[] S = Hex.Decode("D09E8800291CB85396CC6717393284AAA0DA64BA"); + BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" + + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect113r1 + */ + internal class Sect113r1Holder + : X9ECParametersHolder + { + private Sect113r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect113r1Holder(); + + private const int m = 113; + private const int k = 9; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("003088250CA6E7C7FE649CE85820F7"); + BigInteger b = FromHex("00E8BEE4D3E2260744188BE0E9C723"); + byte[] S = Hex.Decode("10E723AB14D696E6768756151756FEBF8FCB49A9"); + BigInteger n = FromHex("0100000000000000D9CCEC8A39E56F"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "009D73616F35F4AB1407D73562C10F" + + "00A52830277958EE84D1315ED31886")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect113r2 + */ + internal class Sect113r2Holder + : X9ECParametersHolder + { + private Sect113r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect113r2Holder(); + + private const int m = 113; + private const int k = 9; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("00689918DBEC7E5A0DD6DFC0AA55C7"); + BigInteger b = FromHex("0095E9A9EC9B297BD4BF36E059184F"); + byte[] S = Hex.Decode("10C0FB15760860DEF1EEF4D696E676875615175D"); + BigInteger n = FromHex("010000000000000108789B2496AF93"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "01A57A6A7B26CA5EF52FCDB8164797" + + "00B3ADC94ED1FE674C06E695BABA1D")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect131r1 + */ + internal class Sect131r1Holder + : X9ECParametersHolder + { + private Sect131r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect131r1Holder(); + + private const int m = 131; + private const int k1 = 2; + private const int k2 = 3; + private const int k3 = 8; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("07A11B09A76B562144418FF3FF8C2570B8"); + BigInteger b = FromHex("0217C05610884B63B9C6C7291678F9D341"); + byte[] S = Hex.Decode("4D696E676875615175985BD3ADBADA21B43A97E2"); + BigInteger n = FromHex("0400000000000000023123953A9464B54D"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0081BAF91FDF9833C40F9C181343638399" + + "078C6E7EA38C001F73C8134B1B4EF9E150")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect131r2 + */ + internal class Sect131r2Holder + : X9ECParametersHolder + { + private Sect131r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect131r2Holder(); + + private const int m = 131; + private const int k1 = 2; + private const int k2 = 3; + private const int k3 = 8; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("03E5A88919D7CAFCBF415F07C2176573B2"); + BigInteger b = FromHex("04B8266A46C55657AC734CE38F018F2192"); + byte[] S = Hex.Decode("985BD3ADBAD4D696E676875615175A21B43A97E3"); + BigInteger n = FromHex("0400000000000000016954A233049BA98F"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0356DCD8F2F95031AD652D23951BB366A8" + + "0648F06D867940A5366D9E265DE9EB240F")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect163k1 + */ + internal class Sect163k1Holder + : X9ECParametersHolder + { + private Sect163k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect163k1Holder(); + + private const int m = 163; + private const int k1 = 3; + private const int k2 = 6; + private const int k3 = 7; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("04000000000000000000020108A2E0CC0D99F8A5EF"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8" + + "0289070FB05D38FF58321F2E800536D538CCDAA3D9")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect163r1 + */ + internal class Sect163r1Holder + : X9ECParametersHolder + { + private Sect163r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect163r1Holder(); + + private const int m = 163; + private const int k1 = 3; + private const int k2 = 6; + private const int k3 = 7; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2"); + BigInteger b = FromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9"); + byte[] S = Hex.Decode("24B7B137C8A14D696E6768756151756FD0DA2E5C"); + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0369979697AB43897789566789567F787A7876A654" + + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect163r2 + */ + internal class Sect163r2Holder + : X9ECParametersHolder + { + private Sect163r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect163r2Holder(); + + private const int m = 163; + private const int k1 = 3; + private const int k2 = 6; + private const int k3 = 7; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("020A601907B8C953CA1481EB10512F78744A3205FD"); + byte[] S = Hex.Decode("85E25BFE5C86226CDB12016F7553F9D0E693A268"); + BigInteger n = FromHex("040000000000000000000292FE77E70C12A4234C33"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "03F0EBA16286A2D57EA0991168D4994637E8343E36" + + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect193r1 + */ + internal class Sect193r1Holder + : X9ECParametersHolder + { + private Sect193r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect193r1Holder(); + + private const int m = 193; + private const int k = 15; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01"); + BigInteger b = FromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814"); + byte[] S = Hex.Decode("103FAEC74D696E676875615175777FC5B191EF30"); + BigInteger n = FromHex("01000000000000000000000000C7F34A778F443ACC920EBA49"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1" + + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect193r2 + */ + internal class Sect193r2Holder + : X9ECParametersHolder + { + private Sect193r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect193r2Holder(); + + private const int m = 193; + private const int k = 15; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B"); + BigInteger b = FromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE"); + byte[] S = Hex.Decode("10B7B4D696E676875615175137C8A16FD0DA2211"); + BigInteger n = FromHex("010000000000000000000000015AAB561B005413CCD4EE99D5"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F" + + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect233k1 + */ + internal class Sect233k1Holder + : X9ECParametersHolder + { + private Sect233k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect233k1Holder(); + + private const int m = 233; + private const int k = 74; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126" + + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect233r1 + */ + internal class Sect233r1Holder + : X9ECParametersHolder + { + private Sect233r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect233r1Holder(); + + private const int m = 233; + private const int k = 74; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD"); + byte[] S = Hex.Decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3"); + BigInteger n = FromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B" + + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect239k1 + */ + internal class Sect239k1Holder + : X9ECParametersHolder + { + private Sect239k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect239k1Holder(); + + private const int m = 239; + private const int k = 158; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC" + + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect283k1 + */ + internal class Sect283k1Holder + : X9ECParametersHolder + { + private Sect283k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect283k1Holder(); + + private const int m = 283; + private const int k1 = 5; + private const int k2 = 7; + private const int k3 = 12; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" + + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect283r1 + */ + internal class Sect283r1Holder + : X9ECParametersHolder + { + private Sect283r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect283r1Holder(); + + private const int m = 283; + private const int k1 = 5; + private const int k2 = 7; + private const int k3 = 12; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5"); + byte[] S = Hex.Decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE"); + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" + + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect409k1 + */ + internal class Sect409k1Holder + : X9ECParametersHolder + { + private Sect409k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect409k1Holder(); + + private const int m = 409; + private const int k = 87; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" + + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect409r1 + */ + internal class Sect409r1Holder + : X9ECParametersHolder + { + private Sect409r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect409r1Holder(); + + private const int m = 409; + private const int k = 87; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F"); + byte[] S = Hex.Decode("4099B5A457F9D69F79213D094C4BCD4D4262210B"); + BigInteger n = FromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" + + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect571k1 + */ + internal class Sect571k1Holder + : X9ECParametersHolder + { + private Sect571k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect571k1Holder(); + + private const int m = 571; + private const int k1 = 2; + private const int k2 = 5; + private const int k3 = 10; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" + + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect571r1 + */ + internal class Sect571r1Holder + : X9ECParametersHolder + { + private Sect571r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect571r1Holder(); + + private const int m = 571; + private const int k1 = 2; + private const int k2 = 5; + private const int k3 = 10; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A"); + byte[] S = Hex.Decode("2AA058F73A0E33AB486B0F610410C53A7F132310"); + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" + + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B")); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + + private static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary curves = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary names = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static SecNamedCurves() + { + DefineCurve("secp112r1", SecObjectIdentifiers.SecP112r1, Secp112r1Holder.Instance); + DefineCurve("secp112r2", SecObjectIdentifiers.SecP112r2, Secp112r2Holder.Instance); + DefineCurve("secp128r1", SecObjectIdentifiers.SecP128r1, Secp128r1Holder.Instance); + DefineCurve("secp128r2", SecObjectIdentifiers.SecP128r2, Secp128r2Holder.Instance); + DefineCurve("secp160k1", SecObjectIdentifiers.SecP160k1, Secp160k1Holder.Instance); + DefineCurve("secp160r1", SecObjectIdentifiers.SecP160r1, Secp160r1Holder.Instance); + DefineCurve("secp160r2", SecObjectIdentifiers.SecP160r2, Secp160r2Holder.Instance); + DefineCurve("secp192k1", SecObjectIdentifiers.SecP192k1, Secp192k1Holder.Instance); + DefineCurve("secp192r1", SecObjectIdentifiers.SecP192r1, Secp192r1Holder.Instance); + DefineCurve("secp224k1", SecObjectIdentifiers.SecP224k1, Secp224k1Holder.Instance); + DefineCurve("secp224r1", SecObjectIdentifiers.SecP224r1, Secp224r1Holder.Instance); + DefineCurve("secp256k1", SecObjectIdentifiers.SecP256k1, Secp256k1Holder.Instance); + DefineCurve("secp256r1", SecObjectIdentifiers.SecP256r1, Secp256r1Holder.Instance); + DefineCurve("secp384r1", SecObjectIdentifiers.SecP384r1, Secp384r1Holder.Instance); + DefineCurve("secp521r1", SecObjectIdentifiers.SecP521r1, Secp521r1Holder.Instance); + + DefineCurve("sect113r1", SecObjectIdentifiers.SecT113r1, Sect113r1Holder.Instance); + DefineCurve("sect113r2", SecObjectIdentifiers.SecT113r2, Sect113r2Holder.Instance); + DefineCurve("sect131r1", SecObjectIdentifiers.SecT131r1, Sect131r1Holder.Instance); + DefineCurve("sect131r2", SecObjectIdentifiers.SecT131r2, Sect131r2Holder.Instance); + DefineCurve("sect163k1", SecObjectIdentifiers.SecT163k1, Sect163k1Holder.Instance); + DefineCurve("sect163r1", SecObjectIdentifiers.SecT163r1, Sect163r1Holder.Instance); + DefineCurve("sect163r2", SecObjectIdentifiers.SecT163r2, Sect163r2Holder.Instance); + DefineCurve("sect193r1", SecObjectIdentifiers.SecT193r1, Sect193r1Holder.Instance); + DefineCurve("sect193r2", SecObjectIdentifiers.SecT193r2, Sect193r2Holder.Instance); + DefineCurve("sect233k1", SecObjectIdentifiers.SecT233k1, Sect233k1Holder.Instance); + DefineCurve("sect233r1", SecObjectIdentifiers.SecT233r1, Sect233r1Holder.Instance); + DefineCurve("sect239k1", SecObjectIdentifiers.SecT239k1, Sect239k1Holder.Instance); + DefineCurve("sect283k1", SecObjectIdentifiers.SecT283k1, Sect283k1Holder.Instance); + DefineCurve("sect283r1", SecObjectIdentifiers.SecT283r1, Sect283r1Holder.Instance); + DefineCurve("sect409k1", SecObjectIdentifiers.SecT409k1, Sect409k1Holder.Instance); + DefineCurve("sect409r1", SecObjectIdentifiers.SecT409r1, Sect409r1Holder.Instance); + DefineCurve("sect571k1", SecObjectIdentifiers.SecT571k1, Sect571k1Holder.Instance); + DefineCurve("sect571r1", SecObjectIdentifiers.SecT571r1, Sect571r1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs.meta new file mode 100644 index 0000000..dbd2bcb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECNamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aedfafe74a7ae674e921b71e86371006 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs new file mode 100644 index 0000000..d9267d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs @@ -0,0 +1,54 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; + +namespace Org.BouncyCastle.Asn1.Sec +{ + public abstract class SecObjectIdentifiers + { + /** + * EllipticCurve OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) + * } + */ + public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier("1.3.132.0"); + + public static readonly DerObjectIdentifier SecT163k1 = new DerObjectIdentifier(EllipticCurve + ".1"); + public static readonly DerObjectIdentifier SecT163r1 = new DerObjectIdentifier(EllipticCurve + ".2"); + public static readonly DerObjectIdentifier SecT239k1 = new DerObjectIdentifier(EllipticCurve + ".3"); + public static readonly DerObjectIdentifier SecT113r1 = new DerObjectIdentifier(EllipticCurve + ".4"); + public static readonly DerObjectIdentifier SecT113r2 = new DerObjectIdentifier(EllipticCurve + ".5"); + public static readonly DerObjectIdentifier SecP112r1 = new DerObjectIdentifier(EllipticCurve + ".6"); + public static readonly DerObjectIdentifier SecP112r2 = new DerObjectIdentifier(EllipticCurve + ".7"); + public static readonly DerObjectIdentifier SecP160r1 = new DerObjectIdentifier(EllipticCurve + ".8"); + public static readonly DerObjectIdentifier SecP160k1 = new DerObjectIdentifier(EllipticCurve + ".9"); + public static readonly DerObjectIdentifier SecP256k1 = new DerObjectIdentifier(EllipticCurve + ".10"); + public static readonly DerObjectIdentifier SecT163r2 = new DerObjectIdentifier(EllipticCurve + ".15"); + public static readonly DerObjectIdentifier SecT283k1 = new DerObjectIdentifier(EllipticCurve + ".16"); + public static readonly DerObjectIdentifier SecT283r1 = new DerObjectIdentifier(EllipticCurve + ".17"); + public static readonly DerObjectIdentifier SecT131r1 = new DerObjectIdentifier(EllipticCurve + ".22"); + public static readonly DerObjectIdentifier SecT131r2 = new DerObjectIdentifier(EllipticCurve + ".23"); + public static readonly DerObjectIdentifier SecT193r1 = new DerObjectIdentifier(EllipticCurve + ".24"); + public static readonly DerObjectIdentifier SecT193r2 = new DerObjectIdentifier(EllipticCurve + ".25"); + public static readonly DerObjectIdentifier SecT233k1 = new DerObjectIdentifier(EllipticCurve + ".26"); + public static readonly DerObjectIdentifier SecT233r1 = new DerObjectIdentifier(EllipticCurve + ".27"); + public static readonly DerObjectIdentifier SecP128r1 = new DerObjectIdentifier(EllipticCurve + ".28"); + public static readonly DerObjectIdentifier SecP128r2 = new DerObjectIdentifier(EllipticCurve + ".29"); + public static readonly DerObjectIdentifier SecP160r2 = new DerObjectIdentifier(EllipticCurve + ".30"); + public static readonly DerObjectIdentifier SecP192k1 = new DerObjectIdentifier(EllipticCurve + ".31"); + public static readonly DerObjectIdentifier SecP224k1 = new DerObjectIdentifier(EllipticCurve + ".32"); + public static readonly DerObjectIdentifier SecP224r1 = new DerObjectIdentifier(EllipticCurve + ".33"); + public static readonly DerObjectIdentifier SecP384r1 = new DerObjectIdentifier(EllipticCurve + ".34"); + public static readonly DerObjectIdentifier SecP521r1 = new DerObjectIdentifier(EllipticCurve + ".35"); + public static readonly DerObjectIdentifier SecT409k1 = new DerObjectIdentifier(EllipticCurve + ".36"); + public static readonly DerObjectIdentifier SecT409r1 = new DerObjectIdentifier(EllipticCurve + ".37"); + public static readonly DerObjectIdentifier SecT571k1 = new DerObjectIdentifier(EllipticCurve + ".38"); + public static readonly DerObjectIdentifier SecT571r1 = new DerObjectIdentifier(EllipticCurve + ".39"); + + public static readonly DerObjectIdentifier SecP192r1 = X9ObjectIdentifiers.Prime192v1; + public static readonly DerObjectIdentifier SecP256r1 = X9ObjectIdentifiers.Prime256v1; + } +} +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs.meta new file mode 100644 index 0000000..8e63805 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/sec/SECObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 76a08db15fb9c8c4b9dd62f83a1de3fa +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust.meta new file mode 100644 index 0000000..2dfc9b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b40fe8af30f4d1546857f2347f88102a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs new file mode 100644 index 0000000..f7403c9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs @@ -0,0 +1,473 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.Collections; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.TeleTrust +{ + /** + * elliptic curves defined in "ECC Brainpool Standard Curves and Curve Generation" + * http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt + */ + public class TeleTrusTNamedCurves + { + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + internal class BrainpoolP160r1Holder + : X9ECParametersHolder + { + private BrainpoolP160r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP160r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q + new BigInteger("340E7BE2A280EB74E2BE61BADA745D97E8F7C300", 16), // a + new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G + n, h); + } + } + + internal class BrainpoolP160t1Holder + : X9ECParametersHolder + { + private BrainpoolP160t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP160t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + // new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z + new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q + new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620C", 16), // a' + new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G + n, h); + } + } + + internal class BrainpoolP192r1Holder + : X9ECParametersHolder + { + private BrainpoolP192r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP192r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q + new BigInteger("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", 16), // a + new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G + n, h); + } + } + + internal class BrainpoolP192t1Holder + : X9ECParametersHolder + { + private BrainpoolP192t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP192t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + //new BigInteger("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") //Z + new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q + new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", 16), // a' + new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G' + n, h); + } + } + + internal class BrainpoolP224r1Holder + : X9ECParametersHolder + { + private BrainpoolP224r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP224r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q + new BigInteger("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", 16), // a + new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G + n, h); + } + } + + internal class BrainpoolP224t1Holder + : X9ECParametersHolder + { + private BrainpoolP224t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP224t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + //new BigInteger("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") //Z + new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q + new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", 16), // a' + new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G' + n, h); + } + } + + internal class BrainpoolP256r1Holder + : X9ECParametersHolder + { + private BrainpoolP256r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP256r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q + new BigInteger("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16), // a + new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G + n, h); + } + } + + internal class BrainpoolP256t1Holder + : X9ECParametersHolder + { + private BrainpoolP256t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP256t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + //new BigInteger("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") //Z + new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q + new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", 16), // a' + new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G' + n, h); + } + } + + internal class BrainpoolP320r1Holder + : X9ECParametersHolder + { + private BrainpoolP320r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP320r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q + new BigInteger("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", 16), // a + new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G + n, h); + } + } + + internal class BrainpoolP320t1Holder + : X9ECParametersHolder + { + private BrainpoolP320t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP320t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + //new BigInteger("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") //Z + new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q + new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", 16), // a' + new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G' + n, h); + } + } + + internal class BrainpoolP384r1Holder + : X9ECParametersHolder + { + private BrainpoolP384r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP384r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q + new BigInteger("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", 16), // a + new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G + n, h); + } + } + + internal class BrainpoolP384t1Holder + : X9ECParametersHolder + { + private BrainpoolP384t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP384t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + //new BigInteger("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") //Z + new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q + new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", 16), // a' + new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G' + n, h); + } + } + + internal class BrainpoolP512r1Holder + : X9ECParametersHolder + { + private BrainpoolP512r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP512r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q + new BigInteger("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", 16), // a + new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16), // b + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G + n, h); + } + } + + internal class BrainpoolP512t1Holder + : X9ECParametersHolder + { + private BrainpoolP512t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP512t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16); + BigInteger h = new BigInteger("01", 16); + + ECCurve curve = ConfigureCurve(new FpCurve( + //new BigInteger("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") //Z + new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q + new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", 16), // a' + new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16), // b' + n, h)); + + return new X9ECParameters( + curve, + new X9ECPoint(curve, Hex.Decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G' + n, h); + } + } + + + private static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary curves = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary names = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static TeleTrusTNamedCurves() + { + DefineCurve("brainpoolP160r1", TeleTrusTObjectIdentifiers.BrainpoolP160R1, BrainpoolP160r1Holder.Instance); + DefineCurve("brainpoolP160t1", TeleTrusTObjectIdentifiers.BrainpoolP160T1, BrainpoolP160t1Holder.Instance); + DefineCurve("brainpoolP192r1", TeleTrusTObjectIdentifiers.BrainpoolP192R1, BrainpoolP192r1Holder.Instance); + DefineCurve("brainpoolP192t1", TeleTrusTObjectIdentifiers.BrainpoolP192T1, BrainpoolP192t1Holder.Instance); + DefineCurve("brainpoolP224r1", TeleTrusTObjectIdentifiers.BrainpoolP224R1, BrainpoolP224r1Holder.Instance); + DefineCurve("brainpoolP224t1", TeleTrusTObjectIdentifiers.BrainpoolP224T1, BrainpoolP224t1Holder.Instance); + DefineCurve("brainpoolP256r1", TeleTrusTObjectIdentifiers.BrainpoolP256R1, BrainpoolP256r1Holder.Instance); + DefineCurve("brainpoolP256t1", TeleTrusTObjectIdentifiers.BrainpoolP256T1, BrainpoolP256t1Holder.Instance); + DefineCurve("brainpoolP320r1", TeleTrusTObjectIdentifiers.BrainpoolP320R1, BrainpoolP320r1Holder.Instance); + DefineCurve("brainpoolP320t1", TeleTrusTObjectIdentifiers.BrainpoolP320T1, BrainpoolP320t1Holder.Instance); + DefineCurve("brainpoolP384r1", TeleTrusTObjectIdentifiers.BrainpoolP384R1, BrainpoolP384r1Holder.Instance); + DefineCurve("brainpoolP384t1", TeleTrusTObjectIdentifiers.BrainpoolP384T1, BrainpoolP384t1Holder.Instance); + DefineCurve("brainpoolP512r1", TeleTrusTObjectIdentifiers.BrainpoolP512R1, BrainpoolP512r1Holder.Instance); + DefineCurve("brainpoolP512t1", TeleTrusTObjectIdentifiers.BrainpoolP512T1, BrainpoolP512t1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + + public static DerObjectIdentifier GetOid( + short curvesize, + bool twisted) + { + return GetOid("brainpoolP" + curvesize + (twisted ? "t" : "r") + "1"); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs.meta new file mode 100644 index 0000000..698506f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTNamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a0a21d207ece6f34bbc1b20fffaac190 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs new file mode 100644 index 0000000..f577b78 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.TeleTrust +{ + public sealed class TeleTrusTObjectIdentifiers + { + private TeleTrusTObjectIdentifiers() + { + } + + public static readonly DerObjectIdentifier TeleTrusTAlgorithm = new DerObjectIdentifier("1.3.36.3"); + + public static readonly DerObjectIdentifier RipeMD160 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.1"); + public static readonly DerObjectIdentifier RipeMD128 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.2"); + public static readonly DerObjectIdentifier RipeMD256 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.3"); + + public static readonly DerObjectIdentifier TeleTrusTRsaSignatureAlgorithm = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.1"); + + public static readonly DerObjectIdentifier RsaSignatureWithRipeMD160 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".2"); + public static readonly DerObjectIdentifier RsaSignatureWithRipeMD128 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".3"); + public static readonly DerObjectIdentifier RsaSignatureWithRipeMD256 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".4"); + + public static readonly DerObjectIdentifier ECSign = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2"); + + public static readonly DerObjectIdentifier ECSignWithSha1 = new DerObjectIdentifier(ECSign + ".1"); + public static readonly DerObjectIdentifier ECSignWithRipeMD160 = new DerObjectIdentifier(ECSign + ".2"); + + public static readonly DerObjectIdentifier EccBrainpool = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2.8"); + public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier(EccBrainpool + ".1"); + public static readonly DerObjectIdentifier VersionOne = new DerObjectIdentifier(EllipticCurve + ".1"); + + public static readonly DerObjectIdentifier BrainpoolP160R1 = new DerObjectIdentifier(VersionOne + ".1"); + public static readonly DerObjectIdentifier BrainpoolP160T1 = new DerObjectIdentifier(VersionOne + ".2"); + public static readonly DerObjectIdentifier BrainpoolP192R1 = new DerObjectIdentifier(VersionOne + ".3"); + public static readonly DerObjectIdentifier BrainpoolP192T1 = new DerObjectIdentifier(VersionOne + ".4"); + public static readonly DerObjectIdentifier BrainpoolP224R1 = new DerObjectIdentifier(VersionOne + ".5"); + public static readonly DerObjectIdentifier BrainpoolP224T1 = new DerObjectIdentifier(VersionOne + ".6"); + public static readonly DerObjectIdentifier BrainpoolP256R1 = new DerObjectIdentifier(VersionOne + ".7"); + public static readonly DerObjectIdentifier BrainpoolP256T1 = new DerObjectIdentifier(VersionOne + ".8"); + public static readonly DerObjectIdentifier BrainpoolP320R1 = new DerObjectIdentifier(VersionOne + ".9"); + public static readonly DerObjectIdentifier BrainpoolP320T1 = new DerObjectIdentifier(VersionOne + ".10"); + public static readonly DerObjectIdentifier BrainpoolP384R1 = new DerObjectIdentifier(VersionOne + ".11"); + public static readonly DerObjectIdentifier BrainpoolP384T1 = new DerObjectIdentifier(VersionOne + ".12"); + public static readonly DerObjectIdentifier BrainpoolP512R1 = new DerObjectIdentifier(VersionOne + ".13"); + public static readonly DerObjectIdentifier BrainpoolP512T1 = new DerObjectIdentifier(VersionOne + ".14"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta new file mode 100644 index 0000000..791cd4b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2bcaf3493b261b3408acb0edd506fb5b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util.meta new file mode 100644 index 0000000..31f0cc6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3c52f2b6f7def7e48816d97f7186277b +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs new file mode 100644 index 0000000..14c82ac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs @@ -0,0 +1,384 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Utilities +{ + public sealed class Asn1Dump + { + private static readonly string NewLine = Org.BouncyCastle.Utilities.Platform.NewLine; + + private Asn1Dump() + { + } + + private const string Tab = " "; + private const int SampleSize = 32; + + /** + * dump a Der object as a formatted string with indentation + * + * @param obj the Asn1Object to be dumped out. + */ + private static void AsString( + string indent, + bool verbose, + Asn1Object obj, + StringBuilder buf) + { + if (obj is Asn1Sequence) + { + string tab = indent + Tab; + buf.Append(indent); + if (obj is BerSequence) + { + buf.Append("BER Sequence"); + } + else if (obj is DerSequence) + { + buf.Append("DER Sequence"); + } + else + { + buf.Append("Sequence"); + } + + buf.Append(NewLine); + + foreach (Asn1Encodable o in ((Asn1Sequence)obj)) + { + if (o == null || o is Asn1Null) + { + buf.Append(tab); + buf.Append("NULL"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.ToAsn1Object(), buf); + } + } + } + else if (obj is DerTaggedObject) + { + string tab = indent + Tab; + buf.Append(indent); + if (obj is BerTaggedObject) + { + buf.Append("BER Tagged ["); + } + else + { + buf.Append("Tagged ["); + } + + DerTaggedObject o = (DerTaggedObject)obj; + + buf.Append(((int)o.TagNo).ToString()); + buf.Append(']'); + + if (!o.IsExplicit()) + { + buf.Append(" IMPLICIT "); + } + + buf.Append(NewLine); + + if (o.IsEmpty()) + { + buf.Append(tab); + buf.Append("EMPTY"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.GetObject(), buf); + } + } + else if (obj is BerSet) + { + string tab = indent + Tab; + + buf.Append(indent); + buf.Append("BER Set"); + buf.Append(NewLine); + + foreach (Asn1Encodable o in ((Asn1Set)obj)) + { + if (o == null) + { + buf.Append(tab); + buf.Append("NULL"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.ToAsn1Object(), buf); + } + } + } + else if (obj is DerSet) + { + string tab = indent + Tab; + + buf.Append(indent); + buf.Append("DER Set"); + buf.Append(NewLine); + + foreach (Asn1Encodable o in ((Asn1Set)obj)) + { + if (o == null) + { + buf.Append(tab); + buf.Append("NULL"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.ToAsn1Object(), buf); + } + } + } + else if (obj is DerObjectIdentifier) + { + buf.Append(indent + "ObjectIdentifier(" + ((DerObjectIdentifier)obj).Id + ")" + NewLine); + } + else if (obj is DerBoolean) + { + buf.Append(indent + "Boolean(" + ((DerBoolean)obj).IsTrue + ")" + NewLine); + } + else if (obj is DerInteger) + { + buf.Append(indent + "Integer(" + ((DerInteger)obj).Value + ")" + NewLine); + } + else if (obj is BerOctetString) + { + byte[] octets = ((Asn1OctetString)obj).GetOctets(); + string extra = verbose ? dumpBinaryDataAsString(indent, octets) : ""; + buf.Append(indent + "BER Octet String" + "[" + octets.Length + "] " + extra + NewLine); + } + else if (obj is DerOctetString) + { + byte[] octets = ((Asn1OctetString)obj).GetOctets(); + string extra = verbose ? dumpBinaryDataAsString(indent, octets) : ""; + buf.Append(indent + "DER Octet String" + "[" + octets.Length + "] " + extra + NewLine); + } + else if (obj is DerBitString) + { + DerBitString bt = (DerBitString)obj; + byte[] bytes = bt.GetBytes(); + string extra = verbose ? dumpBinaryDataAsString(indent, bytes) : ""; + buf.Append(indent + "DER Bit String" + "[" + bytes.Length + ", " + bt.PadBits + "] " + extra + NewLine); + } + else if (obj is DerIA5String) + { + buf.Append(indent + "IA5String(" + ((DerIA5String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerUtf8String) + { + buf.Append(indent + "UTF8String(" + ((DerUtf8String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerPrintableString) + { + buf.Append(indent + "PrintableString(" + ((DerPrintableString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerVisibleString) + { + buf.Append(indent + "VisibleString(" + ((DerVisibleString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerBmpString) + { + buf.Append(indent + "BMPString(" + ((DerBmpString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerT61String) + { + buf.Append(indent + "T61String(" + ((DerT61String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerGraphicString) + { + buf.Append(indent + "GraphicString(" + ((DerGraphicString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerVideotexString) + { + buf.Append(indent + "VideotexString(" + ((DerVideotexString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerUtcTime) + { + buf.Append(indent + "UTCTime(" + ((DerUtcTime)obj).TimeString + ") " + NewLine); + } + else if (obj is DerGeneralizedTime) + { + buf.Append(indent + "GeneralizedTime(" + ((DerGeneralizedTime)obj).GetTime() + ") " + NewLine); + } + else if (obj is BerApplicationSpecific) + { + buf.Append(outputApplicationSpecific("BER", indent, verbose, (BerApplicationSpecific)obj)); + } + else if (obj is DerApplicationSpecific) + { + buf.Append(outputApplicationSpecific("DER", indent, verbose, (DerApplicationSpecific)obj)); + } + else if (obj is DerEnumerated) + { + DerEnumerated en = (DerEnumerated)obj; + buf.Append(indent + "DER Enumerated(" + en.Value + ")" + NewLine); + } + else if (obj is DerExternal) + { + DerExternal ext = (DerExternal)obj; + buf.Append(indent + "External " + NewLine); + string tab = indent + Tab; + + if (ext.DirectReference != null) + { + buf.Append(tab + "Direct Reference: " + ext.DirectReference.Id + NewLine); + } + if (ext.IndirectReference != null) + { + buf.Append(tab + "Indirect Reference: " + ext.IndirectReference.ToString() + NewLine); + } + if (ext.DataValueDescriptor != null) + { + AsString(tab, verbose, ext.DataValueDescriptor, buf); + } + buf.Append(tab + "Encoding: " + ext.Encoding + NewLine); + AsString(tab, verbose, ext.ExternalContent, buf); + } + else + { + buf.Append(indent + obj.ToString() + NewLine); + } + } + + private static string outputApplicationSpecific( + string type, + string indent, + bool verbose, + DerApplicationSpecific app) + { + StringBuilder buf = new StringBuilder(); + + if (app.IsConstructed()) + { + try + { + Asn1Sequence s = Asn1Sequence.GetInstance(app.GetObject(Asn1Tags.Sequence)); + buf.Append(indent + type + " ApplicationSpecific[" + app.ApplicationTag + "]" + NewLine); + foreach (Asn1Encodable ae in s) + { + AsString(indent + Tab, verbose, ae.ToAsn1Object(), buf); + } + } + catch (IOException e) + { + buf.Append(e); + } + return buf.ToString(); + } + + return indent + type + " ApplicationSpecific[" + app.ApplicationTag + "] (" + + Hex.ToHexString(app.GetContents()) + ")" + NewLine; + } + + [Obsolete("Use version accepting Asn1Encodable")] + public static string DumpAsString( + object obj) + { + if (obj is Asn1Encodable) + { + StringBuilder buf = new StringBuilder(); + AsString("", false, ((Asn1Encodable)obj).ToAsn1Object(), buf); + return buf.ToString(); + } + + return "unknown object type " + obj.ToString(); + } + + /** + * dump out a DER object as a formatted string, in non-verbose mode + * + * @param obj the Asn1Encodable to be dumped out. + * @return the resulting string. + */ + public static string DumpAsString( + Asn1Encodable obj) + { + return DumpAsString(obj, false); + } + + /** + * Dump out the object as a string + * + * @param obj the Asn1Encodable to be dumped out. + * @param verbose if true, dump out the contents of octet and bit strings. + * @return the resulting string. + */ + public static string DumpAsString( + Asn1Encodable obj, + bool verbose) + { + StringBuilder buf = new StringBuilder(); + AsString("", verbose, obj.ToAsn1Object(), buf); + return buf.ToString(); + } + + private static string dumpBinaryDataAsString(string indent, byte[] bytes) + { + indent += Tab; + + StringBuilder buf = new StringBuilder(NewLine); + + for (int i = 0; i < bytes.Length; i += SampleSize) + { + if (bytes.Length - i > SampleSize) + { + buf.Append(indent); + buf.Append(Hex.ToHexString(bytes, i, SampleSize)); + buf.Append(Tab); + buf.Append(calculateAscString(bytes, i, SampleSize)); + buf.Append(NewLine); + } + else + { + buf.Append(indent); + buf.Append(Hex.ToHexString(bytes, i, bytes.Length - i)); + for (int j = bytes.Length - i; j != SampleSize; j++) + { + buf.Append(" "); + } + buf.Append(Tab); + buf.Append(calculateAscString(bytes, i, bytes.Length - i)); + buf.Append(NewLine); + } + } + + return buf.ToString(); + } + + private static string calculateAscString( + byte[] bytes, + int off, + int len) + { + StringBuilder buf = new StringBuilder(); + + for (int i = off; i != off + len; i++) + { + char c = (char)bytes[i]; + if (c >= ' ' && c <= '~') + { + buf.Append(c); + } + } + + return buf.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs.meta new file mode 100644 index 0000000..01d6315 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/Asn1Dump.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d11a496b7c22849429b50cb347c4836e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs new file mode 100644 index 0000000..133fbb6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs @@ -0,0 +1,84 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Utilities +{ + public class FilterStream : Stream + { + public FilterStream(Stream s) + { + this.s = s; + } + public override bool CanRead + { + get { return s.CanRead; } + } + public override bool CanSeek + { + get { return s.CanSeek; } + } + public override bool CanWrite + { + get { return s.CanWrite; } + } + public override long Length + { + get { return s.Length; } + } + public override long Position + { + get { return s.Position; } + set { s.Position = value; } + } +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Org.BouncyCastle.Utilities.Platform.Dispose(s); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Org.BouncyCastle.Utilities.Platform.Dispose(s); + base.Close(); + } +#endif + public override void Flush() + { + s.Flush(); + } + public override long Seek(long offset, SeekOrigin origin) + { + return s.Seek(offset, origin); + } + public override void SetLength(long value) + { + s.SetLength(value); + } + public override int Read(byte[] buffer, int offset, int count) + { + return s.Read(buffer, offset, count); + } + public override int ReadByte() + { + return s.ReadByte(); + } + public override void Write(byte[] buffer, int offset, int count) + { + s.Write(buffer, offset, count); + } + public override void WriteByte(byte value) + { + s.WriteByte(value); + } + protected readonly Stream s; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs.meta new file mode 100644 index 0000000..5db1f1f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/util/FilterStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ecc1ac8ab2a920c418f97b8619491c2a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509.meta new file mode 100644 index 0000000..478f87c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6326d041839c09a43bfda92c6aef7274 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs new file mode 100644 index 0000000..a19e44a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs @@ -0,0 +1,99 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AlgorithmIdentifier + : Asn1Encodable + { + private readonly DerObjectIdentifier algorithm; + private readonly Asn1Encodable parameters; + + public static AlgorithmIdentifier GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static AlgorithmIdentifier GetInstance( + object obj) + { + if (obj == null) + return null; + if (obj is AlgorithmIdentifier) + return (AlgorithmIdentifier)obj; + return new AlgorithmIdentifier(Asn1Sequence.GetInstance(obj)); + } + + public AlgorithmIdentifier( + DerObjectIdentifier algorithm) + { + this.algorithm = algorithm; + } + + [Obsolete("Use version taking a DerObjectIdentifier")] + public AlgorithmIdentifier( + string algorithm) + { + this.algorithm = new DerObjectIdentifier(algorithm); + } + + public AlgorithmIdentifier( + DerObjectIdentifier algorithm, + Asn1Encodable parameters) + { + this.algorithm = algorithm; + this.parameters = parameters; + } + + internal AlgorithmIdentifier( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + this.algorithm = DerObjectIdentifier.GetInstance(seq[0]); + this.parameters = seq.Count < 2 ? null : seq[1]; + } + + /// + /// Return the OID in the Algorithm entry of this identifier. + /// + public virtual DerObjectIdentifier Algorithm + { + get { return algorithm; } + } + + [Obsolete("Use 'Algorithm' property instead")] + public virtual DerObjectIdentifier ObjectID + { + get { return algorithm; } + } + + /// + /// Return the parameters structure in the Parameters entry of this identifier. + /// + public virtual Asn1Encodable Parameters + { + get { return parameters; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *      AlgorithmIdentifier ::= Sequence {
+         *                            algorithm OBJECT IDENTIFIER,
+         *                            parameters ANY DEFINED BY algorithm OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(algorithm); + v.AddOptional(parameters); + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs.meta new file mode 100644 index 0000000..bc3ad5e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/AlgorithmIdentifier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8ca01d5013f07794b9fd040bfd8dc6b1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs new file mode 100644 index 0000000..026969d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs @@ -0,0 +1,136 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class BasicConstraints + : Asn1Encodable + { + private readonly DerBoolean cA; + private readonly DerInteger pathLenConstraint; + + public static BasicConstraints GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static BasicConstraints GetInstance( + object obj) + { + if (obj == null || obj is BasicConstraints) + { + return (BasicConstraints) obj; + } + + if (obj is Asn1Sequence) + { + return new BasicConstraints((Asn1Sequence) obj); + } + + if (obj is X509Extension) + { + return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj)); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + private BasicConstraints( + Asn1Sequence seq) + { + if (seq.Count > 0) + { + if (seq[0] is DerBoolean) + { + this.cA = DerBoolean.GetInstance(seq[0]); + } + else + { + this.pathLenConstraint = DerInteger.GetInstance(seq[0]); + } + + if (seq.Count > 1) + { + if (this.cA == null) + throw new ArgumentException("wrong sequence in constructor", "seq"); + + this.pathLenConstraint = DerInteger.GetInstance(seq[1]); + } + } + } + + public BasicConstraints( + bool cA) + { + if (cA) + { + this.cA = DerBoolean.True; + } + } + + /** + * create a cA=true object for the given path length constraint. + * + * @param pathLenConstraint + */ + public BasicConstraints( + int pathLenConstraint) + { + this.cA = DerBoolean.True; + this.pathLenConstraint = new DerInteger(pathLenConstraint); + } + + public bool IsCA() + { + return cA != null && cA.IsTrue; + } + + public BigInteger PathLenConstraint + { + get { return pathLenConstraint == null ? null : pathLenConstraint.Value; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * BasicConstraints := Sequence {
+         *    cA                  Boolean DEFAULT FALSE,
+         *    pathLenConstraint   Integer (0..MAX) OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (cA != null) + { + v.Add(cA); + } + + if (pathLenConstraint != null) // yes some people actually do this when cA is false... + { + v.Add(pathLenConstraint); + } + + return new DerSequence(v); + } + + public override string ToString() + { + if (pathLenConstraint == null) + { + return "BasicConstraints: isCa(" + this.IsCA() + ")"; + } + + return "BasicConstraints: isCa(" + this.IsCA() + "), pathLenConstraint = " + pathLenConstraint.Value; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs.meta new file mode 100644 index 0000000..3c1b0ca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/BasicConstraints.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8d7502b6f25d26e42b47b45c612ce45c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs new file mode 100644 index 0000000..aa9cb3b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs @@ -0,0 +1,96 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class CrlDistPoint + : Asn1Encodable + { + internal readonly Asn1Sequence seq; + + public static CrlDistPoint GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static CrlDistPoint GetInstance( + object obj) + { + if (obj is CrlDistPoint || obj == null) + { + return (CrlDistPoint) obj; + } + + if (obj is Asn1Sequence) + { + return new CrlDistPoint((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + private CrlDistPoint( + Asn1Sequence seq) + { + this.seq = seq; + } + + public CrlDistPoint( + DistributionPoint[] points) + { + seq = new DerSequence(points); + } + + /** + * Return the distribution points making up the sequence. + * + * @return DistributionPoint[] + */ + public DistributionPoint[] GetDistributionPoints() + { + DistributionPoint[] dp = new DistributionPoint[seq.Count]; + + for (int i = 0; i != seq.Count; ++i) + { + dp[i] = DistributionPoint.GetInstance(seq[i]); + } + + return dp; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * CrlDistPoint ::= Sequence SIZE {1..MAX} OF DistributionPoint
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return seq; + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string sep = Org.BouncyCastle.Utilities.Platform.NewLine; + + buf.Append("CRLDistPoint:"); + buf.Append(sep); + DistributionPoint[] dp = GetDistributionPoints(); + for (int i = 0; i != dp.Length; i++) + { + buf.Append(" "); + buf.Append(dp[i]); + buf.Append(sep); + } + return buf.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs.meta new file mode 100644 index 0000000..29721c4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLDistPoint.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 76f76b96a0c72084eb8684b7076c3b0c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs new file mode 100644 index 0000000..a8d9d1e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The CRLNumber object. + *
+     * CRLNumber::= Integer(0..MAX)
+     * 
+ */ + public class CrlNumber + : DerInteger + { + public CrlNumber( + BigInteger number) + : base(number) + { + } + + public BigInteger Number + { + get { return PositiveValue; } + } + + public override string ToString() + { + return "CRLNumber: " + Number; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs.meta new file mode 100644 index 0000000..7ca5efc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLNumber.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71369486ad637924399ae4b4f3b0cdb8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs new file mode 100644 index 0000000..e3f94e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs @@ -0,0 +1,64 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The CRLReason enumeration. + *
+     * CRLReason ::= Enumerated {
+     *  unspecified             (0),
+     *  keyCompromise           (1),
+     *  cACompromise            (2),
+     *  affiliationChanged      (3),
+     *  superseded              (4),
+     *  cessationOfOperation    (5),
+     *  certificateHold         (6),
+     *  removeFromCRL           (8),
+     *  privilegeWithdrawn      (9),
+     *  aACompromise           (10)
+     * }
+     * 
+ */ + public class CrlReason + : DerEnumerated + { + public const int Unspecified = 0; + public const int KeyCompromise = 1; + public const int CACompromise = 2; + public const int AffiliationChanged = 3; + public const int Superseded = 4; + public const int CessationOfOperation = 5; + public const int CertificateHold = 6; + // 7 -> Unknown + public const int RemoveFromCrl = 8; + public const int PrivilegeWithdrawn = 9; + public const int AACompromise = 10; + + private static readonly string[] ReasonString = new string[] + { + "Unspecified", "KeyCompromise", "CACompromise", "AffiliationChanged", + "Superseded", "CessationOfOperation", "CertificateHold", "Unknown", + "RemoveFromCrl", "PrivilegeWithdrawn", "AACompromise" + }; + + public CrlReason( + int reason) + : base(reason) + { + } + + public CrlReason( + DerEnumerated reason) + : base(reason.Value.IntValue) + { + } + + public override string ToString() + { + int reason = Value.IntValue; + string str = (reason < 0 || reason > 10) ? "Invalid" : ReasonString[reason]; + return "CrlReason: " + str; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs.meta new file mode 100644 index 0000000..ed827b6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CRLReason.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c68d2f8100a5066489c0646ae5387d53 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs new file mode 100644 index 0000000..e916171 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs @@ -0,0 +1,116 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * PKIX RFC-2459 + * + * The X.509 v2 CRL syntax is as follows. For signature calculation, + * the data that is to be signed is ASN.1 Der encoded. + * + *
+     * CertificateList  ::=  Sequence  {
+     *      tbsCertList          TbsCertList,
+     *      signatureAlgorithm   AlgorithmIdentifier,
+     *      signatureValue       BIT STRING  }
+     * 
+ */ + public class CertificateList + : Asn1Encodable + { + private readonly TbsCertificateList tbsCertList; + private readonly AlgorithmIdentifier sigAlgID; + private readonly DerBitString sig; + + public static CertificateList GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static CertificateList GetInstance( + object obj) + { + if (obj is CertificateList) + return (CertificateList) obj; + + if (obj != null) + return new CertificateList(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private CertificateList( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("sequence wrong size for CertificateList", "seq"); + + tbsCertList = TbsCertificateList.GetInstance(seq[0]); + sigAlgID = AlgorithmIdentifier.GetInstance(seq[1]); + sig = DerBitString.GetInstance(seq[2]); + } + + public TbsCertificateList TbsCertList + { + get { return tbsCertList; } + } + + public CrlEntry[] GetRevokedCertificates() + { + return tbsCertList.GetRevokedCertificates(); + } + + public IEnumerable GetRevokedCertificateEnumeration() + { + return tbsCertList.GetRevokedCertificateEnumeration(); + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return sigAlgID; } + } + + public DerBitString Signature + { + get { return sig; } + } + + public byte[] GetSignatureOctets() + { + return sig.GetOctets(); + } + + public int Version + { + get { return tbsCertList.Version; } + } + + public X509Name Issuer + { + get { return tbsCertList.Issuer; } + } + + public Time ThisUpdate + { + get { return tbsCertList.ThisUpdate; } + } + + public Time NextUpdate + { + get { return tbsCertList.NextUpdate; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(tbsCertList, sigAlgID, sig); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs.meta new file mode 100644 index 0000000..43af9e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/CertificateList.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c3e7c40fd85c424458bbf921ec3a90d5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs new file mode 100644 index 0000000..68e2fba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class DsaParameter + : Asn1Encodable + { + internal readonly DerInteger p, q, g; + + public static DsaParameter GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static DsaParameter GetInstance( + object obj) + { + if(obj == null || obj is DsaParameter) + { + return (DsaParameter) obj; + } + + if(obj is Asn1Sequence) + { + return new DsaParameter((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid DsaParameter: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + public DsaParameter( + BigInteger p, + BigInteger q, + BigInteger g) + { + this.p = new DerInteger(p); + this.q = new DerInteger(q); + this.g = new DerInteger(g); + } + + private DsaParameter( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.p = DerInteger.GetInstance(seq[0]); + this.q = DerInteger.GetInstance(seq[1]); + this.g = DerInteger.GetInstance(seq[2]); + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger Q + { + get { return q.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(p, q, g); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs.meta new file mode 100644 index 0000000..509ffb1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DSAParameter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 670a21c8c431ee943b56aec700ffc433 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs new file mode 100644 index 0000000..3756107 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The DigestInfo object. + *
+     * DigestInfo::=Sequence{
+     *          digestAlgorithm  AlgorithmIdentifier,
+     *          digest OCTET STRING }
+     * 
+ */ + public class DigestInfo + : Asn1Encodable + { + private readonly byte[] digest; + private readonly AlgorithmIdentifier algID; + + public static DigestInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static DigestInfo GetInstance( + object obj) + { + if (obj is DigestInfo) + { + return (DigestInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new DigestInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public DigestInfo( + AlgorithmIdentifier algID, + byte[] digest) + { + this.digest = digest; + this.algID = algID; + } + + private DigestInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + algID = AlgorithmIdentifier.GetInstance(seq[0]); + digest = Asn1OctetString.GetInstance(seq[1]).GetOctets(); + } + + public AlgorithmIdentifier AlgorithmID + { + get { return algID; } + } + + public byte[] GetDigest() + { + return digest; + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algID, new DerOctetString(digest)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs.meta new file mode 100644 index 0000000..0902b30 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DigestInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bd2bf215172b1644bbeb087773fecc6a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs new file mode 100644 index 0000000..a38a7aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs @@ -0,0 +1,164 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The DistributionPoint object. + *
+     * DistributionPoint ::= Sequence {
+     *      distributionPoint [0] DistributionPointName OPTIONAL,
+     *      reasons           [1] ReasonFlags OPTIONAL,
+     *      cRLIssuer         [2] GeneralNames OPTIONAL
+     * }
+     * 
+ */ + public class DistributionPoint + : Asn1Encodable + { + internal readonly DistributionPointName distributionPoint; + internal readonly ReasonFlags reasons; + internal readonly GeneralNames cRLIssuer; + + public static DistributionPoint GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static DistributionPoint GetInstance( + object obj) + { + if(obj == null || obj is DistributionPoint) + { + return (DistributionPoint) obj; + } + + if(obj is Asn1Sequence) + { + return new DistributionPoint((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid DistributionPoint: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + private DistributionPoint( + Asn1Sequence seq) + { + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject t = Asn1TaggedObject.GetInstance(seq[i]); + + switch (t.TagNo) + { + case 0: + distributionPoint = DistributionPointName.GetInstance(t, true); + break; + case 1: + reasons = new ReasonFlags(DerBitString.GetInstance(t, false)); + break; + case 2: + cRLIssuer = GeneralNames.GetInstance(t, false); + break; + } + } + } + + public DistributionPoint( + DistributionPointName distributionPointName, + ReasonFlags reasons, + GeneralNames crlIssuer) + { + this.distributionPoint = distributionPointName; + this.reasons = reasons; + this.cRLIssuer = crlIssuer; + } + + public DistributionPointName DistributionPointName + { + get { return distributionPoint; } + } + + public ReasonFlags Reasons + { + get { return reasons; } + } + + public GeneralNames CrlIssuer + { + get { return cRLIssuer; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (distributionPoint != null) + { + // + // as this is a CHOICE it must be explicitly tagged + // + v.Add(new DerTaggedObject(0, distributionPoint)); + } + + if (reasons != null) + { + v.Add(new DerTaggedObject(false, 1, reasons)); + } + + if (cRLIssuer != null) + { + v.Add(new DerTaggedObject(false, 2, cRLIssuer)); + } + + return new DerSequence(v); + } + + public override string ToString() + { + string sep = Org.BouncyCastle.Utilities.Platform.NewLine; + StringBuilder buf = new StringBuilder(); + buf.Append("DistributionPoint: ["); + buf.Append(sep); + if (distributionPoint != null) + { + appendObject(buf, sep, "distributionPoint", distributionPoint.ToString()); + } + if (reasons != null) + { + appendObject(buf, sep, "reasons", reasons.ToString()); + } + if (cRLIssuer != null) + { + appendObject(buf, sep, "cRLIssuer", cRLIssuer.ToString()); + } + buf.Append("]"); + buf.Append(sep); + return buf.ToString(); + } + + private void appendObject( + StringBuilder buf, + string sep, + string name, + string val) + { + string indent = " "; + + buf.Append(indent); + buf.Append(name); + buf.Append(":"); + buf.Append(sep); + buf.Append(indent); + buf.Append(indent); + buf.Append(val); + buf.Append(sep); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs.meta new file mode 100644 index 0000000..204247e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPoint.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6e72e206b525eea4fbefb336824b2b3a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs new file mode 100644 index 0000000..aaa9817 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs @@ -0,0 +1,133 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The DistributionPointName object. + *
+     * DistributionPointName ::= CHOICE {
+     *     fullName                 [0] GeneralNames,
+     *     nameRelativeToCRLIssuer  [1] RDN
+     * }
+     * 
+ */ + public class DistributionPointName + : Asn1Encodable, IAsn1Choice + { + internal readonly Asn1Encodable name; + internal readonly int type; + + public const int FullName = 0; + public const int NameRelativeToCrlIssuer = 1; + + public static DistributionPointName GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1TaggedObject.GetInstance(obj, true)); + } + + public static DistributionPointName GetInstance( + object obj) + { + if (obj == null || obj is DistributionPointName) + { + return (DistributionPointName) obj; + } + + if (obj is Asn1TaggedObject) + { + return new DistributionPointName((Asn1TaggedObject) obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public DistributionPointName( + int type, + Asn1Encodable name) + { + this.type = type; + this.name = name; + } + + public DistributionPointName( + GeneralNames name) + : this(FullName, name) + { + } + + public int PointType + { + get { return type; } + } + + public Asn1Encodable Name + { + get { return name; } + } + + public DistributionPointName( + Asn1TaggedObject obj) + { + this.type = obj.TagNo; + + if (type == FullName) + { + this.name = GeneralNames.GetInstance(obj, false); + } + else + { + this.name = Asn1Set.GetInstance(obj, false); + } + } + + public override Asn1Object ToAsn1Object() + { + return new DerTaggedObject(false, type, name); + } + + public override string ToString() + { + string sep = Org.BouncyCastle.Utilities.Platform.NewLine; + StringBuilder buf = new StringBuilder(); + buf.Append("DistributionPointName: ["); + buf.Append(sep); + if (type == FullName) + { + appendObject(buf, sep, "fullName", name.ToString()); + } + else + { + appendObject(buf, sep, "nameRelativeToCRLIssuer", name.ToString()); + } + buf.Append("]"); + buf.Append(sep); + return buf.ToString(); + } + + private void appendObject( + StringBuilder buf, + string sep, + string name, + string val) + { + string indent = " "; + + buf.Append(indent); + buf.Append(name); + buf.Append(":"); + buf.Append(sep); + buf.Append(indent); + buf.Append(indent); + buf.Append(val); + buf.Append(sep); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs.meta new file mode 100644 index 0000000..18aeaeb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/DistributionPointName.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7447a6a6bf3d479479bc3c2ba4ea9617 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs new file mode 100644 index 0000000..22d67b1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs @@ -0,0 +1,422 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using NetUtils = Org.BouncyCastle.Utilities.Net; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The GeneralName object. + *
+     * GeneralName ::= CHOICE {
+     *      otherName                       [0]     OtherName,
+     *      rfc822Name                      [1]     IA5String,
+     *      dNSName                         [2]     IA5String,
+     *      x400Address                     [3]     ORAddress,
+     *      directoryName                   [4]     Name,
+     *      ediPartyName                    [5]     EDIPartyName,
+     *      uniformResourceIdentifier       [6]     IA5String,
+     *      iPAddress                       [7]     OCTET STRING,
+     *      registeredID                    [8]     OBJECT IDENTIFIER}
+     *
+     * OtherName ::= Sequence {
+     *      type-id    OBJECT IDENTIFIER,
+     *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+     *
+     * EDIPartyName ::= Sequence {
+     *      nameAssigner            [0]     DirectoryString OPTIONAL,
+     *      partyName               [1]     DirectoryString }
+     * 
+ */ + public class GeneralName + : Asn1Encodable, IAsn1Choice + { + public const int OtherName = 0; + public const int Rfc822Name = 1; + public const int DnsName = 2; + public const int X400Address = 3; + public const int DirectoryName = 4; + public const int EdiPartyName = 5; + public const int UniformResourceIdentifier = 6; + public const int IPAddress = 7; + public const int RegisteredID = 8; + + internal readonly Asn1Encodable obj; + internal readonly int tag; + + public GeneralName( + X509Name directoryName) + { + this.obj = directoryName; + this.tag = 4; + } + + /** + * When the subjectAltName extension contains an Internet mail address, + * the address MUST be included as an rfc822Name. The format of an + * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822]. + * + * When the subjectAltName extension contains a domain name service + * label, the domain name MUST be stored in the dNSName (an IA5String). + * The name MUST be in the "preferred name syntax," as specified by RFC + * 1034 [RFC 1034]. + * + * When the subjectAltName extension contains a URI, the name MUST be + * stored in the uniformResourceIdentifier (an IA5String). The name MUST + * be a non-relative URL, and MUST follow the URL syntax and encoding + * rules specified in [RFC 1738]. The name must include both a scheme + * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme- + * specific-part must include a fully qualified domain name or IP + * address as the host. + * + * When the subjectAltName extension contains a iPAddress, the address + * MUST be stored in the octet string in "network byte order," as + * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of + * each octet is the LSB of the corresponding byte in the network + * address. For IP Version 4, as specified in RFC 791, the octet string + * MUST contain exactly four octets. For IP Version 6, as specified in + * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC + * 1883]. + */ + public GeneralName( + Asn1Object name, + int tag) + { + this.obj = name; + this.tag = tag; + } + + public GeneralName( + int tag, + Asn1Encodable name) + { + this.obj = name; + this.tag = tag; + } + + /** + * Create a GeneralName for the given tag from the passed in string. + *

+ * This constructor can handle: + *

    + *
  • rfc822Name
  • + *
  • iPAddress
  • + *
  • directoryName
  • + *
  • dNSName
  • + *
  • uniformResourceIdentifier
  • + *
  • registeredID
  • + *
+ * For x400Address, otherName and ediPartyName there is no common string + * format defined. + *

+ * Note: A directory name can be encoded in different ways into a byte + * representation. Be aware of this if the byte representation is used for + * comparing results. + *

+ * + * @param tag tag number + * @param name string representation of name + * @throws ArgumentException if the string encoding is not correct or + * not supported. + */ + public GeneralName( + int tag, + string name) + { + this.tag = tag; + + if (tag == Rfc822Name || tag == DnsName || tag == UniformResourceIdentifier) + { + this.obj = new DerIA5String(name); + } + else if (tag == RegisteredID) + { + this.obj = new DerObjectIdentifier(name); + } + else if (tag == DirectoryName) + { + this.obj = new X509Name(name); + } + else if (tag == IPAddress) + { + byte[] enc = toGeneralNameEncoding(name); + if (enc == null) + throw new ArgumentException("IP Address is invalid", "name"); + + this.obj = new DerOctetString(enc); + } + else + { + throw new ArgumentException("can't process string for tag: " + tag, "tag"); + } + } + + public static GeneralName GetInstance( + object obj) + { + if (obj == null || obj is GeneralName) + { + return (GeneralName) obj; + } + + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tagObj = (Asn1TaggedObject) obj; + int tag = tagObj.TagNo; + + switch (tag) + { + case OtherName: + return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false)); + case Rfc822Name: + return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); + case DnsName: + return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); + case X400Address: + throw new ArgumentException("unknown tag: " + tag); + case DirectoryName: + return new GeneralName(tag, X509Name.GetInstance(tagObj, true)); + case EdiPartyName: + return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false)); + case UniformResourceIdentifier: + return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); + case IPAddress: + return new GeneralName(tag, Asn1OctetString.GetInstance(tagObj, false)); + case RegisteredID: + return new GeneralName(tag, DerObjectIdentifier.GetInstance(tagObj, false)); + } + } + + if (obj is byte[]) + { + try + { + return GetInstance(Asn1Object.FromByteArray((byte[])obj)); + } + catch (IOException) + { + throw new ArgumentException("unable to parse encoded general name"); + } + } + + throw new ArgumentException("unknown object in GetInstance: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public static GeneralName GetInstance( + Asn1TaggedObject tagObj, + bool explicitly) + { + return GetInstance(Asn1TaggedObject.GetInstance(tagObj, true)); + } + + public int TagNo + { + get { return tag; } + } + + public Asn1Encodable Name + { + get { return obj; } + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + buf.Append(tag); + buf.Append(": "); + + switch (tag) + { + case Rfc822Name: + case DnsName: + case UniformResourceIdentifier: + buf.Append(DerIA5String.GetInstance(obj).GetString()); + break; + case DirectoryName: + buf.Append(X509Name.GetInstance(obj).ToString()); + break; + default: + buf.Append(obj.ToString()); + break; + } + + return buf.ToString(); + } + + private byte[] toGeneralNameEncoding( + string ip) + { + if (NetUtils.IPAddress.IsValidIPv6WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv6(ip)) + { + int slashIndex = ip.IndexOf('/'); + + if (slashIndex < 0) + { + byte[] addr = new byte[16]; + int[] parsedIp = parseIPv6(ip); + copyInts(parsedIp, addr, 0); + + return addr; + } + else + { + byte[] addr = new byte[32]; + int[] parsedIp = parseIPv6(ip.Substring(0, slashIndex)); + copyInts(parsedIp, addr, 0); + string mask = ip.Substring(slashIndex + 1); + if (mask.IndexOf(':') > 0) + { + parsedIp = parseIPv6(mask); + } + else + { + parsedIp = parseMask(mask); + } + copyInts(parsedIp, addr, 16); + + return addr; + } + } + else if (NetUtils.IPAddress.IsValidIPv4WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv4(ip)) + { + int slashIndex = ip.IndexOf('/'); + + if (slashIndex < 0) + { + byte[] addr = new byte[4]; + + parseIPv4(ip, addr, 0); + + return addr; + } + else + { + byte[] addr = new byte[8]; + + parseIPv4(ip.Substring(0, slashIndex), addr, 0); + + string mask = ip.Substring(slashIndex + 1); + if (mask.IndexOf('.') > 0) + { + parseIPv4(mask, addr, 4); + } + else + { + parseIPv4Mask(mask, addr, 4); + } + + return addr; + } + } + + return null; + } + + private void parseIPv4Mask(string mask, byte[] addr, int offset) + { + int maskVal = Int32.Parse(mask); + + for (int i = 0; i != maskVal; i++) + { + addr[(i / 8) + offset] |= (byte)(1 << (i % 8)); + } + } + + private void parseIPv4(string ip, byte[] addr, int offset) + { + foreach (string token in ip.Split('.', '/')) + { + addr[offset++] = (byte)Int32.Parse(token); + } + } + + private int[] parseMask(string mask) + { + int[] res = new int[8]; + int maskVal = Int32.Parse(mask); + + for (int i = 0; i != maskVal; i++) + { + res[i / 16] |= 1 << (i % 16); + } + return res; + } + + private void copyInts(int[] parsedIp, byte[] addr, int offSet) + { + for (int i = 0; i != parsedIp.Length; i++) + { + addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8); + addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i]; + } + } + + private int[] parseIPv6(string ip) + { + if (Org.BouncyCastle.Utilities.Platform.StartsWith(ip, "::")) + { + ip = ip.Substring(1); + } + else if (Org.BouncyCastle.Utilities.Platform.EndsWith(ip, "::")) + { + ip = ip.Substring(0, ip.Length - 1); + } + + IEnumerator sEnum = ip.Split(':').GetEnumerator(); + + int index = 0; + int[] val = new int[8]; + + int doubleColon = -1; + + while (sEnum.MoveNext()) + { + string e = (string) sEnum.Current; + + if (e.Length == 0) + { + doubleColon = index; + val[index++] = 0; + } + else + { + if (e.IndexOf('.') < 0) + { + val[index++] = Int32.Parse(e, NumberStyles.AllowHexSpecifier); + } + else + { + string[] tokens = e.Split('.'); + + val[index++] = (Int32.Parse(tokens[0]) << 8) | Int32.Parse(tokens[1]); + val[index++] = (Int32.Parse(tokens[2]) << 8) | Int32.Parse(tokens[3]); + } + } + } + + if (index != val.Length) + { + Array.Copy(val, doubleColon, val, val.Length - (index - doubleColon), index - doubleColon); + for (int i = doubleColon; i != val.Length - (index - doubleColon); i++) + { + val[i] = 0; + } + } + + return val; + } + + public override Asn1Object ToAsn1Object() + { + // Explicitly tagged if DirectoryName + return new DerTaggedObject(tag == DirectoryName, tag, obj); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs.meta new file mode 100644 index 0000000..ee5801b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralName.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8f9fa15cc99df23488aa1a0f35bb278d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs new file mode 100644 index 0000000..66c7c34 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs @@ -0,0 +1,98 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class GeneralNames + : Asn1Encodable + { + private readonly GeneralName[] names; + + public static GeneralNames GetInstance( + object obj) + { + if (obj == null || obj is GeneralNames) + { + return (GeneralNames) obj; + } + + if (obj is Asn1Sequence) + { + return new GeneralNames((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public static GeneralNames GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /// Construct a GeneralNames object containing one GeneralName. + /// The name to be contained. + public GeneralNames( + GeneralName name) + { + names = new GeneralName[]{ name }; + } + + public GeneralNames( + GeneralName[] names) + { + this.names = (GeneralName[])names.Clone(); + } + + private GeneralNames( + Asn1Sequence seq) + { + this.names = new GeneralName[seq.Count]; + + for (int i = 0; i != seq.Count; i++) + { + names[i] = GeneralName.GetInstance(seq[i]); + } + } + + public GeneralName[] GetNames() + { + return (GeneralName[]) names.Clone(); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		 * GeneralNames ::= Sequence SIZE {1..MAX} OF GeneralName
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(names); + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string sep = Org.BouncyCastle.Utilities.Platform.NewLine; + + buf.Append("GeneralNames:"); + buf.Append(sep); + + foreach (GeneralName name in names) + { + buf.Append(" "); + buf.Append(name); + buf.Append(sep); + } + + return buf.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs.meta new file mode 100644 index 0000000..1e0c896 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/GeneralNames.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2f5291483fbf63c488fd9c2eb029e9bc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs new file mode 100644 index 0000000..dfa7c28 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs @@ -0,0 +1,250 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + *
+	 * IssuingDistributionPoint ::= SEQUENCE { 
+	 *   distributionPoint          [0] DistributionPointName OPTIONAL, 
+	 *   onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE, 
+	 *   onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE, 
+	 *   onlySomeReasons            [3] ReasonFlags OPTIONAL, 
+	 *   indirectCRL                [4] BOOLEAN DEFAULT FALSE,
+	 *   onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+	 * 
+ */ + public class IssuingDistributionPoint + : Asn1Encodable + { + private readonly DistributionPointName _distributionPoint; + private readonly bool _onlyContainsUserCerts; + private readonly bool _onlyContainsCACerts; + private readonly ReasonFlags _onlySomeReasons; + private readonly bool _indirectCRL; + private readonly bool _onlyContainsAttributeCerts; + + private readonly Asn1Sequence seq; + + public static IssuingDistributionPoint GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static IssuingDistributionPoint GetInstance( + object obj) + { + if (obj == null || obj is IssuingDistributionPoint) + { + return (IssuingDistributionPoint) obj; + } + + if (obj is Asn1Sequence) + { + return new IssuingDistributionPoint((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from given details. + * + * @param distributionPoint + * May contain an URI as pointer to most current CRL. + * @param onlyContainsUserCerts Covers revocation information for end certificates. + * @param onlyContainsCACerts Covers revocation information for CA certificates. + * + * @param onlySomeReasons + * Which revocation reasons does this point cover. + * @param indirectCRL + * If true then the CRL contains revocation + * information about certificates ssued by other CAs. + * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates. + */ + public IssuingDistributionPoint( + DistributionPointName distributionPoint, + bool onlyContainsUserCerts, + bool onlyContainsCACerts, + ReasonFlags onlySomeReasons, + bool indirectCRL, + bool onlyContainsAttributeCerts) + { + this._distributionPoint = distributionPoint; + this._indirectCRL = indirectCRL; + this._onlyContainsAttributeCerts = onlyContainsAttributeCerts; + this._onlyContainsCACerts = onlyContainsCACerts; + this._onlyContainsUserCerts = onlyContainsUserCerts; + this._onlySomeReasons = onlySomeReasons; + + Asn1EncodableVector vec = new Asn1EncodableVector(); + if (distributionPoint != null) + { // CHOICE item so explicitly tagged + vec.Add(new DerTaggedObject(true, 0, distributionPoint)); + } + if (onlyContainsUserCerts) + { + vec.Add(new DerTaggedObject(false, 1, DerBoolean.True)); + } + if (onlyContainsCACerts) + { + vec.Add(new DerTaggedObject(false, 2, DerBoolean.True)); + } + if (onlySomeReasons != null) + { + vec.Add(new DerTaggedObject(false, 3, onlySomeReasons)); + } + if (indirectCRL) + { + vec.Add(new DerTaggedObject(false, 4, DerBoolean.True)); + } + if (onlyContainsAttributeCerts) + { + vec.Add(new DerTaggedObject(false, 5, DerBoolean.True)); + } + + seq = new DerSequence(vec); + } + + /** + * Constructor from Asn1Sequence + */ + private IssuingDistributionPoint( + Asn1Sequence seq) + { + this.seq = seq; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[i]); + + switch (o.TagNo) + { + case 0: + // CHOICE so explicit + _distributionPoint = DistributionPointName.GetInstance(o, true); + break; + case 1: + _onlyContainsUserCerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 2: + _onlyContainsCACerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 3: + _onlySomeReasons = new ReasonFlags(ReasonFlags.GetInstance(o, false)); + break; + case 4: + _indirectCRL = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 5: + _onlyContainsAttributeCerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + default: + throw new ArgumentException("unknown tag in IssuingDistributionPoint"); + } + } + } + + public bool OnlyContainsUserCerts + { + get { return _onlyContainsUserCerts; } + } + + public bool OnlyContainsCACerts + { + get { return _onlyContainsCACerts; } + } + + public bool IsIndirectCrl + { + get { return _indirectCRL; } + } + + public bool OnlyContainsAttributeCerts + { + get { return _onlyContainsAttributeCerts; } + } + + /** + * @return Returns the distributionPoint. + */ + public DistributionPointName DistributionPoint + { + get { return _distributionPoint; } + } + + /** + * @return Returns the onlySomeReasons. + */ + public ReasonFlags OnlySomeReasons + { + get { return _onlySomeReasons; } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + + public override string ToString() + { + string sep = Org.BouncyCastle.Utilities.Platform.NewLine; + StringBuilder buf = new StringBuilder(); + + buf.Append("IssuingDistributionPoint: ["); + buf.Append(sep); + if (_distributionPoint != null) + { + appendObject(buf, sep, "distributionPoint", _distributionPoint.ToString()); + } + if (_onlyContainsUserCerts) + { + appendObject(buf, sep, "onlyContainsUserCerts", _onlyContainsUserCerts.ToString()); + } + if (_onlyContainsCACerts) + { + appendObject(buf, sep, "onlyContainsCACerts", _onlyContainsCACerts.ToString()); + } + if (_onlySomeReasons != null) + { + appendObject(buf, sep, "onlySomeReasons", _onlySomeReasons.ToString()); + } + if (_onlyContainsAttributeCerts) + { + appendObject(buf, sep, "onlyContainsAttributeCerts", _onlyContainsAttributeCerts.ToString()); + } + if (_indirectCRL) + { + appendObject(buf, sep, "indirectCRL", _indirectCRL.ToString()); + } + buf.Append("]"); + buf.Append(sep); + return buf.ToString(); + } + + private void appendObject( + StringBuilder buf, + string sep, + string name, + string val) + { + string indent = " "; + + buf.Append(indent); + buf.Append(name); + buf.Append(":"); + buf.Append(sep); + buf.Append(indent); + buf.Append(indent); + buf.Append(val); + buf.Append(sep); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs.meta new file mode 100644 index 0000000..e72ab11 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/IssuingDistributionPoint.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 294595b60094c3f47b8d0e7a74f0534d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs new file mode 100644 index 0000000..f7dbb0f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The KeyUsage object. + *
+     *    id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
+     *
+     *    KeyUsage ::= BIT STRING {
+     *         digitalSignature        (0),
+     *         nonRepudiation          (1),
+     *         keyEncipherment         (2),
+     *         dataEncipherment        (3),
+     *         keyAgreement            (4),
+     *         keyCertSign             (5),
+     *         cRLSign                 (6),
+     *         encipherOnly            (7),
+     *         decipherOnly            (8) }
+     * 
+ */ + public class KeyUsage + : DerBitString + { + public const int DigitalSignature = (1 << 7); + public const int NonRepudiation = (1 << 6); + public const int KeyEncipherment = (1 << 5); + public const int DataEncipherment = (1 << 4); + public const int KeyAgreement = (1 << 3); + public const int KeyCertSign = (1 << 2); + public const int CrlSign = (1 << 1); + public const int EncipherOnly = (1 << 0); + public const int DecipherOnly = (1 << 15); + + public static new KeyUsage GetInstance( + object obj) + { + if (obj is KeyUsage) + { + return (KeyUsage)obj; + } + + if (obj is X509Extension) + { + return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj)); + } + + return new KeyUsage(DerBitString.GetInstance(obj)); + } + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (KeyUsage.keyEncipherment | KeyUsage.dataEncipherment) + */ + public KeyUsage(int usage) + : base(usage) + { + } + + private KeyUsage( + DerBitString usage) + : base(usage.GetBytes(), usage.PadBits) + { + } + + public override string ToString() + { + byte[] data = GetBytes(); + if (data.Length == 1) + { + return "KeyUsage: 0x" + (data[0] & 0xff).ToString("X"); + } + + return "KeyUsage: 0x" + ((data[1] & 0xff) << 8 | (data[0] & 0xff)).ToString("X"); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs.meta new file mode 100644 index 0000000..f31998e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/KeyUsage.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4021a83960488554b81323fece140b47 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs new file mode 100644 index 0000000..f17b192 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs @@ -0,0 +1,96 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class RsaPublicKeyStructure + : Asn1Encodable + { + private BigInteger modulus; + private BigInteger publicExponent; + + public static RsaPublicKeyStructure GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static RsaPublicKeyStructure GetInstance( + object obj) + { + if (obj == null || obj is RsaPublicKeyStructure) + { + return (RsaPublicKeyStructure) obj; + } + + if (obj is Asn1Sequence) + { + return new RsaPublicKeyStructure((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid RsaPublicKeyStructure: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj)); + } + + public RsaPublicKeyStructure( + BigInteger modulus, + BigInteger publicExponent) + { + if (modulus == null) + throw new ArgumentNullException("modulus"); + if (publicExponent == null) + throw new ArgumentNullException("publicExponent"); + if (modulus.SignValue <= 0) + throw new ArgumentException("Not a valid RSA modulus", "modulus"); + if (publicExponent.SignValue <= 0) + throw new ArgumentException("Not a valid RSA public exponent", "publicExponent"); + + this.modulus = modulus; + this.publicExponent = publicExponent; + } + + private RsaPublicKeyStructure( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + // Note: we are accepting technically incorrect (i.e. negative) values here + modulus = DerInteger.GetInstance(seq[0]).PositiveValue; + publicExponent = DerInteger.GetInstance(seq[1]).PositiveValue; + } + + public BigInteger Modulus + { + get { return modulus; } + } + + public BigInteger PublicExponent + { + get { return publicExponent; } + } + + /** + * This outputs the key in Pkcs1v2 format. + *
+         *      RSAPublicKey ::= Sequence {
+         *                          modulus Integer, -- n
+         *                          publicExponent Integer, -- e
+         *                      }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence( + new DerInteger(Modulus), + new DerInteger(PublicExponent)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs.meta new file mode 100644 index 0000000..b0ec5da --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/RSAPublicKeyStructure.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bf27e7314c63a8242bc799931359c21d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs new file mode 100644 index 0000000..978a95c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The ReasonFlags object. + *
+     * ReasonFlags ::= BIT STRING {
+     *    unused(0),
+     *    keyCompromise(1),
+     *    cACompromise(2),
+     *    affiliationChanged(3),
+     *    superseded(4),
+     *    cessationOfOperation(5),
+     *    certficateHold(6)
+     * }
+     * 
+ */ + public class ReasonFlags + : DerBitString + { + public const int Unused = (1 << 7); + public const int KeyCompromise = (1 << 6); + public const int CACompromise = (1 << 5); + public const int AffiliationChanged = (1 << 4); + public const int Superseded = (1 << 3); + public const int CessationOfOperation = (1 << 2); + public const int CertificateHold = (1 << 1); + public const int PrivilegeWithdrawn = (1 << 0); + public const int AACompromise = (1 << 15); + + /** + * @param reasons - the bitwise OR of the Key Reason flags giving the + * allowed uses for the key. + */ + public ReasonFlags(int reasons) + : base(reasons) + { + } + + public ReasonFlags( + DerBitString reasons) + : base(reasons.GetBytes(), reasons.PadBits) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs.meta new file mode 100644 index 0000000..e6772e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/ReasonFlags.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8f55944d463a02e419739037579f2686 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs new file mode 100644 index 0000000..48ccbb5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The object that contains the public key stored in a certficate. + *

+ * The GetEncoded() method in the public keys in the JCE produces a DER + * encoded one of these.

+ */ + public class SubjectPublicKeyInfo + : Asn1Encodable + { + private readonly AlgorithmIdentifier algID; + private readonly DerBitString keyData; + + public static SubjectPublicKeyInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static SubjectPublicKeyInfo GetInstance( + object obj) + { + if (obj is SubjectPublicKeyInfo) + return (SubjectPublicKeyInfo) obj; + + if (obj != null) + return new SubjectPublicKeyInfo(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public SubjectPublicKeyInfo( + AlgorithmIdentifier algID, + Asn1Encodable publicKey) + { + this.keyData = new DerBitString(publicKey); + this.algID = algID; + } + + public SubjectPublicKeyInfo( + AlgorithmIdentifier algID, + byte[] publicKey) + { + this.keyData = new DerBitString(publicKey); + this.algID = algID; + } + + private SubjectPublicKeyInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.algID = AlgorithmIdentifier.GetInstance(seq[0]); + this.keyData = DerBitString.GetInstance(seq[1]); + } + + public AlgorithmIdentifier AlgorithmID + { + get { return algID; } + } + + /** + * for when the public key is an encoded object - if the bitstring + * can't be decoded this routine raises an IOException. + * + * @exception IOException - if the bit string doesn't represent a Der + * encoded object. + */ + public Asn1Object GetPublicKey() + { + return Asn1Object.FromByteArray(keyData.GetOctets()); + } + + /** + * for when the public key is raw bits... + */ + public DerBitString PublicKeyData + { + get { return keyData; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * SubjectPublicKeyInfo ::= Sequence {
+         *                          algorithm AlgorithmIdentifier,
+         *                          publicKey BIT STRING }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algID, keyData); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs.meta new file mode 100644 index 0000000..4dfdd9a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/SubjectPublicKeyInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 541f1fea72adbd644a70264d4145b14f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs new file mode 100644 index 0000000..882abd5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs @@ -0,0 +1,278 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class CrlEntry + : Asn1Encodable + { + internal Asn1Sequence seq; + internal DerInteger userCertificate; + internal Time revocationDate; + internal X509Extensions crlEntryExtensions; + + public CrlEntry( + Asn1Sequence seq) + { + if (seq.Count < 2 || seq.Count > 3) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + this.seq = seq; + + userCertificate = DerInteger.GetInstance(seq[0]); + revocationDate = Time.GetInstance(seq[1]); + } + + public DerInteger UserCertificate + { + get { return userCertificate; } + } + + public Time RevocationDate + { + get { return revocationDate; } + } + + public X509Extensions Extensions + { + get + { + if (crlEntryExtensions == null && seq.Count == 3) + { + crlEntryExtensions = X509Extensions.GetInstance(seq[2]); + } + + return crlEntryExtensions; + } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } + + /** + * PKIX RFC-2459 - TbsCertList object. + *
+     * TbsCertList  ::=  Sequence  {
+     *      version                 Version OPTIONAL,
+     *                                   -- if present, shall be v2
+     *      signature               AlgorithmIdentifier,
+     *      issuer                  Name,
+     *      thisUpdate              Time,
+     *      nextUpdate              Time OPTIONAL,
+     *      revokedCertificates     Sequence OF Sequence  {
+     *           userCertificate         CertificateSerialNumber,
+     *           revocationDate          Time,
+     *           crlEntryExtensions      Extensions OPTIONAL
+     *                                         -- if present, shall be v2
+     *                                }  OPTIONAL,
+     *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+     *                                         -- if present, shall be v2
+     *                                }
+     * 
+ */ + public class TbsCertificateList + : Asn1Encodable + { + private class RevokedCertificatesEnumeration + : IEnumerable + { + private readonly IEnumerable en; + + internal RevokedCertificatesEnumeration( + IEnumerable en) + { + this.en = en; + } + + public IEnumerator GetEnumerator() + { + return new RevokedCertificatesEnumerator(en.GetEnumerator()); + } + + private class RevokedCertificatesEnumerator + : IEnumerator + { + private readonly IEnumerator e; + + internal RevokedCertificatesEnumerator( + IEnumerator e) + { + this.e = e; + } + + public bool MoveNext() + { + return e.MoveNext(); + } + + public void Reset() + { + e.Reset(); + } + + public object Current + { + get { return new CrlEntry(Asn1Sequence.GetInstance(e.Current)); } + } + } + } + + internal Asn1Sequence seq; + internal DerInteger version; + internal AlgorithmIdentifier signature; + internal X509Name issuer; + internal Time thisUpdate; + internal Time nextUpdate; + internal Asn1Sequence revokedCertificates; + internal X509Extensions crlExtensions; + + public static TbsCertificateList GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static TbsCertificateList GetInstance( + object obj) + { + TbsCertificateList list = obj as TbsCertificateList; + + if (obj == null || list != null) + { + return list; + } + + if (obj is Asn1Sequence) + { + return new TbsCertificateList((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + internal TbsCertificateList( + Asn1Sequence seq) + { + if (seq.Count < 3 || seq.Count > 7) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + int seqPos = 0; + + this.seq = seq; + + if (seq[seqPos] is DerInteger) + { + version = DerInteger.GetInstance(seq[seqPos++]); + } + else + { + version = new DerInteger(0); + } + + signature = AlgorithmIdentifier.GetInstance(seq[seqPos++]); + issuer = X509Name.GetInstance(seq[seqPos++]); + thisUpdate = Time.GetInstance(seq[seqPos++]); + + if (seqPos < seq.Count + && (seq[seqPos] is DerUtcTime + || seq[seqPos] is DerGeneralizedTime + || seq[seqPos] is Time)) + { + nextUpdate = Time.GetInstance(seq[seqPos++]); + } + + if (seqPos < seq.Count + && !(seq[seqPos] is DerTaggedObject)) + { + revokedCertificates = Asn1Sequence.GetInstance(seq[seqPos++]); + } + + if (seqPos < seq.Count + && seq[seqPos] is DerTaggedObject) + { + crlExtensions = X509Extensions.GetInstance(seq[seqPos]); + } + } + + public int Version + { + get { return version.Value.IntValue + 1; } + } + + public DerInteger VersionNumber + { + get { return version; } + } + + public AlgorithmIdentifier Signature + { + get { return signature; } + } + + public X509Name Issuer + { + get { return issuer; } + } + + public Time ThisUpdate + { + get { return thisUpdate; } + } + + public Time NextUpdate + { + get { return nextUpdate; } + } + + public CrlEntry[] GetRevokedCertificates() + { + if (revokedCertificates == null) + { + return new CrlEntry[0]; + } + + CrlEntry[] entries = new CrlEntry[revokedCertificates.Count]; + + for (int i = 0; i < entries.Length; i++) + { + entries[i] = new CrlEntry(Asn1Sequence.GetInstance(revokedCertificates[i])); + } + + return entries; + } + + public IEnumerable GetRevokedCertificateEnumeration() + { + if (revokedCertificates == null) + { + return EmptyEnumerable.Instance; + } + + return new RevokedCertificatesEnumeration(revokedCertificates); + } + + public X509Extensions Extensions + { + get { return crlExtensions; } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs.meta new file mode 100644 index 0000000..bf2286d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertList.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d6dd3b685770b5141ae5641c5efb878e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs new file mode 100644 index 0000000..58f34b9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs @@ -0,0 +1,188 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The TbsCertificate object. + *
+     * TbsCertificate ::= Sequence {
+     *      version          [ 0 ]  Version DEFAULT v1(0),
+     *      serialNumber            CertificateSerialNumber,
+     *      signature               AlgorithmIdentifier,
+     *      issuer                  Name,
+     *      validity                Validity,
+     *      subject                 Name,
+     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
+     *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+     *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+     *      extensions        [ 3 ] Extensions OPTIONAL
+     *      }
+     * 
+ *

+ * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class + * will parse them, but you really shouldn't be creating new ones.

+ */ + public class TbsCertificateStructure + : Asn1Encodable + { + internal Asn1Sequence seq; + internal DerInteger version; + internal DerInteger serialNumber; + internal AlgorithmIdentifier signature; + internal X509Name issuer; + internal Time startDate, endDate; + internal X509Name subject; + internal SubjectPublicKeyInfo subjectPublicKeyInfo; + internal DerBitString issuerUniqueID; + internal DerBitString subjectUniqueID; + internal X509Extensions extensions; + + public static TbsCertificateStructure GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static TbsCertificateStructure GetInstance( + object obj) + { + if (obj is TbsCertificateStructure) + return (TbsCertificateStructure) obj; + + if (obj != null) + return new TbsCertificateStructure(Asn1Sequence.GetInstance(obj)); + + return null; + } + + internal TbsCertificateStructure( + Asn1Sequence seq) + { + int seqStart = 0; + + this.seq = seq; + + // + // some certficates don't include a version number - we assume v1 + // + if (seq[0] is DerTaggedObject) + { + version = DerInteger.GetInstance((Asn1TaggedObject)seq[0], true); + } + else + { + seqStart = -1; // field 0 is missing! + version = new DerInteger(0); + } + + serialNumber = DerInteger.GetInstance(seq[seqStart + 1]); + + signature = AlgorithmIdentifier.GetInstance(seq[seqStart + 2]); + issuer = X509Name.GetInstance(seq[seqStart + 3]); + + // + // before and after dates + // + Asn1Sequence dates = (Asn1Sequence)seq[seqStart + 4]; + + startDate = Time.GetInstance(dates[0]); + endDate = Time.GetInstance(dates[1]); + + subject = X509Name.GetInstance(seq[seqStart + 5]); + + // + // public key info. + // + subjectPublicKeyInfo = SubjectPublicKeyInfo.GetInstance(seq[seqStart + 6]); + + for (int extras = seq.Count - (seqStart + 6) - 1; extras > 0; extras--) + { + DerTaggedObject extra = (DerTaggedObject) seq[seqStart + 6 + extras]; + + switch (extra.TagNo) + { + case 1: + issuerUniqueID = DerBitString.GetInstance(extra, false); + break; + case 2: + subjectUniqueID = DerBitString.GetInstance(extra, false); + break; + case 3: + extensions = X509Extensions.GetInstance(extra); + break; + } + } + } + + public int Version + { + get { return version.Value.IntValue + 1; } + } + + public DerInteger VersionNumber + { + get { return version; } + } + + public DerInteger SerialNumber + { + get { return serialNumber; } + } + + public AlgorithmIdentifier Signature + { + get { return signature; } + } + + public X509Name Issuer + { + get { return issuer; } + } + + public Time StartDate + { + get { return startDate; } + } + + public Time EndDate + { + get { return endDate; } + } + + public X509Name Subject + { + get { return subject; } + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return subjectPublicKeyInfo; } + } + + public DerBitString IssuerUniqueID + { + get { return issuerUniqueID; } + } + + public DerBitString SubjectUniqueID + { + get { return subjectUniqueID; } + } + + public X509Extensions Extensions + { + get { return extensions; } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs.meta new file mode 100644 index 0000000..c686eb2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/TBSCertificateStructure.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ebe58b240e863284fa86f16c303f818a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs new file mode 100644 index 0000000..3a9552f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs @@ -0,0 +1,125 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Globalization; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class Time + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Object time; + + public static Time GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(obj.GetObject()); + } + + public Time( + Asn1Object time) + { + if (time == null) + throw new ArgumentNullException("time"); + if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + throw new ArgumentException("unknown object passed to Time"); + + this.time = time; + } + + /** + * creates a time object from a given date - if the date is between 1950 + * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime + * is used. + */ + public Time( + DateTime date) + { +#if PORTABLE || NETFX_CORE + string d = date.ToUniversalTime().ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#else + string d = date.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#endif + + int year = int.Parse(d.Substring(0, 4)); + + if (year < 1950 || year > 2049) + { + time = new DerGeneralizedTime(d); + } + else + { + time = new DerUtcTime(d.Substring(2)); + } + } + + public static Time GetInstance( + object obj) + { + if (obj == null || obj is Time) + return (Time)obj; + if (obj is DerUtcTime) + return new Time((DerUtcTime)obj); + if (obj is DerGeneralizedTime) + return new Time((DerGeneralizedTime)obj); + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public string GetTime() + { + if (time is DerUtcTime) + { + return ((DerUtcTime) time).AdjustedTimeString; + } + + return ((DerGeneralizedTime) time).GetTime(); + } + + /// + /// Return our time as DateTime. + /// + /// A date time. + public DateTime ToDateTime() + { + try + { + if (time is DerUtcTime) + { + return ((DerUtcTime)time).ToAdjustedDateTime(); + } + else + { + return ((DerGeneralizedTime)time).ToDateTime(); + } + } + catch (FormatException e) + { + // this should never happen + throw new InvalidOperationException("invalid date string: " + e.Message); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Time ::= CHOICE {
+         *             utcTime        UTCTime,
+         *             generalTime    GeneralizedTime }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return time; + } + + public override string ToString() + { + return GetTime(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs.meta new file mode 100644 index 0000000..9ad2d14 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/Time.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32375cfad4bb7a949954d9ef4def0986 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs new file mode 100644 index 0000000..4d093f1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs @@ -0,0 +1,135 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * an X509Certificate structure. + *
+     *  Certificate ::= Sequence {
+     *      tbsCertificate          TbsCertificate,
+     *      signatureAlgorithm      AlgorithmIdentifier,
+     *      signature               BIT STRING
+     *  }
+     * 
+ */ + public class X509CertificateStructure + : Asn1Encodable + { + private readonly TbsCertificateStructure tbsCert; + private readonly AlgorithmIdentifier sigAlgID; + private readonly DerBitString sig; + + public static X509CertificateStructure GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static X509CertificateStructure GetInstance( + object obj) + { + if (obj is X509CertificateStructure) + return (X509CertificateStructure)obj; + if (obj == null) + return null; + return new X509CertificateStructure(Asn1Sequence.GetInstance(obj)); + } + + public X509CertificateStructure( + TbsCertificateStructure tbsCert, + AlgorithmIdentifier sigAlgID, + DerBitString sig) + { + if (tbsCert == null) + throw new ArgumentNullException("tbsCert"); + if (sigAlgID == null) + throw new ArgumentNullException("sigAlgID"); + if (sig == null) + throw new ArgumentNullException("sig"); + + this.tbsCert = tbsCert; + this.sigAlgID = sigAlgID; + this.sig = sig; + } + + private X509CertificateStructure( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("sequence wrong size for a certificate", "seq"); + + // + // correct x509 certficate + // + tbsCert = TbsCertificateStructure.GetInstance(seq[0]); + sigAlgID = AlgorithmIdentifier.GetInstance(seq[1]); + sig = DerBitString.GetInstance(seq[2]); + } + + public TbsCertificateStructure TbsCertificate + { + get { return tbsCert; } + } + + public int Version + { + get { return tbsCert.Version; } + } + + public DerInteger SerialNumber + { + get { return tbsCert.SerialNumber; } + } + + public X509Name Issuer + { + get { return tbsCert.Issuer; } + } + + public Time StartDate + { + get { return tbsCert.StartDate; } + } + + public Time EndDate + { + get { return tbsCert.EndDate; } + } + + public X509Name Subject + { + get { return tbsCert.Subject; } + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return tbsCert.SubjectPublicKeyInfo; } + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return sigAlgID; } + } + + public DerBitString Signature + { + get { return sig; } + } + + public byte[] GetSignatureOctets() + { + return sig.GetOctets(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(tbsCert, sigAlgID, sig); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs.meta new file mode 100644 index 0000000..e24c882 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509CertificateStructure.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 07b8281eb25e0f54389db97a4909a94b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs new file mode 100644 index 0000000..a6d2bf5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs @@ -0,0 +1,66 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The default converter for X509 DN entries when going from their + * string value to ASN.1 strings. + */ + public class X509DefaultEntryConverter + : X509NameEntryConverter + { + /** + * Apply default conversion for the given value depending on the oid + * and the character range of the value. + * + * @param oid the object identifier for the DN entry + * @param value the value associated with it + * @return the ASN.1 equivalent for the string value. + */ + public override Asn1Object GetConvertedValue( + DerObjectIdentifier oid, + string value) + { + if (value.Length != 0 && value[0] == '#') + { + try + { + return ConvertHexEncoded(value, 1); + } + catch (IOException) + { + throw new Exception("can't recode value for oid " + oid.Id); + } + } + + if (value.Length != 0 && value[0] == '\\') + { + value = value.Substring(1); + } + + if (oid.Equals(X509Name.EmailAddress) || oid.Equals(X509Name.DC)) + { + return new DerIA5String(value); + } + + if (oid.Equals(X509Name.DateOfBirth)) // accept time string as well as # (for compatibility) + { + return new DerGeneralizedTime(value); + } + + if (oid.Equals(X509Name.C) + || oid.Equals(X509Name.SerialNumber) + || oid.Equals(X509Name.DnQualifier) + || oid.Equals(X509Name.TelephoneNumber)) + { + return new DerPrintableString(value); + } + + return new DerUtf8String(value); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs.meta new file mode 100644 index 0000000..31aac59 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509DefaultEntryConverter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d2bf5c5a95b4e0d448438db02c8064bc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs new file mode 100644 index 0000000..be7ee28 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * an object for the elements in the X.509 V3 extension block. + */ + public class X509Extension + { + internal bool critical; + internal Asn1OctetString value; + + public X509Extension( + DerBoolean critical, + Asn1OctetString value) + { + if (critical == null) + { + throw new ArgumentNullException("critical"); + } + + this.critical = critical.IsTrue; + this.value = value; + } + + public X509Extension( + bool critical, + Asn1OctetString value) + { + this.critical = critical; + this.value = value; + } + + public bool IsCritical { get { return critical; } } + + public Asn1OctetString Value { get { return value; } } + + public Asn1Encodable GetParsedValue() + { + return ConvertValueToObject(this); + } + + public override int GetHashCode() + { + int vh = this.Value.GetHashCode(); + + return IsCritical ? vh : ~vh; + } + + public override bool Equals( + object obj) + { + X509Extension other = obj as X509Extension; + if (other == null) + { + return false; + } + + return Value.Equals(other.Value) && IsCritical == other.IsCritical; + } + + /// Convert the value of the passed in extension to an object. + /// The extension to parse. + /// The object the value string contains. + /// If conversion is not possible. + public static Asn1Object ConvertValueToObject( + X509Extension ext) + { + try + { + return Asn1Object.FromByteArray(ext.Value.GetOctets()); + } + catch (Exception e) + { + throw new ArgumentException("can't convert extension", e); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs.meta new file mode 100644 index 0000000..985108d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extension.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bdf1efbea63a3c94781a5a0b7a673bb0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs new file mode 100644 index 0000000..fabe094 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs @@ -0,0 +1,455 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class X509Extensions + : Asn1Encodable + { + /** + * Subject Directory Attributes + */ + public static readonly DerObjectIdentifier SubjectDirectoryAttributes = new DerObjectIdentifier("2.5.29.9"); + + /** + * Subject Key Identifier + */ + public static readonly DerObjectIdentifier SubjectKeyIdentifier = new DerObjectIdentifier("2.5.29.14"); + + /** + * Key Usage + */ + public static readonly DerObjectIdentifier KeyUsage = new DerObjectIdentifier("2.5.29.15"); + + /** + * Private Key Usage Period + */ + public static readonly DerObjectIdentifier PrivateKeyUsagePeriod = new DerObjectIdentifier("2.5.29.16"); + + /** + * Subject Alternative Name + */ + public static readonly DerObjectIdentifier SubjectAlternativeName = new DerObjectIdentifier("2.5.29.17"); + + /** + * Issuer Alternative Name + */ + public static readonly DerObjectIdentifier IssuerAlternativeName = new DerObjectIdentifier("2.5.29.18"); + + /** + * Basic Constraints + */ + public static readonly DerObjectIdentifier BasicConstraints = new DerObjectIdentifier("2.5.29.19"); + + /** + * CRL Number + */ + public static readonly DerObjectIdentifier CrlNumber = new DerObjectIdentifier("2.5.29.20"); + + /** + * Reason code + */ + public static readonly DerObjectIdentifier ReasonCode = new DerObjectIdentifier("2.5.29.21"); + + /** + * Hold Instruction Code + */ + public static readonly DerObjectIdentifier InstructionCode = new DerObjectIdentifier("2.5.29.23"); + + /** + * Invalidity Date + */ + public static readonly DerObjectIdentifier InvalidityDate = new DerObjectIdentifier("2.5.29.24"); + + /** + * Delta CRL indicator + */ + public static readonly DerObjectIdentifier DeltaCrlIndicator = new DerObjectIdentifier("2.5.29.27"); + + /** + * Issuing Distribution Point + */ + public static readonly DerObjectIdentifier IssuingDistributionPoint = new DerObjectIdentifier("2.5.29.28"); + + /** + * Certificate Issuer + */ + public static readonly DerObjectIdentifier CertificateIssuer = new DerObjectIdentifier("2.5.29.29"); + + /** + * Name Constraints + */ + public static readonly DerObjectIdentifier NameConstraints = new DerObjectIdentifier("2.5.29.30"); + + /** + * CRL Distribution Points + */ + public static readonly DerObjectIdentifier CrlDistributionPoints = new DerObjectIdentifier("2.5.29.31"); + + /** + * Certificate Policies + */ + public static readonly DerObjectIdentifier CertificatePolicies = new DerObjectIdentifier("2.5.29.32"); + + /** + * Policy Mappings + */ + public static readonly DerObjectIdentifier PolicyMappings = new DerObjectIdentifier("2.5.29.33"); + + /** + * Authority Key Identifier + */ + public static readonly DerObjectIdentifier AuthorityKeyIdentifier = new DerObjectIdentifier("2.5.29.35"); + + /** + * Policy Constraints + */ + public static readonly DerObjectIdentifier PolicyConstraints = new DerObjectIdentifier("2.5.29.36"); + + /** + * Extended Key Usage + */ + public static readonly DerObjectIdentifier ExtendedKeyUsage = new DerObjectIdentifier("2.5.29.37"); + + /** + * Freshest CRL + */ + public static readonly DerObjectIdentifier FreshestCrl = new DerObjectIdentifier("2.5.29.46"); + + /** + * Inhibit Any Policy + */ + public static readonly DerObjectIdentifier InhibitAnyPolicy = new DerObjectIdentifier("2.5.29.54"); + + /** + * Authority Info Access + */ + public static readonly DerObjectIdentifier AuthorityInfoAccess = new DerObjectIdentifier("1.3.6.1.5.5.7.1.1"); + + /** + * Subject Info Access + */ + public static readonly DerObjectIdentifier SubjectInfoAccess = new DerObjectIdentifier("1.3.6.1.5.5.7.1.11"); + + /** + * Logo Type + */ + public static readonly DerObjectIdentifier LogoType = new DerObjectIdentifier("1.3.6.1.5.5.7.1.12"); + + /** + * BiometricInfo + */ + public static readonly DerObjectIdentifier BiometricInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.1.2"); + + /** + * QCStatements + */ + public static readonly DerObjectIdentifier QCStatements = new DerObjectIdentifier("1.3.6.1.5.5.7.1.3"); + + /** + * Audit identity extension in attribute certificates. + */ + public static readonly DerObjectIdentifier AuditIdentity = new DerObjectIdentifier("1.3.6.1.5.5.7.1.4"); + + /** + * NoRevAvail extension in attribute certificates. + */ + public static readonly DerObjectIdentifier NoRevAvail = new DerObjectIdentifier("2.5.29.56"); + + /** + * TargetInformation extension in attribute certificates. + */ + public static readonly DerObjectIdentifier TargetInformation = new DerObjectIdentifier("2.5.29.55"); + + private readonly IDictionary extensions = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private readonly IList ordering; + + public static X509Extensions GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static X509Extensions GetInstance( + object obj) + { + if (obj == null || obj is X509Extensions) + { + return (X509Extensions) obj; + } + + if (obj is Asn1Sequence) + { + return new X509Extensions((Asn1Sequence) obj); + } + + if (obj is Asn1TaggedObject) + { + return GetInstance(((Asn1TaggedObject) obj).GetObject()); + } + + throw new ArgumentException("unknown object in factory: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + * + * the extensions are a list of constructed sequences, either with (Oid, OctetString) or (Oid, Boolean, OctetString) + */ + private X509Extensions( + Asn1Sequence seq) + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + foreach (Asn1Encodable ae in seq) + { + Asn1Sequence s = Asn1Sequence.GetInstance(ae.ToAsn1Object()); + + if (s.Count < 2 || s.Count > 3) + throw new ArgumentException("Bad sequence size: " + s.Count); + + DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(s[0].ToAsn1Object()); + + bool isCritical = s.Count == 3 + && DerBoolean.GetInstance(s[1].ToAsn1Object()).IsTrue; + + Asn1OctetString octets = Asn1OctetString.GetInstance(s[s.Count - 1].ToAsn1Object()); + + extensions.Add(oid, new X509Extension(isCritical, octets)); + ordering.Add(oid); + } + } + + /** + * constructor from a table of extensions. + *

+ * it's is assumed the table contains Oid/string pairs.

+ */ + public X509Extensions( + IDictionary extensions) + : this(null, extensions) + { + } + + /** + * Constructor from a table of extensions with ordering. + *

+ * It's is assumed the table contains Oid/string pairs.

+ */ + public X509Extensions( + IList ordering, + IDictionary extensions) + { + if (ordering == null) + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(extensions.Keys); + } + else + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(ordering); + } + + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension)extensions[oid]); + } + } + + /** + * Constructor from two vectors + * + * @param objectIDs an ArrayList of the object identifiers. + * @param values an ArrayList of the extension values. + */ + public X509Extensions( + IList oids, + IList values) + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(oids); + + int count = 0; + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension)values[count++]); + } + } + +#if !SILVERLIGHT && !NETFX_CORE && !UNITY_WP8// || !PORTABLE +//#if !(SILVERLIGHT || PORTABLE) + /** + * constructor from a table of extensions. + *

+ * it's is assumed the table contains Oid/string pairs.

+ */ + [Obsolete] + public X509Extensions( + Hashtable extensions) + : this(null, extensions) + { + } + + /** + * Constructor from a table of extensions with ordering. + *

+ * It's is assumed the table contains Oid/string pairs.

+ */ + [Obsolete] + public X509Extensions( + ArrayList ordering, + Hashtable extensions) + { + if (ordering == null) + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(extensions.Keys); + } + else + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(ordering); + } + + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension) extensions[oid]); + } + } + + /** + * Constructor from two vectors + * + * @param objectIDs an ArrayList of the object identifiers. + * @param values an ArrayList of the extension values. + */ + [Obsolete] + public X509Extensions( + ArrayList oids, + ArrayList values) + { + this.ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(oids); + + int count = 0; + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension) values[count++]); + } + } +#endif + + [Obsolete("Use ExtensionOids IEnumerable property")] + public IEnumerator Oids() + { + return ExtensionOids.GetEnumerator(); + } + + /** + * return an Enumeration of the extension field's object ids. + */ + public IEnumerable ExtensionOids + { + get { return new EnumerableProxy(ordering); } + } + + /** + * return the extension represented by the object identifier + * passed in. + * + * @return the extension if it's present, null otherwise. + */ + public X509Extension GetExtension( + DerObjectIdentifier oid) + { + return (X509Extension) extensions[oid]; + } + + /** + *
+		 *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
+		 *
+		 *     Extension         ::=   SEQUENCE {
+		 *        extnId            EXTENSION.&id ({ExtensionSet}),
+		 *        critical          BOOLEAN DEFAULT FALSE,
+		 *        extnValue         OCTET STRING }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector vec = new Asn1EncodableVector(); + + foreach (DerObjectIdentifier oid in ordering) + { + X509Extension ext = (X509Extension) extensions[oid]; + Asn1EncodableVector v = new Asn1EncodableVector(oid); + + if (ext.IsCritical) + { + v.Add(DerBoolean.True); + } + + v.Add(ext.Value); + + vec.Add(new DerSequence(v)); + } + + return new DerSequence(vec); + } + + public bool Equivalent( + X509Extensions other) + { + if (extensions.Count != other.extensions.Count) + return false; + + foreach (DerObjectIdentifier oid in extensions.Keys) + { + if (!extensions[oid].Equals(other.extensions[oid])) + return false; + } + + return true; + } + + public DerObjectIdentifier[] GetExtensionOids() + { + return ToOidArray(ordering); + } + + public DerObjectIdentifier[] GetNonCriticalExtensionOids() + { + return GetExtensionOids(false); + } + + public DerObjectIdentifier[] GetCriticalExtensionOids() + { + return GetExtensionOids(true); + } + + private DerObjectIdentifier[] GetExtensionOids(bool isCritical) + { + IList oids = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + foreach (DerObjectIdentifier oid in this.ordering) + { + X509Extension ext = (X509Extension)extensions[oid]; + if (ext.IsCritical == isCritical) + { + oids.Add(oid); + } + } + + return ToOidArray(oids); + } + + private static DerObjectIdentifier[] ToOidArray(IList oids) + { + DerObjectIdentifier[] oidArray = new DerObjectIdentifier[oids.Count]; + oids.CopyTo(oidArray, 0); + return oidArray; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs.meta new file mode 100644 index 0000000..d816a98 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Extensions.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 00b54aa58571c6e429b23126f5560710 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs new file mode 100644 index 0000000..82b6b8e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs @@ -0,0 +1,1080 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; +using System.IO; +using System.Text; + +#if SILVERLIGHT || PORTABLE || NETFX_CORE +using System.Collections.Generic; +#endif + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + *
+    *     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+    *
+    *     RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
+    *
+    *     AttributeTypeAndValue ::= SEQUENCE {
+    *                                   type  OBJECT IDENTIFIER,
+    *                                   value ANY }
+    * 
+ */ + public class X509Name + : Asn1Encodable + { + /** + * country code - StringType(SIZE(2)) + */ + public static readonly DerObjectIdentifier C = new DerObjectIdentifier("2.5.4.6"); + + /** + * organization - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier O = new DerObjectIdentifier("2.5.4.10"); + + /** + * organizational unit name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier OU = new DerObjectIdentifier("2.5.4.11"); + + /** + * Title + */ + public static readonly DerObjectIdentifier T = new DerObjectIdentifier("2.5.4.12"); + + /** + * common name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier CN = new DerObjectIdentifier("2.5.4.3"); + + /** + * street - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier Street = new DerObjectIdentifier("2.5.4.9"); + + /** + * device serial number name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier SerialNumber = new DerObjectIdentifier("2.5.4.5"); + + /** + * locality name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier L = new DerObjectIdentifier("2.5.4.7"); + + /** + * state, or province name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier ST = new DerObjectIdentifier("2.5.4.8"); + + /** + * Naming attributes of type X520name + */ + public static readonly DerObjectIdentifier Surname = new DerObjectIdentifier("2.5.4.4"); + public static readonly DerObjectIdentifier GivenName = new DerObjectIdentifier("2.5.4.42"); + public static readonly DerObjectIdentifier Initials = new DerObjectIdentifier("2.5.4.43"); + public static readonly DerObjectIdentifier Generation = new DerObjectIdentifier("2.5.4.44"); + public static readonly DerObjectIdentifier UniqueIdentifier = new DerObjectIdentifier("2.5.4.45"); + + /** + * businessCategory - DirectoryString(SIZE(1..128) + */ + public static readonly DerObjectIdentifier BusinessCategory = new DerObjectIdentifier( + "2.5.4.15"); + + /** + * postalCode - DirectoryString(SIZE(1..40) + */ + public static readonly DerObjectIdentifier PostalCode = new DerObjectIdentifier( + "2.5.4.17"); + + /** + * dnQualifier - DirectoryString(SIZE(1..64) + */ + public static readonly DerObjectIdentifier DnQualifier = new DerObjectIdentifier( + "2.5.4.46"); + + /** + * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64) + */ + public static readonly DerObjectIdentifier Pseudonym = new DerObjectIdentifier( + "2.5.4.65"); + + /** + * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z + */ + public static readonly DerObjectIdentifier DateOfBirth = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.1"); + + /** + * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128) + */ + public static readonly DerObjectIdentifier PlaceOfBirth = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.2"); + + /** + * RFC 3039 DateOfBirth - PrintableString (SIZE(1)) -- "M", "F", "m" or "f" + */ + public static readonly DerObjectIdentifier Gender = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.3"); + + /** + * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 + * codes only + */ + public static readonly DerObjectIdentifier CountryOfCitizenship = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.4"); + + /** + * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 + * codes only + */ + public static readonly DerObjectIdentifier CountryOfResidence = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.5"); + + /** + * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64) + */ + public static readonly DerObjectIdentifier NameAtBirth = new DerObjectIdentifier("1.3.36.8.3.14"); + + /** + * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF + * DirectoryString(SIZE(1..30)) + */ + public static readonly DerObjectIdentifier PostalAddress = new DerObjectIdentifier("2.5.4.16"); + + /** + * RFC 2256 dmdName + */ + public static readonly DerObjectIdentifier DmdName = new DerObjectIdentifier("2.5.4.54"); + + /** + * id-at-telephoneNumber + */ + public static readonly DerObjectIdentifier TelephoneNumber = X509ObjectIdentifiers.id_at_telephoneNumber; + + /** + * id-at-name + */ + public static readonly DerObjectIdentifier Name = X509ObjectIdentifiers.id_at_name; + + /** + * Email address (RSA PKCS#9 extension) - IA5String. + *

Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.

+ */ + public static readonly DerObjectIdentifier EmailAddress = PkcsObjectIdentifiers.Pkcs9AtEmailAddress; + + /** + * more from PKCS#9 + */ + public static readonly DerObjectIdentifier UnstructuredName = PkcsObjectIdentifiers.Pkcs9AtUnstructuredName; + public static readonly DerObjectIdentifier UnstructuredAddress = PkcsObjectIdentifiers.Pkcs9AtUnstructuredAddress; + + /** + * email address in Verisign certificates + */ + public static readonly DerObjectIdentifier E = EmailAddress; + + /* + * others... + */ + public static readonly DerObjectIdentifier DC = new DerObjectIdentifier("0.9.2342.19200300.100.1.25"); + + /** + * LDAP User id. + */ + public static readonly DerObjectIdentifier UID = new DerObjectIdentifier("0.9.2342.19200300.100.1.1"); + + /** + * determines whether or not strings should be processed and printed + * from back to front. + */ +// public static bool DefaultReverse = false; + public static bool DefaultReverse + { + get { return defaultReverse[0]; } + set { defaultReverse[0] = value; } + } + + private static readonly bool[] defaultReverse = { false }; + +#if SILVERLIGHT || NETFX_CORE || UNITY_WP8 || PORTABLE + /** + * default look up table translating OID values into their common symbols following + * the convention in RFC 2253 with a few extras + */ + public static readonly IDictionary DefaultSymbols = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 2253 + */ + public static readonly IDictionary RFC2253Symbols = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 1779 + * + */ + public static readonly IDictionary RFC1779Symbols = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + /** + * look up table translating common symbols into their OIDS. + */ + public static readonly IDictionary DefaultLookup = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); +#else + /** + * default look up table translating OID values into their common symbols following + * the convention in RFC 2253 with a few extras + */ + public static readonly Hashtable DefaultSymbols = new Hashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 2253 + */ + public static readonly Hashtable RFC2253Symbols = new Hashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 1779 + * + */ + public static readonly Hashtable RFC1779Symbols = new Hashtable(); + + /** + * look up table translating common symbols into their OIDS. + */ + public static readonly Hashtable DefaultLookup = new Hashtable(); +#endif + + static X509Name() + { + DefaultSymbols.Add(C, "C"); + DefaultSymbols.Add(O, "O"); + DefaultSymbols.Add(T, "T"); + DefaultSymbols.Add(OU, "OU"); + DefaultSymbols.Add(CN, "CN"); + DefaultSymbols.Add(L, "L"); + DefaultSymbols.Add(ST, "ST"); + DefaultSymbols.Add(SerialNumber, "SERIALNUMBER"); + DefaultSymbols.Add(EmailAddress, "E"); + DefaultSymbols.Add(DC, "DC"); + DefaultSymbols.Add(UID, "UID"); + DefaultSymbols.Add(Street, "STREET"); + DefaultSymbols.Add(Surname, "SURNAME"); + DefaultSymbols.Add(GivenName, "GIVENNAME"); + DefaultSymbols.Add(Initials, "INITIALS"); + DefaultSymbols.Add(Generation, "GENERATION"); + DefaultSymbols.Add(UnstructuredAddress, "unstructuredAddress"); + DefaultSymbols.Add(UnstructuredName, "unstructuredName"); + DefaultSymbols.Add(UniqueIdentifier, "UniqueIdentifier"); + DefaultSymbols.Add(DnQualifier, "DN"); + DefaultSymbols.Add(Pseudonym, "Pseudonym"); + DefaultSymbols.Add(PostalAddress, "PostalAddress"); + DefaultSymbols.Add(NameAtBirth, "NameAtBirth"); + DefaultSymbols.Add(CountryOfCitizenship, "CountryOfCitizenship"); + DefaultSymbols.Add(CountryOfResidence, "CountryOfResidence"); + DefaultSymbols.Add(Gender, "Gender"); + DefaultSymbols.Add(PlaceOfBirth, "PlaceOfBirth"); + DefaultSymbols.Add(DateOfBirth, "DateOfBirth"); + DefaultSymbols.Add(PostalCode, "PostalCode"); + DefaultSymbols.Add(BusinessCategory, "BusinessCategory"); + DefaultSymbols.Add(TelephoneNumber, "TelephoneNumber"); + + RFC2253Symbols.Add(C, "C"); + RFC2253Symbols.Add(O, "O"); + RFC2253Symbols.Add(OU, "OU"); + RFC2253Symbols.Add(CN, "CN"); + RFC2253Symbols.Add(L, "L"); + RFC2253Symbols.Add(ST, "ST"); + RFC2253Symbols.Add(Street, "STREET"); + RFC2253Symbols.Add(DC, "DC"); + RFC2253Symbols.Add(UID, "UID"); + + RFC1779Symbols.Add(C, "C"); + RFC1779Symbols.Add(O, "O"); + RFC1779Symbols.Add(OU, "OU"); + RFC1779Symbols.Add(CN, "CN"); + RFC1779Symbols.Add(L, "L"); + RFC1779Symbols.Add(ST, "ST"); + RFC1779Symbols.Add(Street, "STREET"); + + DefaultLookup.Add("c", C); + DefaultLookup.Add("o", O); + DefaultLookup.Add("t", T); + DefaultLookup.Add("ou", OU); + DefaultLookup.Add("cn", CN); + DefaultLookup.Add("l", L); + DefaultLookup.Add("st", ST); + DefaultLookup.Add("serialnumber", SerialNumber); + DefaultLookup.Add("street", Street); + DefaultLookup.Add("emailaddress", E); + DefaultLookup.Add("dc", DC); + DefaultLookup.Add("e", E); + DefaultLookup.Add("uid", UID); + DefaultLookup.Add("surname", Surname); + DefaultLookup.Add("givenname", GivenName); + DefaultLookup.Add("initials", Initials); + DefaultLookup.Add("generation", Generation); + DefaultLookup.Add("unstructuredaddress", UnstructuredAddress); + DefaultLookup.Add("unstructuredname", UnstructuredName); + DefaultLookup.Add("uniqueidentifier", UniqueIdentifier); + DefaultLookup.Add("dn", DnQualifier); + DefaultLookup.Add("pseudonym", Pseudonym); + DefaultLookup.Add("postaladdress", PostalAddress); + DefaultLookup.Add("nameofbirth", NameAtBirth); + DefaultLookup.Add("countryofcitizenship", CountryOfCitizenship); + DefaultLookup.Add("countryofresidence", CountryOfResidence); + DefaultLookup.Add("gender", Gender); + DefaultLookup.Add("placeofbirth", PlaceOfBirth); + DefaultLookup.Add("dateofbirth", DateOfBirth); + DefaultLookup.Add("postalcode", PostalCode); + DefaultLookup.Add("businesscategory", BusinessCategory); + DefaultLookup.Add("telephonenumber", TelephoneNumber); + } + + private readonly IList ordering = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + private readonly X509NameEntryConverter converter; + + private IList values = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + private IList added = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + private Asn1Sequence seq; + + /** + * Return a X509Name based on the passed in tagged object. + * + * @param obj tag object holding name. + * @param explicitly true if explicitly tagged false otherwise. + * @return the X509Name + */ + public static X509Name GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static X509Name GetInstance( + object obj) + { + if (obj == null || obj is X509Name) + return (X509Name)obj; + + if (obj != null) + return new X509Name(Asn1Sequence.GetInstance(obj)); + + throw new ArgumentException("null object in factory", "obj"); + } + + protected X509Name() + { + } + + /** + * Constructor from Asn1Sequence + * + * the principal will be a list of constructed sets, each containing an (OID, string) pair. + */ + protected X509Name( + Asn1Sequence seq) + { + this.seq = seq; + + foreach (Asn1Encodable asn1Obj in seq) + { + Asn1Set asn1Set = Asn1Set.GetInstance(asn1Obj.ToAsn1Object()); + + for (int i = 0; i < asn1Set.Count; i++) + { + Asn1Sequence s = Asn1Sequence.GetInstance(asn1Set[i].ToAsn1Object()); + + if (s.Count != 2) + throw new ArgumentException("badly sized pair"); + + ordering.Add(DerObjectIdentifier.GetInstance(s[0].ToAsn1Object())); + + Asn1Object derValue = s[1].ToAsn1Object(); + if (derValue is IAsn1String && !(derValue is DerUniversalString)) + { + string v = ((IAsn1String)derValue).GetString(); + if (Org.BouncyCastle.Utilities.Platform.StartsWith(v, "#")) + { + v = "\\" + v; + } + + values.Add(v); + } + else + { + values.Add("#" + Hex.ToHexString(derValue.GetEncoded())); + } + + added.Add(i != 0); + } + } + } + + /** + * Constructor from a table of attributes with ordering. + *

+ * it's is assumed the table contains OID/string pairs, and the contents + * of the table are copied into an internal table as part of the + * construction process. The ordering ArrayList should contain the OIDs + * in the order they are meant to be encoded or printed in ToString.

+ */ + public X509Name( + IList ordering, + IDictionary attributes) + : this(ordering, attributes, new X509DefaultEntryConverter()) + { + } + + /** + * Constructor from a table of attributes with ordering. + *

+ * it's is assumed the table contains OID/string pairs, and the contents + * of the table are copied into an internal table as part of the + * construction process. The ordering ArrayList should contain the OIDs + * in the order they are meant to be encoded or printed in ToString.

+ *

+ * The passed in converter will be used to convert the strings into their + * ASN.1 counterparts.

+ */ + public X509Name( + IList ordering, + IDictionary attributes, + X509NameEntryConverter converter) + { + this.converter = converter; + + foreach (DerObjectIdentifier oid in ordering) + { + object attribute = attributes[oid]; + if (attribute == null) + { + throw new ArgumentException("No attribute for object id - " + oid + " - passed to distinguished name"); + } + + this.ordering.Add(oid); + this.added.Add(false); + this.values.Add(attribute); // copy the hash table + } + } + + /** + * Takes two vectors one of the oids and the other of the values. + */ + public X509Name( + IList oids, + IList values) + : this(oids, values, new X509DefaultEntryConverter()) + { + } + + /** + * Takes two vectors one of the oids and the other of the values. + *

+ * The passed in converter will be used to convert the strings into their + * ASN.1 counterparts.

+ */ + public X509Name( + IList oids, + IList values, + X509NameEntryConverter converter) + { + this.converter = converter; + + if (oids.Count != values.Count) + { + throw new ArgumentException("'oids' must be same length as 'values'."); + } + + for (int i = 0; i < oids.Count; i++) + { + this.ordering.Add(oids[i]); + this.values.Add(values[i]); + this.added.Add(false); + } + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. + */ + public X509Name( + string dirName) + : this(DefaultReverse, (IDictionary)DefaultLookup, dirName) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes with each + * string value being converted to its associated ASN.1 type using the passed + * in converter. + */ + public X509Name( + string dirName, + X509NameEntryConverter converter) + : this(DefaultReverse, DefaultLookup, dirName, converter) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. If reverse + * is true, create the encoded version of the sequence starting from the + * last element in the string. + */ + public X509Name( + bool reverse, + string dirName) + : this(reverse, (IDictionary)DefaultLookup, dirName) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes with each + * string value being converted to its associated ASN.1 type using the passed + * in converter. If reverse is true the ASN.1 sequence representing the DN will + * be built by starting at the end of the string, rather than the start. + */ + public X509Name( + bool reverse, + string dirName, + X509NameEntryConverter converter) + : this(reverse, DefaultLookup, dirName, converter) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. lookUp + * should provide a table of lookups, indexed by lowercase only strings and + * yielding a DerObjectIdentifier, other than that OID. and numeric oids + * will be processed automatically. + *
+ * If reverse is true, create the encoded version of the sequence + * starting from the last element in the string. + * @param reverse true if we should start scanning from the end (RFC 2553). + * @param lookUp table of names and their oids. + * @param dirName the X.500 string to be parsed. + */ + public X509Name( + bool reverse, + IDictionary lookUp, + string dirName) + : this(reverse, lookUp, dirName, new X509DefaultEntryConverter()) + { + } + + private DerObjectIdentifier DecodeOid( + string name, + IDictionary lookUp) + { + if (Org.BouncyCastle.Utilities.Platform.StartsWith(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name), "OID.")) + { + return new DerObjectIdentifier(name.Substring(4)); + } + else if (name[0] >= '0' && name[0] <= '9') + { + return new DerObjectIdentifier(name); + } + + DerObjectIdentifier oid = (DerObjectIdentifier)lookUp[Org.BouncyCastle.Utilities.Platform.ToLowerInvariant(name)]; + if (oid == null) + { + throw new ArgumentException("Unknown object id - " + name + " - passed to distinguished name"); + } + + return oid; + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. lookUp + * should provide a table of lookups, indexed by lowercase only strings and + * yielding a DerObjectIdentifier, other than that OID. and numeric oids + * will be processed automatically. The passed in converter is used to convert the + * string values to the right of each equals sign to their ASN.1 counterparts. + *
+ * @param reverse true if we should start scanning from the end, false otherwise. + * @param lookUp table of names and oids. + * @param dirName the string dirName + * @param converter the converter to convert string values into their ASN.1 equivalents + */ + public X509Name( + bool reverse, + IDictionary lookUp, + string dirName, + X509NameEntryConverter converter) + { + this.converter = converter; + X509NameTokenizer nTok = new X509NameTokenizer(dirName); + + while (nTok.HasMoreTokens()) + { + string token = nTok.NextToken(); + int index = token.IndexOf('='); + + if (index == -1) + { + throw new ArgumentException("badly formated directory string"); + } + + string name = token.Substring(0, index); + string value = token.Substring(index + 1); + DerObjectIdentifier oid = DecodeOid(name, lookUp); + + if (value.IndexOf('+') > 0) + { + X509NameTokenizer vTok = new X509NameTokenizer(value, '+'); + string v = vTok.NextToken(); + + this.ordering.Add(oid); + this.values.Add(v); + this.added.Add(false); + + while (vTok.HasMoreTokens()) + { + string sv = vTok.NextToken(); + int ndx = sv.IndexOf('='); + + string nm = sv.Substring(0, ndx); + string vl = sv.Substring(ndx + 1); + this.ordering.Add(DecodeOid(nm, lookUp)); + this.values.Add(vl); + this.added.Add(true); + } + } + else + { + this.ordering.Add(oid); + this.values.Add(value); + this.added.Add(false); + } + } + + if (reverse) + { +// this.ordering.Reverse(); +// this.values.Reverse(); +// this.added.Reverse(); + IList o = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + IList v = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + IList a = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + int count = 1; + + for (int i = 0; i < this.ordering.Count; i++) + { + if (!((bool) this.added[i])) + { + count = 0; + } + + int index = count++; + + o.Insert(index, this.ordering[i]); + v.Insert(index, this.values[i]); + a.Insert(index, this.added[i]); + } + + this.ordering = o; + this.values = v; + this.added = a; + } + } + + /** + * return an IList of the oids in the name, in the order they were found. + */ + public IList GetOidList() + { + return Org.BouncyCastle.Utilities.Platform.CreateArrayList(ordering); + } + + /** + * return an IList of the values found in the name, in the order they + * were found. + */ + public IList GetValueList() + { + return GetValueList(null); + } + + /** + * return an IList of the values found in the name, in the order they + * were found, with the DN label corresponding to passed in oid. + */ + public IList GetValueList(DerObjectIdentifier oid) + { + IList v = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + for (int i = 0; i != values.Count; i++) + { + if (null == oid || oid.Equals(ordering[i])) + { + string val = (string)values[i]; + + if (Org.BouncyCastle.Utilities.Platform.StartsWith(val, "\\#")) + { + val = val.Substring(1); + } + + v.Add(val); + } + } + return v; + } + + public override Asn1Object ToAsn1Object() + { + if (seq == null) + { + Asn1EncodableVector vec = new Asn1EncodableVector(); + Asn1EncodableVector sVec = new Asn1EncodableVector(); + DerObjectIdentifier lstOid = null; + + for (int i = 0; i != ordering.Count; i++) + { + DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; + string str = (string)values[i]; + + if (lstOid == null + || ((bool)this.added[i])) + { + } + else + { + vec.Add(new DerSet(sVec)); + sVec = new Asn1EncodableVector(); + } + + sVec.Add( + new DerSequence( + oid, + converter.GetConvertedValue(oid, str))); + + lstOid = oid; + } + + vec.Add(new DerSet(sVec)); + + seq = new DerSequence(vec); + } + + return seq; + } + + /// The X509Name object to test equivalency against. + /// If true, the order of elements must be the same, + /// as well as the values associated with each element. + public bool Equivalent( + X509Name other, + bool inOrder) + { + if (!inOrder) + return this.Equivalent(other); + + if (other == null) + return false; + + if (other == this) + return true; + + int orderingSize = ordering.Count; + + if (orderingSize != other.ordering.Count) + return false; + + for (int i = 0; i < orderingSize; i++) + { + DerObjectIdentifier oid = (DerObjectIdentifier) ordering[i]; + DerObjectIdentifier oOid = (DerObjectIdentifier) other.ordering[i]; + + if (!oid.Equals(oOid)) + return false; + + string val = (string) values[i]; + string oVal = (string) other.values[i]; + + if (!equivalentStrings(val, oVal)) + return false; + } + + return true; + } + + /** + * test for equivalence - note: case is ignored. + */ + public bool Equivalent( + X509Name other) + { + if (other == null) + return false; + + if (other == this) + return true; + + int orderingSize = ordering.Count; + + if (orderingSize != other.ordering.Count) + { + return false; + } + + bool[] indexes = new bool[orderingSize]; + int start, end, delta; + + if (ordering[0].Equals(other.ordering[0])) // guess forward + { + start = 0; + end = orderingSize; + delta = 1; + } + else // guess reversed - most common problem + { + start = orderingSize - 1; + end = -1; + delta = -1; + } + + for (int i = start; i != end; i += delta) + { + bool found = false; + DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; + string value = (string)values[i]; + + for (int j = 0; j < orderingSize; j++) + { + if (indexes[j]) + { + continue; + } + + DerObjectIdentifier oOid = (DerObjectIdentifier)other.ordering[j]; + + if (oid.Equals(oOid)) + { + string oValue = (string)other.values[j]; + + if (equivalentStrings(value, oValue)) + { + indexes[j] = true; + found = true; + break; + } + } + } + + if (!found) + { + return false; + } + } + + return true; + } + + private static bool equivalentStrings( + string s1, + string s2) + { + string v1 = canonicalize(s1); + string v2 = canonicalize(s2); + + if (!v1.Equals(v2)) + { + v1 = stripInternalSpaces(v1); + v2 = stripInternalSpaces(v2); + + if (!v1.Equals(v2)) + { + return false; + } + } + + return true; + } + + private static string canonicalize( + string s) + { + string v = Org.BouncyCastle.Utilities.Platform.ToLowerInvariant(s).Trim(); + + if (Org.BouncyCastle.Utilities.Platform.StartsWith(v, "#")) + { + Asn1Object obj = decodeObject(v); + + if (obj is IAsn1String) + { + v = Org.BouncyCastle.Utilities.Platform.ToLowerInvariant(((IAsn1String)obj).GetString()).Trim(); + } + } + + return v; + } + + private static Asn1Object decodeObject( + string v) + { + try + { + return Asn1Object.FromByteArray(Hex.Decode(v.Substring(1))); + } + catch (IOException e) + { + throw new InvalidOperationException("unknown encoding in name: " + e.Message, e); + } + } + + private static string stripInternalSpaces( + string str) + { + StringBuilder res = new StringBuilder(); + + if (str.Length != 0) + { + char c1 = str[0]; + + res.Append(c1); + + for (int k = 1; k < str.Length; k++) + { + char c2 = str[k]; + if (!(c1 == ' ' && c2 == ' ')) + { + res.Append(c2); + } + c1 = c2; + } + } + + return res.ToString(); + } + + private void AppendValue( + StringBuilder buf, + IDictionary oidSymbols, + DerObjectIdentifier oid, + string val) + { + string sym = (string)oidSymbols[oid]; + + if (sym != null) + { + buf.Append(sym); + } + else + { + buf.Append(oid.Id); + } + + buf.Append('='); + + int index = buf.Length; + + buf.Append(val); + + int end = buf.Length; + + if (Org.BouncyCastle.Utilities.Platform.StartsWith(val, "\\#")) + { + index += 2; + } + + while (index != end) + { + if ((buf[index] == ',') + || (buf[index] == '"') + || (buf[index] == '\\') + || (buf[index] == '+') + || (buf[index] == '=') + || (buf[index] == '<') + || (buf[index] == '>') + || (buf[index] == ';')) + { + buf.Insert(index++, "\\"); + end++; + } + + index++; + } + } + + /** + * convert the structure to a string - if reverse is true the + * oids and values are listed out starting with the last element + * in the sequence (ala RFC 2253), otherwise the string will begin + * with the first element of the structure. If no string definition + * for the oid is found in oidSymbols the string value of the oid is + * added. Two standard symbol tables are provided DefaultSymbols, and + * RFC2253Symbols as part of this class. + * + * @param reverse if true start at the end of the sequence and work back. + * @param oidSymbols look up table strings for oids. + */ + public string ToString( + bool reverse, + IDictionary oidSymbols) + { +#if SILVERLIGHT || PORTABLE || NETFX_CORE + List components = new List(); +#else + ArrayList components = new ArrayList(); +#endif + + StringBuilder ava = null; + + for (int i = 0; i < ordering.Count; i++) + { + if ((bool) added[i]) + { + ava.Append('+'); + AppendValue(ava, oidSymbols, + (DerObjectIdentifier)ordering[i], + (string)values[i]); + } + else + { + ava = new StringBuilder(); + AppendValue(ava, oidSymbols, + (DerObjectIdentifier)ordering[i], + (string)values[i]); + components.Add(ava); + } + } + + if (reverse) + { + components.Reverse(); + } + + StringBuilder buf = new StringBuilder(); + + if (components.Count > 0) + { + buf.Append(components[0].ToString()); + + for (int i = 1; i < components.Count; ++i) + { + buf.Append(','); + buf.Append(components[i].ToString()); + } + } + + return buf.ToString(); + } + + public override string ToString() + { + return ToString(DefaultReverse, (IDictionary)DefaultSymbols); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs.meta new file mode 100644 index 0000000..90a4e81 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509Name.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c09a00533763e16488d5e052d2be7956 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs new file mode 100644 index 0000000..a87c910 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs @@ -0,0 +1,92 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * It turns out that the number of standard ways the fields in a DN should be + * encoded into their ASN.1 counterparts is rapidly approaching the + * number of machines on the internet. By default the X509Name class + * will produce UTF8Strings in line with the current recommendations (RFC 3280). + *

+ * An example of an encoder look like below: + *

+     * public class X509DirEntryConverter
+     *     : X509NameEntryConverter
+     * {
+     *     public Asn1Object GetConvertedValue(
+     *         DerObjectIdentifier  oid,
+     *         string               value)
+     *     {
+     *         if (str.Length() != 0 && str.charAt(0) == '#')
+     *         {
+     *             return ConvertHexEncoded(str, 1);
+     *         }
+     *         if (oid.Equals(EmailAddress))
+     *         {
+     *             return new DerIA5String(str);
+     *         }
+     *         else if (CanBePrintable(str))
+     *         {
+     *             return new DerPrintableString(str);
+     *         }
+     *         else if (CanBeUTF8(str))
+     *         {
+     *             return new DerUtf8String(str);
+     *         }
+     *         else
+     *         {
+     *             return new DerBmpString(str);
+     *         }
+     *     }
+     * }
+	 * 
+ *

+ */ + public abstract class X509NameEntryConverter + { + /** + * Convert an inline encoded hex string rendition of an ASN.1 + * object back into its corresponding ASN.1 object. + * + * @param str the hex encoded object + * @param off the index at which the encoding starts + * @return the decoded object + */ + protected Asn1Object ConvertHexEncoded( + string hexString, + int offset) + { + string str = hexString.Substring(offset); + + return Asn1Object.FromByteArray(Hex.Decode(str)); + } + + /** + * return true if the passed in string can be represented without + * loss as a PrintableString, false otherwise. + */ + protected bool CanBePrintable( + string str) + { + return DerPrintableString.IsPrintableString(str); + } + + /** + * Convert the passed in string value into the appropriate ASN.1 + * encoded object. + * + * @param oid the oid associated with the value in the DN. + * @param value the value of the particular DN component. + * @return the ASN.1 equivalent for the value. + */ + public abstract Asn1Object GetConvertedValue(DerObjectIdentifier oid, string value); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs.meta new file mode 100644 index 0000000..76bee1d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameEntryConverter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aa46b029d85419b43a5a45f6463a31d6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs new file mode 100644 index 0000000..a90f6a2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs @@ -0,0 +1,107 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System.Text; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * class for breaking up an X500 Name into it's component tokens, ala + * java.util.StringTokenizer. We need this class as some of the + * lightweight Java environment don't support classes like + * StringTokenizer. + */ + public class X509NameTokenizer + { + private string value; + private int index; + private char separator; + private StringBuilder buffer = new StringBuilder(); + + public X509NameTokenizer( + string oid) + : this(oid, ',') + { + } + + public X509NameTokenizer( + string oid, + char separator) + { + this.value = oid; + this.index = -1; + this.separator = separator; + } + + public bool HasMoreTokens() + { + return index != value.Length; + } + + public string NextToken() + { + if (index == value.Length) + { + return null; + } + + int end = index + 1; + bool quoted = false; + bool escaped = false; + + buffer.Remove(0, buffer.Length); + + while (end != value.Length) + { + char c = value[end]; + + if (c == '"') + { + if (!escaped) + { + quoted = !quoted; + } + else + { + buffer.Append(c); + escaped = false; + } + } + else + { + if (escaped || quoted) + { + if (c == '#' && buffer[buffer.Length - 1] == '=') + { + buffer.Append('\\'); + } + else if (c == '+' && separator != '+') + { + buffer.Append('\\'); + } + buffer.Append(c); + escaped = false; + } + else if (c == '\\') + { + escaped = true; + } + else if (c == separator) + { + break; + } + else + { + buffer.Append(c); + } + } + + end++; + } + + index = end; + + return buffer.ToString().Trim(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs.meta new file mode 100644 index 0000000..7af5701 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509NameTokenizer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8316e96f8ca1af14783eb899e5e15cbd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs new file mode 100644 index 0000000..a42530c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs @@ -0,0 +1,62 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.X509 +{ + public abstract class X509ObjectIdentifiers + { + // + // base id + // + internal const string ID = "2.5.4"; + + public static readonly DerObjectIdentifier CommonName = new DerObjectIdentifier(ID + ".3"); + public static readonly DerObjectIdentifier CountryName = new DerObjectIdentifier(ID + ".6"); + public static readonly DerObjectIdentifier LocalityName = new DerObjectIdentifier(ID + ".7"); + public static readonly DerObjectIdentifier StateOrProvinceName = new DerObjectIdentifier(ID + ".8"); + public static readonly DerObjectIdentifier Organization = new DerObjectIdentifier(ID + ".10"); + public static readonly DerObjectIdentifier OrganizationalUnitName = new DerObjectIdentifier(ID + ".11"); + + public static readonly DerObjectIdentifier id_at_telephoneNumber = new DerObjectIdentifier(ID + ".20"); + public static readonly DerObjectIdentifier id_at_name = new DerObjectIdentifier(ID + ".41"); + + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } // + public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26"); + + // + // ripemd160 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) hashAlgorithm(2) RipeMD-160(1)} + // + public static readonly DerObjectIdentifier RipeMD160 = new DerObjectIdentifier("1.3.36.3.2.1"); + + // + // ripemd160WithRSAEncryption OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) signatureAlgorithm(3) rsaSignature(1) rsaSignatureWithripemd160(2) } + // + public static readonly DerObjectIdentifier RipeMD160WithRsaEncryption = new DerObjectIdentifier("1.3.36.3.3.1.2"); + + public static readonly DerObjectIdentifier IdEARsa = new DerObjectIdentifier("2.5.8.1.1"); + + // id-pkix + public static readonly DerObjectIdentifier IdPkix = new DerObjectIdentifier("1.3.6.1.5.5.7"); + + // + // private internet extensions + // + public static readonly DerObjectIdentifier IdPE = new DerObjectIdentifier(IdPkix + ".1"); + + // + // authority information access + // + public static readonly DerObjectIdentifier IdAD = new DerObjectIdentifier(IdPkix + ".48"); + public static readonly DerObjectIdentifier IdADCAIssuers = new DerObjectIdentifier(IdAD + ".2"); + public static readonly DerObjectIdentifier IdADOcsp = new DerObjectIdentifier(IdAD + ".1"); + + // + // OID for ocsp and crl uri in AuthorityInformationAccess extension + // + public static readonly DerObjectIdentifier OcspAccessMethod = IdADOcsp; + public static readonly DerObjectIdentifier CrlAccessMethod = IdADCAIssuers; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs.meta new file mode 100644 index 0000000..d42e4c5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x509/X509ObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 87dba2439330ae349ae823c87363e667 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9.meta new file mode 100644 index 0000000..e185e4c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 76282f28a92d5d448879417bd0de6c37 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs new file mode 100644 index 0000000..3975362 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs @@ -0,0 +1,121 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class DHDomainParameters + : Asn1Encodable + { + private readonly DerInteger p, g, q, j; + private readonly DHValidationParms validationParms; + + public static DHDomainParameters GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static DHDomainParameters GetInstance(object obj) + { + if (obj == null || obj is DHDomainParameters) + return (DHDomainParameters)obj; + + if (obj is Asn1Sequence) + return new DHDomainParameters((Asn1Sequence)obj); + + throw new ArgumentException("Invalid DHDomainParameters: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public DHDomainParameters(DerInteger p, DerInteger g, DerInteger q, DerInteger j, + DHValidationParms validationParms) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + if (q == null) + throw new ArgumentNullException("q"); + + this.p = p; + this.g = g; + this.q = q; + this.j = j; + this.validationParms = validationParms; + } + + private DHDomainParameters(Asn1Sequence seq) + { + if (seq.Count < 3 || seq.Count > 5) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + IEnumerator e = seq.GetEnumerator(); + this.p = DerInteger.GetInstance(GetNext(e)); + this.g = DerInteger.GetInstance(GetNext(e)); + this.q = DerInteger.GetInstance(GetNext(e)); + + Asn1Encodable next = GetNext(e); + + if (next != null && next is DerInteger) + { + this.j = DerInteger.GetInstance(next); + next = GetNext(e); + } + + if (next != null) + { + this.validationParms = DHValidationParms.GetInstance(next.ToAsn1Object()); + } + } + + private static Asn1Encodable GetNext(IEnumerator e) + { + return e.MoveNext() ? (Asn1Encodable)e.Current : null; + } + + public DerInteger P + { + get { return this.p; } + } + + public DerInteger G + { + get { return this.g; } + } + + public DerInteger Q + { + get { return this.q; } + } + + public DerInteger J + { + get { return this.j; } + } + + public DHValidationParms ValidationParms + { + get { return this.validationParms; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(p, g, q); + + if (this.j != null) + { + v.Add(this.j); + } + + if (this.validationParms != null) + { + v.Add(this.validationParms); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs.meta new file mode 100644 index 0000000..482d960 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHDomainParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 37ebcba642487dd429a8bf7303793ea7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs new file mode 100644 index 0000000..03f1a83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs @@ -0,0 +1,49 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class DHPublicKey + : Asn1Encodable + { + private readonly DerInteger y; + + public static DHPublicKey GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(DerInteger.GetInstance(obj, isExplicit)); + } + + public static DHPublicKey GetInstance(object obj) + { + if (obj == null || obj is DHPublicKey) + return (DHPublicKey)obj; + + if (obj is DerInteger) + return new DHPublicKey((DerInteger)obj); + + throw new ArgumentException("Invalid DHPublicKey: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public DHPublicKey(DerInteger y) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public DerInteger Y + { + get { return this.y; } + } + + public override Asn1Object ToAsn1Object() + { + return this.y; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs.meta new file mode 100644 index 0000000..e6c1cbd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHPublicKey.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0b171cae4a7bfd74dafae201bbd43958 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs new file mode 100644 index 0000000..b62d4d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs @@ -0,0 +1,67 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class DHValidationParms + : Asn1Encodable + { + private readonly DerBitString seed; + private readonly DerInteger pgenCounter; + + public static DHValidationParms GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static DHValidationParms GetInstance(object obj) + { + if (obj == null || obj is DHDomainParameters) + return (DHValidationParms)obj; + + if (obj is Asn1Sequence) + return new DHValidationParms((Asn1Sequence)obj); + + throw new ArgumentException("Invalid DHValidationParms: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj"); + } + + public DHValidationParms(DerBitString seed, DerInteger pgenCounter) + { + if (seed == null) + throw new ArgumentNullException("seed"); + if (pgenCounter == null) + throw new ArgumentNullException("pgenCounter"); + + this.seed = seed; + this.pgenCounter = pgenCounter; + } + + private DHValidationParms(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.seed = DerBitString.GetInstance(seq[0]); + this.pgenCounter = DerInteger.GetInstance(seq[1]); + } + + public DerBitString Seed + { + get { return this.seed; } + } + + public DerInteger PgenCounter + { + get { return this.pgenCounter; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(seed, pgenCounter); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs.meta new file mode 100644 index 0000000..895cfb4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/DHValidationParms.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4c6fa04a900b7794bb04300863773f6a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs new file mode 100644 index 0000000..ac7a17d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs @@ -0,0 +1,160 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.Anssi; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * A general class that reads all X9.62 style EC curve tables. + */ + public class ECNamedCurveTable + { + /** + * return a X9ECParameters object representing the passed in named + * curve. The routine returns null if the curve is not present. + * + * @param name the name of the curve requested + * @return an X9ECParameters object or null if the curve is not available. + */ + public static X9ECParameters GetByName(string name) + { + X9ECParameters ecP = X962NamedCurves.GetByName(name); + + if (ecP == null) + { + ecP = SecNamedCurves.GetByName(name); + } + + if (ecP == null) + { + ecP = NistNamedCurves.GetByName(name); + } + + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByName(name); + } + + if (ecP == null) + { + ecP = AnssiNamedCurves.GetByName(name); + } + + return ecP; + } + + public static string GetName(DerObjectIdentifier oid) + { + string name = X962NamedCurves.GetName(oid); + if (name == null) + { + name = SecNamedCurves.GetName(oid); + } + if (name == null) + { + name = NistNamedCurves.GetName(oid); + } + if (name == null) + { + name = TeleTrusTNamedCurves.GetName(oid); + } + if (name == null) + { + name = AnssiNamedCurves.GetName(oid); + } + return name; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid(string name) + { + DerObjectIdentifier oid = X962NamedCurves.GetOid(name); + + if (oid == null) + { + oid = SecNamedCurves.GetOid(name); + } + + if (oid == null) + { + oid = NistNamedCurves.GetOid(name); + } + + if (oid == null) + { + oid = TeleTrusTNamedCurves.GetOid(name); + } + + if (oid == null) + { + oid = AnssiNamedCurves.GetOid(name); + } + + return oid; + } + + /** + * return a X9ECParameters object representing the passed in named + * curve. + * + * @param oid the object id of the curve requested + * @return an X9ECParameters object or null if the curve is not available. + */ + public static X9ECParameters GetByOid(DerObjectIdentifier oid) + { + X9ECParameters ecP = X962NamedCurves.GetByOid(oid); + + if (ecP == null) + { + ecP = SecNamedCurves.GetByOid(oid); + } + + // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup + + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByOid(oid); + } + + if (ecP == null) + { + ecP = AnssiNamedCurves.GetByOid(oid); + } + + return ecP; + } + + /** + * return an enumeration of the names of the available curves. + * + * @return an enumeration of the names of the available curves. + */ + public static IEnumerable Names + { + get + { + IList v = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + CollectionUtilities.AddRange(v, X962NamedCurves.Names); + CollectionUtilities.AddRange(v, SecNamedCurves.Names); + CollectionUtilities.AddRange(v, NistNamedCurves.Names); + CollectionUtilities.AddRange(v, TeleTrusTNamedCurves.Names); + CollectionUtilities.AddRange(v, AnssiNamedCurves.Names); + return v; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs.meta new file mode 100644 index 0000000..6401f7b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/ECNamedCurveTable.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9997102bd93d26b4383c8a708d2109ff +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs new file mode 100644 index 0000000..3c68d69 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs @@ -0,0 +1,754 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * table of the current named curves defined in X.962 EC-DSA. + */ + public sealed class X962NamedCurves + { + private X962NamedCurves() + { + } + + internal class Prime192v1Holder + : X9ECParametersHolder + { + private Prime192v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("ffffffffffffffffffffffff99def836146bc9b1b4d22831", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp192v1 = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), + new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16), + n, h); + + return new X9ECParameters( + cFp192v1, + new X9ECPoint(cFp192v1, + Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), + n, h, + Hex.Decode("3045AE6FC8422f64ED579528D38120EAE12196D5")); + } + } + + internal class Prime192v2Holder + : X9ECParametersHolder + { + private Prime192v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp192v2 = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), + new BigInteger("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953", 16), + n, h); + + return new X9ECParameters( + cFp192v2, + new X9ECPoint(cFp192v2, + Hex.Decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")), + n, h, + Hex.Decode("31a92ee2029fd10d901b113e990710f0d21ac6b6")); + } + } + + internal class Prime192v3Holder + : X9ECParametersHolder + { + private Prime192v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("ffffffffffffffffffffffff7a62d031c83f4294f640ec13", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp192v3 = new FpCurve( + new BigInteger("6277101735386680763835789423207666416083908700390324961279"), + new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), + new BigInteger("22123dc2395a05caa7423daeccc94760a7d462256bd56916", 16), + n, h); + + return new X9ECParameters( + cFp192v3, + new X9ECPoint(cFp192v3, + Hex.Decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")), + n, h, + Hex.Decode("c469684435deb378c4b65ca9591e2a5763059a2e")); + } + } + + internal class Prime239v1Holder + : X9ECParametersHolder + { + private Prime239v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp239v1 = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16), + n, h); + + return new X9ECParameters( + cFp239v1, + new X9ECPoint(cFp239v1, + Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), + n, h, + Hex.Decode("e43bb460f0b80cc0c0b075798e948060f8321b7d")); + } + } + + internal class Prime239v2Holder + : X9ECParametersHolder + { + private Prime239v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp239v2 = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), + new BigInteger("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c", 16), + n, h); + + return new X9ECParameters( + cFp239v2, + new X9ECPoint(cFp239v2, + Hex.Decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")), + n, h, + Hex.Decode("e8b4011604095303ca3b8099982be09fcb9ae616")); + } + } + + internal class Prime239v3Holder + : X9ECParametersHolder + { + private Prime239v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp239v3 = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), + new BigInteger("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e", 16), + n, h); + + return new X9ECParameters( + cFp239v3, + new X9ECPoint(cFp239v3, + Hex.Decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")), + n, h, + Hex.Decode("7d7374168ffe3471b60a857686a19475d3bfa2ff")); + } + } + + internal class Prime256v1Holder + : X9ECParametersHolder + { + private Prime256v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime256v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16); + BigInteger h = BigInteger.One; + + ECCurve cFp256v1 = new FpCurve( + new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), + new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16), + new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16), + n, h); + + return new X9ECParameters( + cFp256v1, + new X9ECPoint(cFp256v1, + Hex.Decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")), + n, h, + Hex.Decode("c49d360886e704936a6678e1139d26b7819f7e90")); + } + } + + /* + * F2m Curves + */ + internal class C2pnb163v1Holder + : X9ECParametersHolder + { + private C2pnb163v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0400000000000000000001E60FC8821CC74DAEAFC1", 16); + BigInteger h = BigInteger.Two; + + ECCurve c2m163v1 = new F2mCurve( + 163, + 1, 2, 8, + new BigInteger("072546B5435234A422E0789675F432C89435DE5242", 16), + new BigInteger("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", 16), + n, h); + + return new X9ECParameters( + c2m163v1, + new X9ECPoint(c2m163v1, + Hex.Decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")), + n, h, + Hex.Decode("D2C0FB15760860DEF1EEF4D696E6768756151754")); + } + } + + internal class C2pnb163v2Holder + : X9ECParametersHolder + { + private C2pnb163v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 16); + BigInteger h = BigInteger.Two; + + ECCurve c2m163v2 = new F2mCurve( + 163, + 1, 2, 8, + new BigInteger("0108B39E77C4B108BED981ED0E890E117C511CF072", 16), + new BigInteger("0667ACEB38AF4E488C407433FFAE4F1C811638DF20", 16), + n, h); + + return new X9ECParameters( + c2m163v2, + new X9ECPoint(c2m163v2, + Hex.Decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")), + n, h, + null); + } + } + + internal class C2pnb163v3Holder + : X9ECParametersHolder + { + private C2pnb163v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 16); + BigInteger h = BigInteger.Two; + + ECCurve c2m163v3 = new F2mCurve( + 163, + 1, 2, 8, + new BigInteger("07A526C63D3E25A256A007699F5447E32AE456B50E", 16), + new BigInteger("03F7061798EB99E238FD6F1BF95B48FEEB4854252B", 16), + n, h); + + return new X9ECParameters( + c2m163v3, + new X9ECPoint(c2m163v3, Hex.Decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")), + n, h, + null); + } + } + + internal class C2pnb176w1Holder + : X9ECParametersHolder + { + private C2pnb176w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb176w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("010092537397ECA4F6145799D62B0A19CE06FE26AD", 16); + BigInteger h = BigInteger.ValueOf(0xFF6E); + + ECCurve c2m176w1 = new F2mCurve( + 176, + 1, 2, 43, + new BigInteger("00E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", 16), + new BigInteger("005DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", 16), + n, h); + + return new X9ECParameters( + c2m176w1, + new X9ECPoint(c2m176w1, + Hex.Decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")), + n, h, + null); + } + } + + internal class C2tnb191v1Holder + : X9ECParametersHolder + { + private C2tnb191v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("40000000000000000000000004A20E90C39067C893BBB9A5", 16); + BigInteger h = BigInteger.Two; + + ECCurve c2m191v1 = new F2mCurve( + 191, + 9, + new BigInteger("2866537B676752636A68F56554E12640276B649EF7526267", 16), + new BigInteger("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", 16), + n, h); + + return new X9ECParameters( + c2m191v1, + new X9ECPoint(c2m191v1, + Hex.Decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")), + n, h, + Hex.Decode("4E13CA542744D696E67687561517552F279A8C84")); + } + } + + internal class C2tnb191v2Holder + : X9ECParametersHolder + { + private C2tnb191v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("20000000000000000000000050508CB89F652824E06B8173", 16); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve c2m191v2 = new F2mCurve( + 191, + 9, + new BigInteger("401028774D7777C7B7666D1366EA432071274F89FF01E718", 16), + new BigInteger("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", 16), + n, h); + + return new X9ECParameters( + c2m191v2, + new X9ECPoint(c2m191v2, + Hex.Decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")), + n, h, + null); + } + } + + internal class C2tnb191v3Holder + : X9ECParametersHolder + { + private C2tnb191v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("155555555555555555555555610C0B196812BFB6288A3EA3", 16); + BigInteger h = BigInteger.ValueOf(6); + + ECCurve c2m191v3 = new F2mCurve( + 191, + 9, + new BigInteger("6C01074756099122221056911C77D77E77A777E7E7E77FCB", 16), + new BigInteger("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", 16), + n, h); + + return new X9ECParameters( + c2m191v3, + new X9ECPoint(c2m191v3, + Hex.Decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")), + n, h, + null); + } + } + + internal class C2pnb208w1Holder + : X9ECParametersHolder + { + private C2pnb208w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb208w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 16); + BigInteger h = BigInteger.ValueOf(0xFE48); + + ECCurve c2m208w1 = new F2mCurve( + 208, + 1, 2, 83, + new BigInteger("0", 16), + new BigInteger("00C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", 16), + n, h); + + return new X9ECParameters( + c2m208w1, + new X9ECPoint(c2m208w1, + Hex.Decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")), + n, h, + null); + } + } + + internal class C2tnb239v1Holder + : X9ECParametersHolder + { + private C2tnb239v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 16); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve c2m239v1 = new F2mCurve( + 239, + 36, + new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), + new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16), + n, h); + + return new X9ECParameters( + c2m239v1, + new X9ECPoint(c2m239v1, + Hex.Decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")), + n, h, + null); + } + } + + internal class C2tnb239v2Holder + : X9ECParametersHolder + { + private C2tnb239v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 16); + BigInteger h = BigInteger.ValueOf(6); + + ECCurve c2m239v2 = new F2mCurve( + 239, + 36, + new BigInteger("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", 16), + new BigInteger("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", 16), + n, h); + + return new X9ECParameters( + c2m239v2, + new X9ECPoint(c2m239v2, + Hex.Decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")), + n, h, + null); + } + } + + internal class C2tnb239v3Holder + : X9ECParametersHolder + { + private C2tnb239v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 16); + BigInteger h = BigInteger.ValueOf(10); + + ECCurve c2m239v3 = new F2mCurve( + 239, + 36, + new BigInteger("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", 16), + new BigInteger("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", 16), + n, h); + + return new X9ECParameters( + c2m239v3, + new X9ECPoint(c2m239v3, + Hex.Decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")), + n, h, + null); + } + } + + internal class C2pnb272w1Holder + : X9ECParametersHolder + { + private C2pnb272w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb272w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", 16); + BigInteger h = BigInteger.ValueOf(0xFF06); + + ECCurve c2m272w1 = new F2mCurve( + 272, + 1, 3, 56, + new BigInteger("0091A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", 16), + new BigInteger("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", 16), + n, h); + + return new X9ECParameters( + c2m272w1, + new X9ECPoint(c2m272w1, + Hex.Decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")), + n, h, + null); + } + } + + internal class C2pnb304w1Holder + : X9ECParametersHolder + { + private C2pnb304w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb304w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", 16); + BigInteger h = BigInteger.ValueOf(0xFE2E); + + ECCurve c2m304w1 = new F2mCurve( + 304, + 1, 2, 11, + new BigInteger("00FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", 16), + new BigInteger("00BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", 16), + n, h); + + return new X9ECParameters( + c2m304w1, + new X9ECPoint(c2m304w1, + Hex.Decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")), + n, h, + null); + } + } + + internal class C2tnb359v1Holder + : X9ECParametersHolder + { + private C2tnb359v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb359v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", 16); + BigInteger h = BigInteger.ValueOf(0x4C); + + ECCurve c2m359v1 = new F2mCurve( + 359, + 68, + new BigInteger("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", 16), + new BigInteger("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", 16), + n, h); + + return new X9ECParameters( + c2m359v1, + new X9ECPoint(c2m359v1, + Hex.Decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")), + n, h, + null); + } + } + + internal class C2pnb368w1Holder + : X9ECParametersHolder + { + private C2pnb368w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb368w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", 16); + BigInteger h = BigInteger.ValueOf(0xFF70); + + ECCurve c2m368w1 = new F2mCurve( + 368, + 1, 2, 85, + new BigInteger("00E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", 16), + new BigInteger("00FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", 16), + n, h); + + return new X9ECParameters( + c2m368w1, + new X9ECPoint(c2m368w1, + Hex.Decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")), + n, h, + null); + } + } + + internal class C2tnb431r1Holder + : X9ECParametersHolder + { + private C2tnb431r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb431r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = new BigInteger("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", 16); + BigInteger h = BigInteger.ValueOf(0x2760); + + ECCurve c2m431r1 = new F2mCurve( + 431, + 120, + new BigInteger("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", 16), + new BigInteger("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", 16), + n, h); + + return new X9ECParameters( + c2m431r1, + new X9ECPoint(c2m431r1, + Hex.Decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")), + n, h, + null); + } + } + + private static readonly IDictionary objIds = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary curves = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary names = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static X962NamedCurves() + { + DefineCurve("prime192v1", X9ObjectIdentifiers.Prime192v1, Prime192v1Holder.Instance); + DefineCurve("prime192v2", X9ObjectIdentifiers.Prime192v2, Prime192v2Holder.Instance); + DefineCurve("prime192v3", X9ObjectIdentifiers.Prime192v3, Prime192v3Holder.Instance); + DefineCurve("prime239v1", X9ObjectIdentifiers.Prime239v1, Prime239v1Holder.Instance); + DefineCurve("prime239v2", X9ObjectIdentifiers.Prime239v2, Prime239v2Holder.Instance); + DefineCurve("prime239v3", X9ObjectIdentifiers.Prime239v3, Prime239v3Holder.Instance); + DefineCurve("prime256v1", X9ObjectIdentifiers.Prime256v1, Prime256v1Holder.Instance); + DefineCurve("c2pnb163v1", X9ObjectIdentifiers.C2Pnb163v1, C2pnb163v1Holder.Instance); + DefineCurve("c2pnb163v2", X9ObjectIdentifiers.C2Pnb163v2, C2pnb163v2Holder.Instance); + DefineCurve("c2pnb163v3", X9ObjectIdentifiers.C2Pnb163v3, C2pnb163v3Holder.Instance); + DefineCurve("c2pnb176w1", X9ObjectIdentifiers.C2Pnb176w1, C2pnb176w1Holder.Instance); + DefineCurve("c2tnb191v1", X9ObjectIdentifiers.C2Tnb191v1, C2tnb191v1Holder.Instance); + DefineCurve("c2tnb191v2", X9ObjectIdentifiers.C2Tnb191v2, C2tnb191v2Holder.Instance); + DefineCurve("c2tnb191v3", X9ObjectIdentifiers.C2Tnb191v3, C2tnb191v3Holder.Instance); + DefineCurve("c2pnb208w1", X9ObjectIdentifiers.C2Pnb208w1, C2pnb208w1Holder.Instance); + DefineCurve("c2tnb239v1", X9ObjectIdentifiers.C2Tnb239v1, C2tnb239v1Holder.Instance); + DefineCurve("c2tnb239v2", X9ObjectIdentifiers.C2Tnb239v2, C2tnb239v2Holder.Instance); + DefineCurve("c2tnb239v3", X9ObjectIdentifiers.C2Tnb239v3, C2tnb239v3Holder.Instance); + DefineCurve("c2pnb272w1", X9ObjectIdentifiers.C2Pnb272w1, C2pnb272w1Holder.Instance); + DefineCurve("c2pnb304w1", X9ObjectIdentifiers.C2Pnb304w1, C2pnb304w1Holder.Instance); + DefineCurve("c2tnb359v1", X9ObjectIdentifiers.C2Tnb359v1, C2tnb359v1Holder.Instance); + DefineCurve("c2pnb368w1", X9ObjectIdentifiers.C2Pnb368w1, C2pnb368w1Holder.Instance); + DefineCurve("c2tnb431r1", X9ObjectIdentifiers.C2Tnb431r1, C2tnb431r1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs.meta new file mode 100644 index 0000000..f10bf08 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962NamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d7cc30986b054f343b703754ae6cf47d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs new file mode 100644 index 0000000..964e6d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs @@ -0,0 +1,91 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class X962Parameters + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Object _params; + + public static X962Parameters GetInstance( + object obj) + { + if (obj == null || obj is X962Parameters) + { + return (X962Parameters)obj; + } + + if (obj is Asn1Object) + { + return new X962Parameters((Asn1Object)obj); + } + + if (obj is byte[]) + { + try + { + return new X962Parameters(Asn1Object.FromByteArray((byte[])obj)); + } + catch (Exception e) + { + throw new ArgumentException("unable to parse encoded data: " + e.Message, e); + } + } + + throw new ArgumentException("unknown object in getInstance()"); + } + + public X962Parameters( + X9ECParameters ecParameters) + { + this._params = ecParameters.ToAsn1Object(); + } + + public X962Parameters( + DerObjectIdentifier namedCurve) + { + this._params = namedCurve; + } + + public X962Parameters( + Asn1Object obj) + { + this._params = obj; + } + + public bool IsNamedCurve + { + get { return (_params is DerObjectIdentifier); } + } + + public bool IsImplicitlyCA + { + get { return (_params is Asn1Null); } + } + + public Asn1Object Parameters + { + get { return _params; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Parameters ::= CHOICE {
+         *    ecParameters ECParameters,
+         *    namedCurve   CURVES.&id({CurveNames}),
+         *    implicitlyCA Null
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return _params; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs.meta new file mode 100644 index 0000000..4bedfd2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X962Parameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 61bfd513d3b6d3440aa9b03f5abe13b4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs new file mode 100644 index 0000000..1d5d52c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs @@ -0,0 +1,149 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve Curve structure. See + * X9.62, for further details. + */ + public class X9Curve + : Asn1Encodable + { + private readonly ECCurve curve; + private readonly byte[] seed; + private readonly DerObjectIdentifier fieldIdentifier; + + public X9Curve( + ECCurve curve) + : this(curve, null) + { + } + + public X9Curve( + ECCurve curve, + byte[] seed) + { + if (curve == null) + throw new ArgumentNullException("curve"); + + this.curve = curve; + this.seed = Arrays.Clone(seed); + + if (ECAlgorithms.IsFpCurve(curve)) + { + this.fieldIdentifier = X9ObjectIdentifiers.PrimeField; + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField; + } + else + { + throw new ArgumentException("This type of ECCurve is not implemented"); + } + } + + public X9Curve( + X9FieldID fieldID, + Asn1Sequence seq) + { + if (fieldID == null) + throw new ArgumentNullException("fieldID"); + if (seq == null) + throw new ArgumentNullException("seq"); + + this.fieldIdentifier = fieldID.Identifier; + + if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField)) + { + BigInteger q = ((DerInteger) fieldID.Parameters).Value; + X9FieldElement x9A = new X9FieldElement(q, (Asn1OctetString) seq[0]); + X9FieldElement x9B = new X9FieldElement(q, (Asn1OctetString) seq[1]); + curve = new FpCurve(q, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger()); + } + else + { + if (fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) + { + // Characteristic two field + DerSequence parameters = (DerSequence)fieldID.Parameters; + int m = ((DerInteger)parameters[0]).Value.IntValue; + DerObjectIdentifier representation + = (DerObjectIdentifier)parameters[1]; + + int k1 = 0; + int k2 = 0; + int k3 = 0; + if (representation.Equals(X9ObjectIdentifiers.TPBasis)) + { + // Trinomial basis representation + k1 = ((DerInteger)parameters[2]).Value.IntValue; + } + else + { + // Pentanomial basis representation + DerSequence pentanomial = (DerSequence) parameters[2]; + k1 = ((DerInteger) pentanomial[0]).Value.IntValue; + k2 = ((DerInteger) pentanomial[1]).Value.IntValue; + k3 = ((DerInteger) pentanomial[2]).Value.IntValue; + } + X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[0]); + X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[1]); + // TODO Is it possible to get the order (n) and cofactor(h) too? + curve = new F2mCurve(m, k1, k2, k3, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger()); + } + } + + if (seq.Count == 3) + { + seed = ((DerBitString) seq[2]).GetBytes(); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public byte[] GetSeed() + { + return Arrays.Clone(seed); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  Curve ::= Sequence {
+         *      a               FieldElement,
+         *      b               FieldElement,
+         *      seed            BIT STRING      OPTIONAL
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField) + || fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) + { + v.Add(new X9FieldElement(curve.A).ToAsn1Object()); + v.Add(new X9FieldElement(curve.B).ToAsn1Object()); + } + + if (seed != null) + { + v.Add(new DerBitString(seed)); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs.meta new file mode 100644 index 0000000..f883b68 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7f72ea46afaacfe4bbf9bb8fbff91598 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs new file mode 100644 index 0000000..5066030 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs @@ -0,0 +1,236 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.Field; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve ECParameters structure. See + * X9.62, for further details. + */ + public class X9ECParameters + : Asn1Encodable + { + private X9FieldID fieldID; + private ECCurve curve; + private X9ECPoint g; + private BigInteger n; + private BigInteger h; + private byte[] seed; + + public static X9ECParameters GetInstance(Object obj) + { + if (obj is X9ECParameters) + { + return (X9ECParameters)obj; + } + + if (obj != null) + { + return new X9ECParameters(Asn1Sequence.GetInstance(obj)); + } + + return null; + } + + public X9ECParameters( + Asn1Sequence seq) + { + if (!(seq[0] is DerInteger) + || !((DerInteger) seq[0]).Value.Equals(BigInteger.One)) + { + throw new ArgumentException("bad version in X9ECParameters"); + } + + X9Curve x9c = new X9Curve( + X9FieldID.GetInstance(seq[1]), + Asn1Sequence.GetInstance(seq[2])); + + this.curve = x9c.Curve; + object p = seq[3]; + + if (p is X9ECPoint) + { + this.g = ((X9ECPoint)p); + } + else + { + this.g = new X9ECPoint(curve, (Asn1OctetString)p); + } + + this.n = ((DerInteger)seq[4]).Value; + this.seed = x9c.GetSeed(); + + if (seq.Count == 6) + { + this.h = ((DerInteger)seq[5]).Value; + } + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, null, null) + { + } + + public X9ECParameters( + ECCurve curve, + X9ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + : this(curve, new X9ECPoint(g), n, h, seed) + { + } + + public X9ECParameters( + ECCurve curve, + X9ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + this.seed = seed; + + if (ECAlgorithms.IsFpCurve(curve)) + { + this.fieldID = new X9FieldID(curve.Field.Characteristic); + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field; + int[] exponents = field.MinimalPolynomial.GetExponentsPresent(); + if (exponents.Length == 3) + { + this.fieldID = new X9FieldID(exponents[2], exponents[1]); + } + else if (exponents.Length == 5) + { + this.fieldID = new X9FieldID(exponents[4], exponents[1], exponents[2], exponents[3]); + } + else + { + throw new ArgumentException("Only trinomial and pentomial curves are supported"); + } + } + else + { + throw new ArgumentException("'curve' is of an unsupported type"); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g.Point; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get { return h; } + } + + public byte[] GetSeed() + { + return seed; + } + + /** + * Return the ASN.1 entry representing the Curve. + * + * @return the X9Curve for the curve in these parameters. + */ + public X9Curve CurveEntry + { + get { return new X9Curve(curve, seed); } + } + + /** + * Return the ASN.1 entry representing the FieldID. + * + * @return the X9FieldID for the FieldID in these parameters. + */ + public X9FieldID FieldIDEntry + { + get { return fieldID; } + } + + /** + * Return the ASN.1 entry representing the base point G. + * + * @return the X9ECPoint for the base point in these parameters. + */ + public X9ECPoint BaseEntry + { + get { return g; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  ECParameters ::= Sequence {
+         *      version         Integer { ecpVer1(1) } (ecpVer1),
+         *      fieldID         FieldID {{FieldTypes}},
+         *      curve           X9Curve,
+         *      base            X9ECPoint,
+         *      order           Integer,
+         *      cofactor        Integer OPTIONAL
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(BigInteger.One), + fieldID, + new X9Curve(curve, seed), + g, + new DerInteger(n)); + + if (h != null) + { + v.Add(new DerInteger(h)); + } + + return new DerSequence(v); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs.meta new file mode 100644 index 0000000..01b4d0f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 68de537605868744dbde9c6576be1805 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs new file mode 100644 index 0000000..20b6368 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9ECParametersHolder + { + private X9ECParameters parameters; + + public X9ECParameters Parameters + { + get + { + lock (this) + { + if (parameters == null) + { + parameters = CreateParameters(); + } + + return parameters; + } + } + } + + protected abstract X9ECParameters CreateParameters(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs.meta new file mode 100644 index 0000000..c99a926 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECParametersHolder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2433893a590e27d438b5bc45cba65e36 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs new file mode 100644 index 0000000..6d30cca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs @@ -0,0 +1,83 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using Org.BouncyCastle.Math.EC; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * class for describing an ECPoint as a Der object. + */ + public class X9ECPoint + : Asn1Encodable + { + private readonly Asn1OctetString encoding; + + private ECCurve c; + private ECPoint p; + + public X9ECPoint(ECPoint p) + : this(p, false) + { + } + + public X9ECPoint(ECPoint p, bool compressed) + { + this.p = p.Normalize(); + this.encoding = new DerOctetString(p.GetEncoded(compressed)); + } + + public X9ECPoint(ECCurve c, byte[] encoding) + { + this.c = c; + this.encoding = new DerOctetString(Arrays.Clone(encoding)); + } + + public X9ECPoint(ECCurve c, Asn1OctetString s) + : this(c, s.GetOctets()) + { + } + + public byte[] GetPointEncoding() + { + return Arrays.Clone(encoding.GetOctets()); + } + + public ECPoint Point + { + get + { + if (p == null) + { + p = c.DecodePoint(encoding.GetOctets()).Normalize(); + } + + return p; + } + } + + public bool IsPointCompressed + { + get + { + byte[] octets = encoding.GetOctets(); + return octets != null && octets.Length > 0 && (octets[0] == 2 || octets[0] == 3); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  ECPoint ::= OCTET STRING
+         * 
+ *

+ * Octet string produced using ECPoint.GetEncoded().

+ */ + public override Asn1Object ToAsn1Object() + { + return encoding; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs.meta new file mode 100644 index 0000000..0316c57 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ECPoint.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7836651622621b946bda8dac7d8d97e8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs new file mode 100644 index 0000000..27e3f93 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs @@ -0,0 +1,72 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * Class for processing an ECFieldElement as a DER object. + */ + public class X9FieldElement + : Asn1Encodable + { + private ECFieldElement f; + + public X9FieldElement( + ECFieldElement f) + { + this.f = f; + } + + public X9FieldElement( + BigInteger p, + Asn1OctetString s) + : this(new FpFieldElement(p, new BigInteger(1, s.GetOctets()))) + { + } + + public X9FieldElement( + int m, + int k1, + int k2, + int k3, + Asn1OctetString s) + : this(new F2mFieldElement(m, k1, k2, k3, new BigInteger(1, s.GetOctets()))) + { + } + + public ECFieldElement Value + { + get { return f; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  FieldElement ::= OCTET STRING
+         * 
+ *

+ *

    + *
  1. if q is an odd prime then the field element is + * processed as an Integer and converted to an octet string + * according to x 9.62 4.3.1.
  2. + *
  3. if q is 2m then the bit string + * contained in the field element is converted into an octet + * string with the same ordering padded at the front if necessary. + *
  4. + *
+ *

+ */ + public override Asn1Object ToAsn1Object() + { + int byteCount = X9IntegerConverter.GetByteLength(f); + byte[] paddedBigInteger = X9IntegerConverter.IntegerToBytes(f.ToBigInteger(), byteCount); + + return new DerOctetString(paddedBigInteger); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs.meta new file mode 100644 index 0000000..7d52569 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9abf4b8380cc5f4fae08ae4356c3729 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs new file mode 100644 index 0000000..f89570a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs @@ -0,0 +1,135 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve Field ID structure. See + * X9.62, for further details. + */ + public class X9FieldID + : Asn1Encodable + { + private readonly DerObjectIdentifier id; + private readonly Asn1Object parameters; + + /** + * Constructor for elliptic curves over prime fields + * F2. + * @param primeP The prime p defining the prime field. + */ + public X9FieldID( + BigInteger primeP) + { + this.id = X9ObjectIdentifiers.PrimeField; + this.parameters = new DerInteger(primeP); + } + + /** + * Constructor for elliptic curves over binary fields + * F2m. + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk1 + 1 + * represents the reduction polynomial f(z). + */ + public X9FieldID(int m, int k1) + : this(m, k1, 0, 0) + { + } + + /** + * Constructor for elliptic curves over binary fields + * F2m. + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).. + */ + public X9FieldID( + int m, + int k1, + int k2, + int k3) + { + this.id = X9ObjectIdentifiers.CharacteristicTwoField; + + Asn1EncodableVector fieldIdParams = new Asn1EncodableVector(new DerInteger(m)); + + if (k2 == 0) + { + if (k3 != 0) + throw new ArgumentException("inconsistent k values"); + + fieldIdParams.Add( + X9ObjectIdentifiers.TPBasis, + new DerInteger(k1)); + } + else + { + if (k2 <= k1 || k3 <= k2) + throw new ArgumentException("inconsistent k values"); + + fieldIdParams.Add( + X9ObjectIdentifiers.PPBasis, + new DerSequence( + new DerInteger(k1), + new DerInteger(k2), + new DerInteger(k3))); + } + + this.parameters = new DerSequence(fieldIdParams); + } + + private X9FieldID(Asn1Sequence seq) + { + this.id = DerObjectIdentifier.GetInstance(seq[0]); + this.parameters = seq[1].ToAsn1Object(); + } + + public static X9FieldID GetInstance(object obj) + { + if (obj is X9FieldID) + return (X9FieldID)obj; + if (obj == null) + return null; + return new X9FieldID(Asn1Sequence.GetInstance(obj)); + } + + public DerObjectIdentifier Identifier + { + get { return id; } + } + + public Asn1Object Parameters + { + get { return parameters; } + } + + /** + * Produce a Der encoding of the following structure. + *
+         *  FieldID ::= Sequence {
+         *      fieldType       FIELD-ID.&id({IOSet}),
+         *      parameters      FIELD-ID.&Type({IOSet}{@fieldType})
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(id, parameters); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs.meta new file mode 100644 index 0000000..88e6998 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9FieldID.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6662fe1cbc846fc4ea6de22585a73840 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs new file mode 100644 index 0000000..60ee0b3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs @@ -0,0 +1,43 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9IntegerConverter + { + public static int GetByteLength(ECFieldElement fe) + { + return (fe.FieldSize + 7) / 8; + } + + public static int GetByteLength(ECCurve c) + { + return (c.FieldSize + 7) / 8; + } + + public static byte[] IntegerToBytes(BigInteger s, int qLength) + { + byte[] bytes = s.ToByteArrayUnsigned(); + + if (qLength < bytes.Length) + { + byte[] tmp = new byte[qLength]; + Array.Copy(bytes, bytes.Length - tmp.Length, tmp, 0, tmp.Length); + return tmp; + } + else if (qLength > bytes.Length) + { + byte[] tmp = new byte[qLength]; + Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length); + return tmp; + } + + return bytes; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs.meta new file mode 100644 index 0000000..4a9afb9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9IntegerConverter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f767dcd9b1855b447b6bb009b1a39508 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs new file mode 100644 index 0000000..3fbdf1c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs @@ -0,0 +1,140 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9ObjectIdentifiers + { + // + // X9.62 + // + // ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x962(10045) } + // + + internal const string AnsiX962 = "1.2.840.10045"; + + public static readonly DerObjectIdentifier ansi_X9_62 = new DerObjectIdentifier(AnsiX962); + + public static readonly DerObjectIdentifier IdFieldType = ansi_X9_62.Branch("1"); + + public static readonly DerObjectIdentifier PrimeField = IdFieldType.Branch("1"); + public static readonly DerObjectIdentifier CharacteristicTwoField = IdFieldType.Branch("2"); + + public static readonly DerObjectIdentifier GNBasis = CharacteristicTwoField.Branch("3.1"); + public static readonly DerObjectIdentifier TPBasis = CharacteristicTwoField.Branch("3.2"); + public static readonly DerObjectIdentifier PPBasis = CharacteristicTwoField.Branch("3.3"); + + [Obsolete("Use 'id_ecSigType' instead")] + public const string IdECSigType = AnsiX962 + ".4"; + public static readonly DerObjectIdentifier id_ecSigType = ansi_X9_62.Branch("4"); + + public static readonly DerObjectIdentifier ECDsaWithSha1 = id_ecSigType.Branch("1"); + + [Obsolete("Use 'id_publicKeyType' instead")] + public const string IdPublicKeyType = AnsiX962 + ".2"; + public static readonly DerObjectIdentifier id_publicKeyType = ansi_X9_62.Branch("2"); + + public static readonly DerObjectIdentifier IdECPublicKey = id_publicKeyType.Branch("1"); + + public static readonly DerObjectIdentifier ECDsaWithSha2 = id_ecSigType.Branch("3"); + + public static readonly DerObjectIdentifier ECDsaWithSha224 = ECDsaWithSha2.Branch("1"); + public static readonly DerObjectIdentifier ECDsaWithSha256 = ECDsaWithSha2.Branch("2"); + public static readonly DerObjectIdentifier ECDsaWithSha384 = ECDsaWithSha2.Branch("3"); + public static readonly DerObjectIdentifier ECDsaWithSha512 = ECDsaWithSha2.Branch("4"); + + + // + // named curves + // + public static readonly DerObjectIdentifier EllipticCurve = ansi_X9_62.Branch("3"); + + // + // Two Curves + // + public static readonly DerObjectIdentifier CTwoCurve = EllipticCurve.Branch("0"); + + public static readonly DerObjectIdentifier C2Pnb163v1 = CTwoCurve.Branch("1"); + public static readonly DerObjectIdentifier C2Pnb163v2 = CTwoCurve.Branch("2"); + public static readonly DerObjectIdentifier C2Pnb163v3 = CTwoCurve.Branch("3"); + public static readonly DerObjectIdentifier C2Pnb176w1 = CTwoCurve.Branch("4"); + public static readonly DerObjectIdentifier C2Tnb191v1 = CTwoCurve.Branch("5"); + public static readonly DerObjectIdentifier C2Tnb191v2 = CTwoCurve.Branch("6"); + public static readonly DerObjectIdentifier C2Tnb191v3 = CTwoCurve.Branch("7"); + public static readonly DerObjectIdentifier C2Onb191v4 = CTwoCurve.Branch("8"); + public static readonly DerObjectIdentifier C2Onb191v5 = CTwoCurve.Branch("9"); + public static readonly DerObjectIdentifier C2Pnb208w1 = CTwoCurve.Branch("10"); + public static readonly DerObjectIdentifier C2Tnb239v1 = CTwoCurve.Branch("11"); + public static readonly DerObjectIdentifier C2Tnb239v2 = CTwoCurve.Branch("12"); + public static readonly DerObjectIdentifier C2Tnb239v3 = CTwoCurve.Branch("13"); + public static readonly DerObjectIdentifier C2Onb239v4 = CTwoCurve.Branch("14"); + public static readonly DerObjectIdentifier C2Onb239v5 = CTwoCurve.Branch("15"); + public static readonly DerObjectIdentifier C2Pnb272w1 = CTwoCurve.Branch("16"); + public static readonly DerObjectIdentifier C2Pnb304w1 = CTwoCurve.Branch("17"); + public static readonly DerObjectIdentifier C2Tnb359v1 = CTwoCurve.Branch("18"); + public static readonly DerObjectIdentifier C2Pnb368w1 = CTwoCurve.Branch("19"); + public static readonly DerObjectIdentifier C2Tnb431r1 = CTwoCurve.Branch("20"); + + // + // Prime + // + public static readonly DerObjectIdentifier PrimeCurve = EllipticCurve.Branch("1"); + + public static readonly DerObjectIdentifier Prime192v1 = PrimeCurve.Branch("1"); + public static readonly DerObjectIdentifier Prime192v2 = PrimeCurve.Branch("2"); + public static readonly DerObjectIdentifier Prime192v3 = PrimeCurve.Branch("3"); + public static readonly DerObjectIdentifier Prime239v1 = PrimeCurve.Branch("4"); + public static readonly DerObjectIdentifier Prime239v2 = PrimeCurve.Branch("5"); + public static readonly DerObjectIdentifier Prime239v3 = PrimeCurve.Branch("6"); + public static readonly DerObjectIdentifier Prime256v1 = PrimeCurve.Branch("7"); + + // + // DSA + // + // dsapublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x957(10040) number-type(4) 1 } + public static readonly DerObjectIdentifier IdDsa = new DerObjectIdentifier("1.2.840.10040.4.1"); + + /** + * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + * us(840) x9-57 (10040) x9cm(4) 3 } + */ + public static readonly DerObjectIdentifier IdDsaWithSha1 = new DerObjectIdentifier("1.2.840.10040.4.3"); + + /** + * X9.63 + */ + public static readonly DerObjectIdentifier X9x63Scheme = new DerObjectIdentifier("1.3.133.16.840.63.0"); + public static readonly DerObjectIdentifier DHSinglePassStdDHSha1KdfScheme = X9x63Scheme.Branch("2"); + public static readonly DerObjectIdentifier DHSinglePassCofactorDHSha1KdfScheme = X9x63Scheme.Branch("3"); + public static readonly DerObjectIdentifier MqvSinglePassSha1KdfScheme = X9x63Scheme.Branch("16"); + + /** + * X9.42 + */ + + public static readonly DerObjectIdentifier ansi_x9_42 = new DerObjectIdentifier("1.2.840.10046"); + + // + // Diffie-Hellman + // + // dhpublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x942(10046) number-type(2) 1 } + // + public static readonly DerObjectIdentifier DHPublicNumber = ansi_x9_42.Branch("2.1"); + + public static readonly DerObjectIdentifier X9x42Schemes = ansi_x9_42.Branch("2.3"); + + public static readonly DerObjectIdentifier DHStatic = X9x42Schemes.Branch("1"); + public static readonly DerObjectIdentifier DHEphem = X9x42Schemes.Branch("2"); + public static readonly DerObjectIdentifier DHOneFlow = X9x42Schemes.Branch("3"); + public static readonly DerObjectIdentifier DHHybrid1 = X9x42Schemes.Branch("4"); + public static readonly DerObjectIdentifier DHHybrid2 = X9x42Schemes.Branch("5"); + public static readonly DerObjectIdentifier DHHybridOneFlow = X9x42Schemes.Branch("6"); + public static readonly DerObjectIdentifier Mqv2 = X9x42Schemes.Branch("7"); + public static readonly DerObjectIdentifier Mqv1 = X9x42Schemes.Branch("8"); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs.meta new file mode 100644 index 0000000..e6af818 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/asn1/x9/X9ObjectIdentifiers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3dd6e9b31ef0ab041a24e2053602a746 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto.meta new file mode 100644 index 0000000..beffab3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 65f5702f015c2304e9152f0d0a52eb2f +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs new file mode 100644 index 0000000..387f9e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs @@ -0,0 +1,56 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * a holding class for public/private parameter pairs. + */ + public class AsymmetricCipherKeyPair + { + private readonly AsymmetricKeyParameter publicParameter; + private readonly AsymmetricKeyParameter privateParameter; + + /** + * basic constructor. + * + * @param publicParam a public key parameters object. + * @param privateParam the corresponding private key parameters. + */ + public AsymmetricCipherKeyPair( + AsymmetricKeyParameter publicParameter, + AsymmetricKeyParameter privateParameter) + { + if (publicParameter.IsPrivate) + throw new ArgumentException("Expected a public key", "publicParameter"); + if (!privateParameter.IsPrivate) + throw new ArgumentException("Expected a private key", "privateParameter"); + + this.publicParameter = publicParameter; + this.privateParameter = privateParameter; + } + + /** + * return the public key parameters. + * + * @return the public key parameters. + */ + public AsymmetricKeyParameter Public + { + get { return publicParameter; } + } + + /** + * return the private key parameters. + * + * @return the private key parameters. + */ + public AsymmetricKeyParameter Private + { + get { return privateParameter; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs.meta new file mode 100644 index 0000000..3b45ef7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricCipherKeyPair.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: eef9b100979b64f49a4f37506e85cbea +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs new file mode 100644 index 0000000..d8c2ad9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs @@ -0,0 +1,51 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto +{ + public abstract class AsymmetricKeyParameter + : ICipherParameters + { + private readonly bool privateKey; + + protected AsymmetricKeyParameter( + bool privateKey) + { + this.privateKey = privateKey; + } + + public bool IsPrivate + { + get { return privateKey; } + } + + public override bool Equals( + object obj) + { + AsymmetricKeyParameter other = obj as AsymmetricKeyParameter; + + if (other == null) + { + return false; + } + + return Equals(other); + } + + protected bool Equals( + AsymmetricKeyParameter other) + { + return privateKey == other.privateKey; + } + + public override int GetHashCode() + { + return privateKey.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs.meta new file mode 100644 index 0000000..03a1456 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/AsymmetricKeyParameter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a345564cb9c4fb64eb3b18227bc3bc11 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs new file mode 100644 index 0000000..8c9a377 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs @@ -0,0 +1,251 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The AEAD block ciphers already handle buffering internally, so this class + * just takes care of implementing IBufferedCipher methods. + */ + public class BufferedAeadBlockCipher + : BufferedCipherBase + { + private readonly IAeadBlockCipher cipher; + + public BufferedAeadBlockCipher( + IAeadBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + cipher.Init(forEncryption, parameters); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public override int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + return cipher.GetUpdateOutputSize(length); + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + return cipher.GetOutputSize(length); + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + return cipher.ProcessByte(input, output, outOff); + } + + public override byte[] ProcessByte( + byte input) + { + int outLength = GetUpdateOutputSize(1); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessByte(input, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (length < 1) + return null; + + int outLength = GetUpdateOutputSize(length); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessBytes(input, inOff, length, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + return cipher.ProcessBytes(input, inOff, length, output, outOff); + } + + public override byte[] DoFinal() + { + byte[] outBytes = new byte[GetOutputSize(0)]; + + int pos = DoFinal(outBytes, 0); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int inLen) + { + if (input == null) + throw new ArgumentNullException("input"); + + byte[] outBytes = new byte[GetOutputSize(inLen)]; + + int pos = (inLen > 0) + ? ProcessBytes(input, inOff, inLen, outBytes, 0) + : 0; + + pos += DoFinal(outBytes, pos); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + return cipher.DoFinal(output, outOff); + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public override void Reset() + { + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs.meta new file mode 100644 index 0000000..ed2ecc5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAeadBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7341cef11d2e8f24e844590b6747bf16 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs new file mode 100644 index 0000000..4ca26f7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs @@ -0,0 +1,156 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Engines; + +namespace Org.BouncyCastle.Crypto +{ + /** + * a buffer wrapper for an asymmetric block cipher, allowing input + * to be accumulated in a piecemeal fashion until final processing. + */ + public class BufferedAsymmetricBlockCipher + : BufferedCipherBase + { + private readonly IAsymmetricBlockCipher cipher; + + private byte[] buffer; + private int bufOff; + + /** + * base constructor. + * + * @param cipher the cipher this buffering object wraps. + */ + public BufferedAsymmetricBlockCipher( + IAsymmetricBlockCipher cipher) + { + this.cipher = cipher; + } + + /** + * return the amount of data sitting in the buffer. + * + * @return the amount of data sitting in the buffer. + */ + internal int GetBufferPosition() + { + return bufOff; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public override int GetBlockSize() + { + return cipher.GetInputBlockSize(); + } + + public override int GetOutputSize( + int length) + { + return cipher.GetOutputBlockSize(); + } + + public override int GetUpdateOutputSize( + int length) + { + return 0; + } + + /** + * initialise the buffer and the underlying cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + Reset(); + + cipher.Init(forEncryption, parameters); + + // + // we allow for an extra byte where people are using their own padding + // mechanisms on a raw cipher. + // + this.buffer = new byte[cipher.GetInputBlockSize() + (forEncryption ? 1 : 0)]; + this.bufOff = 0; + } + + public override byte[] ProcessByte( + byte input) + { + if (bufOff >= buffer.Length) + throw new DataLengthException("attempt to process message to long for cipher"); + + buffer[bufOff++] = input; + return null; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return null; + + if (input == null) + throw new ArgumentNullException("input"); + if (bufOff + length > buffer.Length) + throw new DataLengthException("attempt to process message to long for cipher"); + + Array.Copy(input, inOff, buffer, bufOff, length); + bufOff += length; + return null; + } + + /** + * process the contents of the buffer using the underlying + * cipher. + * + * @return the result of the encryption/decryption process on the + * buffer. + * @exception InvalidCipherTextException if we are given a garbage block. + */ + public override byte[] DoFinal() + { + byte[] outBytes = bufOff > 0 + ? cipher.ProcessBlock(buffer, 0, bufOff) + : EmptyBuffer; + + Reset(); + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + ProcessBytes(input, inOff, length); + return DoFinal(); + } + + /// Reset the buffer + public override void Reset() + { + if (buffer != null) + { + Array.Clear(buffer, 0, buffer.Length); + bufOff = 0; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs.meta new file mode 100644 index 0000000..f86cd7f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedAsymmetricBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f143b86b595928a4ba2e043ae553d1ce +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs new file mode 100644 index 0000000..1884288 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs @@ -0,0 +1,371 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + /** + * A wrapper class that allows block ciphers to be used to process data in + * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the + * buffer is full and more data is being added, or on a doFinal. + *

+ * Note: in the case where the underlying cipher is either a CFB cipher or an + * OFB one the last block may not be a multiple of the block size. + *

+ */ + public class BufferedBlockCipher + : BufferedCipherBase + { + internal byte[] buf; + internal int bufOff; + internal bool forEncryption; + internal IBlockCipher cipher; + + /** + * constructor for subclasses + */ + protected BufferedBlockCipher() + { + } + + /** + * Create a buffered block cipher without padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + * false otherwise. + */ + public BufferedBlockCipher( + IBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + // Note: This doubles as the Init in the event that this cipher is being used as an IWrapper + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + ParametersWithRandom pwr = parameters as ParametersWithRandom; + if (pwr != null) + parameters = pwr.Parameters; + + Reset(); + + cipher.Init(forEncryption, parameters); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public override int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + // Note: Can assume IsPartialBlockOkay is true for purposes of this calculation + return length + bufOff; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + buf[bufOff++] = input; + + if (bufOff == buf.Length) + { + if ((outOff + buf.Length) > output.Length) + throw new DataLengthException("output buffer too short"); + + bufOff = 0; + return cipher.ProcessBlock(buf, 0, output, outOff); + } + + return 0; + } + + public override byte[] ProcessByte( + byte input) + { + int outLength = GetUpdateOutputSize(1); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessByte(input, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (length < 1) + return null; + + int outLength = GetUpdateOutputSize(length); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessBytes(input, inOff, length, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 1) + { + if (length < 0) + throw new ArgumentException("Can't have a negative input length!"); + + return 0; + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + Check.OutputLength(output, outOff, outLength, "output buffer too short"); + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + length -= gapLen; + inOff += gapLen; + while (length > buf.Length) + { + resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + length -= blockSize; + inOff += blockSize; + } + } + Array.Copy(input, inOff, buf, bufOff, length); + bufOff += length; + if (bufOff == buf.Length) + { + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + bufOff = 0; + } + return resultLen; + } + + public override byte[] DoFinal() + { + byte[] outBytes = EmptyBuffer; + + int length = GetOutputSize(0); + if (length > 0) + { + outBytes = new byte[length]; + + int pos = DoFinal(outBytes, 0); + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + } + else + { + Reset(); + } + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int inLen) + { + if (input == null) + throw new ArgumentNullException("input"); + + int length = GetOutputSize(inLen); + + byte[] outBytes = EmptyBuffer; + + if (length > 0) + { + outBytes = new byte[length]; + + int pos = (inLen > 0) + ? ProcessBytes(input, inOff, inLen, outBytes, 0) + : 0; + + pos += DoFinal(outBytes, pos); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + } + else + { + Reset(); + } + + return outBytes; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + try + { + if (bufOff != 0) + { + Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); + Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()"); + + // NB: Can't copy directly, or we may write too much output + cipher.ProcessBlock(buf, 0, buf, 0); + Array.Copy(buf, 0, output, outOff, bufOff); + } + + return bufOff; + } + finally + { + Reset(); + } + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public override void Reset() + { + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs.meta new file mode 100644 index 0000000..a64d089 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e161ee652f7d84c49abc183b5ef37846 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs new file mode 100644 index 0000000..898162b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs @@ -0,0 +1,117 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + public abstract class BufferedCipherBase + : IBufferedCipher + { + protected static readonly byte[] EmptyBuffer = new byte[0]; + + public abstract string AlgorithmName { get; } + + public abstract void Init(bool forEncryption, ICipherParameters parameters); + + public abstract int GetBlockSize(); + + public abstract int GetOutputSize(int inputLen); + public abstract int GetUpdateOutputSize(int inputLen); + + public abstract byte[] ProcessByte(byte input); + + public virtual int ProcessByte( + byte input, + byte[] output, + int outOff) + { + byte[] outBytes = ProcessByte(input); + if (outBytes == null) + return 0; + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public virtual byte[] ProcessBytes( + byte[] input) + { + return ProcessBytes(input, 0, input.Length); + } + + public abstract byte[] ProcessBytes(byte[] input, int inOff, int length); + + public virtual int ProcessBytes( + byte[] input, + byte[] output, + int outOff) + { + return ProcessBytes(input, 0, input.Length, output, outOff); + } + + public virtual int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + byte[] outBytes = ProcessBytes(input, inOff, length); + if (outBytes == null) + return 0; + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public abstract byte[] DoFinal(); + + public virtual byte[] DoFinal( + byte[] input) + { + return DoFinal(input, 0, input.Length); + } + + public abstract byte[] DoFinal( + byte[] input, + int inOff, + int length); + + public virtual int DoFinal( + byte[] output, + int outOff) + { + byte[] outBytes = DoFinal(); + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public virtual int DoFinal( + byte[] input, + byte[] output, + int outOff) + { + return DoFinal(input, 0, input.Length, output, outOff); + } + + public virtual int DoFinal( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + int len = ProcessBytes(input, inOff, length, output, outOff); + len += DoFinal(output, outOff + len); + return len; + } + + public abstract void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs.meta new file mode 100644 index 0000000..7153d2b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedCipherBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2c014e96623bd48488c402407e71df96 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs new file mode 100644 index 0000000..4bf111b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs @@ -0,0 +1,117 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto +{ + public class BufferedIesCipher + : BufferedCipherBase + { + private readonly IesEngine engine; + private bool forEncryption; + private MemoryStream buffer = new MemoryStream(); + + public BufferedIesCipher( + IesEngine engine) + { + if (engine == null) + throw new ArgumentNullException("engine"); + + this.engine = engine; + } + + public override string AlgorithmName + { + // TODO Create IESEngine.AlgorithmName + get { return "IES"; } + } + + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + // TODO + throw Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("IES"); + } + + public override int GetBlockSize() + { + return 0; + } + + public override int GetOutputSize( + int inputLen) + { + if (engine == null) + throw new InvalidOperationException("cipher not initialised"); + + int baseLen = inputLen + (int) buffer.Length; + return forEncryption + ? baseLen + 20 + : baseLen - 20; + } + + public override int GetUpdateOutputSize( + int inputLen) + { + return 0; + } + + public override byte[] ProcessByte( + byte input) + { + buffer.WriteByte(input); + return null; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (inOff < 0) + throw new ArgumentException("inOff"); + if (length < 0) + throw new ArgumentException("length"); + if (inOff + length > input.Length) + throw new ArgumentException("invalid offset/length specified for input array"); + + buffer.Write(input, inOff, length); + return null; + } + + public override byte[] DoFinal() + { + byte[] buf = buffer.ToArray(); + + Reset(); + + return engine.ProcessBlock(buf, 0, buf.Length); + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + ProcessBytes(input, inOff, length); + return DoFinal(); + } + + public override void Reset() + { + buffer.SetLength(0); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs.meta new file mode 100644 index 0000000..891fd38 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedIesCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b73c34a06bcbdb3449c9b9221fc8a9c2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs new file mode 100644 index 0000000..0e962eb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs @@ -0,0 +1,135 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + public class BufferedStreamCipher + : BufferedCipherBase + { + private readonly IStreamCipher cipher; + + public BufferedStreamCipher( + IStreamCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + cipher.Init(forEncryption, parameters); + } + + public override int GetBlockSize() + { + return 0; + } + + public override int GetOutputSize( + int inputLen) + { + return inputLen; + } + + public override int GetUpdateOutputSize( + int inputLen) + { + return inputLen; + } + + public override byte[] ProcessByte( + byte input) + { + return new byte[]{ cipher.ReturnByte(input) }; + } + + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + if (outOff >= output.Length) + throw new DataLengthException("output buffer too short"); + + output[outOff] = cipher.ReturnByte(input); + return 1; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return null; + + byte[] output = new byte[length]; + cipher.ProcessBytes(input, inOff, length, output, 0); + return output; + } + + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 1) + return 0; + + if (length > 0) + { + cipher.ProcessBytes(input, inOff, length, output, outOff); + } + + return length; + } + + public override byte[] DoFinal() + { + Reset(); + + return EmptyBuffer; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return EmptyBuffer; + + byte[] output = ProcessBytes(input, inOff, length); + + Reset(); + + return output; + } + + public override void Reset() + { + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs.meta new file mode 100644 index 0000000..8ff6dc8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/BufferedStreamCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3f552bd4118a37e46b3c3e8b94df1660 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs new file mode 100644 index 0000000..120dfd5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs @@ -0,0 +1,29 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + internal class Check + { + internal static void DataLength(bool condition, string msg) + { + if (condition) + throw new DataLengthException(msg); + } + + internal static void DataLength(byte[] buf, int off, int len, string msg) + { + if (off + len > buf.Length) + throw new DataLengthException(msg); + } + + internal static void OutputLength(byte[] buf, int off, int len, string msg) + { + if (off + len > buf.Length) + throw new OutputLengthException(msg); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs.meta new file mode 100644 index 0000000..68d5419 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/Check.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6dd41045620467949adfc127f66c0e85 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs new file mode 100644 index 0000000..31019cf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs @@ -0,0 +1,87 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base class for symmetric, or secret, cipher key generators. + */ + public class CipherKeyGenerator + { + protected internal SecureRandom random; + protected internal int strength; + private bool uninitialised = true; + private int defaultStrength; + + public CipherKeyGenerator() + { + } + + internal CipherKeyGenerator( + int defaultStrength) + { + if (defaultStrength < 1) + throw new ArgumentException("strength must be a positive value", "defaultStrength"); + + this.defaultStrength = defaultStrength; + } + + public int DefaultStrength + { + get { return defaultStrength; } + } + + /** + * initialise the key generator. + * + * @param param the parameters to be used for key generation + */ + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + this.uninitialised = false; + + engineInit(parameters); + } + + protected virtual void engineInit( + KeyGenerationParameters parameters) + { + this.random = parameters.Random; + this.strength = (parameters.Strength + 7) / 8; + } + + /** + * Generate a secret key. + * + * @return a byte array containing the key value. + */ + public byte[] GenerateKey() + { + if (uninitialised) + { + if (defaultStrength < 1) + throw new InvalidOperationException("Generator has not been initialised"); + + uninitialised = false; + + engineInit(new KeyGenerationParameters(new SecureRandom(), defaultStrength)); + } + + return engineGenerateKey(); + } + + protected virtual byte[] engineGenerateKey() + { + return SecureRandom.GetNextBytes(random, strength); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs.meta new file mode 100644 index 0000000..f056561 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CipherKeyGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 83b99673c89b7be4491f695d8e374d3c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs new file mode 100644 index 0000000..a4d5301 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs @@ -0,0 +1,32 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CryptoException + : Exception + { + public CryptoException() + { + } + + public CryptoException( + string message) + : base(message) + { + } + + public CryptoException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs.meta new file mode 100644 index 0000000..214ea7b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/CryptoException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cd38a0fa65d30fc4eae48fa3319f9645 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs new file mode 100644 index 0000000..b35f8ce --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs @@ -0,0 +1,46 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * this exception is thrown if a buffer that is meant to have output + * copied into it turns out to be too short, or if we've been given + * insufficient input. In general this exception will Get thrown rather + * than an ArrayOutOfBounds exception. + */ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class DataLengthException + : CryptoException + { + /** + * base constructor. + */ + public DataLengthException() + { + } + + /** + * create a DataLengthException with the given message. + * + * @param message the message to be carried with the exception. + */ + public DataLengthException( + string message) + : base(message) + { + } + + public DataLengthException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs.meta new file mode 100644 index 0000000..40029ff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/DataLengthException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 34a508389e47f4745921ea8106b00645 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs new file mode 100644 index 0000000..714f892 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs @@ -0,0 +1,34 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// Base interface for a public/private key block cipher. + public interface IAsymmetricBlockCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// Initialise for encryption if true, for decryption if false. + /// The key or other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + /// The maximum size, in bytes, an input block may be. + int GetInputBlockSize(); + + /// The maximum size, in bytes, an output block will be. + int GetOutputBlockSize(); + + /// Process a block. + /// The input buffer. + /// The offset into inBuf that the input block begins. + /// The length of the input block. + /// Input decrypts improperly. + /// Input is too large for the cipher. + byte[] ProcessBlock(byte[] inBuf, int inOff, int inLen); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs.meta new file mode 100644 index 0000000..cc8e5c5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6abbe02392e03f543a957ac413172bd3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs new file mode 100644 index 0000000..09b1acd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * interface that a public/private key pair generator should conform to. + */ + public interface IAsymmetricCipherKeyPairGenerator + { + /** + * intialise the key pair generator. + * + * @param the parameters the key pair is to be initialised with. + */ + void Init(KeyGenerationParameters parameters); + + /** + * return an AsymmetricCipherKeyPair containing the Generated keys. + * + * @return an AsymmetricCipherKeyPair containing the Generated keys. + */ + AsymmetricCipherKeyPair GenerateKeyPair(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta new file mode 100644 index 0000000..f940c70 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: af1fbd88542b90240bb580ea2247b4cf +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs new file mode 100644 index 0000000..1dfaeec --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The basic interface that basic Diffie-Hellman implementations + * conforms to. + */ + public interface IBasicAgreement + { + /** + * initialise the agreement engine. + */ + void Init(ICipherParameters parameters); + + /** + * return the field size for the agreement algorithm in bytes. + */ + int GetFieldSize(); + + /** + * given a public key from a given party calculate the next + * message in the agreement sequence. + */ + BigInteger CalculateAgreement(ICipherParameters pubKey); + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs.meta new file mode 100644 index 0000000..e029451 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBasicAgreement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cd9d504c0c209eb4ab0ba46c3f015a85 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs new file mode 100644 index 0000000..783e7e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// Base interface for a symmetric key block cipher. + public interface IBlockCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// Initialise for encryption if true, for decryption if false. + /// The key or other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + /// The block size for this cipher, in bytes. + int GetBlockSize(); + + /// Indicates whether this cipher can handle partial blocks. + bool IsPartialBlockOkay { get; } + + /// Process a block. + /// The input buffer. + /// The offset into inBuf that the input block begins. + /// The output buffer. + /// The offset into outBuf to write the output block. + /// If input block is wrong size, or outBuf too small. + /// The number of bytes processed and produced. + int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff); + + /// + /// Reset the cipher to the same state as it was after the last init (if there was one). + /// + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs.meta new file mode 100644 index 0000000..91c876a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4935d5699e88bf6459028d927973e8af +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs new file mode 100644 index 0000000..ab5e471 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Operators that reduce their input to a single block return an object + /// of this type. + /// + public interface IBlockResult + { + /// + /// Return the final result of the operation. + /// + /// A block of bytes, representing the result of an operation. + byte[] Collect(); + + /// + /// Store the final result of the operation by copying it into the destination array. + /// + /// The number of bytes copied into destination. + /// The byte array to copy the result into. + /// The offset into destination to start copying the result at. + int Collect(byte[] destination, int offset); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs.meta new file mode 100644 index 0000000..52dd212 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBlockResult.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8ffde966c8f3b9c4282b23834e282a0c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs new file mode 100644 index 0000000..64755aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// Block cipher engines are expected to conform to this interface. + public interface IBufferedCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// If true the cipher is initialised for encryption, + /// if false for decryption. + /// The key and other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + int GetBlockSize(); + + int GetOutputSize(int inputLen); + + int GetUpdateOutputSize(int inputLen); + + byte[] ProcessByte(byte input); + int ProcessByte(byte input, byte[] output, int outOff); + + byte[] ProcessBytes(byte[] input); + byte[] ProcessBytes(byte[] input, int inOff, int length); + int ProcessBytes(byte[] input, byte[] output, int outOff); + int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff); + + byte[] DoFinal(); + byte[] DoFinal(byte[] input); + byte[] DoFinal(byte[] input, int inOff, int length); + int DoFinal(byte[] output, int outOff); + int DoFinal(byte[] input, byte[] output, int outOff); + int DoFinal(byte[] input, int inOff, int length, byte[] output, int outOff); + + /// + /// Reset the cipher. After resetting the cipher is in the same state + /// as it was after the last init (if there was one). + /// + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs.meta new file mode 100644 index 0000000..85f499c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IBufferedCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c8a92034d413bfc40b6680d876d7f8b1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs new file mode 100644 index 0000000..8d1a7a9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * all parameter classes implement this. + */ + public interface ICipherParameters + { + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs.meta new file mode 100644 index 0000000..f5520ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ICipherParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 48f7fda0d1eff294e9c36d8da4c5b237 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs new file mode 100644 index 0000000..daf68b5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto +{ + /** + * interface for classes implementing the Digital Signature Algorithm + */ + public interface IDsa + { + string AlgorithmName { get; } + + /** + * initialise the signer for signature generation or signature + * verification. + * + * @param forSigning true if we are generating a signature, false + * otherwise. + * @param param key parameters for signature generation. + */ + void Init(bool forSigning, ICipherParameters parameters); + + /** + * sign the passed in message (usually the output of a hash function). + * + * @param message the message to be signed. + * @return two big integers representing the r and s values respectively. + */ + BigInteger[] GenerateSignature(byte[] message); + + /** + * verify the message message against the signature values r and s. + * + * @param message the message that was supposed to have been signed. + * @param r the r signature value. + * @param s the s signature value. + */ + bool VerifySignature(byte[] message, BigInteger r, BigInteger s); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs.meta new file mode 100644 index 0000000..9fa516f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDSA.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8cc954fc8fc070a45955c5a315ebc07a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs new file mode 100644 index 0000000..9ca46ad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * base interface for general purpose byte derivation functions. + */ + public interface IDerivationFunction + { + void Init(IDerivationParameters parameters); + + /** + * return the message digest used as the basis for the function + */ + IDigest Digest + { + get; + } + + int GenerateBytes(byte[] output, int outOff, int length); + //throws DataLengthException, ArgumentException; + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs.meta new file mode 100644 index 0000000..091c105 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationFunction.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4485e5cea1db5dc4ebed2d30a3bfa672 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs new file mode 100644 index 0000000..ea4b5b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * Parameters for key/byte stream derivation classes + */ + public interface IDerivationParameters + { + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs.meta new file mode 100644 index 0000000..7ac5a57 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDerivationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ea9b134ee70b91b42b1ad2b5bf68204c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs new file mode 100644 index 0000000..2a02ee0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs @@ -0,0 +1,65 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * interface that a message digest conforms to. + */ + public interface IDigest + { + /** + * return the algorithm name + * + * @return the algorithm name + */ + string AlgorithmName { get; } + + /** + * return the size, in bytes, of the digest produced by this message digest. + * + * @return the size, in bytes, of the digest produced by this message digest. + */ + int GetDigestSize(); + + /** + * return the size, in bytes, of the internal buffer used by this digest. + * + * @return the size, in bytes, of the internal buffer used by this digest. + */ + int GetByteLength(); + + /** + * update the message digest with a single byte. + * + * @param inByte the input byte to be entered. + */ + void Update(byte input); + + /** + * update the message digest with a block of bytes. + * + * @param input the byte array containing the data. + * @param inOff the offset into the byte array where the data starts. + * @param len the length of the data. + */ + void BlockUpdate(byte[] input, int inOff, int length); + + /** + * Close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * + * @param output the array the digest is to be copied into. + * @param outOff the offset into the out array the digest is to start at. + */ + int DoFinal(byte[] output, int outOff); + + /** + * reset the digest back to it's initial state. + */ + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs.meta new file mode 100644 index 0000000..cc379ff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 232948e340c96d0439b8c002b2ab0ec9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs new file mode 100644 index 0000000..7c5c701 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs @@ -0,0 +1,73 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base interface for implementations of message authentication codes (MACs). + */ + public interface IMac + { + /** + * Initialise the MAC. + * + * @param param the key and other data required by the MAC. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + void Init(ICipherParameters parameters); + + /** + * Return the name of the algorithm the MAC implements. + * + * @return the name of the algorithm the MAC implements. + */ + string AlgorithmName { get; } + + /** + * Return the block size for this MAC (in bytes). + * + * @return the block size for this MAC in bytes. + */ + int GetMacSize(); + + /** + * add a single byte to the mac for processing. + * + * @param in the byte to be processed. + * @exception InvalidOperationException if the MAC is not initialised. + */ + void Update(byte input); + + /** + * @param in the array containing the input. + * @param inOff the index in the array the data begins at. + * @param len the length of the input starting at inOff. + * @exception InvalidOperationException if the MAC is not initialised. + * @exception DataLengthException if there isn't enough data in in. + */ + void BlockUpdate(byte[] input, int inOff, int len); + + /** + * Compute the final stage of the MAC writing the output to the out + * parameter. + *

+ * doFinal leaves the MAC in the same state it was after the last init. + *

+ * @param out the array the MAC is to be output to. + * @param outOff the offset into the out buffer the output is to start at. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the MAC is not initialised. + */ + int DoFinal(byte[] output, int outOff); + + /** + * Reset the MAC. At the end of resetting the MAC should be in the + * in the same state it was after the last init (if there was one). + */ + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs.meta new file mode 100644 index 0000000..9cc26f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 06c6c4ff752285d4181fc6f0f7a3bbc1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs new file mode 100644 index 0000000..d62409d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for operators that serve as stream-based signature calculators. + /// + public interface ISignatureFactory + { + /// The algorithm details object for this calculator. + Object AlgorithmDetails { get ; } + + /// + /// Create a stream calculator for this signature calculator. The stream + /// calculator is used for the actual operation of entering the data to be signed + /// and producing the signature block. + /// + /// A calculator producing an IBlockResult with a signature in it. + IStreamCalculator CreateCalculator(); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs.meta new file mode 100644 index 0000000..94f3289 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignatureFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9b932d94d8fe22545b8c91109d2bf521 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs new file mode 100644 index 0000000..914bbd5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs @@ -0,0 +1,54 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + + +using System; +using System.Text; + +namespace Org.BouncyCastle.Crypto +{ + public interface ISigner + { + /** + * Return the name of the algorithm the signer implements. + * + * @return the name of the algorithm the signer implements. + */ + string AlgorithmName { get; } + + /** + * Initialise the signer for signing or verification. + * + * @param forSigning true if for signing, false otherwise + * @param param necessary parameters. + */ + void Init(bool forSigning, ICipherParameters parameters); + + /** + * update the internal digest with the byte b + */ + void Update(byte input); + + /** + * update the internal digest with the byte array in + */ + void BlockUpdate(byte[] input, int inOff, int length); + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + byte[] GenerateSignature(); + /** + * return true if the internal state represents the signature described + * in the passed in array. + */ + bool VerifySignature(byte[] signature); + + /** + * reset the internal state + */ + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs.meta new file mode 100644 index 0000000..e0bc293 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a3bcb10b760d17945bfcb44c2b23d5a7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs new file mode 100644 index 0000000..d9ca153 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs @@ -0,0 +1,41 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +namespace Org.BouncyCastle.Crypto +{ + /** + * Signer with message recovery. + */ + public interface ISignerWithRecovery + : ISigner + { + /** + * Returns true if the signer has recovered the full message as + * part of signature verification. + * + * @return true if full message recovered. + */ + bool HasFullMessage(); + + /** + * Returns a reference to what message was recovered (if any). + * + * @return full/partial message, null if nothing. + */ + byte[] GetRecoveredMessage(); + + /** + * Perform an update with the recovered message before adding any other data. This must + * be the first update method called, and calling it will result in the signer assuming + * that further calls to update will include message content past what is recoverable. + * + * @param signature the signature that we are in the process of verifying. + * @throws IllegalStateException + */ + void UpdateWithRecoveredMessage(byte[] signature); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs.meta new file mode 100644 index 0000000..8f99218 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ISignerWithRecovery.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e65905090a3ed6d4d8a088adeef895f6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs new file mode 100644 index 0000000..e9de764 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs @@ -0,0 +1,26 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for cryptographic operations such as Hashes, MACs, and Signatures which reduce a stream of data + /// to a single value. + /// + public interface IStreamCalculator + { + /// Return a "sink" stream which only exists to update the implementing object. + /// A stream to write to in order to update the implementing object. + Stream Stream { get; } + + /// + /// Return the result of processing the stream. This value is only available once the stream + /// has been closed. + /// + /// The result of processing the stream. + Object GetResult(); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs.meta new file mode 100644 index 0000000..52aac04 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCalculator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71c66ead22110194abc4b7138f2fa247 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs new file mode 100644 index 0000000..eef5b72 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs @@ -0,0 +1,49 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// The interface stream ciphers conform to. + public interface IStreamCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// If true the cipher is initialised for encryption, + /// if false for decryption. + /// The key and other data required by the cipher. + /// + /// If the parameters argument is inappropriate. + /// + void Init(bool forEncryption, ICipherParameters parameters); + + /// encrypt/decrypt a single byte returning the result. + /// the byte to be processed. + /// the result of processing the input byte. + byte ReturnByte(byte input); + + /// + /// Process a block of bytes from input putting the result into output. + /// + /// The input byte array. + /// + /// The offset into input where the data to be processed starts. + /// + /// The number of bytes to be processed. + /// The output buffer the processed bytes go into. + /// + /// The offset into output the processed data starts at. + /// + /// If the output buffer is too small. + void ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff); + + /// + /// Reset the cipher to the same state as it was after the last init (if there was one). + /// + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs.meta new file mode 100644 index 0000000..2e896d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IStreamCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ef95f78d58f8f2848a0600acae2dbde9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs new file mode 100644 index 0000000..f5a5151 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +namespace Org.BouncyCastle.Crypto +{ + /// + /// Operators that reduce their input to the validation of a signature produce this type. + /// + public interface IVerifier + { + /// + /// Return true if the passed in data matches what is expected by the verification result. + /// + /// The bytes representing the signature. + /// true if the signature verifies, false otherwise. + bool IsVerified(byte[] data); + + /// + /// Return true if the length bytes from off in the source array match the signature + /// expected by the verification result. + /// + /// Byte array containing the signature. + /// The offset into the source array where the signature starts. + /// The number of bytes in source making up the signature. + /// true if the signature verifies, false otherwise. + bool IsVerified(byte[] source, int off, int length); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs.meta new file mode 100644 index 0000000..11b9e0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e9b2937c1d75e3a4a853544b58c02a98 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs new file mode 100644 index 0000000..cc66bfb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for operators that serve as stream-based signature verifiers. + /// + public interface IVerifierFactory + { + /// The algorithm details object for this verifier. + Object AlgorithmDetails { get ; } + + /// + /// Create a stream calculator for this verifier. The stream + /// calculator is used for the actual operation of entering the data to be verified + /// and producing a result which can be used to verify the original signature. + /// + /// A calculator producing an IVerifier which can verify the signature. + IStreamCalculator CreateCalculator(); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs.meta new file mode 100644 index 0000000..a198e4d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2bb89900480afd44dbd6fd6f123f4197 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs new file mode 100644 index 0000000..bfb3e2f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for a provider to support the dynamic creation of signature verifiers. + /// + public interface IVerifierFactoryProvider + { + /// + /// Return a signature verfier for signature algorithm described in the passed in algorithm details object. + /// + /// The details of the signature algorithm verification is required for. + /// A new signature verifier. + IVerifierFactory CreateVerifierFactory (Object algorithmDetails); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs.meta new file mode 100644 index 0000000..6121bac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IVerifierFactoryProvider.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9d25c82ed85117949850d76a12de1304 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs new file mode 100644 index 0000000..c3704fe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs @@ -0,0 +1,22 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + public interface IWrapper + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + void Init(bool forWrapping, ICipherParameters parameters); + + byte[] Wrap(byte[] input, int inOff, int length); + + byte[] Unwrap(byte[] input, int inOff, int length); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs.meta new file mode 100644 index 0000000..7391fbb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IWrapper.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9e6dd993ef516c2419ecc5849e22d756 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs new file mode 100644 index 0000000..05789ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// With FIPS PUB 202 a new kind of message digest was announced which supported extendable output, or variable digest sizes. + /// This interface provides the extra method required to support variable output on a digest implementation. + /// + public interface IXof + : IDigest + { + /// + /// Output the results of the final calculation for this digest to outLen number of bytes. + /// + /// output array to write the output bytes to. + /// offset to start writing the bytes at. + /// the number of output bytes requested. + /// the number of bytes written + int DoFinal(byte[] output, int outOff, int outLen); + + /// + /// Start outputting the results of the final calculation for this digest. Unlike DoFinal, this method + /// will continue producing output until the Xof is explicitly reset, or signals otherwise. + /// + /// output array to write the output bytes to. + /// offset to start writing the bytes at. + /// the number of output bytes requested. + /// the number of bytes written + int DoOutput(byte[] output, int outOff, int outLen); + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs.meta new file mode 100644 index 0000000..228701e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/IXof.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0dc703e606f9afc47a3e7859c663a442 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs new file mode 100644 index 0000000..1a81ce2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * this exception is thrown whenever we find something we don't expect in a + * message. + */ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class InvalidCipherTextException + : CryptoException + { + /** + * base constructor. + */ + public InvalidCipherTextException() + { + } + + /** + * create a InvalidCipherTextException with the given message. + * + * @param message the message to be carried with the exception. + */ + public InvalidCipherTextException( + string message) + : base(message) + { + } + + public InvalidCipherTextException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs.meta new file mode 100644 index 0000000..196fda3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/InvalidCipherTextException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8853d9e74bb4d214ca464e63632d1f0c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs new file mode 100644 index 0000000..1f10bb5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs @@ -0,0 +1,59 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base class for parameters to key generators. + */ + public class KeyGenerationParameters + { + private SecureRandom random; + private int strength; + + /** + * initialise the generator with a source of randomness + * and a strength (in bits). + * + * @param random the random byte source. + * @param strength the size, in bits, of the keys we want to produce. + */ + public KeyGenerationParameters( + SecureRandom random, + int strength) + { + if (random == null) + throw new ArgumentNullException("random"); + if (strength < 1) + throw new ArgumentException("strength must be a positive value", "strength"); + + this.random = random; + this.strength = strength; + } + + /** + * return the random source associated with this + * generator. + * + * @return the generators random source. + */ + public SecureRandom Random + { + get { return random; } + } + + /** + * return the bit strength for keys produced by this generator, + * + * @return the strength of the keys this generator produces (in bits). + */ + public int Strength + { + get { return strength; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..b53addb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/KeyGenerationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 04045d0d5f207b6429614236fbee6859 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs new file mode 100644 index 0000000..c4ba2eb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs @@ -0,0 +1,36 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// This exception is thrown whenever a cipher requires a change of key, iv + /// or similar after x amount of bytes enciphered + /// +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class MaxBytesExceededException + : CryptoException + { + public MaxBytesExceededException() + { + } + + public MaxBytesExceededException( + string message) + : base(message) + { + } + + public MaxBytesExceededException( + string message, + Exception e) + : base(message, e) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs.meta new file mode 100644 index 0000000..fa75382 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/MaxBytesExceededException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 92610e3167822424cbf998e12a4d959a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs new file mode 100644 index 0000000..8a7c3d7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs @@ -0,0 +1,32 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class OutputLengthException + : DataLengthException + { + public OutputLengthException() + { + } + + public OutputLengthException( + string message) + : base(message) + { + } + + public OutputLengthException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs.meta new file mode 100644 index 0000000..3b4d577 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/OutputLengthException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aeef960a80a930f47af2e7599623e501 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs new file mode 100644 index 0000000..85e175f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs @@ -0,0 +1,206 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto +{ + /** + * super class for all Password Based Encyrption (Pbe) parameter generator classes. + */ + public abstract class PbeParametersGenerator + { + protected byte[] mPassword; + protected byte[] mSalt; + protected int mIterationCount; + + /** + * base constructor. + */ + protected PbeParametersGenerator() + { + } + + /** + * initialise the Pbe generator. + * + * @param password the password converted into bytes (see below). + * @param salt the salt to be mixed with the password. + * @param iterationCount the number of iterations the "mixing" function + * is to be applied for. + */ + public virtual void Init( + byte[] password, + byte[] salt, + int iterationCount) + { + if (password == null) + throw new ArgumentNullException("password"); + if (salt == null) + throw new ArgumentNullException("salt"); + + this.mPassword = Arrays.Clone(password); + this.mSalt = Arrays.Clone(salt); + this.mIterationCount = iterationCount; + } + + public virtual byte[] Password + { + get { return Arrays.Clone(mPassword); } + } + + /** + * return the password byte array. + * + * @return the password byte array. + */ + [Obsolete("Use 'Password' property")] + public byte[] GetPassword() + { + return Password; + } + + public virtual byte[] Salt + { + get { return Arrays.Clone(mSalt); } + } + + /** + * return the salt byte array. + * + * @return the salt byte array. + */ + [Obsolete("Use 'Salt' property")] + public byte[] GetSalt() + { + return Salt; + } + + /** + * return the iteration count. + * + * @return the iteration count. + */ + public virtual int IterationCount + { + get { return mIterationCount; } + } + + /** + * Generate derived parameters for a key of length keySize. + * + * @param keySize the length, in bits, of the key required. + * @return a parameters object representing a key. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public abstract ICipherParameters GenerateDerivedParameters(int keySize); + public abstract ICipherParameters GenerateDerivedParameters(string algorithm, int keySize); + + /** + * Generate derived parameters for a key of length keySize, and + * an initialisation vector (IV) of length ivSize. + * + * @param keySize the length, in bits, of the key required. + * @param ivSize the length, in bits, of the iv required. + * @return a parameters object representing a key and an IV. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public abstract ICipherParameters GenerateDerivedParameters(int keySize, int ivSize); + public abstract ICipherParameters GenerateDerivedParameters(string algorithm, int keySize, int ivSize); + + /** + * Generate derived parameters for a key of length keySize, specifically + * for use with a MAC. + * + * @param keySize the length, in bits, of the key required. + * @return a parameters object representing a key. + */ + public abstract ICipherParameters GenerateDerivedMacParameters(int keySize); + + /** + * converts a password to a byte array according to the scheme in + * Pkcs5 (ascii, no padding) + * + * @param password a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] Pkcs5PasswordToBytes( + char[] password) + { + if (password == null) + return new byte[0]; + + return Strings.ToByteArray(password); + } + + [Obsolete("Use version taking 'char[]' instead")] + public static byte[] Pkcs5PasswordToBytes( + string password) + { + if (password == null) + return new byte[0]; + + return Strings.ToByteArray(password); + } + + /** + * converts a password to a byte array according to the scheme in + * PKCS5 (UTF-8, no padding) + * + * @param password a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] Pkcs5PasswordToUtf8Bytes( + char[] password) + { + if (password == null) + return new byte[0]; + + return Encoding.UTF8.GetBytes(password); + } + + [Obsolete("Use version taking 'char[]' instead")] + public static byte[] Pkcs5PasswordToUtf8Bytes( + string password) + { + if (password == null) + return new byte[0]; + + return Encoding.UTF8.GetBytes(password); + } + + /** + * converts a password to a byte array according to the scheme in + * Pkcs12 (unicode, big endian, 2 zero pad bytes at the end). + * + * @param password a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] Pkcs12PasswordToBytes( + char[] password) + { + return Pkcs12PasswordToBytes(password, false); + } + + public static byte[] Pkcs12PasswordToBytes( + char[] password, + bool wrongPkcs12Zero) + { + if (password == null || password.Length < 1) + { + return new byte[wrongPkcs12Zero ? 2 : 0]; + } + + // +1 for extra 2 pad bytes. + byte[] bytes = new byte[(password.Length + 1) * 2]; + + Encoding.BigEndianUnicode.GetBytes(password, 0, password.Length, bytes, 0); + + return bytes; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs.meta new file mode 100644 index 0000000..10c16d3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/PbeParametersGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1e8e08c20f9235643b9bc29aa415dfab +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement.meta new file mode 100644 index 0000000..1b7be6a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2bc69c4ab864f9b47b55d5556201d098 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs new file mode 100644 index 0000000..8e7e192 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs @@ -0,0 +1,68 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * a Diffie-Hellman key agreement class. + *

+ * note: This is only the basic algorithm, it doesn't take advantage of + * long term public keys if they are available. See the DHAgreement class + * for a "better" implementation.

+ */ + public class DHBasicAgreement + : IBasicAgreement + { + private DHPrivateKeyParameters key; + private DHParameters dhParams; + + public virtual void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (!(parameters is DHPrivateKeyParameters)) + { + throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); + } + + this.key = (DHPrivateKeyParameters) parameters; + this.dhParams = key.Parameters; + } + + public virtual int GetFieldSize() + { + return (key.Parameters.P.BitLength + 7) / 8; + } + + /** + * given a short term public key from a given party calculate the next + * message in the agreement sequence. + */ + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + if (this.key == null) + throw new InvalidOperationException("Agreement algorithm not initialised"); + + DHPublicKeyParameters pub = (DHPublicKeyParameters)pubKey; + + if (!pub.Parameters.Equals(dhParams)) + { + throw new ArgumentException("Diffie-Hellman public key has wrong parameters."); + } + + return pub.Y.ModPow(key.X, dhParams.P); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs.meta new file mode 100644 index 0000000..3a7e1c6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/DHBasicAgreement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 784404322f00cbf4d8deb0ae525835dc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs new file mode 100644 index 0000000..8bbbcbc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs @@ -0,0 +1,64 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * P1363 7.2.1 ECSVDP-DH + * + * ECSVDP-DH is Elliptic Curve Secret Value Derivation Primitive, + * Diffie-Hellman version. It is based on the work of [DH76], [Mil86], + * and [Kob87]. This primitive derives a shared secret value from one + * party's private key and another party's public key, where both have + * the same set of EC domain parameters. If two parties correctly + * execute this primitive, they will produce the same output. This + * primitive can be invoked by a scheme to derive a shared secret key; + * specifically, it may be used with the schemes ECKAS-DH1 and + * DL/ECKAS-DH2. It assumes that the input keys are valid (see also + * Section 7.2.2). + */ + public class ECDHBasicAgreement + : IBasicAgreement + { + protected internal ECPrivateKeyParameters privKey; + + public virtual void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).Parameters; + } + + this.privKey = (ECPrivateKeyParameters)parameters; + } + + public virtual int GetFieldSize() + { + return (privKey.Parameters.Curve.FieldSize + 7) / 8; + } + + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + ECPublicKeyParameters pub = (ECPublicKeyParameters) pubKey; + if (!pub.Parameters.Equals(privKey.Parameters)) + throw new InvalidOperationException("ECDH public key has wrong domain parameters"); + + ECPoint P = pub.Q.Multiply(privKey.D).Normalize(); + + if (P.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH"); + + return P.AffineXCoord.ToBigInteger(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs.meta new file mode 100644 index 0000000..891bdf7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/agreement/ECDHBasicAgreement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 113c4d3158892b44b9ffa9a028ad0762 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests.meta new file mode 100644 index 0000000..f95a7e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1e980ab0e11551042aa0a47cac1b3062 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs new file mode 100644 index 0000000..210ffba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs @@ -0,0 +1,360 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of GOST R 34.11-94 + */ + public class Gost3411Digest + : IDigest, IMemoable + { + private const int DIGEST_LENGTH = 32; + + private byte[] H = new byte[32], L = new byte[32], + M = new byte[32], Sum = new byte[32]; + private byte[][] C = MakeC(); + + private byte[] xBuf = new byte[32]; + private int xBufOff; + private ulong byteCount; + + private readonly IBlockCipher cipher = new Gost28147Engine(); + private byte[] sBox; + + private static byte[][] MakeC() + { + byte[][] c = new byte[4][]; + for (int i = 0; i < 4; ++i) + { + c[i] = new byte[32]; + } + return c; + } + + /** + * Standard constructor + */ + public Gost3411Digest() + { + sBox = Gost28147Engine.GetSBox("D-A"); + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + } + + /** + * Constructor to allow use of a particular sbox with GOST28147 + * @see GOST28147Engine#getSBox(String) + */ + public Gost3411Digest(byte[] sBoxParam) + { + sBox = Arrays.Clone(sBoxParam); + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Gost3411Digest(Gost3411Digest t) + { + Reset(t); + } + + public string AlgorithmName + { + get { return "Gost3411"; } + } + + public int GetDigestSize() + { + return DIGEST_LENGTH; + } + + public void Update( + byte input) + { + xBuf[xBufOff++] = input; + if (xBufOff == xBuf.Length) + { + sumByteArray(xBuf); // calc sum M + processBlock(xBuf, 0); + xBufOff = 0; + } + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + while ((xBufOff != 0) && (length > 0)) + { + Update(input[inOff]); + inOff++; + length--; + } + + while (length > xBuf.Length) + { + Array.Copy(input, inOff, xBuf, 0, xBuf.Length); + + sumByteArray(xBuf); // calc sum M + processBlock(xBuf, 0); + inOff += xBuf.Length; + length -= xBuf.Length; + byteCount += (uint)xBuf.Length; + } + + // load in the remainder. + while (length > 0) + { + Update(input[inOff]); + inOff++; + length--; + } + } + + // (i + 1 + 4(k - 1)) = 8i + k i = 0-3, k = 1-8 + private byte[] K = new byte[32]; + + private byte[] P(byte[] input) + { + int fourK = 0; + for(int k = 0; k < 8; k++) + { + K[fourK++] = input[k]; + K[fourK++] = input[8 + k]; + K[fourK++] = input[16 + k]; + K[fourK++] = input[24 + k]; + } + + return K; + } + + //A (x) = (x0 ^ x1) || x3 || x2 || x1 + byte[] a = new byte[8]; + private byte[] A(byte[] input) + { + for(int j=0; j<8; j++) + { + a[j]=(byte)(input[j] ^ input[j+8]); + } + + Array.Copy(input, 8, input, 0, 24); + Array.Copy(a, 0, input, 24, 8); + + return input; + } + + //Encrypt function, ECB mode + private void E(byte[] key, byte[] s, int sOff, byte[] input, int inOff) + { + cipher.Init(true, new KeyParameter(key)); + + cipher.ProcessBlock(input, inOff, s, sOff); + } + + // (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2 + internal short[] wS = new short[16], w_S = new short[16]; + + private void fw(byte[] input) + { + cpyBytesToShort(input, wS); + w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]); + Array.Copy(wS, 1, w_S, 0, 15); + cpyShortToBytes(w_S, input); + } + + // block processing + internal byte[] S = new byte[32], U = new byte[32], V = new byte[32], W = new byte[32]; + + private void processBlock(byte[] input, int inOff) + { + Array.Copy(input, inOff, M, 0, 32); + + //key step 1 + + // H = h3 || h2 || h1 || h0 + // S = s3 || s2 || s1 || s0 + H.CopyTo(U, 0); + M.CopyTo(V, 0); + for (int j=0; j<32; j++) + { + W[j] = (byte)(U[j]^V[j]); + } + // Encrypt gost28147-ECB + E(P(W), S, 0, H, 0); // s0 = EK0 [h0] + + //keys step 2,3,4 + for (int i=1; i<4; i++) + { + byte[] tmpA = A(U); + for (int j=0; j<32; j++) + { + U[j] = (byte)(tmpA[j] ^ C[i][j]); + } + V = A(A(V)); + for (int j=0; j<32; j++) + { + W[j] = (byte)(U[j]^V[j]); + } + // Encrypt gost28147-ECB + E(P(W), S, i * 8, H, i * 8); // si = EKi [hi] + } + + // x(M, H) = y61(H^y(M^y12(S))) + for(int n = 0; n < 12; n++) + { + fw(S); + } + for(int n = 0; n < 32; n++) + { + S[n] = (byte)(S[n] ^ M[n]); + } + + fw(S); + + for(int n = 0; n < 32; n++) + { + S[n] = (byte)(H[n] ^ S[n]); + } + for(int n = 0; n < 61; n++) + { + fw(S); + } + Array.Copy(S, 0, H, 0, H.Length); + } + + private void finish() + { + ulong bitCount = byteCount * 8; + Pack.UInt64_To_LE(bitCount, L); + + while (xBufOff != 0) + { + Update((byte)0); + } + + processBlock(L, 0); + processBlock(Sum, 0); + } + + public int DoFinal( + byte[] output, + int outOff) + { + finish(); + + H.CopyTo(output, outOff); + + Reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables to the IV values. + */ + private static readonly byte[] C2 = { + 0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF, + (byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00, + 0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF, + (byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF + }; + + public void Reset() + { + byteCount = 0; + xBufOff = 0; + + Array.Clear(H, 0, H.Length); + Array.Clear(L, 0, L.Length); + Array.Clear(M, 0, M.Length); + Array.Clear(C[1], 0, C[1].Length); // real index C = +1 because index array with 0. + Array.Clear(C[3], 0, C[3].Length); + Array.Clear(Sum, 0, Sum.Length); + Array.Clear(xBuf, 0, xBuf.Length); + + C2.CopyTo(C[2], 0); + } + + // 256 bitsblock modul -> (Sum + a mod (2^256)) + private void sumByteArray( + byte[] input) + { + int carry = 0; + + for (int i = 0; i != Sum.Length; i++) + { + int sum = (Sum[i] & 0xff) + (input[i] & 0xff) + carry; + + Sum[i] = (byte)sum; + + carry = sum >> 8; + } + } + + private static void cpyBytesToShort(byte[] S, short[] wS) + { + for(int i = 0; i < S.Length / 2; i++) + { + wS[i] = (short)(((S[i*2+1]<<8)&0xFF00)|(S[i*2]&0xFF)); + } + } + + private static void cpyShortToBytes(short[] wS, byte[] S) + { + for(int i=0; i> 8); + S[i*2] = (byte)wS[i]; + } + } + + public int GetByteLength() + { + return 32; + } + + public IMemoable Copy() + { + return new Gost3411Digest(this); + } + + public void Reset(IMemoable other) + { + Gost3411Digest t = (Gost3411Digest)other; + + this.sBox = t.sBox; + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + + Array.Copy(t.H, 0, this.H, 0, t.H.Length); + Array.Copy(t.L, 0, this.L, 0, t.L.Length); + Array.Copy(t.M, 0, this.M, 0, t.M.Length); + Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length); + Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length); + Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length); + Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length); + Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length); + + this.xBufOff = t.xBufOff; + this.byteCount = t.byteCount; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs.meta new file mode 100644 index 0000000..649eec1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GOST3411Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 64f3ba3752b08254c9377349d44de349 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs new file mode 100644 index 0000000..8d9301e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs @@ -0,0 +1,137 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * base implementation of MD4 family style digest as outlined in + * "Handbook of Applied Cryptography", pages 344 - 347. + */ + public abstract class GeneralDigest + : IDigest, IMemoable + { + private const int BYTE_LENGTH = 64; + + private byte[] xBuf; + private int xBufOff; + + private long byteCount; + + internal GeneralDigest() + { + xBuf = new byte[4]; + } + + internal GeneralDigest(GeneralDigest t) + { + xBuf = new byte[t.xBuf.Length]; + CopyIn(t); + } + + protected void CopyIn(GeneralDigest t) + { + Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); + + xBufOff = t.xBufOff; + byteCount = t.byteCount; + } + + public void Update(byte input) + { + xBuf[xBufOff++] = input; + + if (xBufOff == xBuf.Length) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + } + + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + length = System.Math.Max(0, length); + + // + // fill the current word + // + int i = 0; + if (xBufOff != 0) + { + while (i < length) + { + xBuf[xBufOff++] = input[inOff + i++]; + if (xBufOff == 4) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + break; + } + } + } + + // + // process whole words. + // + int limit = ((length - i) & ~3) + i; + for (; i < limit; i += 4) + { + ProcessWord(input, inOff + i); + } + + // + // load in the remainder. + // + while (i < length) + { + xBuf[xBufOff++] = input[inOff + i++]; + } + + byteCount += length; + } + + public void Finish() + { + long bitLength = (byteCount << 3); + + // + // add the pad bytes. + // + Update((byte)128); + + while (xBufOff != 0) Update((byte)0); + ProcessLength(bitLength); + ProcessBlock(); + } + + public virtual void Reset() + { + byteCount = 0; + xBufOff = 0; + Array.Clear(xBuf, 0, xBuf.Length); + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + + internal abstract void ProcessWord(byte[] input, int inOff); + internal abstract void ProcessLength(long bitLength); + internal abstract void ProcessBlock(); + public abstract string AlgorithmName { get; } + public abstract int GetDigestSize(); + public abstract int DoFinal(byte[] output, int outOff); + public abstract IMemoable Copy(); + public abstract void Reset(IMemoable t); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs.meta new file mode 100644 index 0000000..e8eb70c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/GeneralDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 86264b6205260ac4f9c649821fb106eb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs new file mode 100644 index 0000000..61bdca4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs @@ -0,0 +1,538 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// Implementation of Keccak based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ + /// + /// + /// Following the naming conventions used in the C source code to enable easy review of the implementation. + /// + public class KeccakDigest + : IDigest, IMemoable + { + private static readonly ulong[] KeccakRoundConstants = KeccakInitializeRoundConstants(); + + private static readonly int[] KeccakRhoOffsets = KeccakInitializeRhoOffsets(); + + private static ulong[] KeccakInitializeRoundConstants() + { + ulong[] keccakRoundConstants = new ulong[24]; + byte LFSRState = 0x01; + + for (int i = 0; i < 24; i++) + { + keccakRoundConstants[i] = 0; + for (int j = 0; j < 7; j++) + { + int bitPosition = (1 << j) - 1; + + // LFSR86540 + + bool loBit = (LFSRState & 0x01) != 0; + if (loBit) + { + keccakRoundConstants[i] ^= 1UL << bitPosition; + } + + bool hiBit = (LFSRState & 0x80) != 0; + LFSRState <<= 1; + if (hiBit) + { + LFSRState ^= 0x71; + } + + } + } + + return keccakRoundConstants; + } + + private static int[] KeccakInitializeRhoOffsets() + { + int[] keccakRhoOffsets = new int[25]; + int x, y, t, newX, newY; + + int rhoOffset = 0; + keccakRhoOffsets[(((0) % 5) + 5 * ((0) % 5))] = rhoOffset; + x = 1; + y = 0; + for (t = 1; t < 25; t++) + { + //rhoOffset = ((t + 1) * (t + 2) / 2) % 64; + rhoOffset = (rhoOffset + t) & 63; + keccakRhoOffsets[(((x) % 5) + 5 * ((y) % 5))] = rhoOffset; + newX = (0 * x + 1 * y) % 5; + newY = (2 * x + 3 * y) % 5; + x = newX; + y = newY; + } + + return keccakRhoOffsets; + } + + protected byte[] state = new byte[(1600 / 8)]; + protected byte[] dataQueue = new byte[(1536 / 8)]; + protected int rate; + protected int bitsInQueue; + protected int fixedOutputLength; + protected bool squeezing; + protected int bitsAvailableForSqueezing; + protected byte[] chunk; + protected byte[] oneByte; + + private void ClearDataQueueSection(int off, int len) + { + for (int i = off; i != off + len; i++) + { + dataQueue[i] = 0; + } + } + + public KeccakDigest() + : this(288) + { + } + + public KeccakDigest(int bitLength) + { + Init(bitLength); + } + + public KeccakDigest(KeccakDigest source) + { + CopyIn(source); + } + + private void CopyIn(KeccakDigest source) + { + Array.Copy(source.state, 0, this.state, 0, source.state.Length); + Array.Copy(source.dataQueue, 0, this.dataQueue, 0, source.dataQueue.Length); + this.rate = source.rate; + this.bitsInQueue = source.bitsInQueue; + this.fixedOutputLength = source.fixedOutputLength; + this.squeezing = source.squeezing; + this.bitsAvailableForSqueezing = source.bitsAvailableForSqueezing; + this.chunk = Arrays.Clone(source.chunk); + this.oneByte = Arrays.Clone(source.oneByte); + } + + public virtual string AlgorithmName + { + get { return "Keccak-" + fixedOutputLength; } + } + + public virtual int GetDigestSize() + { + return fixedOutputLength / 8; + } + + public virtual void Update(byte input) + { + oneByte[0] = input; + + Absorb(oneByte, 0, 8L); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + Absorb(input, inOff, len * 8L); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + Squeeze(output, outOff, fixedOutputLength); + + Reset(); + + return GetDigestSize(); + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected virtual int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits) + { + if (partialBits > 0) + { + oneByte[0] = partialByte; + Absorb(oneByte, 0, partialBits); + } + + Squeeze(output, outOff, fixedOutputLength); + + Reset(); + + return GetDigestSize(); + } + + public virtual void Reset() + { + Init(fixedOutputLength); + } + + /** + * Return the size of block that the compression function is applied to in bytes. + * + * @return internal byte length of a block. + */ + public virtual int GetByteLength() + { + return rate / 8; + } + + private void Init(int bitLength) + { + switch (bitLength) + { + case 128: + InitSponge(1344, 256); + break; + case 224: + InitSponge(1152, 448); + break; + case 256: + InitSponge(1088, 512); + break; + case 288: + InitSponge(1024, 576); + break; + case 384: + InitSponge(832, 768); + break; + case 512: + InitSponge(576, 1024); + break; + default: + throw new ArgumentException("must be one of 128, 224, 256, 288, 384, or 512.", "bitLength"); + } + } + + private void InitSponge(int rate, int capacity) + { + if (rate + capacity != 1600) + { + throw new InvalidOperationException("rate + capacity != 1600"); + } + if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0)) + { + throw new InvalidOperationException("invalid rate value"); + } + + this.rate = rate; + // this is never read, need to check to see why we want to save it + // this.capacity = capacity; + this.fixedOutputLength = 0; + Arrays.Fill(this.state, (byte)0); + Arrays.Fill(this.dataQueue, (byte)0); + this.bitsInQueue = 0; + this.squeezing = false; + this.bitsAvailableForSqueezing = 0; + this.fixedOutputLength = capacity / 2; + this.chunk = new byte[rate / 8]; + this.oneByte = new byte[1]; + } + + private void AbsorbQueue() + { + KeccakAbsorb(state, dataQueue, rate / 8); + + bitsInQueue = 0; + } + + protected virtual void Absorb(byte[] data, int off, long databitlen) + { + long i, j, wholeBlocks; + + if ((bitsInQueue % 8) != 0) + { + throw new InvalidOperationException("attempt to absorb with odd length queue"); + } + if (squeezing) + { + throw new InvalidOperationException("attempt to absorb while squeezing"); + } + + i = 0; + while (i < databitlen) + { + if ((bitsInQueue == 0) && (databitlen >= rate) && (i <= (databitlen - rate))) + { + wholeBlocks = (databitlen - i) / rate; + + for (j = 0; j < wholeBlocks; j++) + { + Array.Copy(data, (int)(off + (i / 8) + (j * chunk.Length)), chunk, 0, chunk.Length); + + KeccakAbsorb(state, chunk, chunk.Length); + } + + i += wholeBlocks * rate; + } + else + { + int partialBlock = (int)(databitlen - i); + if (partialBlock + bitsInQueue > rate) + { + partialBlock = rate - bitsInQueue; + } + int partialByte = partialBlock % 8; + partialBlock -= partialByte; + Array.Copy(data, off + (int)(i / 8), dataQueue, bitsInQueue / 8, partialBlock / 8); + + bitsInQueue += partialBlock; + i += partialBlock; + if (bitsInQueue == rate) + { + AbsorbQueue(); + } + if (partialByte > 0) + { + int mask = (1 << partialByte) - 1; + dataQueue[bitsInQueue / 8] = (byte)(data[off + ((int)(i / 8))] & mask); + bitsInQueue += partialByte; + i += partialByte; + } + } + } + } + + private void PadAndSwitchToSqueezingPhase() + { + if (bitsInQueue + 1 == rate) + { + dataQueue[bitsInQueue / 8] |= (byte)(1U << (bitsInQueue % 8)); + AbsorbQueue(); + ClearDataQueueSection(0, rate / 8); + } + else + { + ClearDataQueueSection((bitsInQueue + 7) / 8, rate / 8 - (bitsInQueue + 7) / 8); + dataQueue[bitsInQueue / 8] |= (byte)(1U << (bitsInQueue % 8)); + } + dataQueue[(rate - 1) / 8] |= (byte)(1U << ((rate - 1) % 8)); + AbsorbQueue(); + + if (rate == 1024) + { + KeccakExtract1024bits(state, dataQueue); + bitsAvailableForSqueezing = 1024; + } + else + { + KeccakExtract(state, dataQueue, rate / 64); + bitsAvailableForSqueezing = rate; + } + + squeezing = true; + } + + protected virtual void Squeeze(byte[] output, int offset, long outputLength) + { + long i; + int partialBlock; + + if (!squeezing) + { + PadAndSwitchToSqueezingPhase(); + } + if ((outputLength % 8) != 0) + { + throw new InvalidOperationException("outputLength not a multiple of 8"); + } + + i = 0; + while (i < outputLength) + { + if (bitsAvailableForSqueezing == 0) + { + KeccakPermutation(state); + + if (rate == 1024) + { + KeccakExtract1024bits(state, dataQueue); + bitsAvailableForSqueezing = 1024; + } + else + { + KeccakExtract(state, dataQueue, rate / 64); + bitsAvailableForSqueezing = rate; + } + } + partialBlock = bitsAvailableForSqueezing; + if ((long)partialBlock > outputLength - i) + { + partialBlock = (int)(outputLength - i); + } + + Array.Copy(dataQueue, (rate - bitsAvailableForSqueezing) / 8, output, offset + (int)(i / 8), partialBlock / 8); + bitsAvailableForSqueezing -= partialBlock; + i += partialBlock; + } + } + + private static void FromBytesToWords(ulong[] stateAsWords, byte[] state) + { + for (int i = 0; i < (1600 / 64); i++) + { + stateAsWords[i] = 0; + int index = i * (64 / 8); + for (int j = 0; j < (64 / 8); j++) + { + stateAsWords[i] |= ((ulong)state[index + j] & 0xff) << ((8 * j)); + } + } + } + + private static void FromWordsToBytes(byte[] state, ulong[] stateAsWords) + { + for (int i = 0; i < (1600 / 64); i++) + { + int index = i * (64 / 8); + for (int j = 0; j < (64 / 8); j++) + { + state[index + j] = (byte)(stateAsWords[i] >> (8 * j)); + } + } + } + + private void KeccakPermutation(byte[] state) + { + ulong[] longState = new ulong[state.Length / 8]; + + FromBytesToWords(longState, state); + + KeccakPermutationOnWords(longState); + + FromWordsToBytes(state, longState); + } + + private void KeccakPermutationAfterXor(byte[] state, byte[] data, int dataLengthInBytes) + { + for (int i = 0; i < dataLengthInBytes; i++) + { + state[i] ^= data[i]; + } + + KeccakPermutation(state); + } + + private void KeccakPermutationOnWords(ulong[] state) + { + int i; + + for (i = 0; i < 24; i++) + { + Theta(state); + Rho(state); + Pi(state); + Chi(state); + Iota(state, i); + } + } + + ulong[] C = new ulong[5]; + + private void Theta(ulong[] A) + { + for (int x = 0; x < 5; x++) + { + C[x] = 0; + for (int y = 0; y < 5; y++) + { + C[x] ^= A[x + 5 * y]; + } + } + for (int x = 0; x < 5; x++) + { + ulong dX = ((((C[(x + 1) % 5]) << 1) ^ ((C[(x + 1) % 5]) >> (64 - 1)))) ^ C[(x + 4) % 5]; + for (int y = 0; y < 5; y++) + { + A[x + 5 * y] ^= dX; + } + } + } + + private void Rho(ulong[] A) + { + for (int x = 0; x < 5; x++) + { + for (int y = 0; y < 5; y++) + { + int index = x + 5 * y; + A[index] = ((KeccakRhoOffsets[index] != 0) ? (((A[index]) << KeccakRhoOffsets[index]) ^ ((A[index]) >> (64 - KeccakRhoOffsets[index]))) : A[index]); + } + } + } + + ulong[] tempA = new ulong[25]; + + private void Pi(ulong[] A) + { + Array.Copy(A, 0, tempA, 0, tempA.Length); + + for (int x = 0; x < 5; x++) + { + for (int y = 0; y < 5; y++) + { + A[y + 5 * ((2 * x + 3 * y) % 5)] = tempA[x + 5 * y]; + } + } + } + + ulong[] chiC = new ulong[5]; + + private void Chi(ulong[] A) + { + for (int y = 0; y < 5; y++) + { + for (int x = 0; x < 5; x++) + { + chiC[x] = A[x + 5 * y] ^ ((~A[(((x + 1) % 5) + 5 * y)]) & A[(((x + 2) % 5) + 5 * y)]); + } + for (int x = 0; x < 5; x++) + { + A[x + 5 * y] = chiC[x]; + } + } + } + + private static void Iota(ulong[] A, int indexRound) + { + A[(((0) % 5) + 5 * ((0) % 5))] ^= KeccakRoundConstants[indexRound]; + } + + private void KeccakAbsorb(byte[] byteState, byte[] data, int dataInBytes) + { + KeccakPermutationAfterXor(byteState, data, dataInBytes); + } + + private void KeccakExtract1024bits(byte[] byteState, byte[] data) + { + Array.Copy(byteState, 0, data, 0, 128); + } + + private void KeccakExtract(byte[] byteState, byte[] data, int laneCount) + { + Array.Copy(byteState, 0, data, 0, laneCount * 8); + } + + public virtual IMemoable Copy() + { + return new KeccakDigest(this); + } + + public virtual void Reset(IMemoable other) + { + KeccakDigest d = (KeccakDigest)other; + + CopyIn(d); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs.meta new file mode 100644 index 0000000..fea4855 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/KeccakDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ec6fde84d97edb44288b899e7b6b5d8b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs new file mode 100644 index 0000000..202e1e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs @@ -0,0 +1,359 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Base class for SHA-384 and SHA-512. + */ + public abstract class LongDigest + : IDigest, IMemoable + { + private int MyByteLength = 128; + + private byte[] xBuf; + private int xBufOff; + + private long byteCount1; + private long byteCount2; + + internal ulong H1, H2, H3, H4, H5, H6, H7, H8; + + private ulong[] W = new ulong[80]; + private int wOff; + + /** + * Constructor for variable length word + */ + internal LongDigest() + { + xBuf = new byte[8]; + + Reset(); + } + + /** + * Copy constructor. We are using copy constructors in place + * of the object.Clone() interface as this interface is not + * supported by J2ME. + */ + internal LongDigest( + LongDigest t) + { + xBuf = new byte[t.xBuf.Length]; + + CopyIn(t); + } + + protected void CopyIn(LongDigest t) + { + Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); + + xBufOff = t.xBufOff; + byteCount1 = t.byteCount1; + byteCount2 = t.byteCount2; + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.W, 0, W, 0, t.W.Length); + wOff = t.wOff; + } + + public void Update( + byte input) + { + xBuf[xBufOff++] = input; + + if (xBufOff == xBuf.Length) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + } + + byteCount1++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + // + // fill the current word + // + while ((xBufOff != 0) && (length > 0)) + { + Update(input[inOff]); + + inOff++; + length--; + } + + // + // process whole words. + // + while (length > xBuf.Length) + { + ProcessWord(input, inOff); + + inOff += xBuf.Length; + length -= xBuf.Length; + byteCount1 += xBuf.Length; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + + inOff++; + length--; + } + } + + public void Finish() + { + AdjustByteCounts(); + + long lowBitLength = byteCount1 << 3; + long hiBitLength = byteCount2; + + // + // add the pad bytes. + // + Update((byte)128); + + while (xBufOff != 0) + { + Update((byte)0); + } + + ProcessLength(lowBitLength, hiBitLength); + + ProcessBlock(); + } + + public virtual void Reset() + { + byteCount1 = 0; + byteCount2 = 0; + + xBufOff = 0; + for ( int i = 0; i < xBuf.Length; i++ ) + { + xBuf[i] = 0; + } + + wOff = 0; + Array.Clear(W, 0, W.Length); + } + + internal void ProcessWord( + byte[] input, + int inOff) + { + W[wOff] = Pack.BE_To_UInt64(input, inOff); + + if (++wOff == 16) + { + ProcessBlock(); + } + } + + /** + * adjust the byte counts so that byteCount2 represents the + * upper long (less 3 bits) word of the byte count. + */ + private void AdjustByteCounts() + { + if (byteCount1 > 0x1fffffffffffffffL) + { + byteCount2 += (long) ((ulong) byteCount1 >> 61); + byteCount1 &= 0x1fffffffffffffffL; + } + } + + internal void ProcessLength( + long lowW, + long hiW) + { + if (wOff > 14) + { + ProcessBlock(); + } + + W[14] = (ulong)hiW; + W[15] = (ulong)lowW; + } + + internal void ProcessBlock() + { + AdjustByteCounts(); + + // + // expand 16 word block into 80 word blocks. + // + for (int ti = 16; ti <= 79; ++ti) + { + W[ti] = Sigma1(W[ti - 2]) + W[ti - 7] + Sigma0(W[ti - 15]) + W[ti - 16]; + } + + // + // set up working variables. + // + ulong a = H1; + ulong b = H2; + ulong c = H3; + ulong d = H4; + ulong e = H5; + ulong f = H6; + ulong g = H7; + ulong h = H8; + + int t = 0; + for(int i = 0; i < 10; i ++) + { + // t = 8 * i + h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++]; + d += h; + h += Sum0(a) + Maj(a, b, c); + + // t = 8 * i + 1 + g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++]; + c += g; + g += Sum0(h) + Maj(h, a, b); + + // t = 8 * i + 2 + f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++]; + b += f; + f += Sum0(g) + Maj(g, h, a); + + // t = 8 * i + 3 + e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++]; + a += e; + e += Sum0(f) + Maj(f, g, h); + + // t = 8 * i + 4 + d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++]; + h += d; + d += Sum0(e) + Maj(e, f, g); + + // t = 8 * i + 5 + c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++]; + g += c; + c += Sum0(d) + Maj(d, e, f); + + // t = 8 * i + 6 + b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++]; + f += b; + b += Sum0(c) + Maj(c, d, e); + + // t = 8 * i + 7 + a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++]; + e += a; + a += Sum0(b) + Maj(b, c, d); + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + wOff = 0; + Array.Clear(W, 0, 16); + } + + /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */ + private static ulong Ch(ulong x, ulong y, ulong z) + { + return (x & y) ^ (~x & z); + } + + private static ulong Maj(ulong x, ulong y, ulong z) + { + return (x & y) ^ (x & z) ^ (y & z); + } + + private static ulong Sum0(ulong x) + { + return ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39)); + } + + private static ulong Sum1(ulong x) + { + return ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41)); + } + + private static ulong Sigma0(ulong x) + { + return ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7); + } + + private static ulong Sigma1(ulong x) + { + return ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6); + } + + /* SHA-384 and SHA-512 Constants + * (represent the first 64 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + internal static readonly ulong[] K = + { + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, + 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, + 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, + 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, + 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, + 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, + 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, + 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 + }; + + public int GetByteLength() + { + return MyByteLength; + } + + public abstract string AlgorithmName { get; } + public abstract int GetDigestSize(); + public abstract int DoFinal(byte[] output, int outOff); + public abstract IMemoable Copy(); + public abstract void Reset(IMemoable t); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs.meta new file mode 100644 index 0000000..c3cabd6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/LongDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4c09e9ec58127294abaecdc2d14b88e4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs new file mode 100644 index 0000000..7298c89 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs @@ -0,0 +1,273 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /** + * implementation of MD2 + * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992 + */ + public class MD2Digest + : IDigest, IMemoable + { + private const int DigestLength = 16; + private const int BYTE_LENGTH = 16; + + /* X buffer */ + private byte[] X = new byte[48]; + private int xOff; + + /* M buffer */ + + private byte[] M = new byte[16]; + private int mOff; + + /* check sum */ + + private byte[] C = new byte[16]; + private int COff; + + public MD2Digest() + { + Reset(); + } + + public MD2Digest(MD2Digest t) + { + CopyIn(t); + } + + private void CopyIn(MD2Digest t) + { + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + Array.Copy(t.M, 0, M, 0, t.M.Length); + mOff = t.mOff; + Array.Copy(t.C, 0, C, 0, t.C.Length); + COff = t.COff; + } + + /** + * return the algorithm name + * + * @return the algorithm name + */ + public string AlgorithmName + { + get { return "MD2"; } + } + + public int GetDigestSize() + { + return DigestLength; + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + + /** + * Close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * + * @param out the array the digest is to be copied into. + * @param outOff the offset into the out array the digest is to start at. + */ + public int DoFinal(byte[] output, int outOff) + { + // add padding + byte paddingByte = (byte)(M.Length - mOff); + for (int i=mOff;i 0)) + { + Update(input[inOff]); + inOff++; + length--; + } + + // + // process whole words. + // + while (length > 16) + { + Array.Copy(input,inOff,M,0,16); + ProcessChecksum(M); + ProcessBlock(M); + length -= 16; + inOff += 16; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + inOff++; + length--; + } + } + + internal void ProcessChecksum(byte[] m) + { + int L = C[15]; + for (int i=0;i<16;i++) + { + C[i] ^= S[(m[i] ^ L) & 0xff]; + L = C[i]; + } + } + internal void ProcessBlock(byte[] m) + { + for (int i=0;i<16;i++) + { + X[i+16] = m[i]; + X[i+32] = (byte)(m[i] ^ X[i]); + } + // encrypt block + int t = 0; + + for (int j=0;j<18;j++) + { + for (int k=0;k<48;k++) + { + t = X[k] ^= S[t]; + t = t & 0xff; + } + t = (t + j)%256; + } + } + + + + // 256-byte random permutation constructed from the digits of PI + private static readonly byte[] S = { + (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124, + (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240, + (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192, + (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217, + (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87, + (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66, + (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190, + (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73, + (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238, + (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178, + (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11, + (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154, + (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204, + (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25, + (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215, + (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198, + (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125, + (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116, + (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100, + (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101, + (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37, + (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70, + (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85, + (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58, + (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234, + (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40, + (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65, + (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200, + (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123, + (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136, + (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233, + (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57, + (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208, + (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117, + (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143, + (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51, + (byte)159,(byte)17,(byte)131,(byte)20 + }; + + public IMemoable Copy() + { + return new MD2Digest(this); + } + + public void Reset(IMemoable other) + { + MD2Digest d = (MD2Digest)other; + + CopyIn(d); + } + + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs.meta new file mode 100644 index 0000000..97a3bc1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD2Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 148e9d8b628e3e942995c6a5620f1b56 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs new file mode 100644 index 0000000..37efed1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs @@ -0,0 +1,296 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for + * Computer Science and RSA Data Security, Inc. + *

+ * NOTE: This algorithm is only included for backwards compatibility + * with legacy applications, it's not secure, don't use it for anything new!

+ */ + public class MD4Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public MD4Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD4Digest(MD4Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(MD4Digest t) + { + base.CopyIn(t); + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "MD4"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 4); + UnpackWord(H3, output, outOff + 8); + UnpackWord(H4, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H1 = unchecked((int) 0x67452301); + H2 = unchecked((int) 0xefcdab89); + H3 = unchecked((int) 0x98badcfe); + H4 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private const int S11 = 3; + private const int S12 = 7; + private const int S13 = 11; + private const int S14 = 19; + + // + // round 2 left rotates + // + private const int S21 = 3; + private const int S22 = 5; + private const int S23 = 9; + private const int S24 = 13; + + // + // round 3 left rotates + // + private const int S31 = 3; + private const int S32 = 9; + private const int S33 = 11; + private const int S34 = 15; + + /* + * rotate int x left n bits. + */ + private int RotateLeft( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * F, G, H and I are the basic MD4 functions. + */ + private int F( + int u, + int v, + int w) + { + return (u & v) | (~u & w); + } + + private int G( + int u, + int v, + int w) + { + return (u & v) | (u & w) | (v & w); + } + + private int H( + int u, + int v, + int w) + { + return u ^ v ^ w; + } + + internal override void ProcessBlock() + { + int a = H1; + int b = H2; + int c = H3; + int d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = RotateLeft((a + F(b, c, d) + X[ 0]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 1]), S12); + c = RotateLeft((c + F(d, a, b) + X[ 2]), S13); + b = RotateLeft((b + F(c, d, a) + X[ 3]), S14); + a = RotateLeft((a + F(b, c, d) + X[ 4]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 5]), S12); + c = RotateLeft((c + F(d, a, b) + X[ 6]), S13); + b = RotateLeft((b + F(c, d, a) + X[ 7]), S14); + a = RotateLeft((a + F(b, c, d) + X[ 8]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 9]), S12); + c = RotateLeft((c + F(d, a, b) + X[10]), S13); + b = RotateLeft((b + F(c, d, a) + X[11]), S14); + a = RotateLeft((a + F(b, c, d) + X[12]), S11); + d = RotateLeft((d + F(a, b, c) + X[13]), S12); + c = RotateLeft((c + F(d, a, b) + X[14]), S13); + b = RotateLeft((b + F(c, d, a) + X[15]), S14); + + // + // Round 2 - G cycle, 16 times. + // + a = RotateLeft((a + G(b, c, d) + X[ 0] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 4] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[ 8] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[12] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 1] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 5] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[ 9] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[13] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 2] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 6] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[10] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[14] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 3] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 7] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[11] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[15] + 0x5a827999), S24); + + // + // Round 3 - H cycle, 16 times. + // + a = RotateLeft((a + H(b, c, d) + X[ 0] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[ 8] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 4] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[12] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 2] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[10] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 6] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[14] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 1] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[ 9] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 5] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[13] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 3] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[11] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 7] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[15] + 0x6ed9eba1), S34); + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new MD4Digest(this); + } + + public override void Reset(IMemoable other) + { + MD4Digest d = (MD4Digest)other; + + CopyIn(d); + } + + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs.meta new file mode 100644 index 0000000..e0fa63a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD4Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c00e2d62bb704374caa7eae8a01a61c6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs new file mode 100644 index 0000000..41329de --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs @@ -0,0 +1,317 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. + */ + public class MD5Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private uint H1, H2, H3, H4; // IV's + + private uint[] X = new uint[16]; + private int xOff; + + public MD5Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD5Digest(MD5Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(MD5Digest t) + { + base.CopyIn(t); + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "MD5"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.LE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + if (xOff == 15) + X[15] = 0; + + ProcessBlock(); + } + + for (int i = xOff; i < 14; ++i) + { + X[i] = 0; + } + + X[14] = (uint)((ulong)bitLength); + X[15] = (uint)((ulong)bitLength >> 32); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_LE(H1, output, outOff); + Pack.UInt32_To_LE(H2, output, outOff + 4); + Pack.UInt32_To_LE(H3, output, outOff + 8); + Pack.UInt32_To_LE(H4, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private static readonly int S11 = 7; + private static readonly int S12 = 12; + private static readonly int S13 = 17; + private static readonly int S14 = 22; + + // + // round 2 left rotates + // + private static readonly int S21 = 5; + private static readonly int S22 = 9; + private static readonly int S23 = 14; + private static readonly int S24 = 20; + + // + // round 3 left rotates + // + private static readonly int S31 = 4; + private static readonly int S32 = 11; + private static readonly int S33 = 16; + private static readonly int S34 = 23; + + // + // round 4 left rotates + // + private static readonly int S41 = 6; + private static readonly int S42 = 10; + private static readonly int S43 = 15; + private static readonly int S44 = 21; + + /* + * rotate int x left n bits. + */ + private static uint RotateLeft( + uint x, + int n) + { + return (x << n) | (x >> (32 - n)); + } + + /* + * F, G, H and I are the basic MD5 functions. + */ + private static uint F( + uint u, + uint v, + uint w) + { + return (u & v) | (~u & w); + } + + private static uint G( + uint u, + uint v, + uint w) + { + return (u & w) | (v & ~w); + } + + private static uint H( + uint u, + uint v, + uint w) + { + return u ^ v ^ w; + } + + private static uint K( + uint u, + uint v, + uint w) + { + return v ^ (u | ~w); + } + + internal override void ProcessBlock() + { + uint a = H1; + uint b = H2; + uint c = H3; + uint d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = RotateLeft((a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[2] + 0x242070db), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[6] + 0xa8304613), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[7] + 0xfd469501), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[8] + 0x698098d8), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c; + + // + // Round 2 - G cycle, 16 times. + // + a = RotateLeft((a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[6] + 0xc040b340), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c; + + // + // Round 3 - H cycle, 16 times. + // + a = RotateLeft((a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[8] + 0x8771f681), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[6] + 0x04881d05), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c; + + // + // Round 4 - K cycle, 16 times. + // + a = RotateLeft((a + K(b, c, d) + X[0] + 0xf4292244), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[7] + 0x432aff97), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[6] + 0xa3014314), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c; + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + xOff = 0; + } + + public override IMemoable Copy() + { + return new MD5Digest(this); + } + + public override void Reset(IMemoable other) + { + MD5Digest d = (MD5Digest)other; + + CopyIn(d); + } + + } + +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs.meta new file mode 100644 index 0000000..def71f2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/MD5Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 46ef6a4addc052240b7194ef4a92d2c6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs new file mode 100644 index 0000000..328c692 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs @@ -0,0 +1,53 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class NullDigest : IDigest + { + private readonly MemoryStream bOut = new MemoryStream(); + + public string AlgorithmName + { + get { return "NULL"; } + } + + public int GetByteLength() + { + // TODO Is this okay? + return 0; + } + + public int GetDigestSize() + { + return (int) bOut.Length; + } + + public void Update(byte b) + { + bOut.WriteByte(b); + } + + public void BlockUpdate(byte[] inBytes, int inOff, int len) + { + bOut.Write(inBytes, inOff, len); + } + + public int DoFinal(byte[] outBytes, int outOff) + { + byte[] res = bOut.ToArray(); + res.CopyTo(outBytes, outOff); + Reset(); + return res.Length; + } + + public void Reset() + { + bOut.SetLength(0); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs.meta new file mode 100644 index 0000000..78601fd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/NullDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e4ba894a25f89ad4485499b6efb1cd37 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs new file mode 100644 index 0000000..5e2fb44 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs @@ -0,0 +1,488 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of RipeMD128 + */ + public class RipeMD128Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H0, H1, H2, H3; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public RipeMD128Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public RipeMD128Digest(RipeMD128Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD128Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "RIPEMD128"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * f1,f2,f3,f4 are the basic RipeMD128 functions. + */ + + /* + * F + */ + private int F1( + int x, + int y, + int z) + { + return x ^ y ^ z; + } + + /* + * G + */ + private int F2( + int x, + int y, + int z) + { + return (x & y) | (~x & z); + } + + /* + * H + */ + private int F3( + int x, + int y, + int z) + { + return (x | ~y) ^ z; + } + + /* + * I + */ + private int F4( + int x, + int y, + int z) + { + return (x & z) | (y & ~z); + } + + private int F1( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int F2( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int) 0x5a827999), s); + } + + private int F3( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int) 0x6ed9eba1), s); + } + + private int F4( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int) 0x8f1bbcdc), s); + } + + private int FF1( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int FF2( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int) 0x6d703ef3), s); + } + + private int FF3( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int) 0x5c4dd124), s); + } + + private int FF4( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int) 0x50a28be6), s); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + + a = aa = H0; + b = bb = H1; + c = cc = H2; + d = dd = H3; + + // + // Round 1 + // + a = F1(a, b, c, d, X[ 0], 11); + d = F1(d, a, b, c, X[ 1], 14); + c = F1(c, d, a, b, X[ 2], 15); + b = F1(b, c, d, a, X[ 3], 12); + a = F1(a, b, c, d, X[ 4], 5); + d = F1(d, a, b, c, X[ 5], 8); + c = F1(c, d, a, b, X[ 6], 7); + b = F1(b, c, d, a, X[ 7], 9); + a = F1(a, b, c, d, X[ 8], 11); + d = F1(d, a, b, c, X[ 9], 13); + c = F1(c, d, a, b, X[10], 14); + b = F1(b, c, d, a, X[11], 15); + a = F1(a, b, c, d, X[12], 6); + d = F1(d, a, b, c, X[13], 7); + c = F1(c, d, a, b, X[14], 9); + b = F1(b, c, d, a, X[15], 8); + + // + // Round 2 + // + a = F2(a, b, c, d, X[ 7], 7); + d = F2(d, a, b, c, X[ 4], 6); + c = F2(c, d, a, b, X[13], 8); + b = F2(b, c, d, a, X[ 1], 13); + a = F2(a, b, c, d, X[10], 11); + d = F2(d, a, b, c, X[ 6], 9); + c = F2(c, d, a, b, X[15], 7); + b = F2(b, c, d, a, X[ 3], 15); + a = F2(a, b, c, d, X[12], 7); + d = F2(d, a, b, c, X[ 0], 12); + c = F2(c, d, a, b, X[ 9], 15); + b = F2(b, c, d, a, X[ 5], 9); + a = F2(a, b, c, d, X[ 2], 11); + d = F2(d, a, b, c, X[14], 7); + c = F2(c, d, a, b, X[11], 13); + b = F2(b, c, d, a, X[ 8], 12); + + // + // Round 3 + // + a = F3(a, b, c, d, X[ 3], 11); + d = F3(d, a, b, c, X[10], 13); + c = F3(c, d, a, b, X[14], 6); + b = F3(b, c, d, a, X[ 4], 7); + a = F3(a, b, c, d, X[ 9], 14); + d = F3(d, a, b, c, X[15], 9); + c = F3(c, d, a, b, X[ 8], 13); + b = F3(b, c, d, a, X[ 1], 15); + a = F3(a, b, c, d, X[ 2], 14); + d = F3(d, a, b, c, X[ 7], 8); + c = F3(c, d, a, b, X[ 0], 13); + b = F3(b, c, d, a, X[ 6], 6); + a = F3(a, b, c, d, X[13], 5); + d = F3(d, a, b, c, X[11], 12); + c = F3(c, d, a, b, X[ 5], 7); + b = F3(b, c, d, a, X[12], 5); + + // + // Round 4 + // + a = F4(a, b, c, d, X[ 1], 11); + d = F4(d, a, b, c, X[ 9], 12); + c = F4(c, d, a, b, X[11], 14); + b = F4(b, c, d, a, X[10], 15); + a = F4(a, b, c, d, X[ 0], 14); + d = F4(d, a, b, c, X[ 8], 15); + c = F4(c, d, a, b, X[12], 9); + b = F4(b, c, d, a, X[ 4], 8); + a = F4(a, b, c, d, X[13], 9); + d = F4(d, a, b, c, X[ 3], 14); + c = F4(c, d, a, b, X[ 7], 5); + b = F4(b, c, d, a, X[15], 6); + a = F4(a, b, c, d, X[14], 8); + d = F4(d, a, b, c, X[ 5], 6); + c = F4(c, d, a, b, X[ 6], 5); + b = F4(b, c, d, a, X[ 2], 12); + + // + // Parallel round 1 + // + aa = FF4(aa, bb, cc, dd, X[ 5], 8); + dd = FF4(dd, aa, bb, cc, X[14], 9); + cc = FF4(cc, dd, aa, bb, X[ 7], 9); + bb = FF4(bb, cc, dd, aa, X[ 0], 11); + aa = FF4(aa, bb, cc, dd, X[ 9], 13); + dd = FF4(dd, aa, bb, cc, X[ 2], 15); + cc = FF4(cc, dd, aa, bb, X[11], 15); + bb = FF4(bb, cc, dd, aa, X[ 4], 5); + aa = FF4(aa, bb, cc, dd, X[13], 7); + dd = FF4(dd, aa, bb, cc, X[ 6], 7); + cc = FF4(cc, dd, aa, bb, X[15], 8); + bb = FF4(bb, cc, dd, aa, X[ 8], 11); + aa = FF4(aa, bb, cc, dd, X[ 1], 14); + dd = FF4(dd, aa, bb, cc, X[10], 14); + cc = FF4(cc, dd, aa, bb, X[ 3], 12); + bb = FF4(bb, cc, dd, aa, X[12], 6); + + // + // Parallel round 2 + // + aa = FF3(aa, bb, cc, dd, X[ 6], 9); + dd = FF3(dd, aa, bb, cc, X[11], 13); + cc = FF3(cc, dd, aa, bb, X[ 3], 15); + bb = FF3(bb, cc, dd, aa, X[ 7], 7); + aa = FF3(aa, bb, cc, dd, X[ 0], 12); + dd = FF3(dd, aa, bb, cc, X[13], 8); + cc = FF3(cc, dd, aa, bb, X[ 5], 9); + bb = FF3(bb, cc, dd, aa, X[10], 11); + aa = FF3(aa, bb, cc, dd, X[14], 7); + dd = FF3(dd, aa, bb, cc, X[15], 7); + cc = FF3(cc, dd, aa, bb, X[ 8], 12); + bb = FF3(bb, cc, dd, aa, X[12], 7); + aa = FF3(aa, bb, cc, dd, X[ 4], 6); + dd = FF3(dd, aa, bb, cc, X[ 9], 15); + cc = FF3(cc, dd, aa, bb, X[ 1], 13); + bb = FF3(bb, cc, dd, aa, X[ 2], 11); + + // + // Parallel round 3 + // + aa = FF2(aa, bb, cc, dd, X[15], 9); + dd = FF2(dd, aa, bb, cc, X[ 5], 7); + cc = FF2(cc, dd, aa, bb, X[ 1], 15); + bb = FF2(bb, cc, dd, aa, X[ 3], 11); + aa = FF2(aa, bb, cc, dd, X[ 7], 8); + dd = FF2(dd, aa, bb, cc, X[14], 6); + cc = FF2(cc, dd, aa, bb, X[ 6], 6); + bb = FF2(bb, cc, dd, aa, X[ 9], 14); + aa = FF2(aa, bb, cc, dd, X[11], 12); + dd = FF2(dd, aa, bb, cc, X[ 8], 13); + cc = FF2(cc, dd, aa, bb, X[12], 5); + bb = FF2(bb, cc, dd, aa, X[ 2], 14); + aa = FF2(aa, bb, cc, dd, X[10], 13); + dd = FF2(dd, aa, bb, cc, X[ 0], 13); + cc = FF2(cc, dd, aa, bb, X[ 4], 7); + bb = FF2(bb, cc, dd, aa, X[13], 5); + + // + // Parallel round 4 + // + aa = FF1(aa, bb, cc, dd, X[ 8], 15); + dd = FF1(dd, aa, bb, cc, X[ 6], 5); + cc = FF1(cc, dd, aa, bb, X[ 4], 8); + bb = FF1(bb, cc, dd, aa, X[ 1], 11); + aa = FF1(aa, bb, cc, dd, X[ 3], 14); + dd = FF1(dd, aa, bb, cc, X[11], 14); + cc = FF1(cc, dd, aa, bb, X[15], 6); + bb = FF1(bb, cc, dd, aa, X[ 0], 14); + aa = FF1(aa, bb, cc, dd, X[ 5], 6); + dd = FF1(dd, aa, bb, cc, X[12], 9); + cc = FF1(cc, dd, aa, bb, X[ 2], 12); + bb = FF1(bb, cc, dd, aa, X[13], 9); + aa = FF1(aa, bb, cc, dd, X[ 9], 12); + dd = FF1(dd, aa, bb, cc, X[ 7], 5); + cc = FF1(cc, dd, aa, bb, X[10], 15); + bb = FF1(bb, cc, dd, aa, X[14], 8); + + dd += c + H1; // final result for H0 + + // + // combine the results + // + H1 = H2 + d + aa; + H2 = H3 + a + bb; + H3 = H0 + b + cc; + H0 = dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD128Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD128Digest d = (RipeMD128Digest)other; + + CopyIn(d); + } + + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs.meta new file mode 100644 index 0000000..0b04980 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD128Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 19005e1814c7f154599f0788dfc18e96 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs new file mode 100644 index 0000000..ea355e8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs @@ -0,0 +1,449 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of RipeMD see, + * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html + */ + public class RipeMD160Digest + : GeneralDigest + { + private const int DigestLength = 20; + + private int H0, H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public RipeMD160Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public RipeMD160Digest(RipeMD160Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD160Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "RIPEMD160"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + H4 = unchecked((int) 0xc3d2e1f0); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * f1,f2,f3,f4,f5 are the basic RipeMD160 functions. + */ + + /* + * rounds 0-15 + */ + private int F1( + int x, + int y, + int z) + { + return x ^ y ^ z; + } + + /* + * rounds 16-31 + */ + private int F2( + int x, + int y, + int z) + { + return (x & y) | (~x & z); + } + + /* + * rounds 32-47 + */ + private int F3( + int x, + int y, + int z) + { + return (x | ~y) ^ z; + } + + /* + * rounds 48-63 + */ + private int F4( + int x, + int y, + int z) + { + return (x & z) | (y & ~z); + } + + /* + * rounds 64-79 + */ + private int F5( + int x, + int y, + int z) + { + return x ^ (y | ~z); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int e, ee; + + a = aa = H0; + b = bb = H1; + c = cc = H2; + d = dd = H3; + e = ee = H4; + + // + // Rounds 1 - 16 + // + // left + a = RL(a + F1(b,c,d) + X[ 0], 11) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[ 1], 14) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[ 2], 15) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[ 3], 12) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[ 4], 5) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[ 5], 8) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[ 6], 7) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[ 7], 9) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[ 8], 11) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[ 9], 13) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[10], 14) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[11], 15) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[12], 6) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[13], 7) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[14], 9) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[15], 8) + e; c = RL(c, 10); + + // right + aa = RL(aa + F5(bb,cc,dd) + X[ 5] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[14] + unchecked((int) 0x50a28be6), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 7] + unchecked((int) 0x50a28be6), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[ 0] + unchecked((int) 0x50a28be6), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 9] + unchecked((int) 0x50a28be6), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[ 2] + unchecked((int) 0x50a28be6), 15) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[11] + unchecked((int) 0x50a28be6), 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 4] + unchecked((int) 0x50a28be6), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[13] + unchecked((int) 0x50a28be6), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 6] + unchecked((int) 0x50a28be6), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[15] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[ 8] + unchecked((int) 0x50a28be6), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 1] + unchecked((int) 0x50a28be6), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[10] + unchecked((int) 0x50a28be6), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 3] + unchecked((int) 0x50a28be6), 12) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[12] + unchecked((int) 0x50a28be6), 6) + ee; cc = RL(cc, 10); + + // + // Rounds 16-31 + // + // left + e = RL(e + F2(a,b,c) + X[ 7] + unchecked((int) 0x5a827999), 7) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[ 4] + unchecked((int) 0x5a827999), 6) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[13] + unchecked((int) 0x5a827999), 8) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[ 1] + unchecked((int) 0x5a827999), 13) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[10] + unchecked((int) 0x5a827999), 11) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 6] + unchecked((int) 0x5a827999), 9) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[15] + unchecked((int) 0x5a827999), 7) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[ 3] + unchecked((int) 0x5a827999), 15) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[12] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[ 0] + unchecked((int) 0x5a827999), 12) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 9] + unchecked((int) 0x5a827999), 15) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[ 5] + unchecked((int) 0x5a827999), 9) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[ 2] + unchecked((int) 0x5a827999), 11) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[14] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[11] + unchecked((int) 0x5a827999), 13) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 8] + unchecked((int) 0x5a827999), 12) + d; b = RL(b, 10); + + // right + ee = RL(ee + F4(aa,bb,cc) + X[ 6] + unchecked((int) 0x5c4dd124), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[11] + unchecked((int) 0x5c4dd124), 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[ 3] + unchecked((int) 0x5c4dd124), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[ 7] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[ 0] + unchecked((int) 0x5c4dd124), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[13] + unchecked((int) 0x5c4dd124), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[ 5] + unchecked((int) 0x5c4dd124), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[10] + unchecked((int) 0x5c4dd124), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[14] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[15] + unchecked((int) 0x5c4dd124), 7) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[ 8] + unchecked((int) 0x5c4dd124), 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[12] + unchecked((int) 0x5c4dd124), 7) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[ 4] + unchecked((int) 0x5c4dd124), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[ 9] + unchecked((int) 0x5c4dd124), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[ 1] + unchecked((int) 0x5c4dd124), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[ 2] + unchecked((int) 0x5c4dd124), 11) + dd; bb = RL(bb, 10); + + // + // Rounds 32-47 + // + // left + d = RL(d + F3(e,a,b) + X[ 3] + unchecked((int) 0x6ed9eba1), 11) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[10] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[14] + unchecked((int) 0x6ed9eba1), 6) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[ 4] + unchecked((int) 0x6ed9eba1), 7) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 9] + unchecked((int) 0x6ed9eba1), 14) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[15] + unchecked((int) 0x6ed9eba1), 9) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[ 8] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[ 1] + unchecked((int) 0x6ed9eba1), 15) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[ 2] + unchecked((int) 0x6ed9eba1), 14) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 7] + unchecked((int) 0x6ed9eba1), 8) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[ 0] + unchecked((int) 0x6ed9eba1), 13) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[ 6] + unchecked((int) 0x6ed9eba1), 6) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[13] + unchecked((int) 0x6ed9eba1), 5) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[11] + unchecked((int) 0x6ed9eba1), 12) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 5] + unchecked((int) 0x6ed9eba1), 7) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[12] + unchecked((int) 0x6ed9eba1), 5) + c; a = RL(a, 10); + + // right + dd = RL(dd + F3(ee,aa,bb) + X[15] + unchecked((int) 0x6d703ef3), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 5] + unchecked((int) 0x6d703ef3), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[ 1] + unchecked((int) 0x6d703ef3), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[ 3] + unchecked((int) 0x6d703ef3), 11) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 7] + unchecked((int) 0x6d703ef3), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[14] + unchecked((int) 0x6d703ef3), 6) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 6] + unchecked((int) 0x6d703ef3), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[ 9] + unchecked((int) 0x6d703ef3), 14) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[11] + unchecked((int) 0x6d703ef3), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 8] + unchecked((int) 0x6d703ef3), 13) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[12] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 2] + unchecked((int) 0x6d703ef3), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[10] + unchecked((int) 0x6d703ef3), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[ 0] + unchecked((int) 0x6d703ef3), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 4] + unchecked((int) 0x6d703ef3), 7) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[13] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10); + + // + // Rounds 48-63 + // + // left + c = RL(c + F4(d,e,a) + X[ 1] + unchecked((int) 0x8f1bbcdc), 11) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[ 9] + unchecked((int) 0x8f1bbcdc), 12) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[11] + unchecked((int) 0x8f1bbcdc), 14) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[10] + unchecked((int) 0x8f1bbcdc), 15) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 0] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 8] + unchecked((int) 0x8f1bbcdc), 15) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[12] + unchecked((int) 0x8f1bbcdc), 9) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[ 4] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[13] + unchecked((int) 0x8f1bbcdc), 9) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 3] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 7] + unchecked((int) 0x8f1bbcdc), 5) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[15] + unchecked((int) 0x8f1bbcdc), 6) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[14] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[ 5] + unchecked((int) 0x8f1bbcdc), 6) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 6] + unchecked((int) 0x8f1bbcdc), 5) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 2] + unchecked((int) 0x8f1bbcdc), 12) + b; e = RL(e, 10); + + // right + cc = RL(cc + F2(dd,ee,aa) + X[ 8] + unchecked((int) 0x7a6d76e9), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[ 6] + unchecked((int) 0x7a6d76e9), 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 4] + unchecked((int) 0x7a6d76e9), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 1] + unchecked((int) 0x7a6d76e9), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[ 3] + unchecked((int) 0x7a6d76e9), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[11] + unchecked((int) 0x7a6d76e9), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[15] + unchecked((int) 0x7a6d76e9), 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 0] + unchecked((int) 0x7a6d76e9), 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 5] + unchecked((int) 0x7a6d76e9), 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[12] + unchecked((int) 0x7a6d76e9), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[ 2] + unchecked((int) 0x7a6d76e9), 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[13] + unchecked((int) 0x7a6d76e9), 9) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 9] + unchecked((int) 0x7a6d76e9), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 7] + unchecked((int) 0x7a6d76e9), 5) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[10] + unchecked((int) 0x7a6d76e9), 15) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[14] + unchecked((int) 0x7a6d76e9), 8) + bb; ee = RL(ee, 10); + + // + // Rounds 64-79 + // + // left + b = RL(b + F5(c,d,e) + X[ 4] + unchecked((int) 0xa953fd4e), 9) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 0] + unchecked((int) 0xa953fd4e), 15) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[ 5] + unchecked((int) 0xa953fd4e), 5) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[ 9] + unchecked((int) 0xa953fd4e), 11) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[ 7] + unchecked((int) 0xa953fd4e), 6) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[12] + unchecked((int) 0xa953fd4e), 8) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 2] + unchecked((int) 0xa953fd4e), 13) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[10] + unchecked((int) 0xa953fd4e), 12) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[14] + unchecked((int) 0xa953fd4e), 5) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[ 1] + unchecked((int) 0xa953fd4e), 12) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[ 3] + unchecked((int) 0xa953fd4e), 13) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 8] + unchecked((int) 0xa953fd4e), 14) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[11] + unchecked((int) 0xa953fd4e), 11) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[ 6] + unchecked((int) 0xa953fd4e), 8) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[15] + unchecked((int) 0xa953fd4e), 5) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[13] + unchecked((int) 0xa953fd4e), 6) + a; d = RL(d, 10); + + // right + bb = RL(bb + F1(cc,dd,ee) + X[12], 8) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[15], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[10], 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 4], 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 1], 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[ 5], 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[ 8], 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[ 7], 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 6], 8) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 2], 13) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[13], 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[14], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[ 0], 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 3], 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 9], 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[11], 11) + aa; dd = RL(dd, 10); + + dd += c + H1; + H1 = H2 + d + ee; + H2 = H3 + e + aa; + H3 = H4 + a + bb; + H4 = H0 + b + cc; + H0 = dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD160Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD160Digest d = (RipeMD160Digest)other; + + CopyIn(d); + } + + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs.meta new file mode 100644 index 0000000..0b4bf95 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD160Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 588720ec33ec63143abd90df75fee16e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs new file mode 100644 index 0000000..ce36efe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs @@ -0,0 +1,434 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + ///

Implementation of RipeMD256.

+ ///

Note: this algorithm offers the same level of security as RipeMD128.

+ ///
+ public class RipeMD256Digest + : GeneralDigest + { + public override string AlgorithmName + { + get { return "RIPEMD256"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + private const int DigestLength = 32; + + private int H0, H1, H2, H3, H4, H5, H6, H7; // IV's + + private int[] X = new int[16]; + private int xOff; + + /// Standard constructor + public RipeMD256Digest() + { + Reset(); + } + + /// Copy constructor. This will copy the state of the provided + /// message digest. + /// + public RipeMD256Digest(RipeMD256Digest t):base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD256Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong)bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)(uint)word; + outBytes[outOff + 1] = (byte)((uint)word >> 8); + outBytes[outOff + 2] = (byte)((uint)word >> 16); + outBytes[outOff + 3] = (byte)((uint)word >> 24); + } + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + UnpackWord(H5, output, outOff + 20); + UnpackWord(H6, output, outOff + 24); + UnpackWord(H7, output, outOff + 28); + + Reset(); + + return DigestLength; + } + + /// reset the chaining variables to the IV values. + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int)0x67452301); + H1 = unchecked((int)0xefcdab89); + H2 = unchecked((int)0x98badcfe); + H3 = unchecked((int)0x10325476); + H4 = unchecked((int)0x76543210); + H5 = unchecked((int)0xFEDCBA98); + H6 = unchecked((int)0x89ABCDEF); + H7 = unchecked((int)0x01234567); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int)((uint)x >> (32 - n)); + } + + /* + * f1,f2,f3,f4 are the basic RipeMD128 functions. + */ + + /* + * F + */ + private int F1(int x, int y, int z) + { + return x ^ y ^ z; + } + + /* + * G + */ + private int F2(int x, int y, int z) + { + return (x & y) | (~ x & z); + } + + /* + * H + */ + private int F3(int x, int y, int z) + { + return (x | ~ y) ^ z; + } + + /* + * I + */ + private int F4(int x, int y, int z) + { + return (x & z) | (y & ~ z); + } + + private int F1(int a, int b, int c, int d, int x, int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int F2(int a, int b, int c, int d, int x, int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int)0x5a827999), s); + } + + private int F3(int a, int b, int c, int d, int x, int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int)0x6ed9eba1), s); + } + + private int F4(int a, int b, int c, int d, int x, int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int)0x8f1bbcdc), s); + } + + private int FF1(int a, int b, int c, int d, int x, int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int FF2(int a, int b, int c, int d, int x, int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int)0x6d703ef3), s); + } + + private int FF3(int a, int b, int c, int d, int x, int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int)0x5c4dd124), s); + } + + private int FF4(int a, int b, int c, int d, int x, int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int)0x50a28be6), s); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int t; + + a = H0; + b = H1; + c = H2; + d = H3; + aa = H4; + bb = H5; + cc = H6; + dd = H7; + + // + // Round 1 + // + + a = F1(a, b, c, d, X[0], 11); + d = F1(d, a, b, c, X[1], 14); + c = F1(c, d, a, b, X[2], 15); + b = F1(b, c, d, a, X[3], 12); + a = F1(a, b, c, d, X[4], 5); + d = F1(d, a, b, c, X[5], 8); + c = F1(c, d, a, b, X[6], 7); + b = F1(b, c, d, a, X[7], 9); + a = F1(a, b, c, d, X[8], 11); + d = F1(d, a, b, c, X[9], 13); + c = F1(c, d, a, b, X[10], 14); + b = F1(b, c, d, a, X[11], 15); + a = F1(a, b, c, d, X[12], 6); + d = F1(d, a, b, c, X[13], 7); + c = F1(c, d, a, b, X[14], 9); + b = F1(b, c, d, a, X[15], 8); + + aa = FF4(aa, bb, cc, dd, X[5], 8); + dd = FF4(dd, aa, bb, cc, X[14], 9); + cc = FF4(cc, dd, aa, bb, X[7], 9); + bb = FF4(bb, cc, dd, aa, X[0], 11); + aa = FF4(aa, bb, cc, dd, X[9], 13); + dd = FF4(dd, aa, bb, cc, X[2], 15); + cc = FF4(cc, dd, aa, bb, X[11], 15); + bb = FF4(bb, cc, dd, aa, X[4], 5); + aa = FF4(aa, bb, cc, dd, X[13], 7); + dd = FF4(dd, aa, bb, cc, X[6], 7); + cc = FF4(cc, dd, aa, bb, X[15], 8); + bb = FF4(bb, cc, dd, aa, X[8], 11); + aa = FF4(aa, bb, cc, dd, X[1], 14); + dd = FF4(dd, aa, bb, cc, X[10], 14); + cc = FF4(cc, dd, aa, bb, X[3], 12); + bb = FF4(bb, cc, dd, aa, X[12], 6); + + t = a; a = aa; aa = t; + + // + // Round 2 + // + a = F2(a, b, c, d, X[7], 7); + d = F2(d, a, b, c, X[4], 6); + c = F2(c, d, a, b, X[13], 8); + b = F2(b, c, d, a, X[1], 13); + a = F2(a, b, c, d, X[10], 11); + d = F2(d, a, b, c, X[6], 9); + c = F2(c, d, a, b, X[15], 7); + b = F2(b, c, d, a, X[3], 15); + a = F2(a, b, c, d, X[12], 7); + d = F2(d, a, b, c, X[0], 12); + c = F2(c, d, a, b, X[9], 15); + b = F2(b, c, d, a, X[5], 9); + a = F2(a, b, c, d, X[2], 11); + d = F2(d, a, b, c, X[14], 7); + c = F2(c, d, a, b, X[11], 13); + b = F2(b, c, d, a, X[8], 12); + + aa = FF3(aa, bb, cc, dd, X[6], 9); + dd = FF3(dd, aa, bb, cc, X[11], 13); + cc = FF3(cc, dd, aa, bb, X[3], 15); + bb = FF3(bb, cc, dd, aa, X[7], 7); + aa = FF3(aa, bb, cc, dd, X[0], 12); + dd = FF3(dd, aa, bb, cc, X[13], 8); + cc = FF3(cc, dd, aa, bb, X[5], 9); + bb = FF3(bb, cc, dd, aa, X[10], 11); + aa = FF3(aa, bb, cc, dd, X[14], 7); + dd = FF3(dd, aa, bb, cc, X[15], 7); + cc = FF3(cc, dd, aa, bb, X[8], 12); + bb = FF3(bb, cc, dd, aa, X[12], 7); + aa = FF3(aa, bb, cc, dd, X[4], 6); + dd = FF3(dd, aa, bb, cc, X[9], 15); + cc = FF3(cc, dd, aa, bb, X[1], 13); + bb = FF3(bb, cc, dd, aa, X[2], 11); + + t = b; b = bb; bb = t; + + // + // Round 3 + // + a = F3(a, b, c, d, X[3], 11); + d = F3(d, a, b, c, X[10], 13); + c = F3(c, d, a, b, X[14], 6); + b = F3(b, c, d, a, X[4], 7); + a = F3(a, b, c, d, X[9], 14); + d = F3(d, a, b, c, X[15], 9); + c = F3(c, d, a, b, X[8], 13); + b = F3(b, c, d, a, X[1], 15); + a = F3(a, b, c, d, X[2], 14); + d = F3(d, a, b, c, X[7], 8); + c = F3(c, d, a, b, X[0], 13); + b = F3(b, c, d, a, X[6], 6); + a = F3(a, b, c, d, X[13], 5); + d = F3(d, a, b, c, X[11], 12); + c = F3(c, d, a, b, X[5], 7); + b = F3(b, c, d, a, X[12], 5); + + aa = FF2(aa, bb, cc, dd, X[15], 9); + dd = FF2(dd, aa, bb, cc, X[5], 7); + cc = FF2(cc, dd, aa, bb, X[1], 15); + bb = FF2(bb, cc, dd, aa, X[3], 11); + aa = FF2(aa, bb, cc, dd, X[7], 8); + dd = FF2(dd, aa, bb, cc, X[14], 6); + cc = FF2(cc, dd, aa, bb, X[6], 6); + bb = FF2(bb, cc, dd, aa, X[9], 14); + aa = FF2(aa, bb, cc, dd, X[11], 12); + dd = FF2(dd, aa, bb, cc, X[8], 13); + cc = FF2(cc, dd, aa, bb, X[12], 5); + bb = FF2(bb, cc, dd, aa, X[2], 14); + aa = FF2(aa, bb, cc, dd, X[10], 13); + dd = FF2(dd, aa, bb, cc, X[0], 13); + cc = FF2(cc, dd, aa, bb, X[4], 7); + bb = FF2(bb, cc, dd, aa, X[13], 5); + + t = c; c = cc; cc = t; + + // + // Round 4 + // + a = F4(a, b, c, d, X[1], 11); + d = F4(d, a, b, c, X[9], 12); + c = F4(c, d, a, b, X[11], 14); + b = F4(b, c, d, a, X[10], 15); + a = F4(a, b, c, d, X[0], 14); + d = F4(d, a, b, c, X[8], 15); + c = F4(c, d, a, b, X[12], 9); + b = F4(b, c, d, a, X[4], 8); + a = F4(a, b, c, d, X[13], 9); + d = F4(d, a, b, c, X[3], 14); + c = F4(c, d, a, b, X[7], 5); + b = F4(b, c, d, a, X[15], 6); + a = F4(a, b, c, d, X[14], 8); + d = F4(d, a, b, c, X[5], 6); + c = F4(c, d, a, b, X[6], 5); + b = F4(b, c, d, a, X[2], 12); + + aa = FF1(aa, bb, cc, dd, X[8], 15); + dd = FF1(dd, aa, bb, cc, X[6], 5); + cc = FF1(cc, dd, aa, bb, X[4], 8); + bb = FF1(bb, cc, dd, aa, X[1], 11); + aa = FF1(aa, bb, cc, dd, X[3], 14); + dd = FF1(dd, aa, bb, cc, X[11], 14); + cc = FF1(cc, dd, aa, bb, X[15], 6); + bb = FF1(bb, cc, dd, aa, X[0], 14); + aa = FF1(aa, bb, cc, dd, X[5], 6); + dd = FF1(dd, aa, bb, cc, X[12], 9); + cc = FF1(cc, dd, aa, bb, X[2], 12); + bb = FF1(bb, cc, dd, aa, X[13], 9); + aa = FF1(aa, bb, cc, dd, X[9], 12); + dd = FF1(dd, aa, bb, cc, X[7], 5); + cc = FF1(cc, dd, aa, bb, X[10], 15); + bb = FF1(bb, cc, dd, aa, X[14], 8); + + t = d; d = dd; dd = t; + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += aa; + H5 += bb; + H6 += cc; + H7 += dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD256Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD256Digest d = (RipeMD256Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs.meta new file mode 100644 index 0000000..5372ac3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD256Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bf8ef59bb0f190a478b67b9040e142f6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs new file mode 100644 index 0000000..8badbb2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs @@ -0,0 +1,463 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + ///

Implementation of RipeMD 320.

+ ///

Note: this algorithm offers the same level of security as RipeMD160.

+ ///
+ public class RipeMD320Digest + : GeneralDigest + { + public override string AlgorithmName + { + get { return "RIPEMD320"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + private const int DigestLength = 40; + + private int H0, H1, H2, H3, H4, H5, H6, H7, H8, H9; // IV's + + private int[] X = new int[16]; + private int xOff; + + /// Standard constructor + public RipeMD320Digest() + { + Reset(); + } + + /// Copy constructor. This will copy the state of the provided + /// message digest. + /// + public RipeMD320Digest(RipeMD320Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD320Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + H9 = t.H9; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong)bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint)word >> 8); + outBytes[outOff + 2] = (byte)((uint)word >> 16); + outBytes[outOff + 3] = (byte)((uint)word >> 24); + } + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + UnpackWord(H5, output, outOff + 20); + UnpackWord(H6, output, outOff + 24); + UnpackWord(H7, output, outOff + 28); + UnpackWord(H8, output, outOff + 32); + UnpackWord(H9, output, outOff + 36); + + Reset(); + + return DigestLength; + } + + /// reset the chaining variables to the IV values. + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + H4 = unchecked((int) 0xc3d2e1f0); + H5 = unchecked((int) 0x76543210); + H6 = unchecked((int) 0xFEDCBA98); + H7 = unchecked((int) 0x89ABCDEF); + H8 = unchecked((int) 0x01234567); + H9 = unchecked((int) 0x3C2D1E0F); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int)(((uint)x) >> (32 - n)); + } + + /* + * f1,f2,f3,f4,f5 are the basic RipeMD160 functions. + */ + + /* + * rounds 0-15 + */ + private int F1(int x, int y, int z) + { + return x ^ y ^ z; + } + + /* + * rounds 16-31 + */ + private int F2(int x, int y, int z) + { + return (x & y) | (~ x & z); + } + + /* + * rounds 32-47 + */ + private int F3(int x, int y, int z) + { + return (x | ~ y) ^ z; + } + + /* + * rounds 48-63 + */ + private int F4(int x, int y, int z) + { + return (x & z) | (y & ~ z); + } + + /* + * rounds 64-79 + */ + private int F5(int x, int y, int z) + { + return x ^ (y | ~z); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int e, ee; + int t; + + a = H0; + b = H1; + c = H2; + d = H3; + e = H4; + aa = H5; + bb = H6; + cc = H7; + dd = H8; + ee = H9; + + // + // Rounds 1 - 16 + // + // left + a = RL(a + F1(b, c, d) + X[0], 11) + e; c = RL(c, 10); + e = RL(e + F1(a, b, c) + X[1], 14) + d; b = RL(b, 10); + d = RL(d + F1(e, a, b) + X[2], 15) + c; a = RL(a, 10); + c = RL(c + F1(d, e, a) + X[3], 12) + b; e = RL(e, 10); + b = RL(b + F1(c, d, e) + X[4], 5) + a; d = RL(d, 10); + a = RL(a + F1(b, c, d) + X[5], 8) + e; c = RL(c, 10); + e = RL(e + F1(a, b, c) + X[6], 7) + d; b = RL(b, 10); + d = RL(d + F1(e, a, b) + X[7], 9) + c; a = RL(a, 10); + c = RL(c + F1(d, e, a) + X[8], 11) + b; e = RL(e, 10); + b = RL(b + F1(c, d, e) + X[9], 13) + a; d = RL(d, 10); + a = RL(a + F1(b, c, d) + X[10], 14) + e; c = RL(c, 10); + e = RL(e + F1(a, b, c) + X[11], 15) + d; b = RL(b, 10); + d = RL(d + F1(e, a, b) + X[12], 6) + c; a = RL(a, 10); + c = RL(c + F1(d, e, a) + X[13], 7) + b; e = RL(e, 10); + b = RL(b + F1(c, d, e) + X[14], 9) + a; d = RL(d, 10); + a = RL(a + F1(b, c, d) + X[15], 8) + e; c = RL(c, 10); + + // right + aa = RL(aa + F5(bb, cc, dd) + X[5] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa, bb, cc) + X[14] + unchecked((int)0x50a28be6), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee, aa, bb) + X[7] + unchecked((int)0x50a28be6), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd, ee, aa) + X[0] + unchecked((int)0x50a28be6), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc, dd, ee) + X[9] + unchecked((int)0x50a28be6), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb, cc, dd) + X[2] + unchecked((int)0x50a28be6), 15) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa, bb, cc) + X[11] + unchecked((int)0x50a28be6), 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee, aa, bb) + X[4] + unchecked((int)0x50a28be6), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd, ee, aa) + X[13] + unchecked((int)0x50a28be6), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc, dd, ee) + X[6] + unchecked((int)0x50a28be6), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb, cc, dd) + X[15] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa, bb, cc) + X[8] + unchecked((int)0x50a28be6), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee, aa, bb) + X[1] + unchecked((int)0x50a28be6), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd, ee, aa) + X[10] + unchecked((int)0x50a28be6), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc, dd, ee) + X[3] + unchecked((int)0x50a28be6), 12) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb, cc, dd) + X[12] + unchecked((int)0x50a28be6), 6) + ee; cc = RL(cc, 10); + + t = a; a = aa; aa = t; + // + // Rounds 16-31 + // + // left + e = RL(e + F2(a, b, c) + X[7] + unchecked((int)0x5a827999), 7) + d; b = RL(b, 10); + d = RL(d + F2(e, a, b) + X[4] + unchecked((int)0x5a827999), 6) + c; a = RL(a, 10); + c = RL(c + F2(d, e, a) + X[13] + unchecked((int)0x5a827999), 8) + b; e = RL(e, 10); + b = RL(b + F2(c, d, e) + X[1] + unchecked((int)0x5a827999), 13) + a; d = RL(d, 10); + a = RL(a + F2(b, c, d) + X[10] + unchecked((int)0x5a827999), 11) + e; c = RL(c, 10); + e = RL(e + F2(a, b, c) + X[6] + unchecked((int)0x5a827999), 9) + d; b = RL(b, 10); + d = RL(d + F2(e, a, b) + X[15] + unchecked((int)0x5a827999), 7) + c; a = RL(a, 10); + c = RL(c + F2(d, e, a) + X[3] + unchecked((int)0x5a827999), 15) + b; e = RL(e, 10); + b = RL(b + F2(c, d, e) + X[12] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b, c, d) + X[0] + unchecked((int)0x5a827999), 12) + e; c = RL(c, 10); + e = RL(e + F2(a, b, c) + X[9] + unchecked((int)0x5a827999), 15) + d; b = RL(b, 10); + d = RL(d + F2(e, a, b) + X[5] + unchecked((int)0x5a827999), 9) + c; a = RL(a, 10); + c = RL(c + F2(d, e, a) + X[2] + unchecked((int)0x5a827999), 11) + b; e = RL(e, 10); + b = RL(b + F2(c, d, e) + X[14] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b, c, d) + X[11] + unchecked((int)0x5a827999), 13) + e; c = RL(c, 10); + e = RL(e + F2(a, b, c) + X[8] + unchecked((int)0x5a827999), 12) + d; b = RL(b, 10); + + // right + ee = RL(ee + F4(aa, bb, cc) + X[6] + unchecked((int)0x5c4dd124), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee, aa, bb) + X[11] + unchecked((int)0x5c4dd124), 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd, ee, aa) + X[3] + unchecked((int)0x5c4dd124), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc, dd, ee) + X[7] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb, cc, dd) + X[0] + unchecked((int)0x5c4dd124), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa, bb, cc) + X[13] + unchecked((int)0x5c4dd124), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee, aa, bb) + X[5] + unchecked((int)0x5c4dd124), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd, ee, aa) + X[10] + unchecked((int)0x5c4dd124), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc, dd, ee) + X[14] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb, cc, dd) + X[15] + unchecked((int)0x5c4dd124), 7) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa, bb, cc) + X[8] + unchecked((int)0x5c4dd124), 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee, aa, bb) + X[12] + unchecked((int)0x5c4dd124), 7) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd, ee, aa) + X[4] + unchecked((int)0x5c4dd124), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc, dd, ee) + X[9] + unchecked((int)0x5c4dd124), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb, cc, dd) + X[1] + unchecked((int)0x5c4dd124), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa, bb, cc) + X[2] + unchecked((int)0x5c4dd124), 11) + dd; bb = RL(bb, 10); + + t = b; b = bb; bb = t; + + // + // Rounds 32-47 + // + // left + d = RL(d + F3(e, a, b) + X[3] + unchecked((int)0x6ed9eba1), 11) + c; a = RL(a, 10); + c = RL(c + F3(d, e, a) + X[10] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c, d, e) + X[14] + unchecked((int)0x6ed9eba1), 6) + a; d = RL(d, 10); + a = RL(a + F3(b, c, d) + X[4] + unchecked((int)0x6ed9eba1), 7) + e; c = RL(c, 10); + e = RL(e + F3(a, b, c) + X[9] + unchecked((int)0x6ed9eba1), 14) + d; b = RL(b, 10); + d = RL(d + F3(e, a, b) + X[15] + unchecked((int)0x6ed9eba1), 9) + c; a = RL(a, 10); + c = RL(c + F3(d, e, a) + X[8] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c, d, e) + X[1] + unchecked((int)0x6ed9eba1), 15) + a; d = RL(d, 10); + a = RL(a + F3(b, c, d) + X[2] + unchecked((int)0x6ed9eba1), 14) + e; c = RL(c, 10); + e = RL(e + F3(a, b, c) + X[7] + unchecked((int)0x6ed9eba1), 8) + d; b = RL(b, 10); + d = RL(d + F3(e, a, b) + X[0] + unchecked((int)0x6ed9eba1), 13) + c; a = RL(a, 10); + c = RL(c + F3(d, e, a) + X[6] + unchecked((int)0x6ed9eba1), 6) + b; e = RL(e, 10); + b = RL(b + F3(c, d, e) + X[13] + unchecked((int)0x6ed9eba1), 5) + a; d = RL(d, 10); + a = RL(a + F3(b, c, d) + X[11] + unchecked((int)0x6ed9eba1), 12) + e; c = RL(c, 10); + e = RL(e + F3(a, b, c) + X[5] + unchecked((int)0x6ed9eba1), 7) + d; b = RL(b, 10); + d = RL(d + F3(e, a, b) + X[12] + unchecked((int)0x6ed9eba1), 5) + c; a = RL(a, 10); + + // right + dd = RL(dd + F3(ee, aa, bb) + X[15] + unchecked((int)0x6d703ef3), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd, ee, aa) + X[5] + unchecked((int)0x6d703ef3), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc, dd, ee) + X[1] + unchecked((int)0x6d703ef3), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb, cc, dd) + X[3] + unchecked((int)0x6d703ef3), 11) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa, bb, cc) + X[7] + unchecked((int)0x6d703ef3), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee, aa, bb) + X[14] + unchecked((int)0x6d703ef3), 6) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd, ee, aa) + X[6] + unchecked((int)0x6d703ef3), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc, dd, ee) + X[9] + unchecked((int)0x6d703ef3), 14) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb, cc, dd) + X[11] + unchecked((int)0x6d703ef3), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa, bb, cc) + X[8] + unchecked((int)0x6d703ef3), 13) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee, aa, bb) + X[12] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd, ee, aa) + X[2] + unchecked((int)0x6d703ef3), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc, dd, ee) + X[10] + unchecked((int)0x6d703ef3), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb, cc, dd) + X[0] + unchecked((int)0x6d703ef3), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa, bb, cc) + X[4] + unchecked((int)0x6d703ef3), 7) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee, aa, bb) + X[13] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10); + + t = c; c = cc; cc = t; + + // + // Rounds 48-63 + // + // left + c = RL(c + F4(d, e, a) + X[1] + unchecked((int)0x8f1bbcdc), 11) + b; e = RL(e, 10); + b = RL(b + F4(c, d, e) + X[9] + unchecked((int)0x8f1bbcdc), 12) + a; d = RL(d, 10); + a = RL(a + F4(b, c, d) + X[11] + unchecked((int)0x8f1bbcdc), 14) + e; c = RL(c, 10); + e = RL(e + F4(a, b, c) + X[10] + unchecked((int)0x8f1bbcdc), 15) + d; b = RL(b, 10); + d = RL(d + F4(e, a, b) + X[0] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d, e, a) + X[8] + unchecked((int)0x8f1bbcdc), 15) + b; e = RL(e, 10); + b = RL(b + F4(c, d, e) + X[12] + unchecked((int)0x8f1bbcdc), 9) + a; d = RL(d, 10); + a = RL(a + F4(b, c, d) + X[4] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a, b, c) + X[13] + unchecked((int)0x8f1bbcdc), 9) + d; b = RL(b, 10); + d = RL(d + F4(e, a, b) + X[3] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d, e, a) + X[7] + unchecked((int)0x8f1bbcdc), 5) + b; e = RL(e, 10); + b = RL(b + F4(c, d, e) + X[15] + unchecked((int)0x8f1bbcdc), 6) + a; d = RL(d, 10); + a = RL(a + F4(b, c, d) + X[14] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a, b, c) + X[5] + unchecked((int)0x8f1bbcdc), 6) + d; b = RL(b, 10); + d = RL(d + F4(e, a, b) + X[6] + unchecked((int)0x8f1bbcdc), 5) + c; a = RL(a, 10); + c = RL(c + F4(d, e, a) + X[2] + unchecked((int)0x8f1bbcdc), 12) + b; e = RL(e, 10); + + // right + cc = RL(cc + F2(dd, ee, aa) + X[8] + unchecked((int)0x7a6d76e9), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc, dd, ee) + X[6] + unchecked((int)0x7a6d76e9), 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb, cc, dd) + X[4] + unchecked((int)0x7a6d76e9), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa, bb, cc) + X[1] + unchecked((int)0x7a6d76e9), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee, aa, bb) + X[3] + unchecked((int)0x7a6d76e9), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd, ee, aa) + X[11] + unchecked((int)0x7a6d76e9), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc, dd, ee) + X[15] + unchecked((int)0x7a6d76e9), 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb, cc, dd) + X[0] + unchecked((int)0x7a6d76e9), 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa, bb, cc) + X[5] + unchecked((int)0x7a6d76e9), 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee, aa, bb) + X[12] + unchecked((int)0x7a6d76e9), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd, ee, aa) + X[2] + unchecked((int)0x7a6d76e9), 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc, dd, ee) + X[13] + unchecked((int)0x7a6d76e9), 9) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb, cc, dd) + X[9] + unchecked((int)0x7a6d76e9), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa, bb, cc) + X[7] + unchecked((int)0x7a6d76e9), 5) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee, aa, bb) + X[10] + unchecked((int)0x7a6d76e9), 15) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd, ee, aa) + X[14] + unchecked((int)0x7a6d76e9), 8) + bb; ee = RL(ee, 10); + + t = d; d = dd; dd = t; + + // + // Rounds 64-79 + // + // left + b = RL(b + F5(c, d, e) + X[4] + unchecked((int)0xa953fd4e), 9) + a; d = RL(d, 10); + a = RL(a + F5(b, c, d) + X[0] + unchecked((int)0xa953fd4e), 15) + e; c = RL(c, 10); + e = RL(e + F5(a, b, c) + X[5] + unchecked((int)0xa953fd4e), 5) + d; b = RL(b, 10); + d = RL(d + F5(e, a, b) + X[9] + unchecked((int)0xa953fd4e), 11) + c; a = RL(a, 10); + c = RL(c + F5(d, e, a) + X[7] + unchecked((int)0xa953fd4e), 6) + b; e = RL(e, 10); + b = RL(b + F5(c, d, e) + X[12] + unchecked((int)0xa953fd4e), 8) + a; d = RL(d, 10); + a = RL(a + F5(b, c, d) + X[2] + unchecked((int)0xa953fd4e), 13) + e; c = RL(c, 10); + e = RL(e + F5(a, b, c) + X[10] + unchecked((int)0xa953fd4e), 12) + d; b = RL(b, 10); + d = RL(d + F5(e, a, b) + X[14] + unchecked((int)0xa953fd4e), 5) + c; a = RL(a, 10); + c = RL(c + F5(d, e, a) + X[1] + unchecked((int)0xa953fd4e), 12) + b; e = RL(e, 10); + b = RL(b + F5(c, d, e) + X[3] + unchecked((int)0xa953fd4e), 13) + a; d = RL(d, 10); + a = RL(a + F5(b, c, d) + X[8] + unchecked((int)0xa953fd4e), 14) + e; c = RL(c, 10); + e = RL(e + F5(a, b, c) + X[11] + unchecked((int)0xa953fd4e), 11) + d; b = RL(b, 10); + d = RL(d + F5(e, a, b) + X[6] + unchecked((int)0xa953fd4e), 8) + c; a = RL(a, 10); + c = RL(c + F5(d, e, a) + X[15] + unchecked((int)0xa953fd4e), 5) + b; e = RL(e, 10); + b = RL(b + F5(c, d, e) + X[13] + unchecked((int)0xa953fd4e), 6) + a; d = RL(d, 10); + + // right + bb = RL(bb + F1(cc, dd, ee) + X[12], 8) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb, cc, dd) + X[15], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa, bb, cc) + X[10], 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee, aa, bb) + X[4], 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd, ee, aa) + X[1], 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc, dd, ee) + X[5], 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb, cc, dd) + X[8], 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa, bb, cc) + X[7], 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee, aa, bb) + X[6], 8) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd, ee, aa) + X[2], 13) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc, dd, ee) + X[13], 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb, cc, dd) + X[14], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa, bb, cc) + X[0], 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee, aa, bb) + X[3], 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd, ee, aa) + X[9], 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc, dd, ee) + X[11], 11) + aa; dd = RL(dd, 10); + + // + // do (e, ee) swap as part of assignment. + // + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += ee; + H5 += aa; + H6 += bb; + H7 += cc; + H8 += dd; + H9 += e; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD320Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD320Digest d = (RipeMD320Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs.meta new file mode 100644 index 0000000..ea7b5b7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/RipeMD320Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4d7606c4169527a4bb35054b933733a3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs new file mode 100644 index 0000000..2276d87 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs @@ -0,0 +1,90 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// Implementation of SHA-3 based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ + /// + /// + /// Following the naming conventions used in the C source code to enable easy review of the implementation. + /// + public class Sha3Digest + : KeccakDigest + { + private static int CheckBitLength(int bitLength) + { + switch (bitLength) + { + case 224: + case 256: + case 384: + case 512: + return bitLength; + default: + throw new ArgumentException(bitLength + " not supported for SHA-3", "bitLength"); + } + } + + public Sha3Digest() + : this(256) + { + } + + public Sha3Digest(int bitLength) + : base(CheckBitLength(bitLength)) + { + } + + public Sha3Digest(Sha3Digest source) + : base(source) + { + } + + public override string AlgorithmName + { + get { return "SHA3-" + fixedOutputLength; } + } + + public override int DoFinal(byte[] output, int outOff) + { + Absorb(new byte[]{ 0x02 }, 0, 2); + + return base.DoFinal(output, outOff); + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits) + { + if (partialBits < 0 || partialBits > 7) + throw new ArgumentException("must be in the range [0,7]", "partialBits"); + + int finalInput = (partialByte & ((1 << partialBits) - 1)) | (0x02 << partialBits); + Debug.Assert(finalInput >= 0); + int finalBits = partialBits + 2; + + if (finalBits >= 8) + { + oneByte[0] = (byte)finalInput; + Absorb(oneByte, 0, 8); + finalBits -= 8; + finalInput >>= 8; + } + + return base.DoFinal(output, outOff, (byte)finalInput, finalBits); + } + + public override IMemoable Copy() + { + return new Sha3Digest(this); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs.meta new file mode 100644 index 0000000..7c58eba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/SHA3Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 21c525f413c2cbb458589e2c761f3c7e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs new file mode 100644 index 0000000..f2f0426 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs @@ -0,0 +1,288 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /** + * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349. + * + * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5 + * is the "endianness" of the word processing! + */ + public class Sha1Digest + : GeneralDigest + { + private const int DigestLength = 20; + + private uint H1, H2, H3, H4, H5; + + private uint[] X = new uint[80]; + private int xOff; + + public Sha1Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha1Digest(Sha1Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(Sha1Digest t) + { + base.CopyIn(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-1"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.BE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength(long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (uint)((ulong)bitLength >> 32); + X[15] = (uint)((ulong)bitLength); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_BE(H1, output, outOff); + Pack.UInt32_To_BE(H2, output, outOff + 4); + Pack.UInt32_To_BE(H3, output, outOff + 8); + Pack.UInt32_To_BE(H4, output, outOff + 12); + Pack.UInt32_To_BE(H5, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + H5 = 0xc3d2e1f0; + + xOff = 0; + Array.Clear(X, 0, X.Length); + } + + // + // Additive constants + // + private const uint Y1 = 0x5a827999; + private const uint Y2 = 0x6ed9eba1; + private const uint Y3 = 0x8f1bbcdc; + private const uint Y4 = 0xca62c1d6; + + private static uint F(uint u, uint v, uint w) + { + return (u & v) | (~u & w); + } + + private static uint H(uint u, uint v, uint w) + { + return u ^ v ^ w; + } + + private static uint G(uint u, uint v, uint w) + { + return (u & v) | (u & w) | (v & w); + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 80 word block. + // + for (int i = 16; i < 80; i++) + { + uint t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]; + X[i] = t << 1 | t >> 31; + } + + // + // set up working variables. + // + uint A = H1; + uint B = H2; + uint C = H3; + uint D = H4; + uint E = H5; + + // + // round 1 + // + int idx = 0; + + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + F(B, C, D) + X[idx++] + Y1; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + F(A, B, C) + X[idx++] + Y1; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + F(E, A, B) + X[idx++] + Y1; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + F(D, E, A) + X[idx++] + Y1; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + F(C, D, E) + X[idx++] + Y1; + C = C << 30 | (C >> 2); + } + + // + // round 2 + // + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + H(B, C, D) + X[idx++] + Y2; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + H(A, B, C) + X[idx++] + Y2; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + H(E, A, B) + X[idx++] + Y2; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + H(D, E, A) + X[idx++] + Y2; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + H(C, D, E) + X[idx++] + Y2; + C = C << 30 | (C >> 2); + } + + // + // round 3 + // + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + G(B, C, D) + X[idx++] + Y3; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + G(A, B, C) + X[idx++] + Y3; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + G(E, A, B) + X[idx++] + Y3; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + G(D, E, A) + X[idx++] + Y3; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + G(C, D, E) + X[idx++] + Y3; + C = C << 30 | (C >> 2); + } + + // + // round 4 + // + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + H(B, C, D) + X[idx++] + Y4; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + H(A, B, C) + X[idx++] + Y4; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + H(E, A, B) + X[idx++] + Y4; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + H(D, E, A) + X[idx++] + Y4; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + H(C, D, E) + X[idx++] + Y4; + C = C << 30 | (C >> 2); + } + + H1 += A; + H2 += B; + H3 += C; + H4 += D; + H5 += E; + + // + // reset start of the buffer. + // + xOff = 0; + Array.Clear(X, 0, 16); + } + + public override IMemoable Copy() + { + return new Sha1Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha1Digest d = (Sha1Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs.meta new file mode 100644 index 0000000..575e774 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha1Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7ef8d80a00e8bb34093e8e8925dcd039 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs new file mode 100644 index 0000000..9031277 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs @@ -0,0 +1,293 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * SHA-224 as described in RFC 3874 + *
+     *         block  word  digest
+     * SHA-1   512    32    160
+     * SHA-224 512    32    224
+     * SHA-256 512    32    256
+     * SHA-384 1024   64    384
+     * SHA-512 1024   64    512
+     * 
+ */ + public class Sha224Digest + : GeneralDigest + { + private const int DigestLength = 28; + + private uint H1, H2, H3, H4, H5, H6, H7, H8; + + private uint[] X = new uint[64]; + private int xOff; + + /** + * Standard constructor + */ + public Sha224Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha224Digest( + Sha224Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(Sha224Digest t) + { + base.CopyIn(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-224"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.BE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (uint)((ulong)bitLength >> 32); + X[15] = (uint)((ulong)bitLength); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_BE(H1, output, outOff); + Pack.UInt32_To_BE(H2, output, outOff + 4); + Pack.UInt32_To_BE(H3, output, outOff + 8); + Pack.UInt32_To_BE(H4, output, outOff + 12); + Pack.UInt32_To_BE(H5, output, outOff + 16); + Pack.UInt32_To_BE(H6, output, outOff + 20); + Pack.UInt32_To_BE(H7, output, outOff + 24); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-224 initial hash value + */ + H1 = 0xc1059ed8; + H2 = 0x367cd507; + H3 = 0x3070dd17; + H4 = 0xf70e5939; + H5 = 0xffc00b31; + H6 = 0x68581511; + H7 = 0x64f98fa7; + H8 = 0xbefa4fa4; + + xOff = 0; + Array.Clear(X, 0, X.Length); + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 64 word blocks. + // + for (int ti = 16; ti <= 63; ti++) + { + X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16]; + } + + // + // set up working variables. + // + uint a = H1; + uint b = H2; + uint c = H3; + uint d = H4; + uint e = H5; + uint f = H6; + uint g = H7; + uint h = H8; + + int t = 0; + for(int i = 0; i < 8; i ++) + { + // t = 8 * i + h += Sum1(e) + Ch(e, f, g) + K[t] + X[t]; + d += h; + h += Sum0(a) + Maj(a, b, c); + ++t; + + // t = 8 * i + 1 + g += Sum1(d) + Ch(d, e, f) + K[t] + X[t]; + c += g; + g += Sum0(h) + Maj(h, a, b); + ++t; + + // t = 8 * i + 2 + f += Sum1(c) + Ch(c, d, e) + K[t] + X[t]; + b += f; + f += Sum0(g) + Maj(g, h, a); + ++t; + + // t = 8 * i + 3 + e += Sum1(b) + Ch(b, c, d) + K[t] + X[t]; + a += e; + e += Sum0(f) + Maj(f, g, h); + ++t; + + // t = 8 * i + 4 + d += Sum1(a) + Ch(a, b, c) + K[t] + X[t]; + h += d; + d += Sum0(e) + Maj(e, f, g); + ++t; + + // t = 8 * i + 5 + c += Sum1(h) + Ch(h, a, b) + K[t] + X[t]; + g += c; + c += Sum0(d) + Maj(d, e, f); + ++t; + + // t = 8 * i + 6 + b += Sum1(g) + Ch(g, h, a) + K[t] + X[t]; + f += b; + b += Sum0(c) + Maj(c, d, e); + ++t; + + // t = 8 * i + 7 + a += Sum1(f) + Ch(f, g, h) + K[t] + X[t]; + e += a; + a += Sum0(b) + Maj(b, c, d); + ++t; + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + Array.Clear(X, 0, 16); + } + + /* SHA-224 functions */ + private static uint Ch(uint x, uint y, uint z) + { + return (x & y) ^ (~x & z); + } + + private static uint Maj(uint x, uint y, uint z) + { + return (x & y) ^ (x & z) ^ (y & z); + } + + private static uint Sum0(uint x) + { + return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)); + } + + private static uint Sum1(uint x) + { + return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)); + } + + private static uint Theta0(uint x) + { + return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3); + } + + private static uint Theta1(uint x) + { + return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10); + } + + /* SHA-224 Constants + * (represent the first 32 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + internal static readonly uint[] K = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + + public override IMemoable Copy() + { + return new Sha224Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha224Digest d = (Sha224Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs.meta new file mode 100644 index 0000000..afeeeb0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha224Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 030ee55485af2ee4985a31227e05de47 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs new file mode 100644 index 0000000..de4a070 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs @@ -0,0 +1,334 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-256. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+    *         block  word  digest
+    * SHA-1   512    32    160
+    * SHA-256 512    32    256
+    * SHA-384 1024   64    384
+    * SHA-512 1024   64    512
+    * 
+ */ + public class Sha256Digest + : GeneralDigest + { + private const int DigestLength = 32; + + private uint H1, H2, H3, H4, H5, H6, H7, H8; + private uint[] X = new uint[64]; + private int xOff; + + public Sha256Digest() + { + initHs(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha256Digest(Sha256Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(Sha256Digest t) + { + base.CopyIn(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-256"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.BE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (uint)((ulong)bitLength >> 32); + X[15] = (uint)((ulong)bitLength); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_BE((uint)H1, output, outOff); + Pack.UInt32_To_BE((uint)H2, output, outOff + 4); + Pack.UInt32_To_BE((uint)H3, output, outOff + 8); + Pack.UInt32_To_BE((uint)H4, output, outOff + 12); + Pack.UInt32_To_BE((uint)H5, output, outOff + 16); + Pack.UInt32_To_BE((uint)H6, output, outOff + 20); + Pack.UInt32_To_BE((uint)H7, output, outOff + 24); + Pack.UInt32_To_BE((uint)H8, output, outOff + 28); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + initHs(); + + xOff = 0; + Array.Clear(X, 0, X.Length); + } + + private void initHs() + { + /* SHA-256 initial hash value + * The first 32 bits of the fractional parts of the square roots + * of the first eight prime numbers + */ + H1 = 0x6a09e667; + H2 = 0xbb67ae85; + H3 = 0x3c6ef372; + H4 = 0xa54ff53a; + H5 = 0x510e527f; + H6 = 0x9b05688c; + H7 = 0x1f83d9ab; + H8 = 0x5be0cd19; + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 64 word blocks. + // + for (int ti = 16; ti <= 63; ti++) + { + X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16]; + } + + // + // set up working variables. + // + uint a = H1; + uint b = H2; + uint c = H3; + uint d = H4; + uint e = H5; + uint f = H6; + uint g = H7; + uint h = H8; + + int t = 0; + for(int i = 0; i < 8; ++i) + { + // t = 8 * i + h += Sum1Ch(e, f, g) + K[t] + X[t]; + d += h; + h += Sum0Maj(a, b, c); + ++t; + + // t = 8 * i + 1 + g += Sum1Ch(d, e, f) + K[t] + X[t]; + c += g; + g += Sum0Maj(h, a, b); + ++t; + + // t = 8 * i + 2 + f += Sum1Ch(c, d, e) + K[t] + X[t]; + b += f; + f += Sum0Maj(g, h, a); + ++t; + + // t = 8 * i + 3 + e += Sum1Ch(b, c, d) + K[t] + X[t]; + a += e; + e += Sum0Maj(f, g, h); + ++t; + + // t = 8 * i + 4 + d += Sum1Ch(a, b, c) + K[t] + X[t]; + h += d; + d += Sum0Maj(e, f, g); + ++t; + + // t = 8 * i + 5 + c += Sum1Ch(h, a, b) + K[t] + X[t]; + g += c; + c += Sum0Maj(d, e, f); + ++t; + + // t = 8 * i + 6 + b += Sum1Ch(g, h, a) + K[t] + X[t]; + f += b; + b += Sum0Maj(c, d, e); + ++t; + + // t = 8 * i + 7 + a += Sum1Ch(f, g, h) + K[t] + X[t]; + e += a; + a += Sum0Maj(b, c, d); + ++t; + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + Array.Clear(X, 0, 16); + } + + private static uint Sum1Ch( + uint x, + uint y, + uint z) + { +// return Sum1(x) + Ch(x, y, z); + return (((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))) + + ((x & y) ^ ((~x) & z)); + } + + private static uint Sum0Maj( + uint x, + uint y, + uint z) + { +// return Sum0(x) + Maj(x, y, z); + return (((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))) + + ((x & y) ^ (x & z) ^ (y & z)); + } + +// /* SHA-256 functions */ +// private static uint Ch( +// uint x, +// uint y, +// uint z) +// { +// return ((x & y) ^ ((~x) & z)); +// } +// +// private static uint Maj( +// uint x, +// uint y, +// uint z) +// { +// return ((x & y) ^ (x & z) ^ (y & z)); +// } +// +// private static uint Sum0( +// uint x) +// { +// return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)); +// } +// +// private static uint Sum1( +// uint x) +// { +// return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)); +// } + + private static uint Theta0( + uint x) + { + return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3); + } + + private static uint Theta1( + uint x) + { + return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10); + } + + /* SHA-256 Constants + * (represent the first 32 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + private static readonly uint[] K = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + + public override IMemoable Copy() + { + return new Sha256Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha256Digest d = (Sha256Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs.meta new file mode 100644 index 0000000..a736b31 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha256Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1c1f505a2c38e354a832ffbf8fbcbd63 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs new file mode 100644 index 0000000..7da656b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-384. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+     *         block  word  digest
+     * SHA-1   512    32    160
+     * SHA-256 512    32    256
+     * SHA-384 1024   64    384
+     * SHA-512 1024   64    512
+     * 
+ */ + public class Sha384Digest + : LongDigest + { + private const int DigestLength = 48; + + public Sha384Digest() + { + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha384Digest( + Sha384Digest t) + : base(t) + { + } + + public override string AlgorithmName + { + get { return "SHA-384"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt64_To_BE(H1, output, outOff); + Pack.UInt64_To_BE(H2, output, outOff + 8); + Pack.UInt64_To_BE(H3, output, outOff + 16); + Pack.UInt64_To_BE(H4, output, outOff + 24); + Pack.UInt64_To_BE(H5, output, outOff + 32); + Pack.UInt64_To_BE(H6, output, outOff + 40); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-384 initial hash value + * The first 64 bits of the fractional parts of the square roots + * of the 9th through 16th prime numbers + */ + H1 = 0xcbbb9d5dc1059ed8; + H2 = 0x629a292a367cd507; + H3 = 0x9159015a3070dd17; + H4 = 0x152fecd8f70e5939; + H5 = 0x67332667ffc00b31; + H6 = 0x8eb44a8768581511; + H7 = 0xdb0c2e0d64f98fa7; + H8 = 0x47b5481dbefa4fa4; + } + + public override IMemoable Copy() + { + return new Sha384Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha384Digest d = (Sha384Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs.meta new file mode 100644 index 0000000..cb8758d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha384Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 202b9c65c2b4bf3429962b5c945902a0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs new file mode 100644 index 0000000..b4a29da --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-512. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+     *         block  word  digest
+     * SHA-1   512    32    160
+     * SHA-256 512    32    256
+     * SHA-384 1024   64    384
+     * SHA-512 1024   64    512
+     * 
+ */ + public class Sha512Digest + : LongDigest + { + private const int DigestLength = 64; + + public Sha512Digest() + { + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha512Digest( + Sha512Digest t) + : base(t) + { + } + + public override string AlgorithmName + { + get { return "SHA-512"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt64_To_BE(H1, output, outOff); + Pack.UInt64_To_BE(H2, output, outOff + 8); + Pack.UInt64_To_BE(H3, output, outOff + 16); + Pack.UInt64_To_BE(H4, output, outOff + 24); + Pack.UInt64_To_BE(H5, output, outOff + 32); + Pack.UInt64_To_BE(H6, output, outOff + 40); + Pack.UInt64_To_BE(H7, output, outOff + 48); + Pack.UInt64_To_BE(H8, output, outOff + 56); + + Reset(); + + return DigestLength; + + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-512 initial hash value + * The first 64 bits of the fractional parts of the square roots + * of the first eight prime numbers + */ + H1 = 0x6a09e667f3bcc908; + H2 = 0xbb67ae8584caa73b; + H3 = 0x3c6ef372fe94f82b; + H4 = 0xa54ff53a5f1d36f1; + H5 = 0x510e527fade682d1; + H6 = 0x9b05688c2b3e6c1f; + H7 = 0x1f83d9abfb41bd6b; + H8 = 0x5be0cd19137e2179; + } + + public override IMemoable Copy() + { + return new Sha512Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha512Digest d = (Sha512Digest)other; + + CopyIn(d); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs.meta new file mode 100644 index 0000000..ec11726 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512Digest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4adbb7dfd7c2c4f41ba95f6affb474dc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs new file mode 100644 index 0000000..aa41b66 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs @@ -0,0 +1,204 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * FIPS 180-4 implementation of SHA-512/t + */ + public class Sha512tDigest + : LongDigest + { + private const ulong A5 = 0xa5a5a5a5a5a5a5a5UL; + + private readonly int digestLength; + + private ulong H1t, H2t, H3t, H4t, H5t, H6t, H7t, H8t; + + /** + * Standard constructor + */ + public Sha512tDigest(int bitLength) + { + if (bitLength >= 512) + throw new ArgumentException("cannot be >= 512", "bitLength"); + if (bitLength % 8 != 0) + throw new ArgumentException("needs to be a multiple of 8", "bitLength"); + if (bitLength == 384) + throw new ArgumentException("cannot be 384 use SHA384 instead", "bitLength"); + + this.digestLength = bitLength / 8; + + tIvGenerate(digestLength * 8); + + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha512tDigest(Sha512tDigest t) + : base(t) + { + this.digestLength = t.digestLength; + + Reset(t); + } + + public override string AlgorithmName + { + get { return "SHA-512/" + (digestLength * 8); } + } + + public override int GetDigestSize() + { + return digestLength; + } + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + UInt64_To_BE(H1, output, outOff, digestLength); + UInt64_To_BE(H2, output, outOff + 8, digestLength - 8); + UInt64_To_BE(H3, output, outOff + 16, digestLength - 16); + UInt64_To_BE(H4, output, outOff + 24, digestLength - 24); + UInt64_To_BE(H5, output, outOff + 32, digestLength - 32); + UInt64_To_BE(H6, output, outOff + 40, digestLength - 40); + UInt64_To_BE(H7, output, outOff + 48, digestLength - 48); + UInt64_To_BE(H8, output, outOff + 56, digestLength - 56); + + Reset(); + + return digestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* + * initial hash values use the iv generation algorithm for t. + */ + H1 = H1t; + H2 = H2t; + H3 = H3t; + H4 = H4t; + H5 = H5t; + H6 = H6t; + H7 = H7t; + H8 = H8t; + } + + private void tIvGenerate(int bitLength) + { + H1 = 0x6a09e667f3bcc908UL ^ A5; + H2 = 0xbb67ae8584caa73bUL ^ A5; + H3 = 0x3c6ef372fe94f82bUL ^ A5; + H4 = 0xa54ff53a5f1d36f1UL ^ A5; + H5 = 0x510e527fade682d1UL ^ A5; + H6 = 0x9b05688c2b3e6c1fUL ^ A5; + H7 = 0x1f83d9abfb41bd6bUL ^ A5; + H8 = 0x5be0cd19137e2179UL ^ A5; + + Update(0x53); + Update(0x48); + Update(0x41); + Update(0x2D); + Update(0x35); + Update(0x31); + Update(0x32); + Update(0x2F); + + if (bitLength > 100) + { + Update((byte)(bitLength / 100 + 0x30)); + bitLength = bitLength % 100; + Update((byte)(bitLength / 10 + 0x30)); + bitLength = bitLength % 10; + Update((byte)(bitLength + 0x30)); + } + else if (bitLength > 10) + { + Update((byte)(bitLength / 10 + 0x30)); + bitLength = bitLength % 10; + Update((byte)(bitLength + 0x30)); + } + else + { + Update((byte)(bitLength + 0x30)); + } + + Finish(); + + H1t = H1; + H2t = H2; + H3t = H3; + H4t = H4; + H5t = H5; + H6t = H6; + H7t = H7; + H8t = H8; + } + + private static void UInt64_To_BE(ulong n, byte[] bs, int off, int max) + { + if (max > 0) + { + UInt32_To_BE((uint)(n >> 32), bs, off, max); + + if (max > 4) + { + UInt32_To_BE((uint)n, bs, off + 4, max - 4); + } + } + } + + private static void UInt32_To_BE(uint n, byte[] bs, int off, int max) + { + int num = System.Math.Min(4, max); + while (--num >= 0) + { + int shift = 8 * (3 - num); + bs[off + num] = (byte)(n >> shift); + } + } + + public override IMemoable Copy() + { + return new Sha512tDigest(this); + } + + public override void Reset(IMemoable other) + { + Sha512tDigest t = (Sha512tDigest)other; + + if (this.digestLength != t.digestLength) + { + throw new MemoableResetException("digestLength inappropriate in other"); + } + + base.CopyIn(t); + + this.H1t = t.H1t; + this.H2t = t.H2t; + this.H3t = t.H3t; + this.H4t = t.H4t; + this.H5t = t.H5t; + this.H6t = t.H6t; + this.H7t = t.H7t; + this.H8t = t.H8t; + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs.meta new file mode 100644 index 0000000..53df4f5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/Sha512tDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71193c0a7b8cb1d49939d290bb0b4004 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs new file mode 100644 index 0000000..bca42a8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs @@ -0,0 +1,123 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// Implementation of SHAKE based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ + /// + /// + /// Following the naming conventions used in the C source code to enable easy review of the implementation. + /// + public class ShakeDigest + : KeccakDigest, IXof + { + private static int CheckBitLength(int bitLength) + { + switch (bitLength) + { + case 128: + case 256: + return bitLength; + default: + throw new ArgumentException(bitLength + " not supported for SHAKE", "bitLength"); + } + } + + public ShakeDigest() + : this(128) + { + } + + public ShakeDigest(int bitLength) + : base(CheckBitLength(bitLength)) + { + } + + public ShakeDigest(ShakeDigest source) + : base(source) + { + } + + public override string AlgorithmName + { + get { return "SHAKE" + fixedOutputLength; } + } + + public override int DoFinal(byte[] output, int outOff) + { + return DoFinal(output, outOff, GetDigestSize()); + } + + public virtual int DoFinal(byte[] output, int outOff, int outLen) + { + DoOutput(output, outOff, outLen); + + Reset(); + + return outLen; + } + + public virtual int DoOutput(byte[] output, int outOff, int outLen) + { + if (!squeezing) + { + Absorb(new byte[] { 0x0F }, 0, 4); + } + + Squeeze(output, outOff, ((long)outLen) * 8); + + return outLen; + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits) + { + return DoFinal(output, outOff, GetDigestSize(), partialByte, partialBits); + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected virtual int DoFinal(byte[] output, int outOff, int outLen, byte partialByte, int partialBits) + { + if (partialBits < 0 || partialBits > 7) + throw new ArgumentException("must be in the range [0,7]", "partialBits"); + + int finalInput = (partialByte & ((1 << partialBits) - 1)) | (0x0F << partialBits); + Debug.Assert(finalInput >= 0); + int finalBits = partialBits + 4; + + if (finalBits >= 8) + { + oneByte[0] = (byte)finalInput; + Absorb(oneByte, 0, 8); + finalBits -= 8; + finalInput >>= 8; + } + + if (finalBits > 0) + { + oneByte[0] = (byte)finalInput; + Absorb(oneByte, 0, finalBits); + } + + Squeeze(output, outOff, ((long)outLen) * 8); + + Reset(); + + return outLen; + } + + public override IMemoable Copy() + { + return new ShakeDigest(this); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs.meta new file mode 100644 index 0000000..1ccbc5a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/ShakeDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: eaf2e157553c41e44be2794678a8fc53 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs new file mode 100644 index 0000000..de35a7f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs @@ -0,0 +1,887 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of Tiger based on: + * + * http://www.cs.technion.ac.il/~biham/Reports/Tiger + */ + public class TigerDigest + : IDigest, IMemoable + { + private const int MyByteLength = 64; + + /* + * S-Boxes. + */ + private static readonly long[] t1 = { + unchecked((long) 0x02AAB17CF7E90C5EL) /* 0 */, unchecked((long) 0xAC424B03E243A8ECL) /* 1 */, + unchecked((long) 0x72CD5BE30DD5FCD3L) /* 2 */, unchecked((long) 0x6D019B93F6F97F3AL) /* 3 */, + unchecked((long) 0xCD9978FFD21F9193L) /* 4 */, unchecked((long) 0x7573A1C9708029E2L) /* 5 */, + unchecked((long) 0xB164326B922A83C3L) /* 6 */, unchecked((long) 0x46883EEE04915870L) /* 7 */, + unchecked((long) 0xEAACE3057103ECE6L) /* 8 */, unchecked((long) 0xC54169B808A3535CL) /* 9 */, + unchecked((long) 0x4CE754918DDEC47CL) /* 10 */, unchecked((long) 0x0AA2F4DFDC0DF40CL) /* 11 */, + unchecked((long) 0x10B76F18A74DBEFAL) /* 12 */, unchecked((long) 0xC6CCB6235AD1AB6AL) /* 13 */, + unchecked((long) 0x13726121572FE2FFL) /* 14 */, unchecked((long) 0x1A488C6F199D921EL) /* 15 */, + unchecked((long) 0x4BC9F9F4DA0007CAL) /* 16 */, unchecked((long) 0x26F5E6F6E85241C7L) /* 17 */, + unchecked((long) 0x859079DBEA5947B6L) /* 18 */, unchecked((long) 0x4F1885C5C99E8C92L) /* 19 */, + unchecked((long) 0xD78E761EA96F864BL) /* 20 */, unchecked((long) 0x8E36428C52B5C17DL) /* 21 */, + unchecked((long) 0x69CF6827373063C1L) /* 22 */, unchecked((long) 0xB607C93D9BB4C56EL) /* 23 */, + unchecked((long) 0x7D820E760E76B5EAL) /* 24 */, unchecked((long) 0x645C9CC6F07FDC42L) /* 25 */, + unchecked((long) 0xBF38A078243342E0L) /* 26 */, unchecked((long) 0x5F6B343C9D2E7D04L) /* 27 */, + unchecked((long) 0xF2C28AEB600B0EC6L) /* 28 */, unchecked((long) 0x6C0ED85F7254BCACL) /* 29 */, + unchecked((long) 0x71592281A4DB4FE5L) /* 30 */, unchecked((long) 0x1967FA69CE0FED9FL) /* 31 */, + unchecked((long) 0xFD5293F8B96545DBL) /* 32 */, unchecked((long) 0xC879E9D7F2A7600BL) /* 33 */, + unchecked((long) 0x860248920193194EL) /* 34 */, unchecked((long) 0xA4F9533B2D9CC0B3L) /* 35 */, + unchecked((long) 0x9053836C15957613L) /* 36 */, unchecked((long) 0xDB6DCF8AFC357BF1L) /* 37 */, + unchecked((long) 0x18BEEA7A7A370F57L) /* 38 */, unchecked((long) 0x037117CA50B99066L) /* 39 */, + unchecked((long) 0x6AB30A9774424A35L) /* 40 */, unchecked((long) 0xF4E92F02E325249BL) /* 41 */, + unchecked((long) 0x7739DB07061CCAE1L) /* 42 */, unchecked((long) 0xD8F3B49CECA42A05L) /* 43 */, + unchecked((long) 0xBD56BE3F51382F73L) /* 44 */, unchecked((long) 0x45FAED5843B0BB28L) /* 45 */, + unchecked((long) 0x1C813D5C11BF1F83L) /* 46 */, unchecked((long) 0x8AF0E4B6D75FA169L) /* 47 */, + unchecked((long) 0x33EE18A487AD9999L) /* 48 */, unchecked((long) 0x3C26E8EAB1C94410L) /* 49 */, + unchecked((long) 0xB510102BC0A822F9L) /* 50 */, unchecked((long) 0x141EEF310CE6123BL) /* 51 */, + unchecked((long) 0xFC65B90059DDB154L) /* 52 */, unchecked((long) 0xE0158640C5E0E607L) /* 53 */, + unchecked((long) 0x884E079826C3A3CFL) /* 54 */, unchecked((long) 0x930D0D9523C535FDL) /* 55 */, + unchecked((long) 0x35638D754E9A2B00L) /* 56 */, unchecked((long) 0x4085FCCF40469DD5L) /* 57 */, + unchecked((long) 0xC4B17AD28BE23A4CL) /* 58 */, unchecked((long) 0xCAB2F0FC6A3E6A2EL) /* 59 */, + unchecked((long) 0x2860971A6B943FCDL) /* 60 */, unchecked((long) 0x3DDE6EE212E30446L) /* 61 */, + unchecked((long) 0x6222F32AE01765AEL) /* 62 */, unchecked((long) 0x5D550BB5478308FEL) /* 63 */, + unchecked((long) 0xA9EFA98DA0EDA22AL) /* 64 */, unchecked((long) 0xC351A71686C40DA7L) /* 65 */, + unchecked((long) 0x1105586D9C867C84L) /* 66 */, unchecked((long) 0xDCFFEE85FDA22853L) /* 67 */, + unchecked((long) 0xCCFBD0262C5EEF76L) /* 68 */, unchecked((long) 0xBAF294CB8990D201L) /* 69 */, + unchecked((long) 0xE69464F52AFAD975L) /* 70 */, unchecked((long) 0x94B013AFDF133E14L) /* 71 */, + unchecked((long) 0x06A7D1A32823C958L) /* 72 */, unchecked((long) 0x6F95FE5130F61119L) /* 73 */, + unchecked((long) 0xD92AB34E462C06C0L) /* 74 */, unchecked((long) 0xED7BDE33887C71D2L) /* 75 */, + unchecked((long) 0x79746D6E6518393EL) /* 76 */, unchecked((long) 0x5BA419385D713329L) /* 77 */, + unchecked((long) 0x7C1BA6B948A97564L) /* 78 */, unchecked((long) 0x31987C197BFDAC67L) /* 79 */, + unchecked((long) 0xDE6C23C44B053D02L) /* 80 */, unchecked((long) 0x581C49FED002D64DL) /* 81 */, + unchecked((long) 0xDD474D6338261571L) /* 82 */, unchecked((long) 0xAA4546C3E473D062L) /* 83 */, + unchecked((long) 0x928FCE349455F860L) /* 84 */, unchecked((long) 0x48161BBACAAB94D9L) /* 85 */, + unchecked((long) 0x63912430770E6F68L) /* 86 */, unchecked((long) 0x6EC8A5E602C6641CL) /* 87 */, + unchecked((long) 0x87282515337DDD2BL) /* 88 */, unchecked((long) 0x2CDA6B42034B701BL) /* 89 */, + unchecked((long) 0xB03D37C181CB096DL) /* 90 */, unchecked((long) 0xE108438266C71C6FL) /* 91 */, + unchecked((long) 0x2B3180C7EB51B255L) /* 92 */, unchecked((long) 0xDF92B82F96C08BBCL) /* 93 */, + unchecked((long) 0x5C68C8C0A632F3BAL) /* 94 */, unchecked((long) 0x5504CC861C3D0556L) /* 95 */, + unchecked((long) 0xABBFA4E55FB26B8FL) /* 96 */, unchecked((long) 0x41848B0AB3BACEB4L) /* 97 */, + unchecked((long) 0xB334A273AA445D32L) /* 98 */, unchecked((long) 0xBCA696F0A85AD881L) /* 99 */, + unchecked((long) 0x24F6EC65B528D56CL) /* 100 */, unchecked((long) 0x0CE1512E90F4524AL) /* 101 */, + unchecked((long) 0x4E9DD79D5506D35AL) /* 102 */, unchecked((long) 0x258905FAC6CE9779L) /* 103 */, + unchecked((long) 0x2019295B3E109B33L) /* 104 */, unchecked((long) 0xF8A9478B73A054CCL) /* 105 */, + unchecked((long) 0x2924F2F934417EB0L) /* 106 */, unchecked((long) 0x3993357D536D1BC4L) /* 107 */, + unchecked((long) 0x38A81AC21DB6FF8BL) /* 108 */, unchecked((long) 0x47C4FBF17D6016BFL) /* 109 */, + unchecked((long) 0x1E0FAADD7667E3F5L) /* 110 */, unchecked((long) 0x7ABCFF62938BEB96L) /* 111 */, + unchecked((long) 0xA78DAD948FC179C9L) /* 112 */, unchecked((long) 0x8F1F98B72911E50DL) /* 113 */, + unchecked((long) 0x61E48EAE27121A91L) /* 114 */, unchecked((long) 0x4D62F7AD31859808L) /* 115 */, + unchecked((long) 0xECEBA345EF5CEAEBL) /* 116 */, unchecked((long) 0xF5CEB25EBC9684CEL) /* 117 */, + unchecked((long) 0xF633E20CB7F76221L) /* 118 */, unchecked((long) 0xA32CDF06AB8293E4L) /* 119 */, + unchecked((long) 0x985A202CA5EE2CA4L) /* 120 */, unchecked((long) 0xCF0B8447CC8A8FB1L) /* 121 */, + unchecked((long) 0x9F765244979859A3L) /* 122 */, unchecked((long) 0xA8D516B1A1240017L) /* 123 */, + unchecked((long) 0x0BD7BA3EBB5DC726L) /* 124 */, unchecked((long) 0xE54BCA55B86ADB39L) /* 125 */, + unchecked((long) 0x1D7A3AFD6C478063L) /* 126 */, unchecked((long) 0x519EC608E7669EDDL) /* 127 */, + unchecked((long) 0x0E5715A2D149AA23L) /* 128 */, unchecked((long) 0x177D4571848FF194L) /* 129 */, + unchecked((long) 0xEEB55F3241014C22L) /* 130 */, unchecked((long) 0x0F5E5CA13A6E2EC2L) /* 131 */, + unchecked((long) 0x8029927B75F5C361L) /* 132 */, unchecked((long) 0xAD139FABC3D6E436L) /* 133 */, + unchecked((long) 0x0D5DF1A94CCF402FL) /* 134 */, unchecked((long) 0x3E8BD948BEA5DFC8L) /* 135 */, + unchecked((long) 0xA5A0D357BD3FF77EL) /* 136 */, unchecked((long) 0xA2D12E251F74F645L) /* 137 */, + unchecked((long) 0x66FD9E525E81A082L) /* 138 */, unchecked((long) 0x2E0C90CE7F687A49L) /* 139 */, + unchecked((long) 0xC2E8BCBEBA973BC5L) /* 140 */, unchecked((long) 0x000001BCE509745FL) /* 141 */, + unchecked((long) 0x423777BBE6DAB3D6L) /* 142 */, unchecked((long) 0xD1661C7EAEF06EB5L) /* 143 */, + unchecked((long) 0xA1781F354DAACFD8L) /* 144 */, unchecked((long) 0x2D11284A2B16AFFCL) /* 145 */, + unchecked((long) 0xF1FC4F67FA891D1FL) /* 146 */, unchecked((long) 0x73ECC25DCB920ADAL) /* 147 */, + unchecked((long) 0xAE610C22C2A12651L) /* 148 */, unchecked((long) 0x96E0A810D356B78AL) /* 149 */, + unchecked((long) 0x5A9A381F2FE7870FL) /* 150 */, unchecked((long) 0xD5AD62EDE94E5530L) /* 151 */, + unchecked((long) 0xD225E5E8368D1427L) /* 152 */, unchecked((long) 0x65977B70C7AF4631L) /* 153 */, + unchecked((long) 0x99F889B2DE39D74FL) /* 154 */, unchecked((long) 0x233F30BF54E1D143L) /* 155 */, + unchecked((long) 0x9A9675D3D9A63C97L) /* 156 */, unchecked((long) 0x5470554FF334F9A8L) /* 157 */, + unchecked((long) 0x166ACB744A4F5688L) /* 158 */, unchecked((long) 0x70C74CAAB2E4AEADL) /* 159 */, + unchecked((long) 0xF0D091646F294D12L) /* 160 */, unchecked((long) 0x57B82A89684031D1L) /* 161 */, + unchecked((long) 0xEFD95A5A61BE0B6BL) /* 162 */, unchecked((long) 0x2FBD12E969F2F29AL) /* 163 */, + unchecked((long) 0x9BD37013FEFF9FE8L) /* 164 */, unchecked((long) 0x3F9B0404D6085A06L) /* 165 */, + unchecked((long) 0x4940C1F3166CFE15L) /* 166 */, unchecked((long) 0x09542C4DCDF3DEFBL) /* 167 */, + unchecked((long) 0xB4C5218385CD5CE3L) /* 168 */, unchecked((long) 0xC935B7DC4462A641L) /* 169 */, + unchecked((long) 0x3417F8A68ED3B63FL) /* 170 */, unchecked((long) 0xB80959295B215B40L) /* 171 */, + unchecked((long) 0xF99CDAEF3B8C8572L) /* 172 */, unchecked((long) 0x018C0614F8FCB95DL) /* 173 */, + unchecked((long) 0x1B14ACCD1A3ACDF3L) /* 174 */, unchecked((long) 0x84D471F200BB732DL) /* 175 */, + unchecked((long) 0xC1A3110E95E8DA16L) /* 176 */, unchecked((long) 0x430A7220BF1A82B8L) /* 177 */, + unchecked((long) 0xB77E090D39DF210EL) /* 178 */, unchecked((long) 0x5EF4BD9F3CD05E9DL) /* 179 */, + unchecked((long) 0x9D4FF6DA7E57A444L) /* 180 */, unchecked((long) 0xDA1D60E183D4A5F8L) /* 181 */, + unchecked((long) 0xB287C38417998E47L) /* 182 */, unchecked((long) 0xFE3EDC121BB31886L) /* 183 */, + unchecked((long) 0xC7FE3CCC980CCBEFL) /* 184 */, unchecked((long) 0xE46FB590189BFD03L) /* 185 */, + unchecked((long) 0x3732FD469A4C57DCL) /* 186 */, unchecked((long) 0x7EF700A07CF1AD65L) /* 187 */, + unchecked((long) 0x59C64468A31D8859L) /* 188 */, unchecked((long) 0x762FB0B4D45B61F6L) /* 189 */, + unchecked((long) 0x155BAED099047718L) /* 190 */, unchecked((long) 0x68755E4C3D50BAA6L) /* 191 */, + unchecked((long) 0xE9214E7F22D8B4DFL) /* 192 */, unchecked((long) 0x2ADDBF532EAC95F4L) /* 193 */, + unchecked((long) 0x32AE3909B4BD0109L) /* 194 */, unchecked((long) 0x834DF537B08E3450L) /* 195 */, + unchecked((long) 0xFA209DA84220728DL) /* 196 */, unchecked((long) 0x9E691D9B9EFE23F7L) /* 197 */, + unchecked((long) 0x0446D288C4AE8D7FL) /* 198 */, unchecked((long) 0x7B4CC524E169785BL) /* 199 */, + unchecked((long) 0x21D87F0135CA1385L) /* 200 */, unchecked((long) 0xCEBB400F137B8AA5L) /* 201 */, + unchecked((long) 0x272E2B66580796BEL) /* 202 */, unchecked((long) 0x3612264125C2B0DEL) /* 203 */, + unchecked((long) 0x057702BDAD1EFBB2L) /* 204 */, unchecked((long) 0xD4BABB8EACF84BE9L) /* 205 */, + unchecked((long) 0x91583139641BC67BL) /* 206 */, unchecked((long) 0x8BDC2DE08036E024L) /* 207 */, + unchecked((long) 0x603C8156F49F68EDL) /* 208 */, unchecked((long) 0xF7D236F7DBEF5111L) /* 209 */, + unchecked((long) 0x9727C4598AD21E80L) /* 210 */, unchecked((long) 0xA08A0896670A5FD7L) /* 211 */, + unchecked((long) 0xCB4A8F4309EBA9CBL) /* 212 */, unchecked((long) 0x81AF564B0F7036A1L) /* 213 */, + unchecked((long) 0xC0B99AA778199ABDL) /* 214 */, unchecked((long) 0x959F1EC83FC8E952L) /* 215 */, + unchecked((long) 0x8C505077794A81B9L) /* 216 */, unchecked((long) 0x3ACAAF8F056338F0L) /* 217 */, + unchecked((long) 0x07B43F50627A6778L) /* 218 */, unchecked((long) 0x4A44AB49F5ECCC77L) /* 219 */, + unchecked((long) 0x3BC3D6E4B679EE98L) /* 220 */, unchecked((long) 0x9CC0D4D1CF14108CL) /* 221 */, + unchecked((long) 0x4406C00B206BC8A0L) /* 222 */, unchecked((long) 0x82A18854C8D72D89L) /* 223 */, + unchecked((long) 0x67E366B35C3C432CL) /* 224 */, unchecked((long) 0xB923DD61102B37F2L) /* 225 */, + unchecked((long) 0x56AB2779D884271DL) /* 226 */, unchecked((long) 0xBE83E1B0FF1525AFL) /* 227 */, + unchecked((long) 0xFB7C65D4217E49A9L) /* 228 */, unchecked((long) 0x6BDBE0E76D48E7D4L) /* 229 */, + unchecked((long) 0x08DF828745D9179EL) /* 230 */, unchecked((long) 0x22EA6A9ADD53BD34L) /* 231 */, + unchecked((long) 0xE36E141C5622200AL) /* 232 */, unchecked((long) 0x7F805D1B8CB750EEL) /* 233 */, + unchecked((long) 0xAFE5C7A59F58E837L) /* 234 */, unchecked((long) 0xE27F996A4FB1C23CL) /* 235 */, + unchecked((long) 0xD3867DFB0775F0D0L) /* 236 */, unchecked((long) 0xD0E673DE6E88891AL) /* 237 */, + unchecked((long) 0x123AEB9EAFB86C25L) /* 238 */, unchecked((long) 0x30F1D5D5C145B895L) /* 239 */, + unchecked((long) 0xBB434A2DEE7269E7L) /* 240 */, unchecked((long) 0x78CB67ECF931FA38L) /* 241 */, + unchecked((long) 0xF33B0372323BBF9CL) /* 242 */, unchecked((long) 0x52D66336FB279C74L) /* 243 */, + unchecked((long) 0x505F33AC0AFB4EAAL) /* 244 */, unchecked((long) 0xE8A5CD99A2CCE187L) /* 245 */, + unchecked((long) 0x534974801E2D30BBL) /* 246 */, unchecked((long) 0x8D2D5711D5876D90L) /* 247 */, + unchecked((long) 0x1F1A412891BC038EL) /* 248 */, unchecked((long) 0xD6E2E71D82E56648L) /* 249 */, + unchecked((long) 0x74036C3A497732B7L) /* 250 */, unchecked((long) 0x89B67ED96361F5ABL) /* 251 */, + unchecked((long) 0xFFED95D8F1EA02A2L) /* 252 */, unchecked((long) 0xE72B3BD61464D43DL) /* 253 */, + unchecked((long) 0xA6300F170BDC4820L) /* 254 */, unchecked((long) 0xEBC18760ED78A77AL) /* 255 */, + }; + + private static readonly long[] t2 = { + unchecked((long) 0xE6A6BE5A05A12138L) /* 256 */, unchecked((long) 0xB5A122A5B4F87C98L) /* 257 */, + unchecked((long) 0x563C6089140B6990L) /* 258 */, unchecked((long) 0x4C46CB2E391F5DD5L) /* 259 */, + unchecked((long) 0xD932ADDBC9B79434L) /* 260 */, unchecked((long) 0x08EA70E42015AFF5L) /* 261 */, + unchecked((long) 0xD765A6673E478CF1L) /* 262 */, unchecked((long) 0xC4FB757EAB278D99L) /* 263 */, + unchecked((long) 0xDF11C6862D6E0692L) /* 264 */, unchecked((long) 0xDDEB84F10D7F3B16L) /* 265 */, + unchecked((long) 0x6F2EF604A665EA04L) /* 266 */, unchecked((long) 0x4A8E0F0FF0E0DFB3L) /* 267 */, + unchecked((long) 0xA5EDEEF83DBCBA51L) /* 268 */, unchecked((long) 0xFC4F0A2A0EA4371EL) /* 269 */, + unchecked((long) 0xE83E1DA85CB38429L) /* 270 */, unchecked((long) 0xDC8FF882BA1B1CE2L) /* 271 */, + unchecked((long) 0xCD45505E8353E80DL) /* 272 */, unchecked((long) 0x18D19A00D4DB0717L) /* 273 */, + unchecked((long) 0x34A0CFEDA5F38101L) /* 274 */, unchecked((long) 0x0BE77E518887CAF2L) /* 275 */, + unchecked((long) 0x1E341438B3C45136L) /* 276 */, unchecked((long) 0xE05797F49089CCF9L) /* 277 */, + unchecked((long) 0xFFD23F9DF2591D14L) /* 278 */, unchecked((long) 0x543DDA228595C5CDL) /* 279 */, + unchecked((long) 0x661F81FD99052A33L) /* 280 */, unchecked((long) 0x8736E641DB0F7B76L) /* 281 */, + unchecked((long) 0x15227725418E5307L) /* 282 */, unchecked((long) 0xE25F7F46162EB2FAL) /* 283 */, + unchecked((long) 0x48A8B2126C13D9FEL) /* 284 */, unchecked((long) 0xAFDC541792E76EEAL) /* 285 */, + unchecked((long) 0x03D912BFC6D1898FL) /* 286 */, unchecked((long) 0x31B1AAFA1B83F51BL) /* 287 */, + unchecked((long) 0xF1AC2796E42AB7D9L) /* 288 */, unchecked((long) 0x40A3A7D7FCD2EBACL) /* 289 */, + unchecked((long) 0x1056136D0AFBBCC5L) /* 290 */, unchecked((long) 0x7889E1DD9A6D0C85L) /* 291 */, + unchecked((long) 0xD33525782A7974AAL) /* 292 */, unchecked((long) 0xA7E25D09078AC09BL) /* 293 */, + unchecked((long) 0xBD4138B3EAC6EDD0L) /* 294 */, unchecked((long) 0x920ABFBE71EB9E70L) /* 295 */, + unchecked((long) 0xA2A5D0F54FC2625CL) /* 296 */, unchecked((long) 0xC054E36B0B1290A3L) /* 297 */, + unchecked((long) 0xF6DD59FF62FE932BL) /* 298 */, unchecked((long) 0x3537354511A8AC7DL) /* 299 */, + unchecked((long) 0xCA845E9172FADCD4L) /* 300 */, unchecked((long) 0x84F82B60329D20DCL) /* 301 */, + unchecked((long) 0x79C62CE1CD672F18L) /* 302 */, unchecked((long) 0x8B09A2ADD124642CL) /* 303 */, + unchecked((long) 0xD0C1E96A19D9E726L) /* 304 */, unchecked((long) 0x5A786A9B4BA9500CL) /* 305 */, + unchecked((long) 0x0E020336634C43F3L) /* 306 */, unchecked((long) 0xC17B474AEB66D822L) /* 307 */, + unchecked((long) 0x6A731AE3EC9BAAC2L) /* 308 */, unchecked((long) 0x8226667AE0840258L) /* 309 */, + unchecked((long) 0x67D4567691CAECA5L) /* 310 */, unchecked((long) 0x1D94155C4875ADB5L) /* 311 */, + unchecked((long) 0x6D00FD985B813FDFL) /* 312 */, unchecked((long) 0x51286EFCB774CD06L) /* 313 */, + unchecked((long) 0x5E8834471FA744AFL) /* 314 */, unchecked((long) 0xF72CA0AEE761AE2EL) /* 315 */, + unchecked((long) 0xBE40E4CDAEE8E09AL) /* 316 */, unchecked((long) 0xE9970BBB5118F665L) /* 317 */, + unchecked((long) 0x726E4BEB33DF1964L) /* 318 */, unchecked((long) 0x703B000729199762L) /* 319 */, + unchecked((long) 0x4631D816F5EF30A7L) /* 320 */, unchecked((long) 0xB880B5B51504A6BEL) /* 321 */, + unchecked((long) 0x641793C37ED84B6CL) /* 322 */, unchecked((long) 0x7B21ED77F6E97D96L) /* 323 */, + unchecked((long) 0x776306312EF96B73L) /* 324 */, unchecked((long) 0xAE528948E86FF3F4L) /* 325 */, + unchecked((long) 0x53DBD7F286A3F8F8L) /* 326 */, unchecked((long) 0x16CADCE74CFC1063L) /* 327 */, + unchecked((long) 0x005C19BDFA52C6DDL) /* 328 */, unchecked((long) 0x68868F5D64D46AD3L) /* 329 */, + unchecked((long) 0x3A9D512CCF1E186AL) /* 330 */, unchecked((long) 0x367E62C2385660AEL) /* 331 */, + unchecked((long) 0xE359E7EA77DCB1D7L) /* 332 */, unchecked((long) 0x526C0773749ABE6EL) /* 333 */, + unchecked((long) 0x735AE5F9D09F734BL) /* 334 */, unchecked((long) 0x493FC7CC8A558BA8L) /* 335 */, + unchecked((long) 0xB0B9C1533041AB45L) /* 336 */, unchecked((long) 0x321958BA470A59BDL) /* 337 */, + unchecked((long) 0x852DB00B5F46C393L) /* 338 */, unchecked((long) 0x91209B2BD336B0E5L) /* 339 */, + unchecked((long) 0x6E604F7D659EF19FL) /* 340 */, unchecked((long) 0xB99A8AE2782CCB24L) /* 341 */, + unchecked((long) 0xCCF52AB6C814C4C7L) /* 342 */, unchecked((long) 0x4727D9AFBE11727BL) /* 343 */, + unchecked((long) 0x7E950D0C0121B34DL) /* 344 */, unchecked((long) 0x756F435670AD471FL) /* 345 */, + unchecked((long) 0xF5ADD442615A6849L) /* 346 */, unchecked((long) 0x4E87E09980B9957AL) /* 347 */, + unchecked((long) 0x2ACFA1DF50AEE355L) /* 348 */, unchecked((long) 0xD898263AFD2FD556L) /* 349 */, + unchecked((long) 0xC8F4924DD80C8FD6L) /* 350 */, unchecked((long) 0xCF99CA3D754A173AL) /* 351 */, + unchecked((long) 0xFE477BACAF91BF3CL) /* 352 */, unchecked((long) 0xED5371F6D690C12DL) /* 353 */, + unchecked((long) 0x831A5C285E687094L) /* 354 */, unchecked((long) 0xC5D3C90A3708A0A4L) /* 355 */, + unchecked((long) 0x0F7F903717D06580L) /* 356 */, unchecked((long) 0x19F9BB13B8FDF27FL) /* 357 */, + unchecked((long) 0xB1BD6F1B4D502843L) /* 358 */, unchecked((long) 0x1C761BA38FFF4012L) /* 359 */, + unchecked((long) 0x0D1530C4E2E21F3BL) /* 360 */, unchecked((long) 0x8943CE69A7372C8AL) /* 361 */, + unchecked((long) 0xE5184E11FEB5CE66L) /* 362 */, unchecked((long) 0x618BDB80BD736621L) /* 363 */, + unchecked((long) 0x7D29BAD68B574D0BL) /* 364 */, unchecked((long) 0x81BB613E25E6FE5BL) /* 365 */, + unchecked((long) 0x071C9C10BC07913FL) /* 366 */, unchecked((long) 0xC7BEEB7909AC2D97L) /* 367 */, + unchecked((long) 0xC3E58D353BC5D757L) /* 368 */, unchecked((long) 0xEB017892F38F61E8L) /* 369 */, + unchecked((long) 0xD4EFFB9C9B1CC21AL) /* 370 */, unchecked((long) 0x99727D26F494F7ABL) /* 371 */, + unchecked((long) 0xA3E063A2956B3E03L) /* 372 */, unchecked((long) 0x9D4A8B9A4AA09C30L) /* 373 */, + unchecked((long) 0x3F6AB7D500090FB4L) /* 374 */, unchecked((long) 0x9CC0F2A057268AC0L) /* 375 */, + unchecked((long) 0x3DEE9D2DEDBF42D1L) /* 376 */, unchecked((long) 0x330F49C87960A972L) /* 377 */, + unchecked((long) 0xC6B2720287421B41L) /* 378 */, unchecked((long) 0x0AC59EC07C00369CL) /* 379 */, + unchecked((long) 0xEF4EAC49CB353425L) /* 380 */, unchecked((long) 0xF450244EEF0129D8L) /* 381 */, + unchecked((long) 0x8ACC46E5CAF4DEB6L) /* 382 */, unchecked((long) 0x2FFEAB63989263F7L) /* 383 */, + unchecked((long) 0x8F7CB9FE5D7A4578L) /* 384 */, unchecked((long) 0x5BD8F7644E634635L) /* 385 */, + unchecked((long) 0x427A7315BF2DC900L) /* 386 */, unchecked((long) 0x17D0C4AA2125261CL) /* 387 */, + unchecked((long) 0x3992486C93518E50L) /* 388 */, unchecked((long) 0xB4CBFEE0A2D7D4C3L) /* 389 */, + unchecked((long) 0x7C75D6202C5DDD8DL) /* 390 */, unchecked((long) 0xDBC295D8E35B6C61L) /* 391 */, + unchecked((long) 0x60B369D302032B19L) /* 392 */, unchecked((long) 0xCE42685FDCE44132L) /* 393 */, + unchecked((long) 0x06F3DDB9DDF65610L) /* 394 */, unchecked((long) 0x8EA4D21DB5E148F0L) /* 395 */, + unchecked((long) 0x20B0FCE62FCD496FL) /* 396 */, unchecked((long) 0x2C1B912358B0EE31L) /* 397 */, + unchecked((long) 0xB28317B818F5A308L) /* 398 */, unchecked((long) 0xA89C1E189CA6D2CFL) /* 399 */, + unchecked((long) 0x0C6B18576AAADBC8L) /* 400 */, unchecked((long) 0xB65DEAA91299FAE3L) /* 401 */, + unchecked((long) 0xFB2B794B7F1027E7L) /* 402 */, unchecked((long) 0x04E4317F443B5BEBL) /* 403 */, + unchecked((long) 0x4B852D325939D0A6L) /* 404 */, unchecked((long) 0xD5AE6BEEFB207FFCL) /* 405 */, + unchecked((long) 0x309682B281C7D374L) /* 406 */, unchecked((long) 0xBAE309A194C3B475L) /* 407 */, + unchecked((long) 0x8CC3F97B13B49F05L) /* 408 */, unchecked((long) 0x98A9422FF8293967L) /* 409 */, + unchecked((long) 0x244B16B01076FF7CL) /* 410 */, unchecked((long) 0xF8BF571C663D67EEL) /* 411 */, + unchecked((long) 0x1F0D6758EEE30DA1L) /* 412 */, unchecked((long) 0xC9B611D97ADEB9B7L) /* 413 */, + unchecked((long) 0xB7AFD5887B6C57A2L) /* 414 */, unchecked((long) 0x6290AE846B984FE1L) /* 415 */, + unchecked((long) 0x94DF4CDEACC1A5FDL) /* 416 */, unchecked((long) 0x058A5BD1C5483AFFL) /* 417 */, + unchecked((long) 0x63166CC142BA3C37L) /* 418 */, unchecked((long) 0x8DB8526EB2F76F40L) /* 419 */, + unchecked((long) 0xE10880036F0D6D4EL) /* 420 */, unchecked((long) 0x9E0523C9971D311DL) /* 421 */, + unchecked((long) 0x45EC2824CC7CD691L) /* 422 */, unchecked((long) 0x575B8359E62382C9L) /* 423 */, + unchecked((long) 0xFA9E400DC4889995L) /* 424 */, unchecked((long) 0xD1823ECB45721568L) /* 425 */, + unchecked((long) 0xDAFD983B8206082FL) /* 426 */, unchecked((long) 0xAA7D29082386A8CBL) /* 427 */, + unchecked((long) 0x269FCD4403B87588L) /* 428 */, unchecked((long) 0x1B91F5F728BDD1E0L) /* 429 */, + unchecked((long) 0xE4669F39040201F6L) /* 430 */, unchecked((long) 0x7A1D7C218CF04ADEL) /* 431 */, + unchecked((long) 0x65623C29D79CE5CEL) /* 432 */, unchecked((long) 0x2368449096C00BB1L) /* 433 */, + unchecked((long) 0xAB9BF1879DA503BAL) /* 434 */, unchecked((long) 0xBC23ECB1A458058EL) /* 435 */, + unchecked((long) 0x9A58DF01BB401ECCL) /* 436 */, unchecked((long) 0xA070E868A85F143DL) /* 437 */, + unchecked((long) 0x4FF188307DF2239EL) /* 438 */, unchecked((long) 0x14D565B41A641183L) /* 439 */, + unchecked((long) 0xEE13337452701602L) /* 440 */, unchecked((long) 0x950E3DCF3F285E09L) /* 441 */, + unchecked((long) 0x59930254B9C80953L) /* 442 */, unchecked((long) 0x3BF299408930DA6DL) /* 443 */, + unchecked((long) 0xA955943F53691387L) /* 444 */, unchecked((long) 0xA15EDECAA9CB8784L) /* 445 */, + unchecked((long) 0x29142127352BE9A0L) /* 446 */, unchecked((long) 0x76F0371FFF4E7AFBL) /* 447 */, + unchecked((long) 0x0239F450274F2228L) /* 448 */, unchecked((long) 0xBB073AF01D5E868BL) /* 449 */, + unchecked((long) 0xBFC80571C10E96C1L) /* 450 */, unchecked((long) 0xD267088568222E23L) /* 451 */, + unchecked((long) 0x9671A3D48E80B5B0L) /* 452 */, unchecked((long) 0x55B5D38AE193BB81L) /* 453 */, + unchecked((long) 0x693AE2D0A18B04B8L) /* 454 */, unchecked((long) 0x5C48B4ECADD5335FL) /* 455 */, + unchecked((long) 0xFD743B194916A1CAL) /* 456 */, unchecked((long) 0x2577018134BE98C4L) /* 457 */, + unchecked((long) 0xE77987E83C54A4ADL) /* 458 */, unchecked((long) 0x28E11014DA33E1B9L) /* 459 */, + unchecked((long) 0x270CC59E226AA213L) /* 460 */, unchecked((long) 0x71495F756D1A5F60L) /* 461 */, + unchecked((long) 0x9BE853FB60AFEF77L) /* 462 */, unchecked((long) 0xADC786A7F7443DBFL) /* 463 */, + unchecked((long) 0x0904456173B29A82L) /* 464 */, unchecked((long) 0x58BC7A66C232BD5EL) /* 465 */, + unchecked((long) 0xF306558C673AC8B2L) /* 466 */, unchecked((long) 0x41F639C6B6C9772AL) /* 467 */, + unchecked((long) 0x216DEFE99FDA35DAL) /* 468 */, unchecked((long) 0x11640CC71C7BE615L) /* 469 */, + unchecked((long) 0x93C43694565C5527L) /* 470 */, unchecked((long) 0xEA038E6246777839L) /* 471 */, + unchecked((long) 0xF9ABF3CE5A3E2469L) /* 472 */, unchecked((long) 0x741E768D0FD312D2L) /* 473 */, + unchecked((long) 0x0144B883CED652C6L) /* 474 */, unchecked((long) 0xC20B5A5BA33F8552L) /* 475 */, + unchecked((long) 0x1AE69633C3435A9DL) /* 476 */, unchecked((long) 0x97A28CA4088CFDECL) /* 477 */, + unchecked((long) 0x8824A43C1E96F420L) /* 478 */, unchecked((long) 0x37612FA66EEEA746L) /* 479 */, + unchecked((long) 0x6B4CB165F9CF0E5AL) /* 480 */, unchecked((long) 0x43AA1C06A0ABFB4AL) /* 481 */, + unchecked((long) 0x7F4DC26FF162796BL) /* 482 */, unchecked((long) 0x6CBACC8E54ED9B0FL) /* 483 */, + unchecked((long) 0xA6B7FFEFD2BB253EL) /* 484 */, unchecked((long) 0x2E25BC95B0A29D4FL) /* 485 */, + unchecked((long) 0x86D6A58BDEF1388CL) /* 486 */, unchecked((long) 0xDED74AC576B6F054L) /* 487 */, + unchecked((long) 0x8030BDBC2B45805DL) /* 488 */, unchecked((long) 0x3C81AF70E94D9289L) /* 489 */, + unchecked((long) 0x3EFF6DDA9E3100DBL) /* 490 */, unchecked((long) 0xB38DC39FDFCC8847L) /* 491 */, + unchecked((long) 0x123885528D17B87EL) /* 492 */, unchecked((long) 0xF2DA0ED240B1B642L) /* 493 */, + unchecked((long) 0x44CEFADCD54BF9A9L) /* 494 */, unchecked((long) 0x1312200E433C7EE6L) /* 495 */, + unchecked((long) 0x9FFCC84F3A78C748L) /* 496 */, unchecked((long) 0xF0CD1F72248576BBL) /* 497 */, + unchecked((long) 0xEC6974053638CFE4L) /* 498 */, unchecked((long) 0x2BA7B67C0CEC4E4CL) /* 499 */, + unchecked((long) 0xAC2F4DF3E5CE32EDL) /* 500 */, unchecked((long) 0xCB33D14326EA4C11L) /* 501 */, + unchecked((long) 0xA4E9044CC77E58BCL) /* 502 */, unchecked((long) 0x5F513293D934FCEFL) /* 503 */, + unchecked((long) 0x5DC9645506E55444L) /* 504 */, unchecked((long) 0x50DE418F317DE40AL) /* 505 */, + unchecked((long) 0x388CB31A69DDE259L) /* 506 */, unchecked((long) 0x2DB4A83455820A86L) /* 507 */, + unchecked((long) 0x9010A91E84711AE9L) /* 508 */, unchecked((long) 0x4DF7F0B7B1498371L) /* 509 */, + unchecked((long) 0xD62A2EABC0977179L) /* 510 */, unchecked((long) 0x22FAC097AA8D5C0EL) /* 511 */, + }; + + private static readonly long[] t3 = { + unchecked((long) 0xF49FCC2FF1DAF39BL) /* 512 */, unchecked((long) 0x487FD5C66FF29281L) /* 513 */, + unchecked((long) 0xE8A30667FCDCA83FL) /* 514 */, unchecked((long) 0x2C9B4BE3D2FCCE63L) /* 515 */, + unchecked((long) 0xDA3FF74B93FBBBC2L) /* 516 */, unchecked((long) 0x2FA165D2FE70BA66L) /* 517 */, + unchecked((long) 0xA103E279970E93D4L) /* 518 */, unchecked((long) 0xBECDEC77B0E45E71L) /* 519 */, + unchecked((long) 0xCFB41E723985E497L) /* 520 */, unchecked((long) 0xB70AAA025EF75017L) /* 521 */, + unchecked((long) 0xD42309F03840B8E0L) /* 522 */, unchecked((long) 0x8EFC1AD035898579L) /* 523 */, + unchecked((long) 0x96C6920BE2B2ABC5L) /* 524 */, unchecked((long) 0x66AF4163375A9172L) /* 525 */, + unchecked((long) 0x2174ABDCCA7127FBL) /* 526 */, unchecked((long) 0xB33CCEA64A72FF41L) /* 527 */, + unchecked((long) 0xF04A4933083066A5L) /* 528 */, unchecked((long) 0x8D970ACDD7289AF5L) /* 529 */, + unchecked((long) 0x8F96E8E031C8C25EL) /* 530 */, unchecked((long) 0xF3FEC02276875D47L) /* 531 */, + unchecked((long) 0xEC7BF310056190DDL) /* 532 */, unchecked((long) 0xF5ADB0AEBB0F1491L) /* 533 */, + unchecked((long) 0x9B50F8850FD58892L) /* 534 */, unchecked((long) 0x4975488358B74DE8L) /* 535 */, + unchecked((long) 0xA3354FF691531C61L) /* 536 */, unchecked((long) 0x0702BBE481D2C6EEL) /* 537 */, + unchecked((long) 0x89FB24057DEDED98L) /* 538 */, unchecked((long) 0xAC3075138596E902L) /* 539 */, + unchecked((long) 0x1D2D3580172772EDL) /* 540 */, unchecked((long) 0xEB738FC28E6BC30DL) /* 541 */, + unchecked((long) 0x5854EF8F63044326L) /* 542 */, unchecked((long) 0x9E5C52325ADD3BBEL) /* 543 */, + unchecked((long) 0x90AA53CF325C4623L) /* 544 */, unchecked((long) 0xC1D24D51349DD067L) /* 545 */, + unchecked((long) 0x2051CFEEA69EA624L) /* 546 */, unchecked((long) 0x13220F0A862E7E4FL) /* 547 */, + unchecked((long) 0xCE39399404E04864L) /* 548 */, unchecked((long) 0xD9C42CA47086FCB7L) /* 549 */, + unchecked((long) 0x685AD2238A03E7CCL) /* 550 */, unchecked((long) 0x066484B2AB2FF1DBL) /* 551 */, + unchecked((long) 0xFE9D5D70EFBF79ECL) /* 552 */, unchecked((long) 0x5B13B9DD9C481854L) /* 553 */, + unchecked((long) 0x15F0D475ED1509ADL) /* 554 */, unchecked((long) 0x0BEBCD060EC79851L) /* 555 */, + unchecked((long) 0xD58C6791183AB7F8L) /* 556 */, unchecked((long) 0xD1187C5052F3EEE4L) /* 557 */, + unchecked((long) 0xC95D1192E54E82FFL) /* 558 */, unchecked((long) 0x86EEA14CB9AC6CA2L) /* 559 */, + unchecked((long) 0x3485BEB153677D5DL) /* 560 */, unchecked((long) 0xDD191D781F8C492AL) /* 561 */, + unchecked((long) 0xF60866BAA784EBF9L) /* 562 */, unchecked((long) 0x518F643BA2D08C74L) /* 563 */, + unchecked((long) 0x8852E956E1087C22L) /* 564 */, unchecked((long) 0xA768CB8DC410AE8DL) /* 565 */, + unchecked((long) 0x38047726BFEC8E1AL) /* 566 */, unchecked((long) 0xA67738B4CD3B45AAL) /* 567 */, + unchecked((long) 0xAD16691CEC0DDE19L) /* 568 */, unchecked((long) 0xC6D4319380462E07L) /* 569 */, + unchecked((long) 0xC5A5876D0BA61938L) /* 570 */, unchecked((long) 0x16B9FA1FA58FD840L) /* 571 */, + unchecked((long) 0x188AB1173CA74F18L) /* 572 */, unchecked((long) 0xABDA2F98C99C021FL) /* 573 */, + unchecked((long) 0x3E0580AB134AE816L) /* 574 */, unchecked((long) 0x5F3B05B773645ABBL) /* 575 */, + unchecked((long) 0x2501A2BE5575F2F6L) /* 576 */, unchecked((long) 0x1B2F74004E7E8BA9L) /* 577 */, + unchecked((long) 0x1CD7580371E8D953L) /* 578 */, unchecked((long) 0x7F6ED89562764E30L) /* 579 */, + unchecked((long) 0xB15926FF596F003DL) /* 580 */, unchecked((long) 0x9F65293DA8C5D6B9L) /* 581 */, + unchecked((long) 0x6ECEF04DD690F84CL) /* 582 */, unchecked((long) 0x4782275FFF33AF88L) /* 583 */, + unchecked((long) 0xE41433083F820801L) /* 584 */, unchecked((long) 0xFD0DFE409A1AF9B5L) /* 585 */, + unchecked((long) 0x4325A3342CDB396BL) /* 586 */, unchecked((long) 0x8AE77E62B301B252L) /* 587 */, + unchecked((long) 0xC36F9E9F6655615AL) /* 588 */, unchecked((long) 0x85455A2D92D32C09L) /* 589 */, + unchecked((long) 0xF2C7DEA949477485L) /* 590 */, unchecked((long) 0x63CFB4C133A39EBAL) /* 591 */, + unchecked((long) 0x83B040CC6EBC5462L) /* 592 */, unchecked((long) 0x3B9454C8FDB326B0L) /* 593 */, + unchecked((long) 0x56F56A9E87FFD78CL) /* 594 */, unchecked((long) 0x2DC2940D99F42BC6L) /* 595 */, + unchecked((long) 0x98F7DF096B096E2DL) /* 596 */, unchecked((long) 0x19A6E01E3AD852BFL) /* 597 */, + unchecked((long) 0x42A99CCBDBD4B40BL) /* 598 */, unchecked((long) 0xA59998AF45E9C559L) /* 599 */, + unchecked((long) 0x366295E807D93186L) /* 600 */, unchecked((long) 0x6B48181BFAA1F773L) /* 601 */, + unchecked((long) 0x1FEC57E2157A0A1DL) /* 602 */, unchecked((long) 0x4667446AF6201AD5L) /* 603 */, + unchecked((long) 0xE615EBCACFB0F075L) /* 604 */, unchecked((long) 0xB8F31F4F68290778L) /* 605 */, + unchecked((long) 0x22713ED6CE22D11EL) /* 606 */, unchecked((long) 0x3057C1A72EC3C93BL) /* 607 */, + unchecked((long) 0xCB46ACC37C3F1F2FL) /* 608 */, unchecked((long) 0xDBB893FD02AAF50EL) /* 609 */, + unchecked((long) 0x331FD92E600B9FCFL) /* 610 */, unchecked((long) 0xA498F96148EA3AD6L) /* 611 */, + unchecked((long) 0xA8D8426E8B6A83EAL) /* 612 */, unchecked((long) 0xA089B274B7735CDCL) /* 613 */, + unchecked((long) 0x87F6B3731E524A11L) /* 614 */, unchecked((long) 0x118808E5CBC96749L) /* 615 */, + unchecked((long) 0x9906E4C7B19BD394L) /* 616 */, unchecked((long) 0xAFED7F7E9B24A20CL) /* 617 */, + unchecked((long) 0x6509EADEEB3644A7L) /* 618 */, unchecked((long) 0x6C1EF1D3E8EF0EDEL) /* 619 */, + unchecked((long) 0xB9C97D43E9798FB4L) /* 620 */, unchecked((long) 0xA2F2D784740C28A3L) /* 621 */, + unchecked((long) 0x7B8496476197566FL) /* 622 */, unchecked((long) 0x7A5BE3E6B65F069DL) /* 623 */, + unchecked((long) 0xF96330ED78BE6F10L) /* 624 */, unchecked((long) 0xEEE60DE77A076A15L) /* 625 */, + unchecked((long) 0x2B4BEE4AA08B9BD0L) /* 626 */, unchecked((long) 0x6A56A63EC7B8894EL) /* 627 */, + unchecked((long) 0x02121359BA34FEF4L) /* 628 */, unchecked((long) 0x4CBF99F8283703FCL) /* 629 */, + unchecked((long) 0x398071350CAF30C8L) /* 630 */, unchecked((long) 0xD0A77A89F017687AL) /* 631 */, + unchecked((long) 0xF1C1A9EB9E423569L) /* 632 */, unchecked((long) 0x8C7976282DEE8199L) /* 633 */, + unchecked((long) 0x5D1737A5DD1F7ABDL) /* 634 */, unchecked((long) 0x4F53433C09A9FA80L) /* 635 */, + unchecked((long) 0xFA8B0C53DF7CA1D9L) /* 636 */, unchecked((long) 0x3FD9DCBC886CCB77L) /* 637 */, + unchecked((long) 0xC040917CA91B4720L) /* 638 */, unchecked((long) 0x7DD00142F9D1DCDFL) /* 639 */, + unchecked((long) 0x8476FC1D4F387B58L) /* 640 */, unchecked((long) 0x23F8E7C5F3316503L) /* 641 */, + unchecked((long) 0x032A2244E7E37339L) /* 642 */, unchecked((long) 0x5C87A5D750F5A74BL) /* 643 */, + unchecked((long) 0x082B4CC43698992EL) /* 644 */, unchecked((long) 0xDF917BECB858F63CL) /* 645 */, + unchecked((long) 0x3270B8FC5BF86DDAL) /* 646 */, unchecked((long) 0x10AE72BB29B5DD76L) /* 647 */, + unchecked((long) 0x576AC94E7700362BL) /* 648 */, unchecked((long) 0x1AD112DAC61EFB8FL) /* 649 */, + unchecked((long) 0x691BC30EC5FAA427L) /* 650 */, unchecked((long) 0xFF246311CC327143L) /* 651 */, + unchecked((long) 0x3142368E30E53206L) /* 652 */, unchecked((long) 0x71380E31E02CA396L) /* 653 */, + unchecked((long) 0x958D5C960AAD76F1L) /* 654 */, unchecked((long) 0xF8D6F430C16DA536L) /* 655 */, + unchecked((long) 0xC8FFD13F1BE7E1D2L) /* 656 */, unchecked((long) 0x7578AE66004DDBE1L) /* 657 */, + unchecked((long) 0x05833F01067BE646L) /* 658 */, unchecked((long) 0xBB34B5AD3BFE586DL) /* 659 */, + unchecked((long) 0x095F34C9A12B97F0L) /* 660 */, unchecked((long) 0x247AB64525D60CA8L) /* 661 */, + unchecked((long) 0xDCDBC6F3017477D1L) /* 662 */, unchecked((long) 0x4A2E14D4DECAD24DL) /* 663 */, + unchecked((long) 0xBDB5E6D9BE0A1EEBL) /* 664 */, unchecked((long) 0x2A7E70F7794301ABL) /* 665 */, + unchecked((long) 0xDEF42D8A270540FDL) /* 666 */, unchecked((long) 0x01078EC0A34C22C1L) /* 667 */, + unchecked((long) 0xE5DE511AF4C16387L) /* 668 */, unchecked((long) 0x7EBB3A52BD9A330AL) /* 669 */, + unchecked((long) 0x77697857AA7D6435L) /* 670 */, unchecked((long) 0x004E831603AE4C32L) /* 671 */, + unchecked((long) 0xE7A21020AD78E312L) /* 672 */, unchecked((long) 0x9D41A70C6AB420F2L) /* 673 */, + unchecked((long) 0x28E06C18EA1141E6L) /* 674 */, unchecked((long) 0xD2B28CBD984F6B28L) /* 675 */, + unchecked((long) 0x26B75F6C446E9D83L) /* 676 */, unchecked((long) 0xBA47568C4D418D7FL) /* 677 */, + unchecked((long) 0xD80BADBFE6183D8EL) /* 678 */, unchecked((long) 0x0E206D7F5F166044L) /* 679 */, + unchecked((long) 0xE258A43911CBCA3EL) /* 680 */, unchecked((long) 0x723A1746B21DC0BCL) /* 681 */, + unchecked((long) 0xC7CAA854F5D7CDD3L) /* 682 */, unchecked((long) 0x7CAC32883D261D9CL) /* 683 */, + unchecked((long) 0x7690C26423BA942CL) /* 684 */, unchecked((long) 0x17E55524478042B8L) /* 685 */, + unchecked((long) 0xE0BE477656A2389FL) /* 686 */, unchecked((long) 0x4D289B5E67AB2DA0L) /* 687 */, + unchecked((long) 0x44862B9C8FBBFD31L) /* 688 */, unchecked((long) 0xB47CC8049D141365L) /* 689 */, + unchecked((long) 0x822C1B362B91C793L) /* 690 */, unchecked((long) 0x4EB14655FB13DFD8L) /* 691 */, + unchecked((long) 0x1ECBBA0714E2A97BL) /* 692 */, unchecked((long) 0x6143459D5CDE5F14L) /* 693 */, + unchecked((long) 0x53A8FBF1D5F0AC89L) /* 694 */, unchecked((long) 0x97EA04D81C5E5B00L) /* 695 */, + unchecked((long) 0x622181A8D4FDB3F3L) /* 696 */, unchecked((long) 0xE9BCD341572A1208L) /* 697 */, + unchecked((long) 0x1411258643CCE58AL) /* 698 */, unchecked((long) 0x9144C5FEA4C6E0A4L) /* 699 */, + unchecked((long) 0x0D33D06565CF620FL) /* 700 */, unchecked((long) 0x54A48D489F219CA1L) /* 701 */, + unchecked((long) 0xC43E5EAC6D63C821L) /* 702 */, unchecked((long) 0xA9728B3A72770DAFL) /* 703 */, + unchecked((long) 0xD7934E7B20DF87EFL) /* 704 */, unchecked((long) 0xE35503B61A3E86E5L) /* 705 */, + unchecked((long) 0xCAE321FBC819D504L) /* 706 */, unchecked((long) 0x129A50B3AC60BFA6L) /* 707 */, + unchecked((long) 0xCD5E68EA7E9FB6C3L) /* 708 */, unchecked((long) 0xB01C90199483B1C7L) /* 709 */, + unchecked((long) 0x3DE93CD5C295376CL) /* 710 */, unchecked((long) 0xAED52EDF2AB9AD13L) /* 711 */, + unchecked((long) 0x2E60F512C0A07884L) /* 712 */, unchecked((long) 0xBC3D86A3E36210C9L) /* 713 */, + unchecked((long) 0x35269D9B163951CEL) /* 714 */, unchecked((long) 0x0C7D6E2AD0CDB5FAL) /* 715 */, + unchecked((long) 0x59E86297D87F5733L) /* 716 */, unchecked((long) 0x298EF221898DB0E7L) /* 717 */, + unchecked((long) 0x55000029D1A5AA7EL) /* 718 */, unchecked((long) 0x8BC08AE1B5061B45L) /* 719 */, + unchecked((long) 0xC2C31C2B6C92703AL) /* 720 */, unchecked((long) 0x94CC596BAF25EF42L) /* 721 */, + unchecked((long) 0x0A1D73DB22540456L) /* 722 */, unchecked((long) 0x04B6A0F9D9C4179AL) /* 723 */, + unchecked((long) 0xEFFDAFA2AE3D3C60L) /* 724 */, unchecked((long) 0xF7C8075BB49496C4L) /* 725 */, + unchecked((long) 0x9CC5C7141D1CD4E3L) /* 726 */, unchecked((long) 0x78BD1638218E5534L) /* 727 */, + unchecked((long) 0xB2F11568F850246AL) /* 728 */, unchecked((long) 0xEDFABCFA9502BC29L) /* 729 */, + unchecked((long) 0x796CE5F2DA23051BL) /* 730 */, unchecked((long) 0xAAE128B0DC93537CL) /* 731 */, + unchecked((long) 0x3A493DA0EE4B29AEL) /* 732 */, unchecked((long) 0xB5DF6B2C416895D7L) /* 733 */, + unchecked((long) 0xFCABBD25122D7F37L) /* 734 */, unchecked((long) 0x70810B58105DC4B1L) /* 735 */, + unchecked((long) 0xE10FDD37F7882A90L) /* 736 */, unchecked((long) 0x524DCAB5518A3F5CL) /* 737 */, + unchecked((long) 0x3C9E85878451255BL) /* 738 */, unchecked((long) 0x4029828119BD34E2L) /* 739 */, + unchecked((long) 0x74A05B6F5D3CECCBL) /* 740 */, unchecked((long) 0xB610021542E13ECAL) /* 741 */, + unchecked((long) 0x0FF979D12F59E2ACL) /* 742 */, unchecked((long) 0x6037DA27E4F9CC50L) /* 743 */, + unchecked((long) 0x5E92975A0DF1847DL) /* 744 */, unchecked((long) 0xD66DE190D3E623FEL) /* 745 */, + unchecked((long) 0x5032D6B87B568048L) /* 746 */, unchecked((long) 0x9A36B7CE8235216EL) /* 747 */, + unchecked((long) 0x80272A7A24F64B4AL) /* 748 */, unchecked((long) 0x93EFED8B8C6916F7L) /* 749 */, + unchecked((long) 0x37DDBFF44CCE1555L) /* 750 */, unchecked((long) 0x4B95DB5D4B99BD25L) /* 751 */, + unchecked((long) 0x92D3FDA169812FC0L) /* 752 */, unchecked((long) 0xFB1A4A9A90660BB6L) /* 753 */, + unchecked((long) 0x730C196946A4B9B2L) /* 754 */, unchecked((long) 0x81E289AA7F49DA68L) /* 755 */, + unchecked((long) 0x64669A0F83B1A05FL) /* 756 */, unchecked((long) 0x27B3FF7D9644F48BL) /* 757 */, + unchecked((long) 0xCC6B615C8DB675B3L) /* 758 */, unchecked((long) 0x674F20B9BCEBBE95L) /* 759 */, + unchecked((long) 0x6F31238275655982L) /* 760 */, unchecked((long) 0x5AE488713E45CF05L) /* 761 */, + unchecked((long) 0xBF619F9954C21157L) /* 762 */, unchecked((long) 0xEABAC46040A8EAE9L) /* 763 */, + unchecked((long) 0x454C6FE9F2C0C1CDL) /* 764 */, unchecked((long) 0x419CF6496412691CL) /* 765 */, + unchecked((long) 0xD3DC3BEF265B0F70L) /* 766 */, unchecked((long) 0x6D0E60F5C3578A9EL) /* 767 */, + }; + + private static readonly long[] t4 = { + unchecked((long) 0x5B0E608526323C55L) /* 768 */, unchecked((long) 0x1A46C1A9FA1B59F5L) /* 769 */, + unchecked((long) 0xA9E245A17C4C8FFAL) /* 770 */, unchecked((long) 0x65CA5159DB2955D7L) /* 771 */, + unchecked((long) 0x05DB0A76CE35AFC2L) /* 772 */, unchecked((long) 0x81EAC77EA9113D45L) /* 773 */, + unchecked((long) 0x528EF88AB6AC0A0DL) /* 774 */, unchecked((long) 0xA09EA253597BE3FFL) /* 775 */, + unchecked((long) 0x430DDFB3AC48CD56L) /* 776 */, unchecked((long) 0xC4B3A67AF45CE46FL) /* 777 */, + unchecked((long) 0x4ECECFD8FBE2D05EL) /* 778 */, unchecked((long) 0x3EF56F10B39935F0L) /* 779 */, + unchecked((long) 0x0B22D6829CD619C6L) /* 780 */, unchecked((long) 0x17FD460A74DF2069L) /* 781 */, + unchecked((long) 0x6CF8CC8E8510ED40L) /* 782 */, unchecked((long) 0xD6C824BF3A6ECAA7L) /* 783 */, + unchecked((long) 0x61243D581A817049L) /* 784 */, unchecked((long) 0x048BACB6BBC163A2L) /* 785 */, + unchecked((long) 0xD9A38AC27D44CC32L) /* 786 */, unchecked((long) 0x7FDDFF5BAAF410ABL) /* 787 */, + unchecked((long) 0xAD6D495AA804824BL) /* 788 */, unchecked((long) 0xE1A6A74F2D8C9F94L) /* 789 */, + unchecked((long) 0xD4F7851235DEE8E3L) /* 790 */, unchecked((long) 0xFD4B7F886540D893L) /* 791 */, + unchecked((long) 0x247C20042AA4BFDAL) /* 792 */, unchecked((long) 0x096EA1C517D1327CL) /* 793 */, + unchecked((long) 0xD56966B4361A6685L) /* 794 */, unchecked((long) 0x277DA5C31221057DL) /* 795 */, + unchecked((long) 0x94D59893A43ACFF7L) /* 796 */, unchecked((long) 0x64F0C51CCDC02281L) /* 797 */, + unchecked((long) 0x3D33BCC4FF6189DBL) /* 798 */, unchecked((long) 0xE005CB184CE66AF1L) /* 799 */, + unchecked((long) 0xFF5CCD1D1DB99BEAL) /* 800 */, unchecked((long) 0xB0B854A7FE42980FL) /* 801 */, + unchecked((long) 0x7BD46A6A718D4B9FL) /* 802 */, unchecked((long) 0xD10FA8CC22A5FD8CL) /* 803 */, + unchecked((long) 0xD31484952BE4BD31L) /* 804 */, unchecked((long) 0xC7FA975FCB243847L) /* 805 */, + unchecked((long) 0x4886ED1E5846C407L) /* 806 */, unchecked((long) 0x28CDDB791EB70B04L) /* 807 */, + unchecked((long) 0xC2B00BE2F573417FL) /* 808 */, unchecked((long) 0x5C9590452180F877L) /* 809 */, + unchecked((long) 0x7A6BDDFFF370EB00L) /* 810 */, unchecked((long) 0xCE509E38D6D9D6A4L) /* 811 */, + unchecked((long) 0xEBEB0F00647FA702L) /* 812 */, unchecked((long) 0x1DCC06CF76606F06L) /* 813 */, + unchecked((long) 0xE4D9F28BA286FF0AL) /* 814 */, unchecked((long) 0xD85A305DC918C262L) /* 815 */, + unchecked((long) 0x475B1D8732225F54L) /* 816 */, unchecked((long) 0x2D4FB51668CCB5FEL) /* 817 */, + unchecked((long) 0xA679B9D9D72BBA20L) /* 818 */, unchecked((long) 0x53841C0D912D43A5L) /* 819 */, + unchecked((long) 0x3B7EAA48BF12A4E8L) /* 820 */, unchecked((long) 0x781E0E47F22F1DDFL) /* 821 */, + unchecked((long) 0xEFF20CE60AB50973L) /* 822 */, unchecked((long) 0x20D261D19DFFB742L) /* 823 */, + unchecked((long) 0x16A12B03062A2E39L) /* 824 */, unchecked((long) 0x1960EB2239650495L) /* 825 */, + unchecked((long) 0x251C16FED50EB8B8L) /* 826 */, unchecked((long) 0x9AC0C330F826016EL) /* 827 */, + unchecked((long) 0xED152665953E7671L) /* 828 */, unchecked((long) 0x02D63194A6369570L) /* 829 */, + unchecked((long) 0x5074F08394B1C987L) /* 830 */, unchecked((long) 0x70BA598C90B25CE1L) /* 831 */, + unchecked((long) 0x794A15810B9742F6L) /* 832 */, unchecked((long) 0x0D5925E9FCAF8C6CL) /* 833 */, + unchecked((long) 0x3067716CD868744EL) /* 834 */, unchecked((long) 0x910AB077E8D7731BL) /* 835 */, + unchecked((long) 0x6A61BBDB5AC42F61L) /* 836 */, unchecked((long) 0x93513EFBF0851567L) /* 837 */, + unchecked((long) 0xF494724B9E83E9D5L) /* 838 */, unchecked((long) 0xE887E1985C09648DL) /* 839 */, + unchecked((long) 0x34B1D3C675370CFDL) /* 840 */, unchecked((long) 0xDC35E433BC0D255DL) /* 841 */, + unchecked((long) 0xD0AAB84234131BE0L) /* 842 */, unchecked((long) 0x08042A50B48B7EAFL) /* 843 */, + unchecked((long) 0x9997C4EE44A3AB35L) /* 844 */, unchecked((long) 0x829A7B49201799D0L) /* 845 */, + unchecked((long) 0x263B8307B7C54441L) /* 846 */, unchecked((long) 0x752F95F4FD6A6CA6L) /* 847 */, + unchecked((long) 0x927217402C08C6E5L) /* 848 */, unchecked((long) 0x2A8AB754A795D9EEL) /* 849 */, + unchecked((long) 0xA442F7552F72943DL) /* 850 */, unchecked((long) 0x2C31334E19781208L) /* 851 */, + unchecked((long) 0x4FA98D7CEAEE6291L) /* 852 */, unchecked((long) 0x55C3862F665DB309L) /* 853 */, + unchecked((long) 0xBD0610175D53B1F3L) /* 854 */, unchecked((long) 0x46FE6CB840413F27L) /* 855 */, + unchecked((long) 0x3FE03792DF0CFA59L) /* 856 */, unchecked((long) 0xCFE700372EB85E8FL) /* 857 */, + unchecked((long) 0xA7BE29E7ADBCE118L) /* 858 */, unchecked((long) 0xE544EE5CDE8431DDL) /* 859 */, + unchecked((long) 0x8A781B1B41F1873EL) /* 860 */, unchecked((long) 0xA5C94C78A0D2F0E7L) /* 861 */, + unchecked((long) 0x39412E2877B60728L) /* 862 */, unchecked((long) 0xA1265EF3AFC9A62CL) /* 863 */, + unchecked((long) 0xBCC2770C6A2506C5L) /* 864 */, unchecked((long) 0x3AB66DD5DCE1CE12L) /* 865 */, + unchecked((long) 0xE65499D04A675B37L) /* 866 */, unchecked((long) 0x7D8F523481BFD216L) /* 867 */, + unchecked((long) 0x0F6F64FCEC15F389L) /* 868 */, unchecked((long) 0x74EFBE618B5B13C8L) /* 869 */, + unchecked((long) 0xACDC82B714273E1DL) /* 870 */, unchecked((long) 0xDD40BFE003199D17L) /* 871 */, + unchecked((long) 0x37E99257E7E061F8L) /* 872 */, unchecked((long) 0xFA52626904775AAAL) /* 873 */, + unchecked((long) 0x8BBBF63A463D56F9L) /* 874 */, unchecked((long) 0xF0013F1543A26E64L) /* 875 */, + unchecked((long) 0xA8307E9F879EC898L) /* 876 */, unchecked((long) 0xCC4C27A4150177CCL) /* 877 */, + unchecked((long) 0x1B432F2CCA1D3348L) /* 878 */, unchecked((long) 0xDE1D1F8F9F6FA013L) /* 879 */, + unchecked((long) 0x606602A047A7DDD6L) /* 880 */, unchecked((long) 0xD237AB64CC1CB2C7L) /* 881 */, + unchecked((long) 0x9B938E7225FCD1D3L) /* 882 */, unchecked((long) 0xEC4E03708E0FF476L) /* 883 */, + unchecked((long) 0xFEB2FBDA3D03C12DL) /* 884 */, unchecked((long) 0xAE0BCED2EE43889AL) /* 885 */, + unchecked((long) 0x22CB8923EBFB4F43L) /* 886 */, unchecked((long) 0x69360D013CF7396DL) /* 887 */, + unchecked((long) 0x855E3602D2D4E022L) /* 888 */, unchecked((long) 0x073805BAD01F784CL) /* 889 */, + unchecked((long) 0x33E17A133852F546L) /* 890 */, unchecked((long) 0xDF4874058AC7B638L) /* 891 */, + unchecked((long) 0xBA92B29C678AA14AL) /* 892 */, unchecked((long) 0x0CE89FC76CFAADCDL) /* 893 */, + unchecked((long) 0x5F9D4E0908339E34L) /* 894 */, unchecked((long) 0xF1AFE9291F5923B9L) /* 895 */, + unchecked((long) 0x6E3480F60F4A265FL) /* 896 */, unchecked((long) 0xEEBF3A2AB29B841CL) /* 897 */, + unchecked((long) 0xE21938A88F91B4ADL) /* 898 */, unchecked((long) 0x57DFEFF845C6D3C3L) /* 899 */, + unchecked((long) 0x2F006B0BF62CAAF2L) /* 900 */, unchecked((long) 0x62F479EF6F75EE78L) /* 901 */, + unchecked((long) 0x11A55AD41C8916A9L) /* 902 */, unchecked((long) 0xF229D29084FED453L) /* 903 */, + unchecked((long) 0x42F1C27B16B000E6L) /* 904 */, unchecked((long) 0x2B1F76749823C074L) /* 905 */, + unchecked((long) 0x4B76ECA3C2745360L) /* 906 */, unchecked((long) 0x8C98F463B91691BDL) /* 907 */, + unchecked((long) 0x14BCC93CF1ADE66AL) /* 908 */, unchecked((long) 0x8885213E6D458397L) /* 909 */, + unchecked((long) 0x8E177DF0274D4711L) /* 910 */, unchecked((long) 0xB49B73B5503F2951L) /* 911 */, + unchecked((long) 0x10168168C3F96B6BL) /* 912 */, unchecked((long) 0x0E3D963B63CAB0AEL) /* 913 */, + unchecked((long) 0x8DFC4B5655A1DB14L) /* 914 */, unchecked((long) 0xF789F1356E14DE5CL) /* 915 */, + unchecked((long) 0x683E68AF4E51DAC1L) /* 916 */, unchecked((long) 0xC9A84F9D8D4B0FD9L) /* 917 */, + unchecked((long) 0x3691E03F52A0F9D1L) /* 918 */, unchecked((long) 0x5ED86E46E1878E80L) /* 919 */, + unchecked((long) 0x3C711A0E99D07150L) /* 920 */, unchecked((long) 0x5A0865B20C4E9310L) /* 921 */, + unchecked((long) 0x56FBFC1FE4F0682EL) /* 922 */, unchecked((long) 0xEA8D5DE3105EDF9BL) /* 923 */, + unchecked((long) 0x71ABFDB12379187AL) /* 924 */, unchecked((long) 0x2EB99DE1BEE77B9CL) /* 925 */, + unchecked((long) 0x21ECC0EA33CF4523L) /* 926 */, unchecked((long) 0x59A4D7521805C7A1L) /* 927 */, + unchecked((long) 0x3896F5EB56AE7C72L) /* 928 */, unchecked((long) 0xAA638F3DB18F75DCL) /* 929 */, + unchecked((long) 0x9F39358DABE9808EL) /* 930 */, unchecked((long) 0xB7DEFA91C00B72ACL) /* 931 */, + unchecked((long) 0x6B5541FD62492D92L) /* 932 */, unchecked((long) 0x6DC6DEE8F92E4D5BL) /* 933 */, + unchecked((long) 0x353F57ABC4BEEA7EL) /* 934 */, unchecked((long) 0x735769D6DA5690CEL) /* 935 */, + unchecked((long) 0x0A234AA642391484L) /* 936 */, unchecked((long) 0xF6F9508028F80D9DL) /* 937 */, + unchecked((long) 0xB8E319A27AB3F215L) /* 938 */, unchecked((long) 0x31AD9C1151341A4DL) /* 939 */, + unchecked((long) 0x773C22A57BEF5805L) /* 940 */, unchecked((long) 0x45C7561A07968633L) /* 941 */, + unchecked((long) 0xF913DA9E249DBE36L) /* 942 */, unchecked((long) 0xDA652D9B78A64C68L) /* 943 */, + unchecked((long) 0x4C27A97F3BC334EFL) /* 944 */, unchecked((long) 0x76621220E66B17F4L) /* 945 */, + unchecked((long) 0x967743899ACD7D0BL) /* 946 */, unchecked((long) 0xF3EE5BCAE0ED6782L) /* 947 */, + unchecked((long) 0x409F753600C879FCL) /* 948 */, unchecked((long) 0x06D09A39B5926DB6L) /* 949 */, + unchecked((long) 0x6F83AEB0317AC588L) /* 950 */, unchecked((long) 0x01E6CA4A86381F21L) /* 951 */, + unchecked((long) 0x66FF3462D19F3025L) /* 952 */, unchecked((long) 0x72207C24DDFD3BFBL) /* 953 */, + unchecked((long) 0x4AF6B6D3E2ECE2EBL) /* 954 */, unchecked((long) 0x9C994DBEC7EA08DEL) /* 955 */, + unchecked((long) 0x49ACE597B09A8BC4L) /* 956 */, unchecked((long) 0xB38C4766CF0797BAL) /* 957 */, + unchecked((long) 0x131B9373C57C2A75L) /* 958 */, unchecked((long) 0xB1822CCE61931E58L) /* 959 */, + unchecked((long) 0x9D7555B909BA1C0CL) /* 960 */, unchecked((long) 0x127FAFDD937D11D2L) /* 961 */, + unchecked((long) 0x29DA3BADC66D92E4L) /* 962 */, unchecked((long) 0xA2C1D57154C2ECBCL) /* 963 */, + unchecked((long) 0x58C5134D82F6FE24L) /* 964 */, unchecked((long) 0x1C3AE3515B62274FL) /* 965 */, + unchecked((long) 0xE907C82E01CB8126L) /* 966 */, unchecked((long) 0xF8ED091913E37FCBL) /* 967 */, + unchecked((long) 0x3249D8F9C80046C9L) /* 968 */, unchecked((long) 0x80CF9BEDE388FB63L) /* 969 */, + unchecked((long) 0x1881539A116CF19EL) /* 970 */, unchecked((long) 0x5103F3F76BD52457L) /* 971 */, + unchecked((long) 0x15B7E6F5AE47F7A8L) /* 972 */, unchecked((long) 0xDBD7C6DED47E9CCFL) /* 973 */, + unchecked((long) 0x44E55C410228BB1AL) /* 974 */, unchecked((long) 0xB647D4255EDB4E99L) /* 975 */, + unchecked((long) 0x5D11882BB8AAFC30L) /* 976 */, unchecked((long) 0xF5098BBB29D3212AL) /* 977 */, + unchecked((long) 0x8FB5EA14E90296B3L) /* 978 */, unchecked((long) 0x677B942157DD025AL) /* 979 */, + unchecked((long) 0xFB58E7C0A390ACB5L) /* 980 */, unchecked((long) 0x89D3674C83BD4A01L) /* 981 */, + unchecked((long) 0x9E2DA4DF4BF3B93BL) /* 982 */, unchecked((long) 0xFCC41E328CAB4829L) /* 983 */, + unchecked((long) 0x03F38C96BA582C52L) /* 984 */, unchecked((long) 0xCAD1BDBD7FD85DB2L) /* 985 */, + unchecked((long) 0xBBB442C16082AE83L) /* 986 */, unchecked((long) 0xB95FE86BA5DA9AB0L) /* 987 */, + unchecked((long) 0xB22E04673771A93FL) /* 988 */, unchecked((long) 0x845358C9493152D8L) /* 989 */, + unchecked((long) 0xBE2A488697B4541EL) /* 990 */, unchecked((long) 0x95A2DC2DD38E6966L) /* 991 */, + unchecked((long) 0xC02C11AC923C852BL) /* 992 */, unchecked((long) 0x2388B1990DF2A87BL) /* 993 */, + unchecked((long) 0x7C8008FA1B4F37BEL) /* 994 */, unchecked((long) 0x1F70D0C84D54E503L) /* 995 */, + unchecked((long) 0x5490ADEC7ECE57D4L) /* 996 */, unchecked((long) 0x002B3C27D9063A3AL) /* 997 */, + unchecked((long) 0x7EAEA3848030A2BFL) /* 998 */, unchecked((long) 0xC602326DED2003C0L) /* 999 */, + unchecked((long) 0x83A7287D69A94086L) /* 1000 */, unchecked((long) 0xC57A5FCB30F57A8AL) /* 1001 */, + unchecked((long) 0xB56844E479EBE779L) /* 1002 */, unchecked((long) 0xA373B40F05DCBCE9L) /* 1003 */, + unchecked((long) 0xD71A786E88570EE2L) /* 1004 */, unchecked((long) 0x879CBACDBDE8F6A0L) /* 1005 */, + unchecked((long) 0x976AD1BCC164A32FL) /* 1006 */, unchecked((long) 0xAB21E25E9666D78BL) /* 1007 */, + unchecked((long) 0x901063AAE5E5C33CL) /* 1008 */, unchecked((long) 0x9818B34448698D90L) /* 1009 */, + unchecked((long) 0xE36487AE3E1E8ABBL) /* 1010 */, unchecked((long) 0xAFBDF931893BDCB4L) /* 1011 */, + unchecked((long) 0x6345A0DC5FBBD519L) /* 1012 */, unchecked((long) 0x8628FE269B9465CAL) /* 1013 */, + unchecked((long) 0x1E5D01603F9C51ECL) /* 1014 */, unchecked((long) 0x4DE44006A15049B7L) /* 1015 */, + unchecked((long) 0xBF6C70E5F776CBB1L) /* 1016 */, unchecked((long) 0x411218F2EF552BEDL) /* 1017 */, + unchecked((long) 0xCB0C0708705A36A3L) /* 1018 */, unchecked((long) 0xE74D14754F986044L) /* 1019 */, + unchecked((long) 0xCD56D9430EA8280EL) /* 1020 */, unchecked((long) 0xC12591D7535F5065L) /* 1021 */, + unchecked((long) 0xC83223F1720AEF96L) /* 1022 */, unchecked((long) 0xC3A0396F7363A51FL) /* 1023 */ + }; + + private const int DigestLength = 24; + + // + // registers + // + private long a, b, c; + private long byteCount; + + // + // buffers + // + private byte[] Buffer = new byte[8]; + private int bOff; + + private long[] x = new long[8]; + private int xOff; + + /** + * Standard constructor + */ + public TigerDigest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public TigerDigest(TigerDigest t) + { + Reset(t); + } + + public string AlgorithmName + { + get { return "Tiger"; } + } + + public int GetDigestSize() + { + return DigestLength; + } + + public int GetByteLength() + { + return MyByteLength; + } + + private void ProcessWord( + byte[] b, + int off) + { + x[xOff++] = ((long)(b[off + 7] & 0xff) << 56) + | ((long)(b[off + 6] & 0xff) << 48) + | ((long)(b[off + 5] & 0xff) << 40) + | ((long)(b[off + 4] & 0xff) << 32) + | ((long)(b[off + 3] & 0xff) << 24) + | ((long)(b[off + 2] & 0xff) << 16) + | ((long)(b[off + 1] & 0xff) << 8) + | ((uint)(b[off + 0] & 0xff)); + + if (xOff == x.Length) + { + ProcessBlock(); + } + + bOff = 0; + } + + public void Update( + byte input) + { + Buffer[bOff++] = input; + + if (bOff == Buffer.Length) + { + ProcessWord(Buffer, 0); + } + + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + // + // fill the current word + // + while ((bOff != 0) && (length > 0)) + { + Update(input[inOff]); + + inOff++; + length--; + } + + // + // process whole words. + // + while (length > 8) + { + ProcessWord(input, inOff); + + inOff += 8; + length -= 8; + byteCount += 8; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + + inOff++; + length--; + } + } + + private void RoundABC( + long x, + long mul) + { + c ^= x ; + a -= t1[(int)c & 0xff] ^ t2[(int)(c >> 16) & 0xff] + ^ t3[(int)(c >> 32) & 0xff] ^ t4[(int)(c >> 48) & 0xff]; + b += t4[(int)(c >> 8) & 0xff] ^ t3[(int)(c >> 24) & 0xff] + ^ t2[(int)(c >> 40) & 0xff] ^ t1[(int)(c >> 56) & 0xff]; + b *= mul; + } + + private void RoundBCA( + long x, + long mul) + { + a ^= x ; + b -= t1[(int)a & 0xff] ^ t2[(int)(a >> 16) & 0xff] + ^ t3[(int)(a >> 32) & 0xff] ^ t4[(int)(a >> 48) & 0xff]; + c += t4[(int)(a >> 8) & 0xff] ^ t3[(int)(a >> 24) & 0xff] + ^ t2[(int)(a >> 40) & 0xff] ^ t1[(int)(a >> 56) & 0xff]; + c *= mul; + } + + private void RoundCAB( + long x, + long mul) + { + b ^= x ; + c -= t1[(int)b & 0xff] ^ t2[(int)(b >> 16) & 0xff] + ^ t3[(int)(b >> 32) & 0xff] ^ t4[(int)(b >> 48) & 0xff]; + a += t4[(int)(b >> 8) & 0xff] ^ t3[(int)(b >> 24) & 0xff] + ^ t2[(int)(b >> 40) & 0xff] ^ t1[(int)(b >> 56) & 0xff]; + a *= mul; + } + + private void KeySchedule() + { + x[0] -= x[7] ^ unchecked ((long) 0xA5A5A5A5A5A5A5A5L); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1]) << 19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ (long) ((ulong) (~x[4]) >> 23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7]) << 19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ (long) ((ulong) (~x[2]) >> 23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ 0x0123456789ABCDEFL; + } + + private void ProcessBlock() + { + // + // save abc + // + long aa = a; + long bb = b; + long cc = c; + + // + // rounds and schedule + // + RoundABC(x[0], 5); + RoundBCA(x[1], 5); + RoundCAB(x[2], 5); + RoundABC(x[3], 5); + RoundBCA(x[4], 5); + RoundCAB(x[5], 5); + RoundABC(x[6], 5); + RoundBCA(x[7], 5); + + KeySchedule(); + + RoundCAB(x[0], 7); + RoundABC(x[1], 7); + RoundBCA(x[2], 7); + RoundCAB(x[3], 7); + RoundABC(x[4], 7); + RoundBCA(x[5], 7); + RoundCAB(x[6], 7); + RoundABC(x[7], 7); + + KeySchedule(); + + RoundBCA(x[0], 9); + RoundCAB(x[1], 9); + RoundABC(x[2], 9); + RoundBCA(x[3], 9); + RoundCAB(x[4], 9); + RoundABC(x[5], 9); + RoundBCA(x[6], 9); + RoundCAB(x[7], 9); + + // + // feed forward + // + a ^= aa; + b -= bb; + c += cc; + + // + // clear the x buffer + // + xOff = 0; + for (int i = 0; i != x.Length; i++) + { + x[i] = 0; + } + } + + private void UnpackWord( + long r, + byte[] output, + int outOff) + { + output[outOff + 7] = (byte)(r >> 56); + output[outOff + 6] = (byte)(r >> 48); + output[outOff + 5] = (byte)(r >> 40); + output[outOff + 4] = (byte)(r >> 32); + output[outOff + 3] = (byte)(r >> 24); + output[outOff + 2] = (byte)(r >> 16); + output[outOff + 1] = (byte)(r >> 8); + output[outOff] = (byte)r; + } + + private void ProcessLength( + long bitLength) + { + x[7] = bitLength; + } + + private void Finish() + { + long bitLength = (byteCount << 3); + + Update((byte)0x01); + + while (bOff != 0) + { + Update((byte)0); + } + + ProcessLength(bitLength); + + ProcessBlock(); + } + + public int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(a, output, outOff); + UnpackWord(b, output, outOff + 8); + UnpackWord(c, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public void Reset() + { + a = unchecked((long) 0x0123456789ABCDEFL); + b = unchecked((long) 0xFEDCBA9876543210L); + c = unchecked((long) 0xF096A5B4C3B2E187L); + + xOff = 0; + for (int i = 0; i != x.Length; i++) + { + x[i] = 0; + } + + bOff = 0; + for (int i = 0; i != Buffer.Length; i++) + { + Buffer[i] = 0; + } + + byteCount = 0; + } + + public IMemoable Copy() + { + return new TigerDigest(this); + } + + public void Reset(IMemoable other) + { + TigerDigest t = (TigerDigest)other; + + a = t.a; + b = t.b; + c = t.c; + + Array.Copy(t.x, 0, x, 0, t.x.Length); + xOff = t.xOff; + + Array.Copy(t.Buffer, 0, Buffer, 0, t.Buffer.Length); + bOff = t.bOff; + + byteCount = t.byteCount; + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs.meta new file mode 100644 index 0000000..bc7c416 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/TigerDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 57fcb6394b1838042a143a9847924a08 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs new file mode 100644 index 0000000..162c61f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs @@ -0,0 +1,417 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Implementation of WhirlpoolDigest, based on Java source published by Barreto + * and Rijmen. + * + */ + public sealed class WhirlpoolDigest + : IDigest, IMemoable + { + private const int BYTE_LENGTH = 64; + + private const int DIGEST_LENGTH_BYTES = 512 / 8; + private const int ROUNDS = 10; + private const int REDUCTION_POLYNOMIAL = 0x011d; // 2^8 + 2^4 + 2^3 + 2 + 1; + + private static readonly int[] SBOX = + { + 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, + 0x60, 0xbc, 0x9b, 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, 0xfe, 0x57, + 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, + 0xbd, 0x5d, 0x10, 0xf4, 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, 0xd8, + 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33, + 0x63, 0x02, 0xaa, 0x71, 0xc8, 0x19, 0x49, 0xd9, 0xf2, 0xe3, 0x5b, 0x88, 0x9a, 0x26, 0x32, 0xb0, + 0xe9, 0x0f, 0xd5, 0x80, 0xbe, 0xcd, 0x34, 0x48, 0xff, 0x7a, 0x90, 0x5f, 0x20, 0x68, 0x1a, 0xae, + 0xb4, 0x54, 0x93, 0x22, 0x64, 0xf1, 0x73, 0x12, 0x40, 0x08, 0xc3, 0xec, 0xdb, 0xa1, 0x8d, 0x3d, + 0x97, 0x00, 0xcf, 0x2b, 0x76, 0x82, 0xd6, 0x1b, 0xb5, 0xaf, 0x6a, 0x50, 0x45, 0xf3, 0x30, 0xef, + 0x3f, 0x55, 0xa2, 0xea, 0x65, 0xba, 0x2f, 0xc0, 0xde, 0x1c, 0xfd, 0x4d, 0x92, 0x75, 0x06, 0x8a, + 0xb2, 0xe6, 0x0e, 0x1f, 0x62, 0xd4, 0xa8, 0x96, 0xf9, 0xc5, 0x25, 0x59, 0x84, 0x72, 0x39, 0x4c, + 0x5e, 0x78, 0x38, 0x8c, 0xd1, 0xa5, 0xe2, 0x61, 0xb3, 0x21, 0x9c, 0x1e, 0x43, 0xc7, 0xfc, 0x04, + 0x51, 0x99, 0x6d, 0x0d, 0xfa, 0xdf, 0x7e, 0x24, 0x3b, 0xab, 0xce, 0x11, 0x8f, 0x4e, 0xb7, 0xeb, + 0x3c, 0x81, 0x94, 0xf7, 0xb9, 0x13, 0x2c, 0xd3, 0xe7, 0x6e, 0xc4, 0x03, 0x56, 0x44, 0x7f, 0xa9, + 0x2a, 0xbb, 0xc1, 0x53, 0xdc, 0x0b, 0x9d, 0x6c, 0x31, 0x74, 0xf6, 0x46, 0xac, 0x89, 0x14, 0xe1, + 0x16, 0x3a, 0x69, 0x09, 0x70, 0xb6, 0xd0, 0xed, 0xcc, 0x42, 0x98, 0xa4, 0x28, 0x5c, 0xf8, 0x86 + }; + + private static readonly long[] C0 = new long[256]; + private static readonly long[] C1 = new long[256]; + private static readonly long[] C2 = new long[256]; + private static readonly long[] C3 = new long[256]; + private static readonly long[] C4 = new long[256]; + private static readonly long[] C5 = new long[256]; + private static readonly long[] C6 = new long[256]; + private static readonly long[] C7 = new long[256]; + + private readonly long[] _rc = new long[ROUNDS + 1]; + + /* + * increment() can be implemented in this way using 2 arrays or + * by having some temporary variables that are used to set the + * value provided by EIGHT[i] and carry within the loop. + * + * not having done any timing, this seems likely to be faster + * at the slight expense of 32*(sizeof short) bytes + */ + private static readonly short[] EIGHT = new short[BITCOUNT_ARRAY_SIZE]; + + static WhirlpoolDigest() + { + EIGHT[BITCOUNT_ARRAY_SIZE - 1] = 8; + + for (int i = 0; i < 256; i++) + { + int v1 = SBOX[i]; + int v2 = maskWithReductionPolynomial(v1 << 1); + int v4 = maskWithReductionPolynomial(v2 << 1); + int v5 = v4 ^ v1; + int v8 = maskWithReductionPolynomial(v4 << 1); + int v9 = v8 ^ v1; + + C0[i] = packIntoLong(v1, v1, v4, v1, v8, v5, v2, v9); + C1[i] = packIntoLong(v9, v1, v1, v4, v1, v8, v5, v2); + C2[i] = packIntoLong(v2, v9, v1, v1, v4, v1, v8, v5); + C3[i] = packIntoLong(v5, v2, v9, v1, v1, v4, v1, v8); + C4[i] = packIntoLong(v8, v5, v2, v9, v1, v1, v4, v1); + C5[i] = packIntoLong(v1, v8, v5, v2, v9, v1, v1, v4); + C6[i] = packIntoLong(v4, v1, v8, v5, v2, v9, v1, v1); + C7[i] = packIntoLong(v1, v4, v1, v8, v5, v2, v9, v1); + } + } + + public WhirlpoolDigest() + { + _rc[0] = 0L; + for (int r = 1; r <= ROUNDS; r++) + { + int i = 8 * (r - 1); + _rc[r] = (long)((ulong)C0[i] & 0xff00000000000000L) ^ + (C1[i + 1] & (long) 0x00ff000000000000L) ^ + (C2[i + 2] & (long) 0x0000ff0000000000L) ^ + (C3[i + 3] & (long) 0x000000ff00000000L) ^ + (C4[i + 4] & (long) 0x00000000ff000000L) ^ + (C5[i + 5] & (long) 0x0000000000ff0000L) ^ + (C6[i + 6] & (long) 0x000000000000ff00L) ^ + (C7[i + 7] & (long) 0x00000000000000ffL); + } + } + + private static long packIntoLong(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) + { + return + ((long)b7 << 56) ^ + ((long)b6 << 48) ^ + ((long)b5 << 40) ^ + ((long)b4 << 32) ^ + ((long)b3 << 24) ^ + ((long)b2 << 16) ^ + ((long)b1 << 8) ^ + b0; + } + + /* + * int's are used to prevent sign extension. The values that are really being used are + * actually just 0..255 + */ + private static int maskWithReductionPolynomial(int input) + { + int rv = input; + if (rv >= 0x100L) // high bit set + { + rv ^= REDUCTION_POLYNOMIAL; // reduced by the polynomial + } + return rv; + } + + // --------------------------------------------------------------------------------------// + + // -- buffer information -- + private const int BITCOUNT_ARRAY_SIZE = 32; + private byte[] _buffer = new byte[64]; + private int _bufferPos; + private short[] _bitCount = new short[BITCOUNT_ARRAY_SIZE]; + + // -- internal hash state -- + private long[] _hash = new long[8]; + private long[] _K = new long[8]; // the round key + private long[] _L = new long[8]; + private long[] _block = new long[8]; // mu (buffer) + private long[] _state = new long[8]; // the current "cipher" state + + + + /** + * Copy constructor. This will copy the state of the provided message + * digest. + */ + public WhirlpoolDigest(WhirlpoolDigest originalDigest) + { + Reset(originalDigest); + } + + public string AlgorithmName + { + get { return "Whirlpool"; } + } + + public int GetDigestSize() + { + return DIGEST_LENGTH_BYTES; + } + + public int DoFinal(byte[] output, int outOff) + { + // sets output[outOff] .. output[outOff+DIGEST_LENGTH_BYTES] + finish(); + + for (int i = 0; i < 8; i++) + { + convertLongToByteArray(_hash[i], output, outOff + (i * 8)); + } + + Reset(); + + return GetDigestSize(); + } + + /** + * Reset the chaining variables + */ + public void Reset() + { + // set variables to null, blank, whatever + _bufferPos = 0; + Array.Clear(_bitCount, 0, _bitCount.Length); + Array.Clear(_buffer, 0, _buffer.Length); + Array.Clear(_hash, 0, _hash.Length); + Array.Clear(_K, 0, _K.Length); + Array.Clear(_L, 0, _L.Length); + Array.Clear(_block, 0, _block.Length); + Array.Clear(_state, 0, _state.Length); + } + + // this takes a buffer of information and fills the block + private void processFilledBuffer() + { + // copies into the block... + for (int i = 0; i < _state.Length; i++) + { + _block[i] = bytesToLongFromBuffer(_buffer, i * 8); + } + processBlock(); + _bufferPos = 0; + Array.Clear(_buffer, 0, _buffer.Length); + } + + private static long bytesToLongFromBuffer(byte[] buffer, int startPos) + { + long rv = (((buffer[startPos + 0] & 0xffL) << 56) | + ((buffer[startPos + 1] & 0xffL) << 48) | + ((buffer[startPos + 2] & 0xffL) << 40) | + ((buffer[startPos + 3] & 0xffL) << 32) | + ((buffer[startPos + 4] & 0xffL) << 24) | + ((buffer[startPos + 5] & 0xffL) << 16) | + ((buffer[startPos + 6] & 0xffL) << 8) | + ((buffer[startPos + 7]) & 0xffL)); + + return rv; + } + + private static void convertLongToByteArray(long inputLong, byte[] outputArray, int offSet) + { + for (int i = 0; i < 8; i++) + { + outputArray[offSet + i] = (byte)((inputLong >> (56 - (i * 8))) & 0xff); + } + } + + private void processBlock() + { + // buffer contents have been transferred to the _block[] array via + // processFilledBuffer + + // compute and apply K^0 + for (int i = 0; i < 8; i++) + { + _state[i] = _block[i] ^ (_K[i] = _hash[i]); + } + + // iterate over the rounds + for (int round = 1; round <= ROUNDS; round++) + { + for (int i = 0; i < 8; i++) + { + _L[i] = 0; + _L[i] ^= C0[(int)(_K[(i - 0) & 7] >> 56) & 0xff]; + _L[i] ^= C1[(int)(_K[(i - 1) & 7] >> 48) & 0xff]; + _L[i] ^= C2[(int)(_K[(i - 2) & 7] >> 40) & 0xff]; + _L[i] ^= C3[(int)(_K[(i - 3) & 7] >> 32) & 0xff]; + _L[i] ^= C4[(int)(_K[(i - 4) & 7] >> 24) & 0xff]; + _L[i] ^= C5[(int)(_K[(i - 5) & 7] >> 16) & 0xff]; + _L[i] ^= C6[(int)(_K[(i - 6) & 7] >> 8) & 0xff]; + _L[i] ^= C7[(int)(_K[(i - 7) & 7]) & 0xff]; + } + + Array.Copy(_L, 0, _K, 0, _K.Length); + + _K[0] ^= _rc[round]; + + // apply the round transformation + for (int i = 0; i < 8; i++) + { + _L[i] = _K[i]; + + _L[i] ^= C0[(int)(_state[(i - 0) & 7] >> 56) & 0xff]; + _L[i] ^= C1[(int)(_state[(i - 1) & 7] >> 48) & 0xff]; + _L[i] ^= C2[(int)(_state[(i - 2) & 7] >> 40) & 0xff]; + _L[i] ^= C3[(int)(_state[(i - 3) & 7] >> 32) & 0xff]; + _L[i] ^= C4[(int)(_state[(i - 4) & 7] >> 24) & 0xff]; + _L[i] ^= C5[(int)(_state[(i - 5) & 7] >> 16) & 0xff]; + _L[i] ^= C6[(int)(_state[(i - 6) & 7] >> 8) & 0xff]; + _L[i] ^= C7[(int)(_state[(i - 7) & 7]) & 0xff]; + } + + // save the current state + Array.Copy(_L, 0, _state, 0, _state.Length); + } + + // apply Miuaguchi-Preneel compression + for (int i = 0; i < 8; i++) + { + _hash[i] ^= _state[i] ^ _block[i]; + } + + } + + public void Update(byte input) + { + _buffer[_bufferPos] = input; + + //Console.WriteLine("adding to buffer = "+_buffer[_bufferPos]); + + ++_bufferPos; + + if (_bufferPos == _buffer.Length) + { + processFilledBuffer(); + } + + increment(); + } + + private void increment() + { + int carry = 0; + for (int i = _bitCount.Length - 1; i >= 0; i--) + { + int sum = (_bitCount[i] & 0xff) + EIGHT[i] + carry; + + carry = sum >> 8; + _bitCount[i] = (short)(sum & 0xff); + } + } + + public void BlockUpdate(byte[] input, int inOff, int length) + { + while (length > 0) + { + Update(input[inOff]); + ++inOff; + --length; + } + + } + + private void finish() + { + /* + * this makes a copy of the current bit length. at the expense of an + * object creation of 32 bytes rather than providing a _stopCounting + * boolean which was the alternative I could think of. + */ + byte[] bitLength = copyBitLength(); + + _buffer[_bufferPos++] |= 0x80; + + if (_bufferPos == _buffer.Length) + { + processFilledBuffer(); + } + + /* + * Final block contains + * [ ... data .... ][0][0][0][ length ] + * + * if [ length ] cannot fit. Need to create a new block. + */ + if (_bufferPos > 32) + { + while (_bufferPos != 0) + { + Update((byte)0); + } + } + + while (_bufferPos <= 32) + { + Update((byte)0); + } + + // copy the length information to the final 32 bytes of the + // 64 byte block.... + Array.Copy(bitLength, 0, _buffer, 32, bitLength.Length); + + processFilledBuffer(); + } + + private byte[] copyBitLength() + { + byte[] rv = new byte[BITCOUNT_ARRAY_SIZE]; + for (int i = 0; i < rv.Length; i++) + { + rv[i] = (byte)(_bitCount[i] & 0xff); + } + return rv; + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + + public IMemoable Copy() + { + return new WhirlpoolDigest(this); + } + + public void Reset(IMemoable other) + { + WhirlpoolDigest originalDigest = (WhirlpoolDigest)other; + + Array.Copy(originalDigest._rc, 0, _rc, 0, _rc.Length); + + Array.Copy(originalDigest._buffer, 0, _buffer, 0, _buffer.Length); + + this._bufferPos = originalDigest._bufferPos; + Array.Copy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.Length); + + // -- internal hash state -- + Array.Copy(originalDigest._hash, 0, _hash, 0, _hash.Length); + Array.Copy(originalDigest._K, 0, _K, 0, _K.Length); + Array.Copy(originalDigest._L, 0, _L, 0, _L.Length); + Array.Copy(originalDigest._block, 0, _block, 0, _block.Length); + Array.Copy(originalDigest._state, 0, _state, 0, _state.Length); + } + + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs.meta new file mode 100644 index 0000000..b1d305b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/digests/WhirlpoolDigest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c1514667bb945848a2337e88af6340c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec.meta new file mode 100644 index 0000000..8361e8d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e0048515318c6fb408c1cc5edd0586a2 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs new file mode 100644 index 0000000..add0e44 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs @@ -0,0 +1,892 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Custom.Djb; +using Org.BouncyCastle.Math.EC.Custom.Sec; +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.EC +{ + public sealed class CustomNamedCurves + { + private CustomNamedCurves() + { + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.Decode(hex)); + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p) + { + return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create(); + } + + /* + * curve25519 + */ + internal class Curve25519Holder + : X9ECParametersHolder + { + private Curve25519Holder() { } + + internal static readonly X9ECParametersHolder Instance = new Curve25519Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new Curve25519()); + + /* + * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form + * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3). + * + * The Curve25519 paper doesn't say which of the two possible y values the base + * point has. The choice here is guided by language in the Ed25519 paper. + * + * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14) + */ + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A" + + "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9")); + + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp128r1 + */ + internal class SecP128R1Holder + : X9ECParametersHolder + { + private SecP128R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP128R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("000E0D4D696E6768756151750CC03A4473D03679"); + ECCurve curve = ConfigureCurve(new SecP128R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "161FF7528B899B2D0C28607CA52C5B86" + + "CF5AC8395BAFEB13C02DA292DDED7A83")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp160k1 + */ + internal class SecP160K1Holder + : X9ECParametersHolder + { + private SecP160K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP160K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), + new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176); + ECCurve curve = ConfigureCurveGlv(new SecP160K1Curve(), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" + + "938CF935318FDCED6BC28286531733C3F03C4FEE")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp160r1 + */ + internal class SecP160R1Holder + : X9ECParametersHolder + { + private SecP160R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP160R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("1053CDE42C14D696E67687561517533BF3F83345"); + ECCurve curve = ConfigureCurve(new SecP160R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "4A96B5688EF573284664698968C38BB913CBFC82" + + "23A628553168947D59DCC912042351377AC5FB32")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp160r2 + */ + internal class SecP160R2Holder + : X9ECParametersHolder + { + private SecP160R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP160R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("B99B99B099B323E02709A4D696E6768756151751"); + ECCurve curve = ConfigureCurve(new SecP160R2Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "52DCB034293A117E1F4FF11B30F7199D3144CE6D" + + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp192k1 + */ + internal class SecP192K1Holder + : X9ECParametersHolder + { + private SecP192K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP192K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), + new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208); + ECCurve curve = ConfigureCurveGlv(new SecP192K1Curve(), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" + + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp192r1 + */ + internal class SecP192R1Holder + : X9ECParametersHolder + { + private SecP192R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP192R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); + ECCurve curve = ConfigureCurve(new SecP192R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" + + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp224k1 + */ + internal class SecP224K1Holder + : X9ECParametersHolder + { + private SecP224K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP224K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), + new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240); + ECCurve curve = ConfigureCurveGlv(new SecP224K1Curve(), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C" + + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp224r1 + */ + internal class SecP224R1Holder + : X9ECParametersHolder + { + private SecP224R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP224R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + ECCurve curve = ConfigureCurve(new SecP224R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" + + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp256k1 + */ + internal class SecP256K1Holder + : X9ECParametersHolder + { + private SecP256K1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new SecP256K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), + new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272); + ECCurve curve = ConfigureCurveGlv(new SecP256K1Curve(), glv); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp256r1 + */ + internal class SecP256R1Holder + : X9ECParametersHolder + { + private SecP256R1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new SecP256R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("C49D360886E704936A6678E1139D26B7819F7E90"); + ECCurve curve = ConfigureCurve(new SecP256R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp384r1 + */ + internal class SecP384R1Holder + : X9ECParametersHolder + { + private SecP384R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP384R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("A335926AA319A27A1D00896A6773A4827ACDAC73"); + ECCurve curve = ConfigureCurve(new SecP384R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" + + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp521r1 + */ + internal class SecP521R1Holder + : X9ECParametersHolder + { + private SecP521R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP521R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("D09E8800291CB85396CC6717393284AAA0DA64BA"); + ECCurve curve = ConfigureCurve(new SecP521R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" + + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * sect113r1 + */ + internal class SecT113R1Holder + : X9ECParametersHolder + { + private SecT113R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT113R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("10E723AB14D696E6768756151756FEBF8FCB49A9"); + ECCurve curve = ConfigureCurve(new SecT113R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "009D73616F35F4AB1407D73562C10F" + + "00A52830277958EE84D1315ED31886")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect113r2 + */ + internal class SecT113R2Holder + : X9ECParametersHolder + { + private SecT113R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT113R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("10C0FB15760860DEF1EEF4D696E676875615175D"); + ECCurve curve = ConfigureCurve(new SecT113R2Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "01A57A6A7B26CA5EF52FCDB8164797" + + "00B3ADC94ED1FE674C06E695BABA1D")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect131r1 + */ + internal class SecT131R1Holder + : X9ECParametersHolder + { + private SecT131R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT131R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("4D696E676875615175985BD3ADBADA21B43A97E2"); + ECCurve curve = ConfigureCurve(new SecT131R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0081BAF91FDF9833C40F9C181343638399" + + "078C6E7EA38C001F73C8134B1B4EF9E150")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect131r2 + */ + internal class SecT131R2Holder + : X9ECParametersHolder + { + private SecT131R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT131R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("985BD3ADBAD4D696E676875615175A21B43A97E3"); + ECCurve curve = ConfigureCurve(new SecT131R2Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0356DCD8F2F95031AD652D23951BB366A8" + + "0648F06D867940A5366D9E265DE9EB240F")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect163k1 + */ + internal class SecT163K1Holder + : X9ECParametersHolder + { + private SecT163K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT163K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT163K1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8" + + "0289070FB05D38FF58321F2E800536D538CCDAA3D9")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect163r1 + */ + internal class SecT163R1Holder + : X9ECParametersHolder + { + private SecT163R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT163R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("24B7B137C8A14D696E6768756151756FD0DA2E5C"); + ECCurve curve = ConfigureCurve(new SecT163R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0369979697AB43897789566789567F787A7876A654" + + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect163r2 + */ + internal class SecT163R2Holder + : X9ECParametersHolder + { + private SecT163R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT163R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("85E25BFE5C86226CDB12016F7553F9D0E693A268"); + ECCurve curve = ConfigureCurve(new SecT163R2Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "03F0EBA16286A2D57EA0991168D4994637E8343E36" + + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect193r1 + */ + internal class SecT193R1Holder + : X9ECParametersHolder + { + private SecT193R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT193R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("103FAEC74D696E676875615175777FC5B191EF30"); + ECCurve curve = ConfigureCurve(new SecT193R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1" + + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect193r2 + */ + internal class SecT193R2Holder + : X9ECParametersHolder + { + private SecT193R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT193R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("10B7B4D696E676875615175137C8A16FD0DA2211"); + ECCurve curve = ConfigureCurve(new SecT193R2Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F" + + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect233k1 + */ + internal class SecT233K1Holder + : X9ECParametersHolder + { + private SecT233K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT233K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT233K1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126" + + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect233r1 + */ + internal class SecT233R1Holder + : X9ECParametersHolder + { + private SecT233R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT233R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3"); + ECCurve curve = ConfigureCurve(new SecT233R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B" + + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect239k1 + */ + internal class SecT239K1Holder + : X9ECParametersHolder + { + private SecT239K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT239K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT239K1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC" + + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect283k1 + */ + internal class SecT283K1Holder + : X9ECParametersHolder + { + private SecT283K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT283K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT283K1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" + + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect283r1 + */ + internal class SecT283R1Holder + : X9ECParametersHolder + { + private SecT283R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT283R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE"); + ECCurve curve = ConfigureCurve(new SecT283R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" + + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect409k1 + */ + internal class SecT409K1Holder + : X9ECParametersHolder + { + private SecT409K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT409K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT409K1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" + + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect409r1 + */ + internal class SecT409R1Holder + : X9ECParametersHolder + { + private SecT409R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT409R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("4099B5A457F9D69F79213D094C4BCD4D4262210B"); + ECCurve curve = ConfigureCurve(new SecT409R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" + + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect571k1 + */ + internal class SecT571K1Holder + : X9ECParametersHolder + { + private SecT571K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT571K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT571K1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" + + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect571r1 + */ + internal class SecT571R1Holder + : X9ECParametersHolder + { + private SecT571R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT571R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.Decode("2AA058F73A0E33AB486B0F610410C53A7F132310"); + ECCurve curve = ConfigureCurve(new SecT571R1Curve()); + X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" + + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B")); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + + private static readonly IDictionary nameToCurve = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary nameToOid = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary oidToCurve = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary oidToName = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IList names = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + private static void DefineCurve(string name, X9ECParametersHolder holder) + { + names.Add(name); + name = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name); + nameToCurve.Add(name, holder); + } + + private static void DefineCurveWithOid(string name, DerObjectIdentifier oid, X9ECParametersHolder holder) + { + names.Add(name); + oidToName.Add(oid, name); + oidToCurve.Add(oid, holder); + name = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name); + nameToOid.Add(name, oid); + nameToCurve.Add(name, holder); + } + + private static void DefineCurveAlias(string name, DerObjectIdentifier oid) + { + object curve = oidToCurve[oid]; + if (curve == null) + throw new InvalidOperationException(); + + name = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name); + nameToOid.Add(name, oid); + nameToCurve.Add(name, curve); + } + + static CustomNamedCurves() + { + DefineCurve("curve25519", Curve25519Holder.Instance); + + //DefineCurveWithOid("secp112r1", SecObjectIdentifiers.SecP112r1, SecP112R1Holder.Instance); + //DefineCurveWithOid("secp112r2", SecObjectIdentifiers.SecP112r2, SecP112R2Holder.Instance); + DefineCurveWithOid("secp128r1", SecObjectIdentifiers.SecP128r1, SecP128R1Holder.Instance); + //DefineCurveWithOid("secp128r2", SecObjectIdentifiers.SecP128r2, SecP128R2Holder.Instance); + DefineCurveWithOid("secp160k1", SecObjectIdentifiers.SecP160k1, SecP160K1Holder.Instance); + DefineCurveWithOid("secp160r1", SecObjectIdentifiers.SecP160r1, SecP160R1Holder.Instance); + DefineCurveWithOid("secp160r2", SecObjectIdentifiers.SecP160r2, SecP160R2Holder.Instance); + DefineCurveWithOid("secp192k1", SecObjectIdentifiers.SecP192k1, SecP192K1Holder.Instance); + DefineCurveWithOid("secp192r1", SecObjectIdentifiers.SecP192r1, SecP192R1Holder.Instance); + DefineCurveWithOid("secp224k1", SecObjectIdentifiers.SecP224k1, SecP224K1Holder.Instance); + DefineCurveWithOid("secp224r1", SecObjectIdentifiers.SecP224r1, SecP224R1Holder.Instance); + DefineCurveWithOid("secp256k1", SecObjectIdentifiers.SecP256k1, SecP256K1Holder.Instance); + DefineCurveWithOid("secp256r1", SecObjectIdentifiers.SecP256r1, SecP256R1Holder.Instance); + DefineCurveWithOid("secp384r1", SecObjectIdentifiers.SecP384r1, SecP384R1Holder.Instance); + DefineCurveWithOid("secp521r1", SecObjectIdentifiers.SecP521r1, SecP521R1Holder.Instance); + + DefineCurveWithOid("sect113r1", SecObjectIdentifiers.SecT113r1, SecT113R1Holder.Instance); + DefineCurveWithOid("sect113r2", SecObjectIdentifiers.SecT113r2, SecT113R2Holder.Instance); + DefineCurveWithOid("sect131r1", SecObjectIdentifiers.SecT131r1, SecT131R1Holder.Instance); + DefineCurveWithOid("sect131r2", SecObjectIdentifiers.SecT131r2, SecT131R2Holder.Instance); + DefineCurveWithOid("sect163k1", SecObjectIdentifiers.SecT163k1, SecT163K1Holder.Instance); + DefineCurveWithOid("sect163r1", SecObjectIdentifiers.SecT163r1, SecT163R1Holder.Instance); + DefineCurveWithOid("sect163r2", SecObjectIdentifiers.SecT163r2, SecT163R2Holder.Instance); + DefineCurveWithOid("sect193r1", SecObjectIdentifiers.SecT193r1, SecT193R1Holder.Instance); + DefineCurveWithOid("sect193r2", SecObjectIdentifiers.SecT193r2, SecT193R2Holder.Instance); + DefineCurveWithOid("sect233k1", SecObjectIdentifiers.SecT233k1, SecT233K1Holder.Instance); + DefineCurveWithOid("sect233r1", SecObjectIdentifiers.SecT233r1, SecT233R1Holder.Instance); + DefineCurveWithOid("sect239k1", SecObjectIdentifiers.SecT239k1, SecT239K1Holder.Instance); + DefineCurveWithOid("sect283k1", SecObjectIdentifiers.SecT283k1, SecT283K1Holder.Instance); + DefineCurveWithOid("sect283r1", SecObjectIdentifiers.SecT283r1, SecT283R1Holder.Instance); + DefineCurveWithOid("sect409k1", SecObjectIdentifiers.SecT409k1, SecT409K1Holder.Instance); + DefineCurveWithOid("sect409r1", SecObjectIdentifiers.SecT409r1, SecT409R1Holder.Instance); + DefineCurveWithOid("sect571k1", SecObjectIdentifiers.SecT571k1, SecT571K1Holder.Instance); + DefineCurveWithOid("sect571r1", SecObjectIdentifiers.SecT571r1, SecT571R1Holder.Instance); + + DefineCurveAlias("B-163", SecObjectIdentifiers.SecT163r2); + DefineCurveAlias("B-233", SecObjectIdentifiers.SecT233r1); + DefineCurveAlias("B-283", SecObjectIdentifiers.SecT283r1); + DefineCurveAlias("B-409", SecObjectIdentifiers.SecT409r1); + DefineCurveAlias("B-571", SecObjectIdentifiers.SecT571r1); + + DefineCurveAlias("K-163", SecObjectIdentifiers.SecT163k1); + DefineCurveAlias("K-233", SecObjectIdentifiers.SecT233k1); + DefineCurveAlias("K-283", SecObjectIdentifiers.SecT283k1); + DefineCurveAlias("K-409", SecObjectIdentifiers.SecT409k1); + DefineCurveAlias("K-571", SecObjectIdentifiers.SecT571k1); + + DefineCurveAlias("P-192", SecObjectIdentifiers.SecP192r1); + DefineCurveAlias("P-224", SecObjectIdentifiers.SecP224r1); + DefineCurveAlias("P-256", SecObjectIdentifiers.SecP256r1); + DefineCurveAlias("P-384", SecObjectIdentifiers.SecP384r1); + DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1); + } + + public static X9ECParameters GetByName(string name) + { + X9ECParametersHolder holder = (X9ECParametersHolder)nameToCurve[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid(DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)oidToCurve[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid(string name) + { + return (DerObjectIdentifier)nameToOid[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName(DerObjectIdentifier oid) + { + return (string)oidToName[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names); } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs.meta new file mode 100644 index 0000000..9ea20ca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/ec/CustomNamedCurves.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32ffbd2c58332be4cb98527094e5ea00 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings.meta new file mode 100644 index 0000000..aa30e7a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 35397ea2ff7827c429fbd3f646b14705 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs new file mode 100644 index 0000000..d8dbbd1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs @@ -0,0 +1,277 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * ISO 9796-1 padding. Note in the light of recent results you should + * only use this with RSA (rather than the "simpler" Rabin keys) and you + * should never use it with anything other than a hash (ie. even if the + * message is small don't sign the message, sign it's hash) or some "random" + * value. See your favorite search engine for details. + */ + public class ISO9796d1Encoding + : IAsymmetricBlockCipher + { + private static readonly BigInteger Sixteen = BigInteger.ValueOf(16); + private static readonly BigInteger Six = BigInteger.ValueOf(6); + + private static readonly byte[] shadows = { 0xe, 0x3, 0x5, 0x8, 0x9, 0x4, 0x2, 0xf, + 0x0, 0xd, 0xb, 0x6, 0x7, 0xa, 0xc, 0x1 }; + private static readonly byte[] inverse = { 0x8, 0xf, 0x6, 0x1, 0x5, 0x2, 0xb, 0xc, + 0x3, 0x4, 0xd, 0xa, 0xe, 0x9, 0x0, 0x7 }; + + private readonly IAsymmetricBlockCipher engine; + private bool forEncryption; + private int bitSize; + private int padBits = 0; + private BigInteger modulus; + + public ISO9796d1Encoding( + IAsymmetricBlockCipher cipher) + { + this.engine = cipher; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/ISO9796-1Padding"; } + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + RsaKeyParameters kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + kParam = (RsaKeyParameters)rParam.Parameters; + } + else + { + kParam = (RsaKeyParameters)parameters; + } + + engine.Init(forEncryption, parameters); + + modulus = kParam.Modulus; + bitSize = modulus.BitLength; + + this.forEncryption = forEncryption; + } + + /** + * return the input block size. The largest message we can process + * is (key_size_in_bits + 3)/16, which in our world comes to + * key_size_in_bytes / 2. + */ + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + if (forEncryption) + { + return (baseBlockSize + 1) / 2; + } + else + { + return baseBlockSize; + } + } + + /** + * return the maximum possible size for the output. + */ + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return (baseBlockSize + 1) / 2; + } + } + + /** + * set the number of bits in the next message to be treated as + * pad bits. + */ + public void SetPadBits( + int padBits) + { + if (padBits > 7) + { + throw new ArgumentException("padBits > 7"); + } + + this.padBits = padBits; + } + + /** + * retrieve the number of pad bits in the last decoded message. + */ + public int GetPadBits() + { + return padBits; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + if (forEncryption) + { + return EncodeBlock(input, inOff, length); + } + else + { + return DecodeBlock(input, inOff, length); + } + } + + private byte[] EncodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = new byte[(bitSize + 7) / 8]; + int r = padBits + 1; + int z = inLen; + int t = (bitSize + 13) / 16; + + for (int i = 0; i < t; i += z) + { + if (i > t - z) + { + Array.Copy(input, inOff + inLen - (t - i), + block, block.Length - t, t - i); + } + else + { + Array.Copy(input, inOff, block, block.Length - (i + z), z); + } + } + + for (int i = block.Length - 2 * t; i != block.Length; i += 2) + { + byte val = block[block.Length - t + i / 2]; + + block[i] = (byte)((shadows[(uint) (val & 0xff) >> 4] << 4) + | shadows[val & 0x0f]); + block[i + 1] = val; + } + + block[block.Length - 2 * z] ^= (byte) r; + block[block.Length - 1] = (byte)((block[block.Length - 1] << 4) | 0x06); + + int maxBit = (8 - (bitSize - 1) % 8); + int offSet = 0; + + if (maxBit != 8) + { + block[0] &= (byte) ((ushort) 0xff >> maxBit); + block[0] |= (byte) ((ushort) 0x80 >> maxBit); + } + else + { + block[0] = 0x00; + block[1] |= 0x80; + offSet = 1; + } + + return engine.ProcessBlock(block, offSet, block.Length - offSet); + } + + /** + * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string + */ + private byte[] DecodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = engine.ProcessBlock(input, inOff, inLen); + int r = 1; + int t = (bitSize + 13) / 16; + + BigInteger iS = new BigInteger(1, block); + BigInteger iR; + if (iS.Mod(Sixteen).Equals(Six)) + { + iR = iS; + } + else + { + iR = modulus.Subtract(iS); + + if (!iR.Mod(Sixteen).Equals(Six)) + throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16"); + } + + block = iR.ToByteArrayUnsigned(); + + if ((block[block.Length - 1] & 0x0f) != 0x6) + throw new InvalidCipherTextException("invalid forcing byte in block"); + + block[block.Length - 1] = + (byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4) + | ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4)); + + block[0] = (byte)((shadows[(uint) (block[1] & 0xff) >> 4] << 4) + | shadows[block[1] & 0x0f]); + + bool boundaryFound = false; + int boundary = 0; + + for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2) + { + int val = ((shadows[(uint) (block[i] & 0xff) >> 4] << 4) + | shadows[block[i] & 0x0f]); + + if (((block[i - 1] ^ val) & 0xff) != 0) + { + if (!boundaryFound) + { + boundaryFound = true; + r = (block[i - 1] ^ val) & 0xff; + boundary = i - 1; + } + else + { + throw new InvalidCipherTextException("invalid tsums in block"); + } + } + } + + block[boundary] = 0; + + byte[] nblock = new byte[(block.Length - boundary) / 2]; + + for (int i = 0; i < nblock.Length; i++) + { + nblock[i] = block[2 * i + boundary + 1]; + } + + padBits = r - 1; + + return nblock; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs.meta new file mode 100644 index 0000000..3fd1abd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/ISO9796d1Encoding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4a70193810adfc84bb1c2b7d0cfbdda8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs new file mode 100644 index 0000000..8bc147d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs @@ -0,0 +1,353 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2. + */ + public class OaepEncoding + : IAsymmetricBlockCipher + { + private byte[] defHash; + private IDigest hash; + private IDigest mgf1Hash; + + private IAsymmetricBlockCipher engine; + private SecureRandom random; + private bool forEncryption; + + public OaepEncoding( + IAsymmetricBlockCipher cipher) + : this(cipher, new Sha1Digest(), null) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash) + : this(cipher, hash, null) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash, + byte[] encodingParams) + : this(cipher, hash, hash, encodingParams) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash, + IDigest mgf1Hash, + byte[] encodingParams) + { + this.engine = cipher; + this.hash = hash; + this.mgf1Hash = mgf1Hash; + this.defHash = new byte[hash.GetDigestSize()]; + + if (encodingParams != null) + { + hash.BlockUpdate(encodingParams, 0, encodingParams.Length); + } + + hash.DoFinal(defHash, 0); + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/OAEPPadding"; } + } + + public void Init( + bool forEncryption, + ICipherParameters param) + { + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + this.random = rParam.Random; + } + else + { + this.random = new SecureRandom(); + } + + engine.Init(forEncryption, param); + + this.forEncryption = forEncryption; + } + + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + if (forEncryption) + { + return baseBlockSize - 1 - 2 * defHash.Length; + } + else + { + return baseBlockSize; + } + } + + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return baseBlockSize - 1 - 2 * defHash.Length; + } + } + + public byte[] ProcessBlock( + byte[] inBytes, + int inOff, + int inLen) + { + if (forEncryption) + { + return EncodeBlock(inBytes, inOff, inLen); + } + else + { + return DecodeBlock(inBytes, inOff, inLen); + } + } + + private byte[] EncodeBlock( + byte[] inBytes, + int inOff, + int inLen) + { + byte[] block = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length]; + + // + // copy in the message + // + Array.Copy(inBytes, inOff, block, block.Length - inLen, inLen); + + // + // add sentinel + // + block[block.Length - inLen - 1] = 0x01; + + // + // as the block is already zeroed - there's no need to add PS (the >= 0 pad of 0) + // + + // + // add the hash of the encoding params. + // + Array.Copy(defHash, 0, block, defHash.Length, defHash.Length); + + // + // generate the seed. + // + byte[] seed = SecureRandom.GetNextBytes(random, defHash.Length); + + // + // mask the message block. + // + byte[] mask = maskGeneratorFunction1(seed, 0, seed.Length, block.Length - defHash.Length); + + for (int i = defHash.Length; i != block.Length; i++) + { + block[i] ^= mask[i - defHash.Length]; + } + + // + // add in the seed + // + Array.Copy(seed, 0, block, 0, defHash.Length); + + // + // mask the seed. + // + mask = maskGeneratorFunction1( + block, defHash.Length, block.Length - defHash.Length, defHash.Length); + + for (int i = 0; i != defHash.Length; i++) + { + block[i] ^= mask[i]; + } + + return engine.ProcessBlock(block, 0, block.Length); + } + + /** + * @exception InvalidCipherTextException if the decrypted block turns out to + * be badly formatted. + */ + private byte[] DecodeBlock( + byte[] inBytes, + int inOff, + int inLen) + { + byte[] data = engine.ProcessBlock(inBytes, inOff, inLen); + byte[] block; + + // + // as we may have zeros in our leading bytes for the block we produced + // on encryption, we need to make sure our decrypted block comes back + // the same size. + // + if (data.Length < engine.GetOutputBlockSize()) + { + block = new byte[engine.GetOutputBlockSize()]; + + Array.Copy(data, 0, block, block.Length - data.Length, data.Length); + } + else + { + block = data; + } + + if (block.Length < (2 * defHash.Length) + 1) + { + throw new InvalidCipherTextException("data too short"); + } + + // + // unmask the seed. + // + byte[] mask = maskGeneratorFunction1( + block, defHash.Length, block.Length - defHash.Length, defHash.Length); + + for (int i = 0; i != defHash.Length; i++) + { + block[i] ^= mask[i]; + } + + // + // unmask the message block. + // + mask = maskGeneratorFunction1(block, 0, defHash.Length, block.Length - defHash.Length); + + for (int i = defHash.Length; i != block.Length; i++) + { + block[i] ^= mask[i - defHash.Length]; + } + + // + // check the hash of the encoding params. + // long check to try to avoid this been a source of a timing attack. + // + { + int diff = 0; + for (int i = 0; i < defHash.Length; ++i) + { + diff |= (byte)(defHash[i] ^ block[defHash.Length + i]); + } + + if (diff != 0) + throw new InvalidCipherTextException("data hash wrong"); + } + + // + // find the data block + // + int start; + for (start = 2 * defHash.Length; start != block.Length; start++) + { + if (block[start] != 0) + { + break; + } + } + + if (start > (block.Length - 1) || block[start] != 1) + { + throw new InvalidCipherTextException("data start wrong " + start); + } + + start++; + + // + // extract the data block + // + byte[] output = new byte[block.Length - start]; + + Array.Copy(block, start, output, 0, output.Length); + + return output; + } + + /** + * int to octet string. + */ + private void ItoOSP( + int i, + byte[] sp) + { + sp[0] = (byte)((uint)i >> 24); + sp[1] = (byte)((uint)i >> 16); + sp[2] = (byte)((uint)i >> 8); + sp[3] = (byte)((uint)i >> 0); + } + + /** + * mask generator function, as described in PKCS1v2. + */ + private byte[] maskGeneratorFunction1( + byte[] Z, + int zOff, + int zLen, + int length) + { + byte[] mask = new byte[length]; + byte[] hashBuf = new byte[mgf1Hash.GetDigestSize()]; + byte[] C = new byte[4]; + int counter = 0; + + hash.Reset(); + + do + { + ItoOSP(counter, C); + + mgf1Hash.BlockUpdate(Z, zOff, zLen); + mgf1Hash.BlockUpdate(C, 0, C.Length); + mgf1Hash.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * hashBuf.Length, hashBuf.Length); + } + while (++counter < (length / hashBuf.Length)); + + if ((counter * hashBuf.Length) < length) + { + ItoOSP(counter, C); + + mgf1Hash.BlockUpdate(Z, zOff, zLen); + mgf1Hash.BlockUpdate(C, 0, C.Length); + mgf1Hash.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * hashBuf.Length, mask.Length - (counter * hashBuf.Length)); + } + + return mask; + } + } +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs.meta new file mode 100644 index 0000000..10b9567 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/OaepEncoding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 60f0db7343141334d896810ce58bf1bb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs new file mode 100644 index 0000000..adddc54 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs @@ -0,0 +1,386 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * this does your basic Pkcs 1 v1.5 padding - whether or not you should be using this + * depends on your application - see Pkcs1 Version 2 for details. + */ + public class Pkcs1Encoding + : IAsymmetricBlockCipher + { + /** + * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to + * work with one of these set the system property Org.BouncyCastle.Pkcs1.Strict to false. + */ + public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict"; + + private const int HeaderLength = 10; + + /** + * The same effect can be achieved by setting the static property directly + *

+ * The static property is checked during construction of the encoding object, it is set to + * true by default. + *

+ */ + public static bool StrictLengthEnabled + { + get { return strictLengthEnabled[0]; } + set { strictLengthEnabled[0] = value; } + } + + private static readonly bool[] strictLengthEnabled; + + static Pkcs1Encoding() + { + string strictProperty = Org.BouncyCastle.Utilities.Platform.GetEnvironmentVariable(StrictLengthEnabledProperty); + + strictLengthEnabled = new bool[]{ strictProperty == null || strictProperty.Equals("true")}; + } + + + private SecureRandom random; + private IAsymmetricBlockCipher engine; + private bool forEncryption; + private bool forPrivateKey; + private bool useStrictLength; + private int pLen = -1; + private byte[] fallback = null; + + /** + * Basic constructor. + * @param cipher + */ + public Pkcs1Encoding( + IAsymmetricBlockCipher cipher) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + } + + /** + * Constructor for decryption with a fixed plaintext length. + * + * @param cipher The cipher to use for cryptographic operation. + * @param pLen Length of the expected plaintext. + */ + public Pkcs1Encoding(IAsymmetricBlockCipher cipher, int pLen) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + this.pLen = pLen; + } + + /** + * Constructor for decryption with a fixed plaintext length and a fallback + * value that is returned, if the padding is incorrect. + * + * @param cipher + * The cipher to use for cryptographic operation. + * @param fallback + * The fallback value, we don't to a arraycopy here. + */ + public Pkcs1Encoding(IAsymmetricBlockCipher cipher, byte[] fallback) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + this.fallback = fallback; + this.pLen = fallback.Length; + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/PKCS1Padding"; } + } + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + AsymmetricKeyParameter kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + kParam = (AsymmetricKeyParameter)rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + kParam = (AsymmetricKeyParameter)parameters; + } + + engine.Init(forEncryption, parameters); + + this.forPrivateKey = kParam.IsPrivate; + this.forEncryption = forEncryption; + } + + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + return forEncryption + ? baseBlockSize - HeaderLength + : baseBlockSize; + } + + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + return forEncryption + ? baseBlockSize + : baseBlockSize - HeaderLength; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + return forEncryption + ? EncodeBlock(input, inOff, length) + : DecodeBlock(input, inOff, length); + } + + private byte[] EncodeBlock( + byte[] input, + int inOff, + int inLen) + { + if (inLen > GetInputBlockSize()) + throw new ArgumentException("input data too large", "inLen"); + + byte[] block = new byte[engine.GetInputBlockSize()]; + + if (forPrivateKey) + { + block[0] = 0x01; // type code 1 + + for (int i = 1; i != block.Length - inLen - 1; i++) + { + block[i] = (byte)0xFF; + } + } + else + { + random.NextBytes(block); // random fill + + block[0] = 0x02; // type code 2 + + // + // a zero byte marks the end of the padding, so all + // the pad bytes must be non-zero. + // + for (int i = 1; i != block.Length - inLen - 1; i++) + { + while (block[i] == 0) + { + block[i] = (byte)random.NextInt(); + } + } + } + + block[block.Length - inLen - 1] = 0x00; // mark the end of the padding + Array.Copy(input, inOff, block, block.Length - inLen, inLen); + + return engine.ProcessBlock(block, 0, block.Length); + } + + /** + * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext + * for encryption. + * + * @param encoded The Plaintext. + * @param pLen Expected length of the plaintext. + * @return Either 0, if the encoding is correct, or -1, if it is incorrect. + */ + private static int CheckPkcs1Encoding(byte[] encoded, int pLen) + { + int correct = 0; + /* + * Check if the first two bytes are 0 2 + */ + correct |= (encoded[0] ^ 2); + + /* + * Now the padding check, check for no 0 byte in the padding + */ + int plen = encoded.Length - ( + pLen /* Lenght of the PMS */ + + 1 /* Final 0-byte before PMS */ + ); + + for (int i = 1; i < plen; i++) + { + int tmp = encoded[i]; + tmp |= tmp >> 1; + tmp |= tmp >> 2; + tmp |= tmp >> 4; + correct |= (tmp & 1) - 1; + } + + /* + * Make sure the padding ends with a 0 byte. + */ + correct |= encoded[encoded.Length - (pLen + 1)]; + + /* + * Return 0 or 1, depending on the result. + */ + correct |= correct >> 1; + correct |= correct >> 2; + correct |= correct >> 4; + return ~((correct & 1) - 1); + } + + /** + * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct. + * + * @param in The encrypted block. + * @param inOff Offset in the encrypted block. + * @param inLen Length of the encrypted block. + * @param pLen Length of the desired output. + * @return The plaintext without padding, or a random value if the padding was incorrect. + * + * @throws InvalidCipherTextException + */ + private byte[] DecodeBlockOrRandom(byte[] input, int inOff, int inLen) + { + if (!forPrivateKey) + throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing"); + + byte[] block = engine.ProcessBlock(input, inOff, inLen); + byte[] random = null; + if (this.fallback == null) + { + random = new byte[this.pLen]; + this.random.NextBytes(random); + } + else + { + random = fallback; + } + + /* + * TODO: This is a potential dangerous side channel. However, you can + * fix this by changing the RSA engine in a way, that it will always + * return blocks of the same length and prepend them with 0 bytes if + * needed. + */ + if (block.Length < GetOutputBlockSize()) + throw new InvalidCipherTextException("block truncated"); + + /* + * TODO: Potential side channel. Fix it by making the engine always + * return blocks of the correct length. + */ + if (useStrictLength && block.Length != engine.GetOutputBlockSize()) + throw new InvalidCipherTextException("block incorrect size"); + + /* + * Check the padding. + */ + int correct = Pkcs1Encoding.CheckPkcs1Encoding(block, this.pLen); + + /* + * Now, to a constant time constant memory copy of the decrypted value + * or the random value, depending on the validity of the padding. + */ + byte[] result = new byte[this.pLen]; + for (int i = 0; i < this.pLen; i++) + { + result[i] = (byte)((block[i+(block.Length-pLen)]&(~correct)) | (random[i]&correct)); + } + + return result; + } + + /** + * @exception InvalidCipherTextException if the decrypted block is not in Pkcs1 format. + */ + private byte[] DecodeBlock( + byte[] input, + int inOff, + int inLen) + { + /* + * If the length of the expected plaintext is known, we use a constant-time decryption. + * If the decryption fails, we return a random value. + */ + if (this.pLen != -1) + { + return this.DecodeBlockOrRandom(input, inOff, inLen); + } + + byte[] block = engine.ProcessBlock(input, inOff, inLen); + + if (block.Length < GetOutputBlockSize()) + { + throw new InvalidCipherTextException("block truncated"); + } + + byte type = block[0]; + + if (type != 1 && type != 2) + { + throw new InvalidCipherTextException("unknown block type"); + } + + if (useStrictLength && block.Length != engine.GetOutputBlockSize()) + { + throw new InvalidCipherTextException("block incorrect size"); + } + + // + // find and extract the message block. + // + int start; + for (start = 1; start != block.Length; start++) + { + byte pad = block[start]; + + if (pad == 0) + { + break; + } + + if (type == 1 && pad != (byte)0xff) + { + throw new InvalidCipherTextException("block padding incorrect"); + } + } + + start++; // data should start at the next byte + + if (start > block.Length || start < HeaderLength) + { + throw new InvalidCipherTextException("no data in block"); + } + + byte[] result = new byte[block.Length - start]; + + Array.Copy(block, start, result, 0, result.Length); + + return result; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs.meta new file mode 100644 index 0000000..429dd4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/encodings/Pkcs1Encoding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5b1316d7c7c9dbc42b6ed758a5b1e70e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines.meta new file mode 100644 index 0000000..11d5d3f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7b265757931cf134392d9b1ab2925c86 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs new file mode 100644 index 0000000..e9381a5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs @@ -0,0 +1,611 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael), from FIPS-197. + *

+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor, they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first. + * + * The slowest version uses no static tables at all and computes the values in each round. + *

+ *

+ * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. + *

+ */ + public class AesEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, + 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, + 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, + 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, + 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, + 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, + 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, + 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, + 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, + 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, + 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, + 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, + 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, + 65, 153, 45, 15, 176, 84, 187, 22, + }; + + // The inverse S-box + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, + 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, + 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, + 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, + 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, + 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, + 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, + 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, + 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, + 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, + 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, + 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, + 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, + 225, 105, 20, 99, 85, 33, 12, 125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + // precomputation tables of calculations for rounds + private static readonly uint[] T0 = + { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, + 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, + 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, + 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, + 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, + 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, + 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, + 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, + 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, + 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, + 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, + 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, + 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, + 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, + 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, + 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, + 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, + 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, + 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, + 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, + 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, + 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, + 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, + 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, + 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, + 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, + 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, + 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, + 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, + 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, + 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, + 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, + 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, + 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, + 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, + 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, + 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, + 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, + 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, + 0x3a16162c + }; + + private static readonly uint[] Tinv0 = + { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, + 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, + 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, + 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, + 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, + 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, + 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, + 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, + 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, + 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, + 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, + 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, + 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, + 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, + 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, + 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, + 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, + 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, + 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, + 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, + 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, + 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, + 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, + 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, + 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, + 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, + 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, + 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, + 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, + 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, + 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, + 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, + 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, + 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, + 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, + 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, + 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, + 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, + 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, + 0x4257b8d0 + }; + + private static uint Shift(uint r, int shift) + { + return (r >> shift) | (r << (32 - shift)); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const uint m1 = 0x80808080; + private const uint m2 = 0x7f7f7f7f; + private const uint m3 = 0x0000001b; + private const uint m4 = 0xC0C0C0C0; + private const uint m5 = 0x3f3f3f3f; + + private static uint FFmulX(uint x) + { + return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3); + } + + private static uint FFmulX2(uint x) + { + uint t0 = (x & m5) << 2; + uint t1 = (x & m4); + t1 ^= (t1 >> 1); + return t0 ^ (t1 >> 2) ^ (t1 >> 5); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private static uint Inv_Mcol(uint x) + { + uint t0, t1; + t0 = x; + t1 = t0 ^ Shift(t0, 8); + t0 ^= FFmulX(t1); + t1 ^= FFmulX2(t0); + t0 ^= t1 ^ Shift(t1, 16); + return t0; + } + + private static uint SubWord(uint x) + { + return (uint)S[x&255] + | (((uint)S[(x>>8)&255]) << 8) + | (((uint)S[(x>>16)&255]) << 16) + | (((uint)S[(x>>24)&255]) << 24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) + { + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) + throw new ArgumentException("Key length not 128/192/256 bits."); + + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + + uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block + for (int i = 0; i <= ROUNDS; ++i) + { + W[i] = new uint[4]; + } + + switch (KC) + { + case 4: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; + } + case 6: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; + + break; + } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; + + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } + } + + if (!forEncryption) + { + for (int j = 1; j < ROUNDS; j++) + { + uint[] w = W[j]; + for (int i = 0; i < 4; i++) + { + w[i] = Inv_Mcol(w[i]); + } + } + } + + return W; + } + + private int ROUNDS; + private uint[][] WorkingKey; + private uint C0, C1, C2, C3; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to AES init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption); + + this.forEncryption = forEncryption; + } + + public virtual string AlgorithmName + { + get { return "AES"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (WorkingKey == null) + throw new InvalidOperationException("AES engine not initialised"); + + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); + + UnPackBlock(input, inOff); + + if (forEncryption) + { + EncryptBlock(WorkingKey); + } + else + { + DecryptBlock(WorkingKey); + } + + PackBlock(output, outOff); + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + C0 = Pack.LE_To_UInt32(bytes, off); + C1 = Pack.LE_To_UInt32(bytes, off + 4); + C2 = Pack.LE_To_UInt32(bytes, off + 8); + C3 = Pack.LE_To_UInt32(bytes, off + 12); + } + + private void PackBlock( + byte[] bytes, + int off) + { + Pack.UInt32_To_LE(C0, bytes, off); + Pack.UInt32_To_LE(C1, bytes, off + 4); + Pack.UInt32_To_LE(C2, bytes, off + 8); + Pack.UInt32_To_LE(C3, bytes, off + 12); + } + + private void EncryptBlock(uint[][] KW) + { + uint[] kw = KW[0]; + uint t0 = this.C0 ^ kw[0]; + uint t1 = this.C1 ^ kw[1]; + uint t2 = this.C2 ^ kw[2]; + + uint r0, r1, r2, r3 = this.C3 ^ kw[3]; + int r = 1; + while (r < ROUNDS - 1) + { + kw = KW[r++]; + r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0]; + r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1]; + r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2]; + r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3]; + kw = KW[r++]; + t0 = T0[r0 & 255] ^ Shift(T0[(r1 >> 8) & 255], 24) ^ Shift(T0[(r2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0]; + t1 = T0[r1 & 255] ^ Shift(T0[(r2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(r0 >> 24) & 255], 8) ^ kw[1]; + t2 = T0[r2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(r0 >> 16) & 255], 16) ^ Shift(T0[(r1 >> 24) & 255], 8) ^ kw[2]; + r3 = T0[r3 & 255] ^ Shift(T0[(r0 >> 8) & 255], 24) ^ Shift(T0[(r1 >> 16) & 255], 16) ^ Shift(T0[(r2 >> 24) & 255], 8) ^ kw[3]; + } + + kw = KW[r++]; + r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0]; + r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1]; + r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2]; + r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + kw = KW[r]; + this.C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24) ^ kw[0]; + this.C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24) ^ kw[1]; + this.C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2]; + this.C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3]; + } + + private void DecryptBlock(uint[][] KW) + { + uint[] kw = KW[ROUNDS]; + uint t0 = this.C0 ^ kw[0]; + uint t1 = this.C1 ^ kw[1]; + uint t2 = this.C2 ^ kw[2]; + + uint r0, r1, r2, r3 = this.C3 ^ kw[3]; + int r = ROUNDS - 1; + while (r > 1) + { + kw = KW[r--]; + r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3]; + kw = KW[r--]; + t0 = Tinv0[r0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(r2 >> 16) & 255], 16) ^ Shift(Tinv0[(r1 >> 24) & 255], 8) ^ kw[0]; + t1 = Tinv0[r1 & 255] ^ Shift(Tinv0[(r0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(r2 >> 24) & 255], 8) ^ kw[1]; + t2 = Tinv0[r2 & 255] ^ Shift(Tinv0[(r1 >> 8) & 255], 24) ^ Shift(Tinv0[(r0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(r2 >> 8) & 255], 24) ^ Shift(Tinv0[(r1 >> 16) & 255], 16) ^ Shift(Tinv0[(r0 >> 24) & 255], 8) ^ kw[3]; + } + + kw = KW[1]; + r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + kw = KW[0]; + this.C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0]; + this.C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[(r2 >> 24) & 255]) << 24) ^ kw[1]; + this.C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[(r3 >> 24) & 255]) << 24) ^ kw[2]; + this.C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[(r0 >> 24) & 255]) << 24) ^ kw[3]; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs.meta new file mode 100644 index 0000000..d58ea18 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c62f38dc79ccd334b9e0b7c898f109cc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs new file mode 100644 index 0000000..cb9b33f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs @@ -0,0 +1,1186 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael)), from FIPS-197. + *

+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor), they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations), 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each), for a total of 2Kbytes), + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first + * + * The slowest version uses no static tables at all and computes the values in each round + *

+ *

+ * This file contains the fast version with 8Kbytes of static tables for round precomputation + *

+ */ + public sealed class AesFastEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, + 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, + 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, + 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, + 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, + 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, + 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, + 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, + 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, + 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, + 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, + 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, + 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, + 65, 153, 45, 15, 176, 84, 187, 22, + }; + + // The inverse S-box + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, + 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, + 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, + 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, + 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, + 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, + 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, + 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, + 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, + 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, + 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, + 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, + 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, + 225, 105, 20, 99, 85, 33, 12, 125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + // precomputation tables of calculations for rounds + private static readonly uint[] T0 = + { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, + 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, + 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, + 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, + 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, + 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, + 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, + 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, + 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, + 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, + 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, + 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, + 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, + 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, + 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, + 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, + 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, + 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, + 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, + 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, + 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, + 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, + 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, + 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, + 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, + 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, + 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, + 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, + 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, + 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, + 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, + 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, + 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, + 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, + 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, + 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, + 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, + 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, + 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, + 0x3a16162c + }; + + private static readonly uint[] T1 = + { + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, + 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, + 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, + 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, + 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, + 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, + 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, + 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x0404080c, 0xc7c79552, + 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, + 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, + 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, + 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, + 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, + 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, + 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, + 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, + 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, + 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, + 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, + 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, + 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, + 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, + 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, + 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, + 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, + 0x06060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, + 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, + 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, + 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, + 0xaeae47e9, 0x08081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, + 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, + 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, + 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, + 0x0e0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, + 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, + 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, + 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, + 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, + 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, + 0x16162c3a + }; + + private static readonly uint[] T2 = + { + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, + 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, + 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, + 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, + 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, + 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, + 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, + 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x04080c04, 0xc79552c7, + 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, + 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, + 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, + 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, + 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, + 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, + 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, + 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, + 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, + 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, + 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, + 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, + 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, + 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, + 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, + 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, + 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, + 0x060c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, + 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, + 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, + 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, + 0xae47e9ae, 0x08101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, + 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, + 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, + 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, + 0x0e1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, + 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, + 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, + 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, + 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, + 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, + 0x162c3a16 + }; + + private static readonly uint[] T3 = + { + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, + 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, + 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, + 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, + 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, + 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, + 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, + 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x080c0404, 0x9552c7c7, + 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, + 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, + 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, + 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, + 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, + 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, + 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, + 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, + 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, + 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, + 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, + 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, + 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, + 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, + 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, + 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, + 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, + 0x0c0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, + 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, + 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, + 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, + 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, + 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, + 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, + 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, + 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, + 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, + 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, + 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, + 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, + 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, + 0x2c3a1616 + }; + + private static readonly uint[] Tinv0 = + { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, + 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, + 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, + 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, + 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, + 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, + 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, + 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, + 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, + 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, + 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, + 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, + 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, + 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, + 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, + 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, + 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, + 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, + 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, + 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, + 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, + 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, + 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, + 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, + 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, + 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, + 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, + 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, + 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, + 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, + 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, + 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, + 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, + 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, + 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, + 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, + 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, + 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, + 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, + 0x4257b8d0 + }; + + private static readonly uint[] Tinv1 = + { + 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, + 0x459d1ff1, 0x58faacab, 0x03e34b93, 0xfa302055, 0x6d76adf6, + 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, + 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, + 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7, + 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, + 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, + 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, + 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, + 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, + 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x024b72e2, 0x8f1fe357, + 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, + 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, + 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, + 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, + 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, + 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, 0x8d5491b5, + 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697, + 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, + 0xeec879db, 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, + 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb, + 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, + 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2, + 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, + 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0x0d090e0b, + 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x0775af4c, + 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, + 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, + 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, + 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, + 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, + 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, + 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf, + 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d, + 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, + 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, + 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, + 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, + 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x099fead4, + 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, + 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, + 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, + 0x4daacc54, 0x0496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, + 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, + 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c, + 0x0ca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, + 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, + 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, + 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, + 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x01a83971, 0xb30c08de, + 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, + 0x57b8d042 + }; + + private static readonly uint[] Tinv2 = + { + 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, + 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, + 0xcc889176, 0x02f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, + 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, + 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f, + 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, + 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, + 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, + 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, + 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, 0x48705868, 0x458f19fd, + 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, + 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, + 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, 0xcf8a2b1c, + 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x0506d5be, + 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, + 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, + 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, + 0xc471055d, 0x06046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9, + 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, + 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, + 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0x0efdfbff, + 0x850f5638, 0xae3d1ed5, 0x2d362739, 0x0f0a64d9, 0x5c6821a6, + 0x5b9bd154, 0x36243a2e, 0x0a0cb167, 0x57930fe7, 0xeeb4d296, + 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, + 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x090e0b0d, + 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, + 0x99eebbdd, 0x7fa3fd60, 0x01f79f26, 0x725cbcf5, 0x6644c53b, + 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, + 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, + 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, + 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, + 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, + 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, + 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92, + 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, + 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, + 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, + 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, + 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409, + 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, + 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x04f14a98, + 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, + 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, + 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, + 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61, + 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, + 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, + 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, + 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, + 0xe2bc0c25, 0x3c288b49, 0x0dff4195, 0xa8397101, 0x0c08deb3, + 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, + 0xb8d04257 + }; + + private static readonly uint[] Tinv3 = + { + 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, + 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, + 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, + 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, + 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x03e75f8f, + 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, + 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, + 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, + 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, + 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, + 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, + 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, + 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, + 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, + 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x0532e18a, + 0xa475ebf6, 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, + 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, + 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd, + 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, + 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, + 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, + 0x0f563885, 0x3d1ed5ae, 0x3627392d, 0x0a64d90f, 0x6821a65c, + 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757, 0xb4d296ee, + 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, + 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, + 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, + 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, + 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, + 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, + 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, + 0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, + 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, + 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, + 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278, + 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, + 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, + 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, + 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, + 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f, + 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, + 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, + 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, + 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, + 0x467f5165, 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, + 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7, + 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, + 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, + 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, + 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, + 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, + 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, + 0xd04257b8 + }; + + private static uint Shift(uint r, int shift) + { + return (r >> shift) | (r << (32 - shift)); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const uint m1 = 0x80808080; + private const uint m2 = 0x7f7f7f7f; + private const uint m3 = 0x0000001b; + private const uint m4 = 0xC0C0C0C0; + private const uint m5 = 0x3f3f3f3f; + + private static uint FFmulX(uint x) + { + return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3); + } + + private static uint FFmulX2(uint x) + { + uint t0 = (x & m5) << 2; + uint t1 = (x & m4); + t1 ^= (t1 >> 1); + return t0 ^ (t1 >> 2) ^ (t1 >> 5); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private static uint Inv_Mcol(uint x) + { + uint t0, t1; + t0 = x; + t1 = t0 ^ Shift(t0, 8); + t0 ^= FFmulX(t1); + t1 ^= FFmulX2(t0); + t0 ^= t1 ^ Shift(t1, 16); + return t0; + } + + private static uint SubWord(uint x) + { + return (uint)S[x & 255] + | (((uint)S[(x >> 8) & 255]) << 8) + | (((uint)S[(x >> 16) & 255]) << 16) + | (((uint)S[(x >> 24) & 255]) << 24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) + { + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) + throw new ArgumentException("Key length not 128/192/256 bits."); + + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + + uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block + for (int i = 0; i <= ROUNDS; ++i) + { + W[i] = new uint[4]; + } + + switch (KC) + { + case 4: + { + uint t0 = Pack.LE_To_UInt32(key, 0); + W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); + W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); + W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); + W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; + W[i][0] = t0; + t1 ^= t0; + W[i][1] = t1; + t2 ^= t1; + W[i][2] = t2; + t3 ^= t2; + W[i][3] = t3; + } + + break; + } + case 6: + { + uint t0 = Pack.LE_To_UInt32(key, 0); + W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); + W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); + W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); + W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); + W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); + W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; + rcon <<= 1; + t0 ^= u; + W[1][2] = t0; + t1 ^= t0; + W[1][3] = t1; + t2 ^= t1; + W[2][0] = t2; + t3 ^= t2; + W[2][1] = t3; + t4 ^= t3; + W[2][2] = t4; + t5 ^= t4; + W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; + rcon <<= 1; + t0 ^= u; + W[i][0] = t0; + t1 ^= t0; + W[i][1] = t1; + t2 ^= t1; + W[i][2] = t2; + t3 ^= t2; + W[i][3] = t3; + t4 ^= t3; + W[i + 1][0] = t4; + t5 ^= t4; + W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; + rcon <<= 1; + t0 ^= u; + W[i + 1][2] = t0; + t1 ^= t0; + W[i + 1][3] = t1; + t2 ^= t1; + W[i + 2][0] = t2; + t3 ^= t2; + W[i + 2][1] = t3; + t4 ^= t3; + W[i + 2][2] = t4; + t5 ^= t4; + W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; + W[12][0] = t0; + t1 ^= t0; + W[12][1] = t1; + t2 ^= t1; + W[12][2] = t2; + t3 ^= t2; + W[12][3] = t3; + + break; + } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); + W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); + W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); + W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); + W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); + W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); + W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); + W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); + W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; + rcon <<= 1; + t0 ^= u; + W[i][0] = t0; + t1 ^= t0; + W[i][1] = t1; + t2 ^= t1; + W[i][2] = t2; + t3 ^= t2; + W[i][3] = t3; + u = SubWord(t3); + t4 ^= u; + W[i + 1][0] = t4; + t5 ^= t4; + W[i + 1][1] = t5; + t6 ^= t5; + W[i + 1][2] = t6; + t7 ^= t6; + W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; + W[14][0] = t0; + t1 ^= t0; + W[14][1] = t1; + t2 ^= t1; + W[14][2] = t2; + t3 ^= t2; + W[14][3] = t3; + + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } + } + + if (!forEncryption) + { + for (int j = 1; j < ROUNDS; j++) + { + uint[] w = W[j]; + for (int i = 0; i < 4; i++) + { + w[i] = Inv_Mcol(w[i]); + } + } + } + + return W; + } + + private int ROUNDS; + private uint[][] WorkingKey; + private uint C0, C1, C2, C3; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesFastEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public /*virtual */void Init( + bool forEncryption, + ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to AES init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption); + + this.forEncryption = forEncryption; + } + + public /*virtual */string AlgorithmName + { + get { return "AES"; } + } + + public /*virtual */bool IsPartialBlockOkay + { + get { return false; } + } + + public /*virtual */int GetBlockSize() + { + return BLOCK_SIZE; + } + +#if false //ENABLE_IL2CPP && !UNITY_WEBGL + public /*virtual */ unsafe int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (WorkingKey == null) + throw new InvalidOperationException("AES engine not initialised"); + + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); + + //UnPackBlock(input, inOff); + unsafe + { + fixed (byte* pbytes = input) + { + C0 = (uint)pbytes[inOff] | (uint)pbytes[inOff + 1] << 8 | (uint)pbytes[inOff + 2] << 16 | (uint)pbytes[inOff + 3] << 24; + C1 = (uint)pbytes[inOff + 4] | (uint)pbytes[inOff + 5] << 8 | (uint)pbytes[inOff + 6] << 16 | (uint)pbytes[inOff + 7] << 24; + C2 = (uint)pbytes[inOff + 8] | (uint)pbytes[inOff + 9] << 8 | (uint)pbytes[inOff + 10] << 16 | (uint)pbytes[inOff + 11] << 24; + C3 = (uint)pbytes[inOff + 12] | (uint)pbytes[inOff + 13] << 8 | (uint)pbytes[inOff + 14] << 16 | (uint)pbytes[inOff + 15] << 24; + } + } + + if (forEncryption) + { + //EncryptBlock(WorkingKey); + fixed (uint* pskw = WorkingKey[0]) + { + uint t0 = this.C0 ^ pskw[0]; + uint t1 = this.C1 ^ pskw[1]; + uint t2 = this.C2 ^ pskw[2]; + + uint r0, r1, r2, r3 = this.C3 ^ pskw[3]; + int r = 1; + fixed (uint* pT0 = T0) + fixed (uint* pT1 = T1) + fixed (uint* pT2 = T2) + fixed (uint* pT3 = T3) + { + while (r < ROUNDS - 1) + { + fixed (uint* pkw = WorkingKey[r++]) + { + //kw = KW[r++]; + r0 = pT0[t0 & 255] ^ pT1[(t1 >> 8) & 255] ^ pT2[(t2 >> 16) & 255] ^ pT3[r3 >> 24] ^ pkw[0]; + r1 = pT0[t1 & 255] ^ pT1[(t2 >> 8) & 255] ^ pT2[(r3 >> 16) & 255] ^ pT3[t0 >> 24] ^ pkw[1]; + r2 = pT0[t2 & 255] ^ pT1[(r3 >> 8) & 255] ^ pT2[(t0 >> 16) & 255] ^ pT3[t1 >> 24] ^ pkw[2]; + r3 = pT0[r3 & 255] ^ pT1[(t0 >> 8) & 255] ^ pT2[(t1 >> 16) & 255] ^ pT3[t2 >> 24] ^ pkw[3]; + } + + fixed (uint* pkw = WorkingKey[r++]) + { + //kw = KW[r++]; + t0 = pT0[r0 & 255] ^ pT1[(r1 >> 8) & 255] ^ pT2[(r2 >> 16) & 255] ^ pT3[r3 >> 24] ^ pkw[0]; + t1 = pT0[r1 & 255] ^ pT1[(r2 >> 8) & 255] ^ pT2[(r3 >> 16) & 255] ^ pT3[r0 >> 24] ^ pkw[1]; + t2 = pT0[r2 & 255] ^ pT1[(r3 >> 8) & 255] ^ pT2[(r0 >> 16) & 255] ^ pT3[r1 >> 24] ^ pkw[2]; + r3 = pT0[r3 & 255] ^ pT1[(r0 >> 8) & 255] ^ pT2[(r1 >> 16) & 255] ^ pT3[r2 >> 24] ^ pkw[3]; + } + } + + fixed (uint* pkw = WorkingKey[r++]) + { + //kw = KW[r++]; + r0 = pT0[t0 & 255] ^ pT1[(t1 >> 8) & 255] ^ pT2[(t2 >> 16) & 255] ^ pT3[r3 >> 24] ^ pkw[0]; + r1 = pT0[t1 & 255] ^ pT1[(t2 >> 8) & 255] ^ pT2[(r3 >> 16) & 255] ^ pT3[t0 >> 24] ^ pkw[1]; + r2 = pT0[t2 & 255] ^ pT1[(r3 >> 8) & 255] ^ pT2[(t0 >> 16) & 255] ^ pT3[t1 >> 24] ^ pkw[2]; + r3 = pT0[r3 & 255] ^ pT1[(t0 >> 8) & 255] ^ pT2[(t1 >> 16) & 255] ^ pT3[t2 >> 24] ^ pkw[3]; + } + } + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + fixed (uint* pkw = WorkingKey[r++]) + fixed (byte* pS = S) + { + //uint* pSS = (uint*)pS; + //kw = KW[r]; + this.C0 = (uint)pS[r0 & 255] ^ (((uint)pS[(r1 >> 8) & 255]) << 8) ^ (((uint)pS[(r2 >> 16) & 255]) << 16) ^ (((uint)pS[r3 >> 24]) << 24) ^ pkw[0]; + this.C1 = (uint)pS[r1 & 255] ^ (((uint)pS[(r2 >> 8) & 255]) << 8) ^ (((uint)pS[(r3 >> 16) & 255]) << 16) ^ (((uint)pS[r0 >> 24]) << 24) ^ pkw[1]; + this.C2 = (uint)pS[r2 & 255] ^ (((uint)pS[(r3 >> 8) & 255]) << 8) ^ (((uint)pS[(r0 >> 16) & 255]) << 16) ^ (((uint)pS[r1 >> 24]) << 24) ^ pkw[2]; + this.C3 = (uint)pS[r3 & 255] ^ (((uint)pS[(r0 >> 8) & 255]) << 8) ^ (((uint)pS[(r1 >> 16) & 255]) << 16) ^ (((uint)pS[r2 >> 24]) << 24) ^ pkw[3]; + } + } + } + else + { + //DecryptBlock(WorkingKey); + fixed (uint* pskw = WorkingKey[ROUNDS]) + { + uint t0 = this.C0 ^ pskw[0]; + uint t1 = this.C1 ^ pskw[1]; + uint t2 = this.C2 ^ pskw[2]; + + uint r0 = 0, r1 = 0, r2 = 0, r3 = this.C3 ^ pskw[3]; + int r = ROUNDS - 1; + + fixed (uint* pTinv0 = Tinv0) + fixed (uint* pTinv1 = Tinv1) + fixed (uint* pTinv2 = Tinv2) + fixed (uint* pTinv3 = Tinv3) + while (r > 1) + { + fixed (uint* pkw = WorkingKey[r--]) + { + //kw = KW[r--]; + r0 = pTinv0[t0 & 255] ^ pTinv1[(r3 >> 8) & 255] ^ pTinv2[(t2 >> 16) & 255] ^ pTinv3[t1 >> 24] ^ pkw[0]; + r1 = pTinv0[t1 & 255] ^ pTinv1[(t0 >> 8) & 255] ^ pTinv2[(r3 >> 16) & 255] ^ pTinv3[t2 >> 24] ^ pkw[1]; + r2 = pTinv0[t2 & 255] ^ pTinv1[(t1 >> 8) & 255] ^ pTinv2[(t0 >> 16) & 255] ^ pTinv3[r3 >> 24] ^ pkw[2]; + r3 = pTinv0[r3 & 255] ^ pTinv1[(t2 >> 8) & 255] ^ pTinv2[(t1 >> 16) & 255] ^ pTinv3[t0 >> 24] ^ pkw[3]; + } + + fixed (uint* pkw = WorkingKey[r--]) + { + //kw = KW[r--]; + t0 = pTinv0[r0 & 255] ^ pTinv1[(r3 >> 8) & 255] ^ pTinv2[(r2 >> 16) & 255] ^ pTinv3[r1 >> 24] ^ pkw[0]; + t1 = pTinv0[r1 & 255] ^ pTinv1[(r0 >> 8) & 255] ^ pTinv2[(r3 >> 16) & 255] ^ pTinv3[r2 >> 24] ^ pkw[1]; + t2 = pTinv0[r2 & 255] ^ pTinv1[(r1 >> 8) & 255] ^ pTinv2[(r0 >> 16) & 255] ^ pTinv3[r3 >> 24] ^ pkw[2]; + r3 = pTinv0[r3 & 255] ^ pTinv1[(r2 >> 8) & 255] ^ pTinv2[(r1 >> 16) & 255] ^ pTinv3[r0 >> 24] ^ pkw[3]; + } + + + fixed (uint* pkw = WorkingKey[1]) + { + //kw = KW[1]; + r0 = pTinv0[t0 & 255] ^ pTinv1[(r3 >> 8) & 255] ^ pTinv2[(t2 >> 16) & 255] ^ pTinv3[t1 >> 24] ^ pkw[0]; + r1 = pTinv0[t1 & 255] ^ pTinv1[(t0 >> 8) & 255] ^ pTinv2[(r3 >> 16) & 255] ^ pTinv3[t2 >> 24] ^ pkw[1]; + r2 = pTinv0[t2 & 255] ^ pTinv1[(t1 >> 8) & 255] ^ pTinv2[(t0 >> 16) & 255] ^ pTinv3[r3 >> 24] ^ pkw[2]; + r3 = pTinv0[r3 & 255] ^ pTinv1[(t2 >> 8) & 255] ^ pTinv2[(t1 >> 16) & 255] ^ pTinv3[t0 >> 24] ^ pkw[3]; + } + } + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + fixed (uint* pkw = WorkingKey[1]) + fixed (byte* pSi = Si) + { + //kw = KW[0]; + this.C0 = (uint)pSi[r0 & 255] ^ (((uint)pSi[(r3 >> 8) & 255]) << 8) ^ (((uint)pSi[(r2 >> 16) & 255]) << 16) ^ (((uint)pSi[r1 >> 24]) << 24) ^ pkw[0]; + this.C1 = (uint)pSi[r1 & 255] ^ (((uint)pSi[(r0 >> 8) & 255]) << 8) ^ (((uint)pSi[(r3 >> 16) & 255]) << 16) ^ (((uint)pSi[r2 >> 24]) << 24) ^ pkw[1]; + this.C2 = (uint)pSi[r2 & 255] ^ (((uint)pSi[(r1 >> 8) & 255]) << 8) ^ (((uint)pSi[(r0 >> 16) & 255]) << 16) ^ (((uint)pSi[r3 >> 24]) << 24) ^ pkw[2]; + this.C3 = (uint)pSi[r3 & 255] ^ (((uint)pSi[(r2 >> 8) & 255]) << 8) ^ (((uint)pSi[(r1 >> 16) & 255]) << 16) ^ (((uint)pSi[r0 >> 24]) << 24) ^ pkw[3]; + } + } + } + + //PackBlock(output, outOff); + unsafe + { + fixed (byte* pbytes = output) + { + pbytes[outOff + 0] = (byte)(C0); + pbytes[outOff + 1] = (byte)(C0 >> 8); + pbytes[outOff + 2] = (byte)(C0 >> 16); + pbytes[outOff + 3] = (byte)(C0 >> 24); + + pbytes[outOff + 4] = (byte)(C1); + pbytes[outOff + 5] = (byte)(C1 >> 8); + pbytes[outOff + 6] = (byte)(C1 >> 16); + pbytes[outOff + 7] = (byte)(C1 >> 24); + + pbytes[outOff + 8] = (byte)(C2); + pbytes[outOff + 9] = (byte)(C2 >> 8); + pbytes[outOff + 10] = (byte)(C2 >> 16); + pbytes[outOff + 11] = (byte)(C2 >> 24); + + pbytes[outOff + 12] = (byte)(C3); + pbytes[outOff + 13] = (byte)(C3 >> 8); + pbytes[outOff + 14] = (byte)(C3 >> 16); + pbytes[outOff + 15] = (byte)(C3 >> 24); + } + } + + return BLOCK_SIZE; + } +#endif + + public /*virtual */ void Reset() + { + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + public /*virtual */int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (WorkingKey == null) + throw new InvalidOperationException("AES engine not initialised"); + + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); + + UnPackBlock(input, inOff); + + if (forEncryption) + { + EncryptBlock(WorkingKey); + } + else + { + DecryptBlock(WorkingKey); + } + + PackBlock(output, outOff); + + return BLOCK_SIZE; + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + C0 = Pack.LE_To_UInt32(bytes, off); + C1 = Pack.LE_To_UInt32(bytes, off + 4); + C2 = Pack.LE_To_UInt32(bytes, off + 8); + C3 = Pack.LE_To_UInt32(bytes, off + 12); + } + + private void PackBlock( + byte[] bytes, + int off) + { + Pack.UInt32_To_LE(C0, bytes, off); + Pack.UInt32_To_LE(C1, bytes, off + 4); + Pack.UInt32_To_LE(C2, bytes, off + 8); + Pack.UInt32_To_LE(C3, bytes, off + 12); + } + + private void EncryptBlock(uint[][] KW) + { + uint[] kw = KW[0]; + uint t0 = this.C0 ^ kw[0]; + uint t1 = this.C1 ^ kw[1]; + uint t2 = this.C2 ^ kw[2]; + + uint r0, r1, r2, r3 = this.C3 ^ kw[3]; + int r = 1; + while (r < ROUNDS - 1) + { + kw = KW[r++]; + r0 = T0[t0 & 255] ^ T1[(t1 >> 8) & 255] ^ T2[(t2 >> 16) & 255] ^ T3[r3 >> 24] ^ kw[0]; + r1 = T0[t1 & 255] ^ T1[(t2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[t0 >> 24] ^ kw[1]; + r2 = T0[t2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(t0 >> 16) & 255] ^ T3[t1 >> 24] ^ kw[2]; + r3 = T0[r3 & 255] ^ T1[(t0 >> 8) & 255] ^ T2[(t1 >> 16) & 255] ^ T3[t2 >> 24] ^ kw[3]; + kw = KW[r++]; + t0 = T0[r0 & 255] ^ T1[(r1 >> 8) & 255] ^ T2[(r2 >> 16) & 255] ^ T3[r3 >> 24] ^ kw[0]; + t1 = T0[r1 & 255] ^ T1[(r2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[r0 >> 24] ^ kw[1]; + t2 = T0[r2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(r0 >> 16) & 255] ^ T3[r1 >> 24] ^ kw[2]; + r3 = T0[r3 & 255] ^ T1[(r0 >> 8) & 255] ^ T2[(r1 >> 16) & 255] ^ T3[r2 >> 24] ^ kw[3]; + } + + kw = KW[r++]; + r0 = T0[t0 & 255] ^ T1[(t1 >> 8) & 255] ^ T2[(t2 >> 16) & 255] ^ T3[r3 >> 24] ^ kw[0]; + r1 = T0[t1 & 255] ^ T1[(t2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[t0 >> 24] ^ kw[1]; + r2 = T0[t2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(t0 >> 16) & 255] ^ T3[t1 >> 24] ^ kw[2]; + r3 = T0[r3 & 255] ^ T1[(t0 >> 8) & 255] ^ T2[(t1 >> 16) & 255] ^ T3[t2 >> 24] ^ kw[3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + kw = KW[r]; + this.C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[r3 >> 24]) << 24) ^ kw[0]; + this.C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[r0 >> 24]) << 24) ^ kw[1]; + this.C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[r1 >> 24]) << 24) ^ kw[2]; + this.C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[r2 >> 24]) << 24) ^ kw[3]; + } + + private void DecryptBlock(uint[][] KW) + { + uint[] kw = KW[ROUNDS]; + uint t0 = this.C0 ^ kw[0]; + uint t1 = this.C1 ^ kw[1]; + uint t2 = this.C2 ^ kw[2]; + + uint r0, r1, r2, r3 = this.C3 ^ kw[3]; + int r = ROUNDS - 1; + while (r > 1) + { + kw = KW[r--]; + r0 = Tinv0[t0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(t2 >> 16) & 255] ^ Tinv3[t1 >> 24] ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Tinv1[(t0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[t2 >> 24] ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Tinv1[(t1 >> 8) & 255] ^ Tinv2[(t0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Tinv1[(t2 >> 8) & 255] ^ Tinv2[(t1 >> 16) & 255] ^ Tinv3[t0 >> 24] ^ kw[3]; + kw = KW[r--]; + t0 = Tinv0[r0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(r2 >> 16) & 255] ^ Tinv3[r1 >> 24] ^ kw[0]; + t1 = Tinv0[r1 & 255] ^ Tinv1[(r0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[r2 >> 24] ^ kw[1]; + t2 = Tinv0[r2 & 255] ^ Tinv1[(r1 >> 8) & 255] ^ Tinv2[(r0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Tinv1[(r2 >> 8) & 255] ^ Tinv2[(r1 >> 16) & 255] ^ Tinv3[r0 >> 24] ^ kw[3]; + } + + kw = KW[1]; + r0 = Tinv0[t0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(t2 >> 16) & 255] ^ Tinv3[t1 >> 24] ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Tinv1[(t0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[t2 >> 24] ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Tinv1[(t1 >> 8) & 255] ^ Tinv2[(t0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Tinv1[(t2 >> 8) & 255] ^ Tinv2[(t1 >> 16) & 255] ^ Tinv3[t0 >> 24] ^ kw[3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + kw = KW[0]; + this.C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[r1 >> 24]) << 24) ^ kw[0]; + this.C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[r2 >> 24]) << 24) ^ kw[1]; + this.C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[r3 >> 24]) << 24) ^ kw[2]; + this.C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[r0 >> 24]) << 24) ^ kw[3]; + } +#endif + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs.meta new file mode 100644 index 0000000..a5b3735 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesFastEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 05eb307d46de52e42a911fd8244278df +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs new file mode 100644 index 0000000..8743b72 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the AES Key Wrapper from the NIST Key Wrap Specification. + ///

+ /// For further details see: http://csrc.nist.gov/encryption/kms/key-wrap.pdf. + /// + public class AesWrapEngine + : Rfc3394WrapEngine + { + public AesWrapEngine() + : base(new AesFastEngine()) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs.meta new file mode 100644 index 0000000..3f6c7a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/AesWrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 298095ce0aa6ae74e812fd919e59cdee +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs new file mode 100644 index 0000000..54489b2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs @@ -0,0 +1,557 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides Blowfish key encryption operations, + * such as encoding data and generating keys. + * All the algorithms herein are from Applied Cryptography + * and implement a simplified cryptography interface. + */ + public sealed class BlowfishEngine + : IBlockCipher + { + private readonly static uint[] KP = + { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B + }, + KS0 = + { + 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A + }, + KS1 = + { + 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 + }, + KS2 = + { + 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 + }, + KS3 = + { + 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 + }; + + //==================================== + // Useful constants + //==================================== + + private static readonly int ROUNDS = 16; + private const int BLOCK_SIZE = 8; // bytes = 64 bits + private static readonly int SBOX_SK = 256; + private static readonly int P_SZ = ROUNDS+2; + + private readonly uint[] S0, S1, S2, S3; // the s-boxes + private readonly uint[] P; // the p-array + + private bool encrypting; + + private byte[] workingKey; + + public BlowfishEngine() + { + S0 = new uint[SBOX_SK]; + S1 = new uint[SBOX_SK]; + S2 = new uint[SBOX_SK]; + S3 = new uint[SBOX_SK]; + P = new uint[P_SZ]; + } + + /** + * initialise a Blowfish cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to Blowfish init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + this.encrypting = forEncryption; + this.workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(this.workingKey); + } + + public string AlgorithmName + { + get { return "Blowfish"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Blowfish not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + private uint F(uint x) + { + return (((S0[x >> 24] + S1[(x >> 16) & 0xff]) ^ S2[(x >> 8) & 0xff]) + S3[x & 0xff]); + } + + /** + * apply the encryption cycle to each value pair in the table. + */ + private void ProcessTable( + uint xl, + uint xr, + uint[] table) + { + int size = table.Length; + + for (int s = 0; s < size; s += 2) + { + xl ^= P[0]; + + for (int i = 1; i < ROUNDS; i += 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i + 1]; + } + + xr ^= P[ROUNDS + 1]; + + table[s] = xr; + table[s + 1] = xl; + + xr = xl; // end of cycle swap + xl = table[s]; + } + } + + private void SetKey(byte[] key) + { + /* + * - comments are from _Applied Crypto_, Schneier, p338 + * please be careful comparing the two, AC numbers the + * arrays from 1, the enclosed code from 0. + * + * (1) + * Initialise the S-boxes and the P-array, with a fixed string + * This string contains the hexadecimal digits of pi (3.141...) + */ + Array.Copy(KS0, 0, S0, 0, SBOX_SK); + Array.Copy(KS1, 0, S1, 0, SBOX_SK); + Array.Copy(KS2, 0, S2, 0, SBOX_SK); + Array.Copy(KS3, 0, S3, 0, SBOX_SK); + + Array.Copy(KP, 0, P, 0, P_SZ); + + /* + * (2) + * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the + * second 32-bits of the key, and so on for all bits of the key + * (up to P[17]). Repeatedly cycle through the key bits until the + * entire P-array has been XOR-ed with the key bits + */ + int keyLength = key.Length; + int keyIndex = 0; + + for (int i=0; i < P_SZ; i++) + { + // Get the 32 bits of the key, in 4 * 8 bit chunks + uint data = 0x0000000; + for (int j=0; j < 4; j++) + { + // create a 32 bit block + data = (data << 8) | (uint)key[keyIndex++]; + + // wrap when we get to the end of the key + if (keyIndex >= keyLength) + { + keyIndex = 0; + } + } + // XOR the newly created 32 bit chunk onto the P-array + P[i] ^= data; + } + + /* + * (3) + * Encrypt the all-zero string with the Blowfish algorithm, using + * the subkeys described in (1) and (2) + * + * (4) + * Replace P1 and P2 with the output of step (3) + * + * (5) + * Encrypt the output of step(3) using the Blowfish algorithm, + * with the modified subkeys. + * + * (6) + * Replace P3 and P4 with the output of step (5) + * + * (7) + * Continue the process, replacing all elements of the P-array + * and then all four S-boxes in order, with the output of the + * continuously changing Blowfish algorithm + */ + + ProcessTable(0, 0, P); + ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S0); + ProcessTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1); + ProcessTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2); + ProcessTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3); + } + + /** + * Encrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * The input will be an exact multiple of our blocksize. + */ + private void EncryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + uint xl = Pack.BE_To_UInt32(src, srcIndex); + uint xr = Pack.BE_To_UInt32(src, srcIndex+4); + + xl ^= P[0]; + + for (int i = 1; i < ROUNDS; i += 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i + 1]; + } + + xr ^= P[ROUNDS + 1]; + + Pack.UInt32_To_BE(xr, dst, dstIndex); + Pack.UInt32_To_BE(xl, dst, dstIndex + 4); + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * The input will be an exact multiple of our blocksize. + */ + private void DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + uint xl = Pack.BE_To_UInt32(src, srcIndex); + uint xr = Pack.BE_To_UInt32(src, srcIndex + 4); + + xl ^= P[ROUNDS + 1]; + + for (int i = ROUNDS; i > 0 ; i -= 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i - 1]; + } + + xr ^= P[0]; + + Pack.UInt32_To_BE(xr, dst, dstIndex); + Pack.UInt32_To_BE(xl, dst, dstIndex + 4); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs.meta new file mode 100644 index 0000000..7b0b8d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/BlowfishEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7f53324f77555fe42bd19122a07da1dc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs new file mode 100644 index 0000000..1249657 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs @@ -0,0 +1,672 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Camellia - based on RFC 3713. + */ + public class CamelliaEngine + : IBlockCipher + { + private bool initialised = false; + private bool _keyIs128; + + private const int BLOCK_SIZE = 16; + + private uint[] subkey = new uint[24 * 4]; + private uint[] kw = new uint[4 * 2]; // for whitening + private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1) + private uint[] state = new uint[4]; // for encryption and decryption + + private static readonly uint[] SIGMA = new uint[]{ + 0xa09e667f, 0x3bcc908b, + 0xb67ae858, 0x4caa73b2, + 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, + 0x10e527fa, 0xde682d1d, + 0xb05688c2, 0xb3e6c1fd + }; + + /* + * + * S-box data + * + */ + private static readonly uint[] SBOX1_1110 = new uint[]{ + 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, + 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, + 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, + 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, + 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, + 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, + 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, + 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, + 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, + 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, + 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, + 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, + 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, + 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, + 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, + 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, + 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, + 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, + 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, + 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, + 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, + 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 + }; + + private static readonly uint[] SBOX4_4404 = new uint[]{ + 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, + 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, + 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, + 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, + 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, + 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, + 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, + 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, + 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, + 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, + 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, + 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, + 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, + 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, + 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, + 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, + 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, + 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, + 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, + 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, + 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, + 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e + }; + + private static readonly uint[] SBOX2_0222 = new uint[]{ + 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, + 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, + 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, + 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, + 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, + 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, + 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, + 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, + 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, + 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, + 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, + 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, + 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, + 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, + 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, + 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, + 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, + 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, + 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, + 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, + 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, + 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d + }; + + private static readonly uint[] SBOX3_3033 = new uint[]{ + 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, + 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, + 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, + 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, + 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, + 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, + 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, + 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, + 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, + 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, + 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, + 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, + 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, + 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, + 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, + 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, + 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, + 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, + 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, + 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, + 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, + 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f + }; + + private static uint rightRotate(uint x, int s) + { + return ((x >> s) + (x << (32 - s))); + } + + private static uint leftRotate(uint x, int s) + { + return (x << s) + (x >> (32 - s)); + } + + private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot)); + ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot)); + ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot)); + ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot)); + ki[0 + ioff] = ko[0 + ooff]; + ki[1 + ioff] = ko[1 + ooff]; + ki[2 + ioff] = ko[2 + ooff]; + ki[3 + ioff] = ko[3 + ooff]; + } + + private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot)); + ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot)); + ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot)); + ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot)); + ki[0 + ioff] = ko[2 + ooff]; + ki[1 + ioff] = ko[3 + ooff]; + ki[2 + ioff] = ko[0 + ooff]; + ki[3 + ioff] = ko[1 + ooff]; + } + + private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot)); + ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot)); + ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot)); + ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot)); + ki[0 + ioff] = ko[0 + ooff]; + ki[1 + ioff] = ko[1 + ooff]; + ki[2 + ioff] = ko[2 + ooff]; + ki[3 + ioff] = ko[3 + ooff]; + } + + private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot)); + ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot)); + ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot)); + ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot)); + ki[0 + ioff] = ko[2 + ooff]; + ki[1 + ioff] = ko[3 + ooff]; + ki[2 + ioff] = ko[0 + ooff]; + ki[3 + ioff] = ko[1 + ooff]; + } + + private static uint bytes2uint(byte[] src, int offset) + { + uint word = 0; + for (int i = 0; i < 4; i++) + { + word = (word << 8) + (uint)src[i + offset]; + } + return word; + } + + private static void uint2bytes(uint word, byte[] dst, int offset) + { + for (int i = 0; i < 4; i++) + { + dst[(3 - i) + offset] = (byte)word; + word >>= 8; + } + } + + private static void camelliaF2(uint[] s, uint[] skey, int keyoff) + { + uint t1, t2, u, v; + + t1 = s[0] ^ skey[0 + keyoff]; + u = SBOX4_4404[(byte)t1]; + u ^= SBOX3_3033[(byte)(t1 >> 8)]; + u ^= SBOX2_0222[(byte)(t1 >> 16)]; + u ^= SBOX1_1110[(byte)(t1 >> 24)]; + t2 = s[1] ^ skey[1 + keyoff]; + v = SBOX1_1110[(byte)t2]; + v ^= SBOX4_4404[(byte)(t2 >> 8)]; + v ^= SBOX3_3033[(byte)(t2 >> 16)]; + v ^= SBOX2_0222[(byte)(t2 >> 24)]; + + s[2] ^= u ^ v; + s[3] ^= u ^ v ^ rightRotate(u, 8); + + t1 = s[2] ^ skey[2 + keyoff]; + u = SBOX4_4404[(byte)t1]; + u ^= SBOX3_3033[(byte)(t1 >> 8)]; + u ^= SBOX2_0222[(byte)(t1 >> 16)]; + u ^= SBOX1_1110[(byte)(t1 >> 24)]; + t2 = s[3] ^ skey[3 + keyoff]; + v = SBOX1_1110[(byte)t2]; + v ^= SBOX4_4404[(byte)(t2 >> 8)]; + v ^= SBOX3_3033[(byte)(t2 >> 16)]; + v ^= SBOX2_0222[(byte)(t2 >> 24)]; + + s[0] ^= u ^ v; + s[1] ^= u ^ v ^ rightRotate(u, 8); + } + + private static void camelliaFLs(uint[] s, uint[] fkey, int keyoff) + { + + s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1); + s[0] ^= fkey[1 + keyoff] | s[1]; + + s[2] ^= fkey[3 + keyoff] | s[3]; + s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1); + } + + private void setKey(bool forEncryption, byte[] key) + { + uint[] k = new uint[8]; + uint[] ka = new uint[4]; + uint[] kb = new uint[4]; + uint[] t = new uint[4]; + + switch (key.Length) + { + case 16: + _keyIs128 = true; + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = k[5] = k[6] = k[7] = 0; + break; + case 24: + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = bytes2uint(key, 16); + k[5] = bytes2uint(key, 20); + k[6] = ~k[4]; + k[7] = ~k[5]; + _keyIs128 = false; + break; + case 32: + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = bytes2uint(key, 16); + k[5] = bytes2uint(key, 20); + k[6] = bytes2uint(key, 24); + k[7] = bytes2uint(key, 28); + _keyIs128 = false; + break; + default: + throw new ArgumentException("key sizes are only 16/24/32 bytes."); + } + + for (int i = 0; i < 4; i++) + { + ka[i] = k[i] ^ k[i + 4]; + } + /* compute KA */ + camelliaF2(ka, SIGMA, 0); + for (int i = 0; i < 4; i++) + { + ka[i] ^= k[i]; + } + camelliaF2(ka, SIGMA, 4); + + if (_keyIs128) + { + if (forEncryption) + { + /* KL dependant keys */ + kw[0] = k[0]; + kw[1] = k[1]; + kw[2] = k[2]; + kw[3] = k[3]; + roldq(15, k, 0, subkey, 4); + roldq(30, k, 0, subkey, 12); + roldq(15, k, 0, t, 0); + subkey[18] = t[2]; + subkey[19] = t[3]; + roldq(17, k, 0, ke, 4); + roldq(17, k, 0, subkey, 24); + roldq(17, k, 0, subkey, 32); + /* KA dependant keys */ + subkey[0] = ka[0]; + subkey[1] = ka[1]; + subkey[2] = ka[2]; + subkey[3] = ka[3]; + roldq(15, ka, 0, subkey, 8); + roldq(15, ka, 0, ke, 0); + roldq(15, ka, 0, t, 0); + subkey[16] = t[0]; + subkey[17] = t[1]; + roldq(15, ka, 0, subkey, 20); + roldqo32(34, ka, 0, subkey, 28); + roldq(17, ka, 0, kw, 4); + + } + else + { // decryption + /* KL dependant keys */ + kw[4] = k[0]; + kw[5] = k[1]; + kw[6] = k[2]; + kw[7] = k[3]; + decroldq(15, k, 0, subkey, 28); + decroldq(30, k, 0, subkey, 20); + decroldq(15, k, 0, t, 0); + subkey[16] = t[0]; + subkey[17] = t[1]; + decroldq(17, k, 0, ke, 0); + decroldq(17, k, 0, subkey, 8); + decroldq(17, k, 0, subkey, 0); + /* KA dependant keys */ + subkey[34] = ka[0]; + subkey[35] = ka[1]; + subkey[32] = ka[2]; + subkey[33] = ka[3]; + decroldq(15, ka, 0, subkey, 24); + decroldq(15, ka, 0, ke, 4); + decroldq(15, ka, 0, t, 0); + subkey[18] = t[2]; + subkey[19] = t[3]; + decroldq(15, ka, 0, subkey, 12); + decroldqo32(34, ka, 0, subkey, 4); + roldq(17, ka, 0, kw, 0); + } + } + else + { // 192bit or 256bit + /* compute KB */ + for (int i = 0; i < 4; i++) + { + kb[i] = ka[i] ^ k[i + 4]; + } + camelliaF2(kb, SIGMA, 8); + + if (forEncryption) + { + /* KL dependant keys */ + kw[0] = k[0]; + kw[1] = k[1]; + kw[2] = k[2]; + kw[3] = k[3]; + roldqo32(45, k, 0, subkey, 16); + roldq(15, k, 0, ke, 4); + roldq(17, k, 0, subkey, 32); + roldqo32(34, k, 0, subkey, 44); + /* KR dependant keys */ + roldq(15, k, 4, subkey, 4); + roldq(15, k, 4, ke, 0); + roldq(30, k, 4, subkey, 24); + roldqo32(34, k, 4, subkey, 36); + /* KA dependant keys */ + roldq(15, ka, 0, subkey, 8); + roldq(30, ka, 0, subkey, 20); + /* 32bit rotation */ + ke[8] = ka[1]; + ke[9] = ka[2]; + ke[10] = ka[3]; + ke[11] = ka[0]; + roldqo32(49, ka, 0, subkey, 40); + + /* KB dependant keys */ + subkey[0] = kb[0]; + subkey[1] = kb[1]; + subkey[2] = kb[2]; + subkey[3] = kb[3]; + roldq(30, kb, 0, subkey, 12); + roldq(30, kb, 0, subkey, 28); + roldqo32(51, kb, 0, kw, 4); + + } + else + { // decryption + /* KL dependant keys */ + kw[4] = k[0]; + kw[5] = k[1]; + kw[6] = k[2]; + kw[7] = k[3]; + decroldqo32(45, k, 0, subkey, 28); + decroldq(15, k, 0, ke, 4); + decroldq(17, k, 0, subkey, 12); + decroldqo32(34, k, 0, subkey, 0); + /* KR dependant keys */ + decroldq(15, k, 4, subkey, 40); + decroldq(15, k, 4, ke, 8); + decroldq(30, k, 4, subkey, 20); + decroldqo32(34, k, 4, subkey, 8); + /* KA dependant keys */ + decroldq(15, ka, 0, subkey, 36); + decroldq(30, ka, 0, subkey, 24); + /* 32bit rotation */ + ke[2] = ka[1]; + ke[3] = ka[2]; + ke[0] = ka[3]; + ke[1] = ka[0]; + decroldqo32(49, ka, 0, subkey, 4); + + /* KB dependant keys */ + subkey[46] = kb[0]; + subkey[47] = kb[1]; + subkey[44] = kb[2]; + subkey[45] = kb[3]; + decroldq(30, kb, 0, subkey, 32); + decroldq(30, kb, 0, subkey, 16); + roldqo32(51, kb, 0, kw, 0); + } + } + } + + private int processBlock128(byte[] input, int inOff, byte[] output, int outOff) + { + for (int i = 0; i < 4; i++) + { + state[i] = bytes2uint(input, inOff + (i * 4)); + state[i] ^= kw[i]; + } + + camelliaF2(state, subkey, 0); + camelliaF2(state, subkey, 4); + camelliaF2(state, subkey, 8); + camelliaFLs(state, ke, 0); + camelliaF2(state, subkey, 12); + camelliaF2(state, subkey, 16); + camelliaF2(state, subkey, 20); + camelliaFLs(state, ke, 4); + camelliaF2(state, subkey, 24); + camelliaF2(state, subkey, 28); + camelliaF2(state, subkey, 32); + + state[2] ^= kw[4]; + state[3] ^= kw[5]; + state[0] ^= kw[6]; + state[1] ^= kw[7]; + + uint2bytes(state[2], output, outOff); + uint2bytes(state[3], output, outOff + 4); + uint2bytes(state[0], output, outOff + 8); + uint2bytes(state[1], output, outOff + 12); + + return BLOCK_SIZE; + } + + private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff) + { + for (int i = 0; i < 4; i++) + { + state[i] = bytes2uint(input, inOff + (i * 4)); + state[i] ^= kw[i]; + } + + camelliaF2(state, subkey, 0); + camelliaF2(state, subkey, 4); + camelliaF2(state, subkey, 8); + camelliaFLs(state, ke, 0); + camelliaF2(state, subkey, 12); + camelliaF2(state, subkey, 16); + camelliaF2(state, subkey, 20); + camelliaFLs(state, ke, 4); + camelliaF2(state, subkey, 24); + camelliaF2(state, subkey, 28); + camelliaF2(state, subkey, 32); + camelliaFLs(state, ke, 8); + camelliaF2(state, subkey, 36); + camelliaF2(state, subkey, 40); + camelliaF2(state, subkey, 44); + + state[2] ^= kw[4]; + state[3] ^= kw[5]; + state[0] ^= kw[6]; + state[1] ^= kw[7]; + + uint2bytes(state[2], output, outOff); + uint2bytes(state[3], output, outOff + 4); + uint2bytes(state[0], output, outOff + 8); + uint2bytes(state[1], output, outOff + 12); + return BLOCK_SIZE; + } + + public CamelliaEngine() + { + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("only simple KeyParameter expected."); + + setKey(forEncryption, ((KeyParameter)parameters).GetKey()); + + initialised = true; + } + + public virtual string AlgorithmName + { + get { return "Camellia"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException("Camellia engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (_keyIs128) + { + return processBlock128(input, inOff, output, outOff); + } + else + { + return processBlock192or256(input, inOff, output, outOff); + } + } + + public virtual void Reset() + { + // nothing + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs.meta new file mode 100644 index 0000000..e2c7506 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4f140d1eda7db7a44a1f175275ecc0f5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs new file mode 100644 index 0000000..820692b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the Camellia key wrapper based on RFC 3657/RFC 3394. + ///

+ /// For further details see: http://www.ietf.org/rfc/rfc3657.txt. + /// + public class CamelliaWrapEngine + : Rfc3394WrapEngine + { + public CamelliaWrapEngine() + : base(new CamelliaEngine()) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs.meta new file mode 100644 index 0000000..76c48f7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/CamelliaWrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b75fafaaa8f1b1041ae39378d6ce4a00 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs new file mode 100644 index 0000000..7de5688 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs @@ -0,0 +1,806 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides CAST key encryption operations, + * such as encoding data and generating keys. + * + * All the algorithms herein are from the Internet RFC's + * + * RFC2144 - Cast5 (64bit block, 40-128bit key) + * RFC2612 - CAST6 (128bit block, 128-256bit key) + * + * and implement a simplified cryptography interface. + */ + public class Cast5Engine + : IBlockCipher + { + internal static readonly uint[] S1 = + { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf + }, + S2 = + { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 + }, + S3 = + { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 + }, + S4 = + { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 + }, + S5 = + { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 + }, + S6 = + { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f + }, + S7 = + { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 + }, + S8 = + { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e + }; + + //==================================== + // Useful constants + //==================================== + + internal static readonly int MAX_ROUNDS = 16; + internal static readonly int RED_ROUNDS = 12; + + private const int BLOCK_SIZE = 8; // bytes = 64 bits + + private int[] _Kr = new int[17]; // the rotating round key + private uint[] _Km = new uint[17]; // the masking round key + + private bool _encrypting; + + private byte[] _workingKey; + private int _rounds = MAX_ROUNDS; + + public Cast5Engine() + { + } + + /** + * initialise a CAST cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("Invalid parameter passed to "+ AlgorithmName +" init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + _encrypting = forEncryption; + _workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(_workingKey); + } + + public virtual string AlgorithmName + { + get { return "CAST5"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int blockSize = GetBlockSize(); + if (_workingKey == null) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, blockSize, "input buffer too short"); + Check.OutputLength(output, outOff, blockSize, "output buffer too short"); + + if (_encrypting) + { + return EncryptBlock(input, inOff, output, outOff); + } + else + { + return DecryptBlock(input, inOff, output, outOff); + } + } + + public virtual void Reset() + { + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + /* + * Creates the subkeys using the same nomenclature + * as described in RFC2144. + * + * See section 2.4 + */ + internal virtual void SetKey(byte[] key) + { + /* + * Determine the key size here, if required + * + * if keysize <= 80bits, use 12 rounds instead of 16 + * if keysize < 128bits, pad with 0 + * + * Typical key sizes => 40, 64, 80, 128 + */ + + if (key.Length < 11) + { + _rounds = RED_ROUNDS; + } + + int [] z = new int[16]; + int [] x = new int[16]; + + uint z03, z47, z8B, zCF; + uint x03, x47, x8B, xCF; + + /* copy the key into x */ + for (int i=0; i< key.Length; i++) + { + x[i] = (int)(key[i] & 0xff); + } + + /* + * This will look different because the selection of + * bytes from the input key I've already chosen the + * correct int. + */ + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Km[ 1]= S5[z[0x8]] ^ S6[z[0x9]] ^ S7[z[0x7]] ^ S8[z[0x6]] ^ S5[z[0x2]]; + _Km[ 2]= S5[z[0xA]] ^ S6[z[0xB]] ^ S7[z[0x5]] ^ S8[z[0x4]] ^ S6[z[0x6]]; + _Km[ 3]= S5[z[0xC]] ^ S6[z[0xD]] ^ S7[z[0x3]] ^ S8[z[0x2]] ^ S7[z[0x9]]; + _Km[ 4]= S5[z[0xE]] ^ S6[z[0xF]] ^ S7[z[0x1]] ^ S8[z[0x0]] ^ S8[z[0xC]]; + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Km[ 5]= S5[x[0x3]] ^ S6[x[0x2]] ^ S7[x[0xC]] ^ S8[x[0xD]] ^ S5[x[0x8]]; + _Km[ 6]= S5[x[0x1]] ^ S6[x[0x0]] ^ S7[x[0xE]] ^ S8[x[0xF]] ^ S6[x[0xD]]; + _Km[ 7]= S5[x[0x7]] ^ S6[x[0x6]] ^ S7[x[0x8]] ^ S8[x[0x9]] ^ S7[x[0x3]]; + _Km[ 8]= S5[x[0x5]] ^ S6[x[0x4]] ^ S7[x[0xA]] ^ S8[x[0xB]] ^ S8[x[0x7]]; + + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Km[ 9]= S5[z[0x3]] ^ S6[z[0x2]] ^ S7[z[0xC]] ^ S8[z[0xD]] ^ S5[z[0x9]]; + _Km[10]= S5[z[0x1]] ^ S6[z[0x0]] ^ S7[z[0xE]] ^ S8[z[0xF]] ^ S6[z[0xc]]; + _Km[11]= S5[z[0x7]] ^ S6[z[0x6]] ^ S7[z[0x8]] ^ S8[z[0x9]] ^ S7[z[0x2]]; + _Km[12]= S5[z[0x5]] ^ S6[z[0x4]] ^ S7[z[0xA]] ^ S8[z[0xB]] ^ S8[z[0x6]]; + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Km[13]= S5[x[0x8]] ^ S6[x[0x9]] ^ S7[x[0x7]] ^ S8[x[0x6]] ^ S5[x[0x3]]; + _Km[14]= S5[x[0xA]] ^ S6[x[0xB]] ^ S7[x[0x5]] ^ S8[x[0x4]] ^ S6[x[0x7]]; + _Km[15]= S5[x[0xC]] ^ S6[x[0xD]] ^ S7[x[0x3]] ^ S8[x[0x2]] ^ S7[x[0x8]]; + _Km[16]= S5[x[0xE]] ^ S6[x[0xF]] ^ S7[x[0x1]] ^ S8[x[0x0]] ^ S8[x[0xD]]; + + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Kr[ 1]=(int)((S5[z[0x8]]^S6[z[0x9]]^S7[z[0x7]]^S8[z[0x6]] ^ S5[z[0x2]])&0x1f); + _Kr[ 2]=(int)((S5[z[0xA]]^S6[z[0xB]]^S7[z[0x5]]^S8[z[0x4]] ^ S6[z[0x6]])&0x1f); + _Kr[ 3]=(int)((S5[z[0xC]]^S6[z[0xD]]^S7[z[0x3]]^S8[z[0x2]] ^ S7[z[0x9]])&0x1f); + _Kr[ 4]=(int)((S5[z[0xE]]^S6[z[0xF]]^S7[z[0x1]]^S8[z[0x0]] ^ S8[z[0xC]])&0x1f); + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Kr[ 5]=(int)((S5[x[0x3]]^S6[x[0x2]]^S7[x[0xC]]^S8[x[0xD]]^S5[x[0x8]])&0x1f); + _Kr[ 6]=(int)((S5[x[0x1]]^S6[x[0x0]]^S7[x[0xE]]^S8[x[0xF]]^S6[x[0xD]])&0x1f); + _Kr[ 7]=(int)((S5[x[0x7]]^S6[x[0x6]]^S7[x[0x8]]^S8[x[0x9]]^S7[x[0x3]])&0x1f); + _Kr[ 8]=(int)((S5[x[0x5]]^S6[x[0x4]]^S7[x[0xA]]^S8[x[0xB]]^S8[x[0x7]])&0x1f); + + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Kr[ 9]=(int)((S5[z[0x3]]^S6[z[0x2]]^S7[z[0xC]]^S8[z[0xD]]^S5[z[0x9]])&0x1f); + _Kr[10]=(int)((S5[z[0x1]]^S6[z[0x0]]^S7[z[0xE]]^S8[z[0xF]]^S6[z[0xc]])&0x1f); + _Kr[11]=(int)((S5[z[0x7]]^S6[z[0x6]]^S7[z[0x8]]^S8[z[0x9]]^S7[z[0x2]])&0x1f); + _Kr[12]=(int)((S5[z[0x5]]^S6[z[0x4]]^S7[z[0xA]]^S8[z[0xB]]^S8[z[0x6]])&0x1f); + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Kr[13]=(int)((S5[x[0x8]]^S6[x[0x9]]^S7[x[0x7]]^S8[x[0x6]]^S5[x[0x3]])&0x1f); + _Kr[14]=(int)((S5[x[0xA]]^S6[x[0xB]]^S7[x[0x5]]^S8[x[0x4]]^S6[x[0x7]])&0x1f); + _Kr[15]=(int)((S5[x[0xC]]^S6[x[0xD]]^S7[x[0x3]]^S8[x[0x2]]^S7[x[0x8]])&0x1f); + _Kr[16]=(int)((S5[x[0xE]]^S6[x[0xF]]^S7[x[0x1]]^S8[x[0x0]]^S8[x[0xD]])&0x1f); + } + + /** + * Encrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal virtual int EncryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into a 32 bit chunk and go for it + // the array is in bytes, the increment is 8x8 bits = 64 + + uint L0 = Pack.BE_To_UInt32(src, srcIndex); + uint R0 = Pack.BE_To_UInt32(src, srcIndex + 4); + + uint[] result = new uint[2]; + CAST_Encipher(L0, R0, result); + + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + + return BLOCK_SIZE; + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal virtual int DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into a 32 bit chunk and go for it + // the array is in bytes, the increment is 8x8 bits = 64 + uint L16 = Pack.BE_To_UInt32(src, srcIndex); + uint R16 = Pack.BE_To_UInt32(src, srcIndex + 4); + + uint[] result = new uint[2]; + CAST_Decipher(L16, R16, result); + + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + + return BLOCK_SIZE; + } + + /** + * The first of the three processing functions for the + * encryption and decryption. + * + * @param D the input to be processed + * @param Kmi the mask to be used from Km[n] + * @param Kri the rotation value to be used + * + */ + internal static uint F1(uint D, uint Kmi, int Kri) + { + uint I = Kmi + D; + I = I << Kri | (I >> (32-Kri)); + return ((S1[(I>>24)&0xff]^S2[(I>>16)&0xff])-S3[(I>>8)&0xff])+S4[I&0xff]; + } + + /** + * The second of the three processing functions for the + * encryption and decryption. + * + * @param D the input to be processed + * @param Kmi the mask to be used from Km[n] + * @param Kri the rotation value to be used + * + */ + internal static uint F2(uint D, uint Kmi, int Kri) + { + uint I = Kmi ^ D; + I = I << Kri | (I >> (32-Kri)); + return ((S1[(I>>24)&0xff]-S2[(I>>16)&0xff])+S3[(I>>8)&0xff])^S4[I&0xff]; + } + + /** + * The third of the three processing functions for the + * encryption and decryption. + * + * @param D the input to be processed + * @param Kmi the mask to be used from Km[n] + * @param Kri the rotation value to be used + * + */ + internal static uint F3(uint D, uint Kmi, int Kri) + { + uint I = Kmi - D; + I = I << Kri | (I >> (32-Kri)); + return ((S1[(I>>24)&0xff]+S2[(I>>16)&0xff])^S3[(I>>8)&0xff])-S4[I&0xff]; + } + + /** + * Does the 16 rounds to encrypt the block. + * + * @param L0 the LH-32bits of the plaintext block + * @param R0 the RH-32bits of the plaintext block + */ + internal void CAST_Encipher(uint L0, uint R0, uint[] result) + { + uint Lp = L0; // the previous value, equiv to L[i-1] + uint Rp = R0; // equivalent to R[i-1] + + /* + * numbering consistent with paper to make + * checking and validating easier + */ + uint Li = L0, Ri = R0; + + for (int i = 1; i<=_rounds ; i++) + { + Lp = Li; + Rp = Ri; + + Li = Rp; + switch (i) + { + case 1: + case 4: + case 7: + case 10: + case 13: + case 16: + Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]); + break; + case 2: + case 5: + case 8: + case 11: + case 14: + Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]); + break; + case 3: + case 6: + case 9: + case 12: + case 15: + Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]); + break; + } + } + + result[0] = Ri; + result[1] = Li; + + return; + } + + internal void CAST_Decipher(uint L16, uint R16, uint[] result) + { + uint Lp = L16; // the previous value, equiv to L[i-1] + uint Rp = R16; // equivalent to R[i-1] + + /* + * numbering consistent with paper to make + * checking and validating easier + */ + uint Li = L16, Ri = R16; + + for (int i = _rounds; i > 0; i--) + { + Lp = Li; + Rp = Ri; + + Li = Rp; + switch (i) + { + case 1: + case 4: + case 7: + case 10: + case 13: + case 16: + Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]); + break; + case 2: + case 5: + case 8: + case 11: + case 14: + Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]); + break; + case 3: + case 6: + case 9: + case 12: + case 15: + Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]); + break; + } + } + + result[0] = Ri; + result[1] = Li; + + return; + } + + internal static void Bits32ToInts(uint inData, int[] b, int offset) + { + b[offset + 3] = (int) (inData & 0xff); + b[offset + 2] = (int) ((inData >> 8) & 0xff); + b[offset + 1] = (int) ((inData >> 16) & 0xff); + b[offset] = (int) ((inData >> 24) & 0xff); + } + + internal static uint IntsTo32bits(int[] b, int i) + { + return (uint)(((b[i] & 0xff) << 24) | + ((b[i+1] & 0xff) << 16) | + ((b[i+2] & 0xff) << 8) | + ((b[i+3] & 0xff))); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs.meta new file mode 100644 index 0000000..ffc3922 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast5Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8e6be43f32217e342897a427819c9724 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs new file mode 100644 index 0000000..f9b057f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides CAST6 key encryption operations, + * such as encoding data and generating keys. + * + * All the algorithms herein are from the Internet RFC + * + * RFC2612 - CAST6 (128bit block, 128-256bit key) + * + * and implement a simplified cryptography interface. + */ + public sealed class Cast6Engine + : Cast5Engine + { + //==================================== + // Useful constants + //==================================== + private const int ROUNDS = 12; + private const int BLOCK_SIZE = 16; // bytes = 128 bits + + /* + * Put the round and mask keys into an array. + * Kr0[i] => _Kr[i*4 + 0] + */ + private int []_Kr = new int[ROUNDS*4]; // the rotating round key(s) + private uint []_Km = new uint[ROUNDS*4]; // the masking round key(s) + + /* + * Key setup + */ + private int []_Tr = new int[24 * 8]; + private uint []_Tm = new uint[24 * 8]; + private uint[] _workingKey = new uint[8]; + + public Cast6Engine() + { + } + + public override string AlgorithmName + { + get { return "CAST6"; } + } + + public override void Reset() + { + } + + public override int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + /* + * Creates the subkeys using the same nomenclature + * as described in RFC2612. + * + * See section 2.4 + */ + internal override void SetKey( + byte[] key) + { + uint Cm = 0x5a827999; + uint Mm = 0x6ed9eba1; + int Cr = 19; + int Mr = 17; + /* + * Determine the key size here, if required + * + * if keysize < 256 bytes, pad with 0 + * + * Typical key sizes => 128, 160, 192, 224, 256 + */ + for (int i=0; i< 24; i++) + { + for (int j=0; j< 8; j++) + { + _Tm[i*8 + j] = Cm; + Cm += Mm; //mod 2^32; + _Tr[i*8 + j] = Cr; + Cr = (Cr + Mr) & 0x1f; // mod 32 + } + } + + byte[] tmpKey = new byte[64]; + key.CopyTo(tmpKey, 0); + + // now create ABCDEFGH + for (int i = 0; i < 8; i++) + { + _workingKey[i] = Pack.BE_To_UInt32(tmpKey, i*4); + } + + // Generate the key schedule + for (int i = 0; i < 12; i++) + { + // KAPPA <- W2i(KAPPA) + int i2 = i*2 *8; + _workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]); + _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]); + _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]); + _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]); + _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]); + _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]); + _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]); + _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]); + // KAPPA <- W2i+1(KAPPA) + i2 = (i*2 + 1)*8; + _workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]); + _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]); + _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]); + _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]); + _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]); + _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]); + _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]); + _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]); + // Kr_(i) <- KAPPA + _Kr[i*4] = (int)(_workingKey[0] & 0x1f); + _Kr[i*4 + 1] = (int)(_workingKey[2] & 0x1f); + _Kr[i*4 + 2] = (int)(_workingKey[4] & 0x1f); + _Kr[i*4 + 3] = (int)(_workingKey[6] & 0x1f); + // Km_(i) <- KAPPA + _Km[i*4] = _workingKey[7]; + _Km[i*4 + 1] = _workingKey[5]; + _Km[i*4 + 2] = _workingKey[3]; + _Km[i*4 + 3] = _workingKey[1]; + } + } + + /** + * Encrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal override int EncryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into 4x32 bit chunks and go for it + uint A = Pack.BE_To_UInt32(src, srcIndex); + uint B = Pack.BE_To_UInt32(src, srcIndex + 4); + uint C = Pack.BE_To_UInt32(src, srcIndex + 8); + uint D = Pack.BE_To_UInt32(src, srcIndex + 12); + uint[] result = new uint[4]; + CAST_Encipher(A, B, C, D, result); + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + Pack.UInt32_To_BE(result[2], dst, dstIndex + 8); + Pack.UInt32_To_BE(result[3], dst, dstIndex + 12); + return BLOCK_SIZE; + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal override int DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into 4x32 bit chunks and go for it + uint A = Pack.BE_To_UInt32(src, srcIndex); + uint B = Pack.BE_To_UInt32(src, srcIndex + 4); + uint C = Pack.BE_To_UInt32(src, srcIndex + 8); + uint D = Pack.BE_To_UInt32(src, srcIndex + 12); + uint[] result = new uint[4]; + CAST_Decipher(A, B, C, D, result); + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + Pack.UInt32_To_BE(result[2], dst, dstIndex + 8); + Pack.UInt32_To_BE(result[3], dst, dstIndex + 12); + return BLOCK_SIZE; + } + + /** + * Does the 12 quad rounds rounds to encrypt the block. + * + * @param A the 00-31 bits of the plaintext block + * @param B the 32-63 bits of the plaintext block + * @param C the 64-95 bits of the plaintext block + * @param D the 96-127 bits of the plaintext block + * @param result the resulting ciphertext + */ + private void CAST_Encipher( + uint A, + uint B, + uint C, + uint D, + uint[] result) + { + for (int i = 0; i < 6; i++) + { + int x = i*4; + // BETA <- Qi(BETA) + C ^= F1(D, _Km[x], _Kr[x]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + } + for (int i = 6; i < 12; i++) + { + int x = i*4; + // BETA <- QBARi(BETA) + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + C ^= F1(D, _Km[x], _Kr[x]); + } + result[0] = A; + result[1] = B; + result[2] = C; + result[3] = D; + } + + /** + * Does the 12 quad rounds rounds to decrypt the block. + * + * @param A the 00-31 bits of the ciphertext block + * @param B the 32-63 bits of the ciphertext block + * @param C the 64-95 bits of the ciphertext block + * @param D the 96-127 bits of the ciphertext block + * @param result the resulting plaintext + */ + private void CAST_Decipher( + uint A, + uint B, + uint C, + uint D, + uint[] result) + { + for (int i = 0; i < 6; i++) + { + int x = (11-i)*4; + // BETA <- Qi(BETA) + C ^= F1(D, _Km[x], _Kr[x]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + } + for (int i=6; i<12; i++) + { + int x = (11-i)*4; + // BETA <- QBARi(BETA) + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + C ^= F1(D, _Km[x], _Kr[x]); + } + result[0] = A; + result[1] = B; + result[2] = C; + result[3] = D; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs.meta new file mode 100644 index 0000000..e3af1bf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Cast6Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4d1669c52f77c2147bfccea922c6c851 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs new file mode 100644 index 0000000..2824be4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs @@ -0,0 +1,66 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + ///

+ /// Implementation of Daniel J. Bernstein's ChaCha stream cipher. + /// + public class ChaCha7539Engine + : Salsa20Engine + { + /// + /// Creates a 20 rounds ChaCha engine. + /// + public ChaCha7539Engine() + { + } + + public override string AlgorithmName + { + get { return "ChaCha" + rounds; } + } + + protected override int NonceSize + { + get { return 12; } + } + + protected override void AdvanceCounter() + { + if (++engineState[12] == 0) + throw new InvalidOperationException("attempt to increase counter past 2^32."); + } + + protected override void ResetCounter() + { + engineState[12] = 0; + } + + protected override void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes != null) + { + if (keyBytes.Length != 32) + throw new ArgumentException(AlgorithmName + " requires 256 bit key"); + + PackTauOrSigma(keyBytes.Length, engineState, 0); + + // Key + Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 8); + } + + // IV + Pack.LE_To_UInt32(ivBytes, 0, engineState, 13, 3); + } + + protected override void GenerateKeyStream(byte[] output) + { + ChaChaEngine.ChachaCore(rounds, engineState, x); + Pack.UInt32_To_LE(x, output, 0); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs.meta new file mode 100644 index 0000000..c7fa924 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaCha7539Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5a57a7d360758b345a64cca79b830e0c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs new file mode 100644 index 0000000..1e08617 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs @@ -0,0 +1,161 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// Implementation of Daniel J. Bernstein's ChaCha stream cipher. + /// + public class ChaChaEngine + : Salsa20Engine + { + /// + /// Creates a 20 rounds ChaCha engine. + /// + public ChaChaEngine() + { + } + + /// + /// Creates a ChaCha engine with a specific number of rounds. + /// + /// the number of rounds (must be an even number). + public ChaChaEngine(int rounds) + : base(rounds) + { + } + + public override string AlgorithmName + { + get { return "ChaCha" + rounds; } + } + + protected override void AdvanceCounter() + { + if (++engineState[12] == 0) + { + ++engineState[13]; + } + } + + protected override void ResetCounter() + { + engineState[12] = engineState[13] = 0; + } + + protected override void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes != null) + { + if ((keyBytes.Length != 16) && (keyBytes.Length != 32)) + throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key"); + + PackTauOrSigma(keyBytes.Length, engineState, 0); + + // Key + Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 4); + Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 8, 4); + } + + // IV + Pack.LE_To_UInt32(ivBytes, 0, engineState, 14, 2); + } + + protected override void GenerateKeyStream(byte[] output) + { + ChachaCore(rounds, engineState, x); + Pack.UInt32_To_LE(x, output, 0); + } + + /// + /// ChaCha function. + /// + /// The number of ChaCha rounds to execute + /// The input words. + /// The ChaCha state to modify. + internal static void ChachaCore(int rounds, uint[] input, uint[] x) + { + if (input.Length != 16) + throw new ArgumentException(); + if (x.Length != 16) + throw new ArgumentException(); + if (rounds % 2 != 0) + throw new ArgumentException("Number of rounds must be even"); + + uint x00 = input[ 0]; + uint x01 = input[ 1]; + uint x02 = input[ 2]; + uint x03 = input[ 3]; + uint x04 = input[ 4]; + uint x05 = input[ 5]; + uint x06 = input[ 6]; + uint x07 = input[ 7]; + uint x08 = input[ 8]; + uint x09 = input[ 9]; + uint x10 = input[10]; + uint x11 = input[11]; + uint x12 = input[12]; + uint x13 = input[13]; + uint x14 = input[14]; + uint x15 = input[15]; + + for (int i = rounds; i > 0; i -= 2) + { + x00 += x04; x12 = R(x12 ^ x00, 16); + x08 += x12; x04 = R(x04 ^ x08, 12); + x00 += x04; x12 = R(x12 ^ x00, 8); + x08 += x12; x04 = R(x04 ^ x08, 7); + x01 += x05; x13 = R(x13 ^ x01, 16); + x09 += x13; x05 = R(x05 ^ x09, 12); + x01 += x05; x13 = R(x13 ^ x01, 8); + x09 += x13; x05 = R(x05 ^ x09, 7); + x02 += x06; x14 = R(x14 ^ x02, 16); + x10 += x14; x06 = R(x06 ^ x10, 12); + x02 += x06; x14 = R(x14 ^ x02, 8); + x10 += x14; x06 = R(x06 ^ x10, 7); + x03 += x07; x15 = R(x15 ^ x03, 16); + x11 += x15; x07 = R(x07 ^ x11, 12); + x03 += x07; x15 = R(x15 ^ x03, 8); + x11 += x15; x07 = R(x07 ^ x11, 7); + x00 += x05; x15 = R(x15 ^ x00, 16); + x10 += x15; x05 = R(x05 ^ x10, 12); + x00 += x05; x15 = R(x15 ^ x00, 8); + x10 += x15; x05 = R(x05 ^ x10, 7); + x01 += x06; x12 = R(x12 ^ x01, 16); + x11 += x12; x06 = R(x06 ^ x11, 12); + x01 += x06; x12 = R(x12 ^ x01, 8); + x11 += x12; x06 = R(x06 ^ x11, 7); + x02 += x07; x13 = R(x13 ^ x02, 16); + x08 += x13; x07 = R(x07 ^ x08, 12); + x02 += x07; x13 = R(x13 ^ x02, 8); + x08 += x13; x07 = R(x07 ^ x08, 7); + x03 += x04; x14 = R(x14 ^ x03, 16); + x09 += x14; x04 = R(x04 ^ x09, 12); + x03 += x04; x14 = R(x14 ^ x03, 8); + x09 += x14; x04 = R(x04 ^ x09, 7); + } + + x[ 0] = x00 + input[ 0]; + x[ 1] = x01 + input[ 1]; + x[ 2] = x02 + input[ 2]; + x[ 3] = x03 + input[ 3]; + x[ 4] = x04 + input[ 4]; + x[ 5] = x05 + input[ 5]; + x[ 6] = x06 + input[ 6]; + x[ 7] = x07 + input[ 7]; + x[ 8] = x08 + input[ 8]; + x[ 9] = x09 + input[ 9]; + x[10] = x10 + input[10]; + x[11] = x11 + input[11]; + x[12] = x12 + input[12]; + x[13] = x13 + input[13]; + x[14] = x14 + input[14]; + x[15] = x15 + input[15]; + } + } +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs.meta new file mode 100644 index 0000000..2b14f0b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ChaChaEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 64e919c1d89f77543913b622c89de806 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs new file mode 100644 index 0000000..806f107 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs @@ -0,0 +1,104 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// A class that provides a basic DESede (or Triple DES) engine. + public class DesEdeEngine + : DesEngine + { + private int[] workingKey1, workingKey2, workingKey3; + private bool forEncryption; + + /** + * initialise a DESede cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to DESede init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + byte[] keyMaster = ((KeyParameter)parameters).GetKey(); + if (keyMaster.Length != 24 && keyMaster.Length != 16) + throw new ArgumentException("key size must be 16 or 24 bytes."); + + this.forEncryption = forEncryption; + + byte[] key1 = new byte[8]; + Array.Copy(keyMaster, 0, key1, 0, key1.Length); + workingKey1 = GenerateWorkingKey(forEncryption, key1); + + byte[] key2 = new byte[8]; + Array.Copy(keyMaster, 8, key2, 0, key2.Length); + workingKey2 = GenerateWorkingKey(!forEncryption, key2); + + if (keyMaster.Length == 24) + { + byte[] key3 = new byte[8]; + Array.Copy(keyMaster, 16, key3, 0, key3.Length); + workingKey3 = GenerateWorkingKey(forEncryption, key3); + } + else // 16 byte key + { + workingKey3 = workingKey1; + } + } + + public override string AlgorithmName + { + get { return "DESede"; } + } + + public override int GetBlockSize() + { + return BLOCK_SIZE; + } + + public override int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey1 == null) + throw new InvalidOperationException("DESede engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + byte[] temp = new byte[BLOCK_SIZE]; + + if (forEncryption) + { + DesFunc(workingKey1, input, inOff, temp, 0); + DesFunc(workingKey2, temp, 0, temp, 0); + DesFunc(workingKey3, temp, 0, output, outOff); + } + else + { + DesFunc(workingKey3, input, inOff, temp, 0); + DesFunc(workingKey2, temp, 0, temp, 0); + DesFunc(workingKey1, temp, 0, output, outOff); + } + + return BLOCK_SIZE; + } + + public override void Reset() + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs.meta new file mode 100644 index 0000000..471ef4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 40f7755f6290bac4fa55c0f4ad40923a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs new file mode 100644 index 0000000..b8aae3e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs @@ -0,0 +1,326 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Wrap keys according to + * + * draft-ietf-smime-key-wrap-01.txt. + *

+ * Note: + *

    + *
  • this is based on a draft, and as such is subject to change - don't use this class for anything requiring long term storage.
  • + *
  • if you are using this to wrap triple-des keys you need to set the + * parity bits on the key and, if it's a two-key triple-des key, pad it + * yourself.
  • + *
+ *

+ */ + public class DesEdeWrapEngine + : IWrapper + { + /** Field engine */ + private CbcBlockCipher engine; + /** Field param */ + private KeyParameter param; + /** Field paramPlusIV */ + private ParametersWithIV paramPlusIV; + /** Field iv */ + private byte[] iv; + /** Field forWrapping */ + private bool forWrapping; + /** Field IV2 */ + private static readonly byte[] IV2 = { (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, + (byte) 0x2c, (byte) 0x79, (byte) 0xe8, + (byte) 0x21, (byte) 0x05 }; + + // + // checksum digest + // + private readonly IDigest sha1 = new Sha1Digest(); + private readonly byte[] digest = new byte[20]; + + /** + * Method init + * + * @param forWrapping + * @param param + */ + public virtual void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + this.engine = new CbcBlockCipher(new DesEdeEngine()); + + SecureRandom sr; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom pr = (ParametersWithRandom) parameters; + parameters = pr.Parameters; + sr = pr.Random; + } + else + { + sr = new SecureRandom(); + } + + if (parameters is KeyParameter) + { + this.param = (KeyParameter) parameters; + if (this.forWrapping) + { + // Hm, we have no IV but we want to wrap ?!? + // well, then we have to create our own IV. + this.iv = new byte[8]; + sr.NextBytes(iv); + + this.paramPlusIV = new ParametersWithIV(this.param, this.iv); + } + } + else if (parameters is ParametersWithIV) + { + if (!forWrapping) + throw new ArgumentException("You should not supply an IV for unwrapping"); + + this.paramPlusIV = (ParametersWithIV) parameters; + this.iv = this.paramPlusIV.GetIV(); + this.param = (KeyParameter) this.paramPlusIV.Parameters; + + if (this.iv.Length != 8) + throw new ArgumentException("IV is not 8 octets", "parameters"); + } + } + + /** + * Method GetAlgorithmName + * + * @return + */ + public virtual string AlgorithmName + { + get { return "DESede"; } + } + + /** + * Method wrap + * + * @param in + * @param inOff + * @param inLen + * @return + */ + public virtual byte[] Wrap( + byte[] input, + int inOff, + int length) + { + if (!forWrapping) + { + throw new InvalidOperationException("Not initialized for wrapping"); + } + + byte[] keyToBeWrapped = new byte[length]; + Array.Copy(input, inOff, keyToBeWrapped, 0, length); + + // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. + byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped); + + // Let WKCKS = WK || CKS where || is concatenation. + byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length]; + Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length); + Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length); + + // Encrypt WKCKS in CBC mode using KEK as the key and IV as the + // initialization vector. Call the results TEMP1. + + int blockSize = engine.GetBlockSize(); + + if (WKCKS.Length % blockSize != 0) + throw new InvalidOperationException("Not multiple of block length"); + + engine.Init(true, paramPlusIV); + + byte [] TEMP1 = new byte[WKCKS.Length]; + + for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(WKCKS, currentBytePos, TEMP1, currentBytePos); + } + + // Let TEMP2 = IV || TEMP1. + byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length]; + Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length); + Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length); + + // Reverse the order of the octets in TEMP2 and call the result TEMP3. + byte[] TEMP3 = reverse(TEMP2); + + // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector + // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired + // result. It is 40 octets long if a 168 bit key is being wrapped. + ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); + this.engine.Init(true, param2); + + for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + return TEMP3; + } + + /** + * Method unwrap + * + * @param in + * @param inOff + * @param inLen + * @return + * @throws InvalidCipherTextException + */ + public virtual byte[] Unwrap( + byte[] input, + int inOff, + int length) + { + if (forWrapping) + { + throw new InvalidOperationException("Not set for unwrapping"); + } + if (input == null) + { + throw new InvalidCipherTextException("Null pointer as ciphertext"); + } + + int blockSize = engine.GetBlockSize(); + + if (length % blockSize != 0) + { + throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize); + } + + /* + // Check if the length of the cipher text is reasonable given the key + // type. It must be 40 bytes for a 168 bit key and either 32, 40, or + // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported + // or inconsistent with the algorithm for which the key is intended, + // return error. + // + // we do not accept 168 bit keys. it has to be 192 bit. + int lengthA = (estimatedKeyLengthInBit / 8) + 16; + int lengthB = estimatedKeyLengthInBit % 8; + if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) { + throw new XMLSecurityException("empty"); + } + */ + + // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK + // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. + ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); + this.engine.Init(false, param2); + + byte [] TEMP3 = new byte[length]; + + for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(input, inOff + currentBytePos, TEMP3, currentBytePos); + } + + // Reverse the order of the octets in TEMP3 and call the result TEMP2. + byte[] TEMP2 = reverse(TEMP3); + + // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. + this.iv = new byte[8]; + byte[] TEMP1 = new byte[TEMP2.Length - 8]; + Array.Copy(TEMP2, 0, this.iv, 0, 8); + Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8); + + // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV + // found in the previous step. Call the result WKCKS. + this.paramPlusIV = new ParametersWithIV(this.param, this.iv); + this.engine.Init(false, this.paramPlusIV); + + byte[] WKCKS = new byte[TEMP1.Length]; + + for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(TEMP1, currentBytePos, WKCKS, currentBytePos); + } + + // Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are + // those octets before the CKS. + byte[] result = new byte[WKCKS.Length - 8]; + byte[] CKStoBeVerified = new byte[8]; + Array.Copy(WKCKS, 0, result, 0, WKCKS.Length - 8); + Array.Copy(WKCKS, WKCKS.Length - 8, CKStoBeVerified, 0, 8); + + // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare + // with the CKS extracted in the above step. If they are not equal, return error. + if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) { + throw new InvalidCipherTextException( + "Checksum inside ciphertext is corrupted"); + } + + // WK is the wrapped key, now extracted for use in data decryption. + return result; + } + + /** + * Some key wrap algorithms make use of the Key Checksum defined + * in CMS [CMS-Algorithms]. This is used to provide an integrity + * check value for the key being wrapped. The algorithm is + * + * - Compute the 20 octet SHA-1 hash on the key being wrapped. + * - Use the first 8 octets of this hash as the checksum value. + * + * @param key + * @return + * @throws Exception + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private byte[] CalculateCmsKeyChecksum( + byte[] key) + { + sha1.BlockUpdate(key, 0, key.Length); + sha1.DoFinal(digest, 0); + + byte[] result = new byte[8]; + Array.Copy(digest, 0, result, 0, 8); + return result; + } + + /** + * @param key + * @param checksum + * @return + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private bool CheckCmsKeyChecksum( + byte[] key, + byte[] checksum) + { + return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum); + } + + private static byte[] reverse(byte[] bs) + { + byte[] result = new byte[bs.Length]; + for (int i = 0; i < bs.Length; i++) + { + result[i] = bs[bs.Length - (i + 1)]; + } + return result; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs.meta new file mode 100644 index 0000000..faad464 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEdeWrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f34c10037e77a294fa8cf56041b48c29 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs new file mode 100644 index 0000000..f263a97 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs @@ -0,0 +1,479 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// A class that provides a basic DES engine. + public class DesEngine + : IBlockCipher + { + internal const int BLOCK_SIZE = 8; + + private int[] workingKey; + + public virtual int[] GetWorkingKey() + { + return workingKey; + } + + /** + * initialise a DES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to DES init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "DES"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("DES engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + DesFunc(workingKey, input, inOff, output, outOff); + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + /** + * what follows is mainly taken from "Applied Cryptography", by + * Bruce Schneier, however it also bears great resemblance to Richard + * Outerbridge's D3DES... + */ + +// private static readonly short[] Df_Key = +// { +// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, +// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, +// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 +// }; + + private static readonly short[] bytebit = + { + 128, 64, 32, 16, 8, 4, 2, 1 + }; + + private static readonly int[] bigbyte = + { + 0x800000, 0x400000, 0x200000, 0x100000, + 0x80000, 0x40000, 0x20000, 0x10000, + 0x8000, 0x4000, 0x2000, 0x1000, + 0x800, 0x400, 0x200, 0x100, + 0x80, 0x40, 0x20, 0x10, + 0x8, 0x4, 0x2, 0x1 + }; + + /* + * Use the key schedule specified in the Standard (ANSI X3.92-1981). + */ + private static readonly byte[] pc1 = + { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 + }; + + private static readonly byte[] totrot = + { + 1, 2, 4, 6, 8, 10, 12, 14, + 15, 17, 19, 21, 23, 25, 27, 28 + }; + + private static readonly byte[] pc2 = + { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 + }; + + private static readonly uint[] SP1 = + { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 + }; + + private static readonly uint[] SP2 = + { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 + }; + + private static readonly uint[] SP3 = + { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 + }; + + private static readonly uint[] SP4 = + { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 + }; + + private static readonly uint[] SP5 = + { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 + }; + + private static readonly uint[] SP6 = + { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 + }; + + private static readonly uint[] SP7 = + { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 + }; + + private static readonly uint[] SP8 = + { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 + }; + + /** + * Generate an integer based working key based on our secret key + * and what we processing we are planning to do. + * + * Acknowledgements for this routine go to James Gillogly and Phil Karn. + * (whoever, and wherever they are!). + */ + protected static int[] GenerateWorkingKey( + bool encrypting, + byte[] key) + { + int[] newKey = new int[32]; + bool[] pc1m = new bool[56]; + bool[] pcr = new bool[56]; + + for (int j = 0; j < 56; j++ ) + { + int l = pc1[j]; + + pc1m[j] = ((key[(uint) l >> 3] & bytebit[l & 07]) != 0); + } + + for (int i = 0; i < 16; i++) + { + int l, m, n; + + if (encrypting) + { + m = i << 1; + } + else + { + m = (15 - i) << 1; + } + + n = m + 1; + newKey[m] = newKey[n] = 0; + + for (int j = 0; j < 28; j++) + { + l = j + totrot[i]; + if ( l < 28 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for (int j = 28; j < 56; j++) + { + l = j + totrot[i]; + if (l < 56 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for (int j = 0; j < 24; j++) + { + if (pcr[pc2[j]]) + { + newKey[m] |= bigbyte[j]; + } + + if (pcr[pc2[j + 24]]) + { + newKey[n] |= bigbyte[j]; + } + } + } + + // + // store the processed key + // + for (int i = 0; i != 32; i += 2) + { + int i1, i2; + + i1 = newKey[i]; + i2 = newKey[i + 1]; + + newKey[i] = (int) ( (uint) ((i1 & 0x00fc0000) << 6) | + (uint) ((i1 & 0x00000fc0) << 10) | + ((uint) (i2 & 0x00fc0000) >> 10) | + ((uint) (i2 & 0x00000fc0) >> 6)); + + newKey[i + 1] = (int) ( (uint) ((i1 & 0x0003f000) << 12) | + (uint) ((i1 & 0x0000003f) << 16) | + ((uint) (i2 & 0x0003f000) >> 4) | + (uint) (i2 & 0x0000003f)); + } + + return newKey; + } + + /** + * the DES engine. + */ + internal static void DesFunc( + int[] wKey, + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + uint left = Pack.BE_To_UInt32(input, inOff); + uint right = Pack.BE_To_UInt32(input, inOff + 4); + uint work; + + work = ((left >> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + left ^= (work << 4); + work = ((left >> 16) ^ right) & 0x0000ffff; + right ^= work; + left ^= (work << 16); + work = ((right >> 2) ^ left) & 0x33333333; + left ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ left) & 0x00ff00ff; + left ^= work; + right ^= (work << 8); + right = (right << 1) | (right >> 31); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = (left << 1) | (left >> 31); + + for (int round = 0; round < 8; round++) + { + uint fval; + + work = (right << 28) | (right >> 4); + work ^= (uint)wKey[round * 4 + 0]; + fval = SP7[work & 0x3f]; + fval |= SP5[(work >> 8) & 0x3f]; + fval |= SP3[(work >> 16) & 0x3f]; + fval |= SP1[(work >> 24) & 0x3f]; + work = right ^ (uint)wKey[round * 4 + 1]; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >> 8) & 0x3f]; + fval |= SP4[(work >> 16) & 0x3f]; + fval |= SP2[(work >> 24) & 0x3f]; + left ^= fval; + work = (left << 28) | (left >> 4); + work ^= (uint)wKey[round * 4 + 2]; + fval = SP7[ work & 0x3f]; + fval |= SP5[(work >> 8) & 0x3f]; + fval |= SP3[(work >> 16) & 0x3f]; + fval |= SP1[(work >> 24) & 0x3f]; + work = left ^ (uint)wKey[round * 4 + 3]; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >> 8) & 0x3f]; + fval |= SP4[(work >> 16) & 0x3f]; + fval |= SP2[(work >> 24) & 0x3f]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = (left << 31) | (left >> 1); + work = ((left >> 8) ^ right) & 0x00ff00ff; + right ^= work; + left ^= (work << 8); + work = ((left >> 2) ^ right) & 0x33333333; + right ^= work; + left ^= (work << 2); + work = ((right >> 16) ^ left) & 0x0000ffff; + left ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ left) & 0x0f0f0f0f; + left ^= work; + right ^= (work << 4); + + Pack.UInt32_To_BE(right, outBytes, outOff); + Pack.UInt32_To_BE(left, outBytes, outOff + 4); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs.meta new file mode 100644 index 0000000..1630010 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/DesEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f19a6fb9b287c8f449b0d2caee173303 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs new file mode 100644 index 0000000..ecfceee --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs @@ -0,0 +1,182 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic ElGamal algorithm. + */ + public class ElGamalEngine + : IAsymmetricBlockCipher + { + private ElGamalKeyParameters key; + private SecureRandom random; + private bool forEncryption; + private int bitSize; + + public virtual string AlgorithmName + { + get { return "ElGamal"; } + } + + /** + * initialise the ElGamal engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary ElGamal key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) parameters; + + this.key = (ElGamalKeyParameters) p.Parameters; + this.random = p.Random; + } + else + { + this.key = (ElGamalKeyParameters) parameters; + this.random = new SecureRandom(); + } + + this.forEncryption = forEncryption; + this.bitSize = key.Parameters.P.BitLength; + + if (forEncryption) + { + if (!(key is ElGamalPublicKeyParameters)) + { + throw new ArgumentException("ElGamalPublicKeyParameters are required for encryption."); + } + } + else + { + if (!(key is ElGamalPrivateKeyParameters)) + { + throw new ArgumentException("ElGamalPrivateKeyParameters are required for decryption."); + } + } + } + + /** + * Return the maximum size for an input block to this engine. + * For ElGamal this is always one byte less than the size of P on + * encryption, and twice the length as the size of P on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + if (forEncryption) + { + return (bitSize - 1) / 8; + } + + return 2 * ((bitSize + 7) / 8); + } + + /** + * Return the maximum size for an output block to this engine. + * For ElGamal this is always one byte less than the size of P on + * decryption, and twice the length as the size of P on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + if (forEncryption) + { + return 2 * ((bitSize + 7) / 8); + } + + return (bitSize - 1) / 8; + } + + /** + * Process a single block using the basic ElGamal algorithm. + * + * @param in the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param length the length of the data to be processed. + * @return the result of the ElGamal process. + * @exception DataLengthException the input block is too large. + */ + public virtual byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + if (key == null) + throw new InvalidOperationException("ElGamal engine not initialised"); + + int maxLength = forEncryption + ? (bitSize - 1 + 7) / 8 + : GetInputBlockSize(); + + if (length > maxLength) + throw new DataLengthException("input too large for ElGamal cipher.\n"); + + BigInteger p = key.Parameters.P; + + byte[] output; + if (key is ElGamalPrivateKeyParameters) // decryption + { + int halfLength = length / 2; + BigInteger gamma = new BigInteger(1, input, inOff, halfLength); + BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength); + + ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key; + + // a shortcut, which generally relies on p being prime amongst other things. + // if a problem with this shows up, check the p and g values! + BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p); + + output = m.ToByteArrayUnsigned(); + } + else // encryption + { + BigInteger tmp = new BigInteger(1, input, inOff, length); + + if (tmp.BitLength >= p.BitLength) + throw new DataLengthException("input too large for ElGamal cipher.\n"); + + + ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters) key; + + BigInteger pSub2 = p.Subtract(BigInteger.Two); + + // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated + BigInteger k; + do + { + k = new BigInteger(p.BitLength, random); + } + while (k.SignValue == 0 || k.CompareTo(pSub2) > 0); + + BigInteger g = key.Parameters.G; + BigInteger gamma = g.ModPow(k, p); + BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p); + + output = new byte[this.GetOutputBlockSize()]; + + // TODO Add methods to allow writing BigInteger to existing byte array? + byte[] out1 = gamma.ToByteArrayUnsigned(); + byte[] out2 = phi.ToByteArrayUnsigned(); + out1.CopyTo(output, output.Length / 2 - out1.Length); + out2.CopyTo(output, output.Length - out2.Length); + } + + return output; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs.meta new file mode 100644 index 0000000..629c88b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/ElGamalEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aeba69dc4e3260b439d2c421e50fce8b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs new file mode 100644 index 0000000..f8f183b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs @@ -0,0 +1,372 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * implementation of GOST 28147-89 + */ + public class Gost28147Engine + : IBlockCipher + { + private const int BlockSize = 8; + private int[] workingKey = null; + private bool forEncryption; + + private byte[] S = Sbox_Default; + + // these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 + // This is default S-box! + private static readonly byte[] Sbox_Default = { + 0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3, + 0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9, + 0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB, + 0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3, + 0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2, + 0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE, + 0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC, + 0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC + }; + + /* + * class content S-box parameters for encrypting + * getting from, see: http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-01.txt + * http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-02.txt + */ + private static readonly byte[] ESbox_Test = { + 0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6, + 0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5, + 0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB, + 0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8, + 0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4, + 0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4, + 0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD, + 0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8 + }; + + private static readonly byte[] ESbox_A = { + 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, + 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, + 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, + 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, + 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, + 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, + 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, + 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 + }; + + private static readonly byte[] ESbox_B = { + 0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF, + 0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE, + 0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4, + 0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8, + 0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3, + 0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5, + 0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE, + 0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC + }; + + private static readonly byte[] ESbox_C = { + 0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3, + 0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3, + 0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB, + 0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4, + 0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7, + 0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD, + 0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7, + 0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8 + }; + + private static readonly byte[] ESbox_D = { + 0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3, + 0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1, + 0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2, + 0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8, + 0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1, + 0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6, + 0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7, + 0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE + }; + + //S-box for digest + private static readonly byte[] DSbox_Test = { + 0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3, + 0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9, + 0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB, + 0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3, + 0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2, + 0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE, + 0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC, + 0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC + }; + + private static readonly byte[] DSbox_A = { + 0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF, + 0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8, + 0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD, + 0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3, + 0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5, + 0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3, + 0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB, + 0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC + }; + + // + // pre-defined sbox table + // + private static readonly IDictionary sBoxes = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + static Gost28147Engine() + { + AddSBox("Default", Sbox_Default); + AddSBox("E-TEST", ESbox_Test); + AddSBox("E-A", ESbox_A); + AddSBox("E-B", ESbox_B); + AddSBox("E-C", ESbox_C); + AddSBox("E-D", ESbox_D); + AddSBox("D-TEST", DSbox_Test); + AddSBox("D-A", DSbox_A); + } + + private static void AddSBox(string sBoxName, byte[] sBox) + { + sBoxes.Add(Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(sBoxName), sBox); + } + + /** + * standard constructor. + */ + public Gost28147Engine() + { + } + + /** + * initialise an Gost28147 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithSBox) + { + ParametersWithSBox param = (ParametersWithSBox)parameters; + + // + // Set the S-Box + // + byte[] sBox = param.GetSBox(); + if (sBox.Length != Sbox_Default.Length) + throw new ArgumentException("invalid S-box passed to GOST28147 init"); + + this.S = Arrays.Clone(sBox); + + // + // set key if there is one + // + if (param.Parameters != null) + { + workingKey = generateWorkingKey(forEncryption, + ((KeyParameter)param.Parameters).GetKey()); + } + } + else if (parameters is KeyParameter) + { + workingKey = generateWorkingKey(forEncryption, + ((KeyParameter)parameters).GetKey()); + } + else if (parameters != null) + { + throw new ArgumentException("invalid parameter passed to Gost28147 init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + } + + public virtual string AlgorithmName + { + get { return "Gost28147"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Gost28147 engine not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + Gost28147Func(workingKey, input, inOff, output, outOff); + + return BlockSize; + } + + public virtual void Reset() + { + } + + private int[] generateWorkingKey( + bool forEncryption, + byte[] userKey) + { + this.forEncryption = forEncryption; + + if (userKey.Length != 32) + { + throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); + } + + int[] key = new int[8]; + for(int i=0; i!=8; i++) + { + key[i] = bytesToint(userKey,i*4); + } + + return key; + } + + private int Gost28147_mainStep(int n1, int key) + { + int cm = (key + n1); // CM1 + + // S-box replacing + + int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); + om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); + om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); + om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); + om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); + om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); + om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); + om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); + +// return om << 11 | om >>> (32-11); // 11-leftshift + int omLeft = om << 11; + int omRight = (int)(((uint) om) >> (32 - 11)); // Note: Casts required to get unsigned bit rotation + + return omLeft | omRight; + } + + private void Gost28147Func( + int[] workingKey, + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + int N1, N2, tmp; //tmp -> for saving N1 + N1 = bytesToint(inBytes, inOff); + N2 = bytesToint(inBytes, inOff + 4); + + if (this.forEncryption) + { + for(int k = 0; k < 3; k++) // 1-24 steps + { + for(int j = 0; j < 8; j++) + { + tmp = N1; + int step = Gost28147_mainStep(N1, workingKey[j]); + N1 = N2 ^ step; // CM2 + N2 = tmp; + } + } + for(int j = 7; j > 0; j--) // 25-31 steps + { + tmp = N1; + N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + else //decrypt + { + for(int j = 0; j < 8; j++) // 1-8 steps + { + tmp = N1; + N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + for(int k = 0; k < 3; k++) //9-31 steps + { + for(int j = 7; j >= 0; j--) + { + if ((k == 2) && (j==0)) + { + break; // break 32 step + } + tmp = N1; + N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + } + + N2 = N2 ^ Gost28147_mainStep(N1, workingKey[0]); // 32 step (N1=N1) + + intTobytes(N1, outBytes, outOff); + intTobytes(N2, outBytes, outOff + 4); + } + + //array of bytes to type int + private static int bytesToint( + byte[] inBytes, + int inOff) + { + return (int)((inBytes[inOff + 3] << 24) & 0xff000000) + ((inBytes[inOff + 2] << 16) & 0xff0000) + + ((inBytes[inOff + 1] << 8) & 0xff00) + (inBytes[inOff] & 0xff); + } + + //int to array of bytes + private static void intTobytes( + int num, + byte[] outBytes, + int outOff) + { + outBytes[outOff + 3] = (byte)(num >> 24); + outBytes[outOff + 2] = (byte)(num >> 16); + outBytes[outOff + 1] = (byte)(num >> 8); + outBytes[outOff] = (byte)num; + } + + /** + * Return the S-Box associated with SBoxName + * @param sBoxName name of the S-Box + * @return byte array representing the S-Box + */ + public static byte[] GetSBox( + string sBoxName) + { + byte[] sBox = (byte[])sBoxes[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(sBoxName)]; + + if (sBox == null) + { + throw new ArgumentException("Unknown S-Box - possible types: " + + "\"Default\", \"E-Test\", \"E-A\", \"E-B\", \"E-C\", \"E-D\", \"D-Test\", \"D-A\"."); + } + + return Arrays.Clone(sBox); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs.meta new file mode 100644 index 0000000..72c5899 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/GOST28147Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4c737f7f68f496f4a860774bee5eb7a9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs new file mode 100644 index 0000000..e238158 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs @@ -0,0 +1,239 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * HC-128 is a software-efficient stream cipher created by Hongjun Wu. It + * generates keystream from a 128-bit secret key and a 128-bit initialization + * vector. + *

+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf + *

+ * It is a third phase candidate in the eStream contest, and is patent-free. + * No attacks are known as of today (April 2007). See + * + * http://www.ecrypt.eu.org/stream/hcp3.html + *

+ */ + public class HC128Engine + : IStreamCipher + { + private uint[] p = new uint[512]; + private uint[] q = new uint[512]; + private uint cnt = 0; + + private static uint F1(uint x) + { + return RotateRight(x, 7) ^ RotateRight(x, 18) ^ (x >> 3); + } + + private static uint F2(uint x) + { + return RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10); + } + + private uint G1(uint x, uint y, uint z) + { + return (RotateRight(x, 10) ^ RotateRight(z, 23)) + RotateRight(y, 8); + } + + private uint G2(uint x, uint y, uint z) + { + return (RotateLeft(x, 10) ^ RotateLeft(z, 23)) + RotateLeft(y, 8); + } + + private static uint RotateLeft(uint x, int bits) + { + return (x << bits) | (x >> -bits); + } + + private static uint RotateRight(uint x, int bits) + { + return (x >> bits) | (x << -bits); + } + + private uint H1(uint x) + { + return q[x & 0xFF] + q[((x >> 16) & 0xFF) + 256]; + } + + private uint H2(uint x) + { + return p[x & 0xFF] + p[((x >> 16) & 0xFF) + 256]; + } + + private static uint Mod1024(uint x) + { + return x & 0x3FF; + } + + private static uint Mod512(uint x) + { + return x & 0x1FF; + } + + private static uint Dim(uint x, uint y) + { + return Mod512(x - y); + } + + private uint Step() + { + uint j = Mod512(cnt); + uint ret; + if (cnt < 512) + { + p[j] += G1(p[Dim(j, 3)], p[Dim(j, 10)], p[Dim(j, 511)]); + ret = H1(p[Dim(j, 12)]) ^ p[j]; + } + else + { + q[j] += G2(q[Dim(j, 3)], q[Dim(j, 10)], q[Dim(j, 511)]); + ret = H2(q[Dim(j, 12)]) ^ q[j]; + } + cnt = Mod1024(cnt + 1); + return ret; + } + + private byte[] key, iv; + private bool initialised; + + private void Init() + { + if (key.Length != 16) + throw new ArgumentException("The key must be 128 bits long"); + + idx = 0; + cnt = 0; + + uint[] w = new uint[1280]; + + for (int i = 0; i < 16; i++) + { + w[i >> 2] |= ((uint)key[i] << (8 * (i & 0x3))); + } + Array.Copy(w, 0, w, 4, 4); + + for (int i = 0; i < iv.Length && i < 16; i++) + { + w[(i >> 2) + 8] |= ((uint)iv[i] << (8 * (i & 0x3))); + } + Array.Copy(w, 8, w, 12, 4); + + for (uint i = 16; i < 1280; i++) + { + w[i] = F2(w[i - 2]) + w[i - 7] + F1(w[i - 15]) + w[i - 16] + i; + } + + Array.Copy(w, 256, p, 0, 512); + Array.Copy(w, 768, q, 0, 512); + + for (int i = 0; i < 512; i++) + { + p[i] = Step(); + } + for (int i = 0; i < 512; i++) + { + q[i] = Step(); + } + + cnt = 0; + } + + public virtual string AlgorithmName + { + get { return "HC-128"; } + } + + /** + * Initialise a HC-128 cipher. + * + * @param forEncryption whether or not we are for encryption. Irrelevant, as + * encryption and decryption are the same. + * @param params the parameters required to set up the cipher. + * @throws ArgumentException if the params argument is + * inappropriate (ie. the key is not 128 bit long). + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + ICipherParameters keyParam = parameters; + + if (parameters is ParametersWithIV) + { + iv = ((ParametersWithIV)parameters).GetIV(); + keyParam = ((ParametersWithIV)parameters).Parameters; + } + else + { + iv = new byte[0]; + } + + if (keyParam is KeyParameter) + { + key = ((KeyParameter)keyParam).GetKey(); + Init(); + } + else + { + throw new ArgumentException( + "Invalid parameter passed to HC128 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), + "parameters"); + } + + initialised = true; + } + + private byte[] buf = new byte[4]; + private int idx = 0; + + private byte GetByte() + { + if (idx == 0) + { + Pack.UInt32_To_LE(Step(), buf); + } + byte ret = buf[idx]; + idx = idx + 1 & 0x3; + return ret; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); + } + } + + public virtual void Reset() + { + Init(); + } + + public virtual byte ReturnByte(byte input) + { + return (byte)(input ^ GetByte()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs.meta new file mode 100644 index 0000000..f876e8d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC128Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 181b21bf264bc414aa9f03db25c3431d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs new file mode 100644 index 0000000..01941aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs @@ -0,0 +1,228 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * HC-256 is a software-efficient stream cipher created by Hongjun Wu. It + * generates keystream from a 256-bit secret key and a 256-bit initialization + * vector. + *

+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf + *

+ * Its brother, HC-128, is a third phase candidate in the eStream contest. + * The algorithm is patent-free. No attacks are known as of today (April 2007). + * See + * + * http://www.ecrypt.eu.org/stream/hcp3.html + *

+ */ + public class HC256Engine + : IStreamCipher + { + private uint[] p = new uint[1024]; + private uint[] q = new uint[1024]; + private uint cnt = 0; + + private uint Step() + { + uint j = cnt & 0x3FF; + uint ret; + if (cnt < 1024) + { + uint x = p[(j - 3 & 0x3FF)]; + uint y = p[(j - 1023 & 0x3FF)]; + p[j] += p[(j - 10 & 0x3FF)] + + (RotateRight(x, 10) ^ RotateRight(y, 23)) + + q[((x ^ y) & 0x3FF)]; + + x = p[(j - 12 & 0x3FF)]; + ret = (q[x & 0xFF] + q[((x >> 8) & 0xFF) + 256] + + q[((x >> 16) & 0xFF) + 512] + q[((x >> 24) & 0xFF) + 768]) + ^ p[j]; + } + else + { + uint x = q[(j - 3 & 0x3FF)]; + uint y = q[(j - 1023 & 0x3FF)]; + q[j] += q[(j - 10 & 0x3FF)] + + (RotateRight(x, 10) ^ RotateRight(y, 23)) + + p[((x ^ y) & 0x3FF)]; + + x = q[(j - 12 & 0x3FF)]; + ret = (p[x & 0xFF] + p[((x >> 8) & 0xFF) + 256] + + p[((x >> 16) & 0xFF) + 512] + p[((x >> 24) & 0xFF) + 768]) + ^ q[j]; + } + cnt = cnt + 1 & 0x7FF; + return ret; + } + + private byte[] key, iv; + private bool initialised; + + private void Init() + { + if (key.Length != 32 && key.Length != 16) + throw new ArgumentException("The key must be 128/256 bits long"); + + if (iv.Length < 16) + throw new ArgumentException("The IV must be at least 128 bits long"); + + if (key.Length != 32) + { + byte[] k = new byte[32]; + + Array.Copy(key, 0, k, 0, key.Length); + Array.Copy(key, 0, k, 16, key.Length); + + key = k; + } + + if (iv.Length < 32) + { + byte[] newIV = new byte[32]; + + Array.Copy(iv, 0, newIV, 0, iv.Length); + Array.Copy(iv, 0, newIV, iv.Length, newIV.Length - iv.Length); + + iv = newIV; + } + + idx = 0; + cnt = 0; + + uint[] w = new uint[2560]; + + for (int i = 0; i < 32; i++) + { + w[i >> 2] |= ((uint)key[i] << (8 * (i & 0x3))); + } + + for (int i = 0; i < 32; i++) + { + w[(i >> 2) + 8] |= ((uint)iv[i] << (8 * (i & 0x3))); + } + + for (uint i = 16; i < 2560; i++) + { + uint x = w[i - 2]; + uint y = w[i - 15]; + w[i] = (RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10)) + + w[i - 7] + + (RotateRight(y, 7) ^ RotateRight(y, 18) ^ (y >> 3)) + + w[i - 16] + i; + } + + Array.Copy(w, 512, p, 0, 1024); + Array.Copy(w, 1536, q, 0, 1024); + + for (int i = 0; i < 4096; i++) + { + Step(); + } + + cnt = 0; + } + + public virtual string AlgorithmName + { + get { return "HC-256"; } + } + + /** + * Initialise a HC-256 cipher. + * + * @param forEncryption whether or not we are for encryption. Irrelevant, as + * encryption and decryption are the same. + * @param params the parameters required to set up the cipher. + * @throws ArgumentException if the params argument is + * inappropriate (ie. the key is not 256 bit long). + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + ICipherParameters keyParam = parameters; + + if (parameters is ParametersWithIV) + { + iv = ((ParametersWithIV)parameters).GetIV(); + keyParam = ((ParametersWithIV)parameters).Parameters; + } + else + { + iv = new byte[0]; + } + + if (keyParam is KeyParameter) + { + key = ((KeyParameter)keyParam).GetKey(); + Init(); + } + else + { + throw new ArgumentException( + "Invalid parameter passed to HC256 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), + "parameters"); + } + + initialised = true; + } + + private byte[] buf = new byte[4]; + private int idx = 0; + + private byte GetByte() + { + if (idx == 0) + { + Pack.UInt32_To_LE(Step(), buf); + } + byte ret = buf[idx]; + idx = idx + 1 & 0x3; + return ret; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); + } + } + + public virtual void Reset() + { + Init(); + } + + public virtual byte ReturnByte(byte input) + { + return (byte)(input ^ GetByte()); + } + + private static uint RotateRight(uint x, int bits) + { + return (x >> bits) | (x << -bits); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs.meta new file mode 100644 index 0000000..cd19a1e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/HC256Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a97c4e05480602c42b965ee80fd861b8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs new file mode 100644 index 0000000..7139bf6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs @@ -0,0 +1,336 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides a basic International Data Encryption Algorithm (IDEA) engine. + *

+ * This implementation is based on the "HOWTO: INTERNATIONAL DATA ENCRYPTION ALGORITHM" + * implementation summary by Fauzan Mirza (F.U.Mirza@sheffield.ac.uk). (baring 1 typo at the + * end of the mulinv function!). + *

+ *

+ * It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/ + *

+ *

+ * Note 1: This algorithm is patented in the USA, Japan, and Europe including + * at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland + * and the United Kingdom. Non-commercial use is free, however any commercial + * products are liable for royalties. Please see + * www.mediacrypt.com for + * further details. This announcement has been included at the request of + * the patent holders. + *

+ *

+ * Note 2: Due to the requests concerning the above, this algorithm is now only + * included in the extended assembly. It is not included in the default distributions. + *

+ */ + public class IdeaEngine + : IBlockCipher + { + private const int BLOCK_SIZE = 8; + private int[] workingKey; + /** + * standard constructor. + */ + public IdeaEngine() + { + } + /** + * initialise an IDEA cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to IDEA init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + workingKey = GenerateWorkingKey(forEncryption, + ((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "IDEA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("IDEA engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + IdeaFunc(workingKey, input, inOff, output, outOff); + return BLOCK_SIZE; + } + public virtual void Reset() + { + } + private static readonly int MASK = 0xffff; + private static readonly int BASE = 0x10001; + private int BytesToWord( + byte[] input, + int inOff) + { + return ((input[inOff] << 8) & 0xff00) + (input[inOff + 1] & 0xff); + } + private void WordToBytes( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)((uint) word >> 8); + outBytes[outOff + 1] = (byte)word; + } + /** + * return x = x * y where the multiplication is done modulo + * 65537 (0x10001) (as defined in the IDEA specification) and + * a zero input is taken to be 65536 (0x10000). + * + * @param x the x value + * @param y the y value + * @return x = x * y + */ + private int Mul( + int x, + int y) + { + if (x == 0) + { + x = (BASE - y); + } + else if (y == 0) + { + x = (BASE - x); + } + else + { + int p = x * y; + y = p & MASK; + x = (int) ((uint) p >> 16); + x = y - x + ((y < x) ? 1 : 0); + } + return x & MASK; + } + private void IdeaFunc( + int[] workingKey, + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x0, x1, x2, x3, t0, t1; + int keyOff = 0; + x0 = BytesToWord(input, inOff); + x1 = BytesToWord(input, inOff + 2); + x2 = BytesToWord(input, inOff + 4); + x3 = BytesToWord(input, inOff + 6); + for (int round = 0; round < 8; round++) + { + x0 = Mul(x0, workingKey[keyOff++]); + x1 += workingKey[keyOff++]; + x1 &= MASK; + x2 += workingKey[keyOff++]; + x2 &= MASK; + x3 = Mul(x3, workingKey[keyOff++]); + t0 = x1; + t1 = x2; + x2 ^= x0; + x1 ^= x3; + x2 = Mul(x2, workingKey[keyOff++]); + x1 += x2; + x1 &= MASK; + x1 = Mul(x1, workingKey[keyOff++]); + x2 += x1; + x2 &= MASK; + x0 ^= x1; + x3 ^= x2; + x1 ^= t1; + x2 ^= t0; + } + WordToBytes(Mul(x0, workingKey[keyOff++]), outBytes, outOff); + WordToBytes(x2 + workingKey[keyOff++], outBytes, outOff + 2); /* NB: Order */ + WordToBytes(x1 + workingKey[keyOff++], outBytes, outOff + 4); + WordToBytes(Mul(x3, workingKey[keyOff]), outBytes, outOff + 6); + } + /** + * The following function is used to expand the user key to the encryption + * subkey. The first 16 bytes are the user key, and the rest of the subkey + * is calculated by rotating the previous 16 bytes by 25 bits to the left, + * and so on until the subkey is completed. + */ + private int[] ExpandKey( + byte[] uKey) + { + int[] key = new int[52]; + if (uKey.Length < 16) + { + byte[] tmp = new byte[16]; + Array.Copy(uKey, 0, tmp, tmp.Length - uKey.Length, uKey.Length); + uKey = tmp; + } + for (int i = 0; i < 8; i++) + { + key[i] = BytesToWord(uKey, i * 2); + } + for (int i = 8; i < 52; i++) + { + if ((i & 7) < 6) + { + key[i] = ((key[i - 7] & 127) << 9 | key[i - 6] >> 7) & MASK; + } + else if ((i & 7) == 6) + { + key[i] = ((key[i - 7] & 127) << 9 | key[i - 14] >> 7) & MASK; + } + else + { + key[i] = ((key[i - 15] & 127) << 9 | key[i - 14] >> 7) & MASK; + } + } + return key; + } + /** + * This function computes multiplicative inverse using Euclid's Greatest + * Common Divisor algorithm. Zero and one are self inverse. + *

+ * i.e. x * MulInv(x) == 1 (modulo BASE) + *

+ */ + private int MulInv( + int x) + { + int t0, t1, q, y; + + if (x < 2) + { + return x; + } + t0 = 1; + t1 = BASE / x; + y = BASE % x; + while (y != 1) + { + q = x / y; + x = x % y; + t0 = (t0 + (t1 * q)) & MASK; + if (x == 1) + { + return t0; + } + q = y / x; + y = y % x; + t1 = (t1 + (t0 * q)) & MASK; + } + return (1 - t1) & MASK; + } + /** + * Return the additive inverse of x. + *

+ * i.e. x + AddInv(x) == 0 + *

+ */ + int AddInv( + int x) + { + return (0 - x) & MASK; + } + + /** + * The function to invert the encryption subkey to the decryption subkey. + * It also involves the multiplicative inverse and the additive inverse functions. + */ + private int[] InvertKey( + int[] inKey) + { + int t1, t2, t3, t4; + int p = 52; /* We work backwards */ + int[] key = new int[52]; + int inOff = 0; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff++]); + key[--p] = t4; + key[--p] = t3; + key[--p] = t2; + key[--p] = t1; + + for (int round = 1; round < 8; round++) + { + t1 = inKey[inOff++]; + t2 = inKey[inOff++]; + key[--p] = t2; + key[--p] = t1; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff++]); + key[--p] = t4; + key[--p] = t2; /* NB: Order */ + key[--p] = t3; + key[--p] = t1; + } + t1 = inKey[inOff++]; + t2 = inKey[inOff++]; + key[--p] = t2; + key[--p] = t1; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff]); + key[--p] = t4; + key[--p] = t3; + key[--p] = t2; + key[--p] = t1; + return key; + } + + private int[] GenerateWorkingKey( + bool forEncryption, + byte[] userKey) + { + if (forEncryption) + { + return ExpandKey(userKey); + } + else + { + return InvertKey(ExpandKey(userKey)); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs.meta new file mode 100644 index 0000000..860b5a3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IdeaEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4803aa4dab7fb004db3a42672bcbb85a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs new file mode 100644 index 0000000..d9b087f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs @@ -0,0 +1,247 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * support class for constructing intergrated encryption ciphers + * for doing basic message exchanges on top of key agreement ciphers + */ + public class IesEngine + { + private readonly IBasicAgreement agree; + private readonly IDerivationFunction kdf; + private readonly IMac mac; + private readonly BufferedBlockCipher cipher; + private readonly byte[] macBuf; + + private bool forEncryption; + private ICipherParameters privParam, pubParam; + private IesParameters param; + + /** + * set up for use with stream mode, where the key derivation function + * is used to provide a stream of bytes to xor with the message. + * + * @param agree the key agreement used as the basis for the encryption + * @param kdf the key derivation function used for byte generation + * @param mac the message authentication code generator for the message + */ + public IesEngine( + IBasicAgreement agree, + IDerivationFunction kdf, + IMac mac) + { + this.agree = agree; + this.kdf = kdf; + this.mac = mac; + this.macBuf = new byte[mac.GetMacSize()]; +// this.cipher = null; + } + + /** + * set up for use in conjunction with a block cipher to handle the + * message. + * + * @param agree the key agreement used as the basis for the encryption + * @param kdf the key derivation function used for byte generation + * @param mac the message authentication code generator for the message + * @param cipher the cipher to used for encrypting the message + */ + public IesEngine( + IBasicAgreement agree, + IDerivationFunction kdf, + IMac mac, + BufferedBlockCipher cipher) + { + this.agree = agree; + this.kdf = kdf; + this.mac = mac; + this.macBuf = new byte[mac.GetMacSize()]; + this.cipher = cipher; + } + + /** + * Initialise the encryptor. + * + * @param forEncryption whether or not this is encryption/decryption. + * @param privParam our private key parameters + * @param pubParam the recipient's/sender's public key parameters + * @param param encoding and derivation parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters privParameters, + ICipherParameters pubParameters, + ICipherParameters iesParameters) + { + this.forEncryption = forEncryption; + this.privParam = privParameters; + this.pubParam = pubParameters; + this.param = (IesParameters)iesParameters; + } + + private byte[] DecryptBlock( + byte[] in_enc, + int inOff, + int inLen, + byte[] z) + { + byte[] M = null; + KeyParameter macKey = null; + KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); + int macKeySize = param.MacKeySize; + + kdf.Init(kParam); + + // Ensure that the length of the input is greater than the MAC in bytes + if (inLen < mac.GetMacSize()) + throw new InvalidCipherTextException("Length of input must be greater than the MAC"); + + inLen -= mac.GetMacSize(); + + if (cipher == null) // stream mode + { + byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); + + M = new byte[inLen]; + + for (int i = 0; i != inLen; i++) + { + M[i] = (byte)(in_enc[inOff + i] ^ Buffer[i]); + } + + macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); + } + else + { + int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; + byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); + + cipher.Init(false, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); + + M = cipher.DoFinal(in_enc, inOff, inLen); + + macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); + } + + byte[] macIV = param.GetEncodingV(); + + mac.Init(macKey); + mac.BlockUpdate(in_enc, inOff, inLen); + mac.BlockUpdate(macIV, 0, macIV.Length); + mac.DoFinal(macBuf, 0); + + inOff += inLen; + + byte[] T1 = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length); + + if (!Arrays.ConstantTimeAreEqual(T1, macBuf)) + throw (new InvalidCipherTextException("Invalid MAC.")); + + return M; + } + + private byte[] EncryptBlock( + byte[] input, + int inOff, + int inLen, + byte[] z) + { + byte[] C = null; + KeyParameter macKey = null; + KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); + int c_text_length = 0; + int macKeySize = param.MacKeySize; + + if (cipher == null) // stream mode + { + byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); + + C = new byte[inLen + mac.GetMacSize()]; + c_text_length = inLen; + + for (int i = 0; i != inLen; i++) + { + C[i] = (byte)(input[inOff + i] ^ Buffer[i]); + } + + macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); + } + else + { + int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; + byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); + + cipher.Init(true, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); + + c_text_length = cipher.GetOutputSize(inLen); + byte[] tmp = new byte[c_text_length]; + + int len = cipher.ProcessBytes(input, inOff, inLen, tmp, 0); + len += cipher.DoFinal(tmp, len); + + C = new byte[len + mac.GetMacSize()]; + c_text_length = len; + + Array.Copy(tmp, 0, C, 0, len); + + macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); + } + + byte[] macIV = param.GetEncodingV(); + + mac.Init(macKey); + mac.BlockUpdate(C, 0, c_text_length); + mac.BlockUpdate(macIV, 0, macIV.Length); + // + // return the message and it's MAC + // + mac.DoFinal(C, c_text_length); + return C; + } + + private byte[] GenerateKdfBytes( + KdfParameters kParam, + int length) + { + byte[] buf = new byte[length]; + + kdf.Init(kParam); + + kdf.GenerateBytes(buf, 0, buf.Length); + + return buf; + } + + public virtual byte[] ProcessBlock( + byte[] input, + int inOff, + int inLen) + { + agree.Init(privParam); + + BigInteger z = agree.CalculateAgreement(pubParam); + + byte[] zBytes = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), z); + + try + { + return forEncryption + ? EncryptBlock(input, inOff, inLen, zBytes) + : DecryptBlock(input, inOff, inLen, zBytes); + } + finally + { + Array.Clear(zBytes, 0, zBytes.Length); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs.meta new file mode 100644 index 0000000..793d2c1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/IesEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7cea1426e4f8131488b05c998910d4ac +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs new file mode 100644 index 0000000..6adad78 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs @@ -0,0 +1,245 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A Noekeon engine, using direct-key mode. + */ + public class NoekeonEngine + : IBlockCipher + { + private const int GenericSize = 16; // Block and key size, as well as the amount of rounds. + + private static readonly uint[] nullVector = + { + 0x00, 0x00, 0x00, 0x00 // Used in decryption + }; + + private static readonly uint[] roundConstants = + { + 0x80, 0x1b, 0x36, 0x6c, + 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, + 0xd4 + }; + + private uint[] state = new uint[4], // a + subKeys = new uint[4], // k + decryptKeys = new uint[4]; + + private bool _initialised, _forEncryption; + + /** + * Create an instance of the Noekeon encryption algorithm + * and set some defaults + */ + public NoekeonEngine() + { + _initialised = false; + } + + public virtual string AlgorithmName + { + get { return "Noekeon"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return GenericSize; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("Invalid parameters passed to Noekeon init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), "parameters"); + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, GenericSize, "input buffer too short"); + Check.OutputLength(output, outOff, GenericSize, "output buffer too short"); + + return _forEncryption + ? encryptBlock(input, inOff, output, outOff) + : decryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + // TODO This should do something in case the encryption is aborted + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey(byte[] key) + { + subKeys[0] = Pack.BE_To_UInt32(key, 0); + subKeys[1] = Pack.BE_To_UInt32(key, 4); + subKeys[2] = Pack.BE_To_UInt32(key, 8); + subKeys[3] = Pack.BE_To_UInt32(key, 12); + } + + private int encryptBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + state[0] = Pack.BE_To_UInt32(input, inOff); + state[1] = Pack.BE_To_UInt32(input, inOff+4); + state[2] = Pack.BE_To_UInt32(input, inOff+8); + state[3] = Pack.BE_To_UInt32(input, inOff+12); + + int i; + for (i = 0; i < GenericSize; i++) + { + state[0] ^= roundConstants[i]; + theta(state, subKeys); + pi1(state); + gamma(state); + pi2(state); + } + + state[0] ^= roundConstants[i]; + theta(state, subKeys); + + Pack.UInt32_To_BE(state[0], output, outOff); + Pack.UInt32_To_BE(state[1], output, outOff+4); + Pack.UInt32_To_BE(state[2], output, outOff+8); + Pack.UInt32_To_BE(state[3], output, outOff+12); + + return GenericSize; + } + + private int decryptBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + state[0] = Pack.BE_To_UInt32(input, inOff); + state[1] = Pack.BE_To_UInt32(input, inOff+4); + state[2] = Pack.BE_To_UInt32(input, inOff+8); + state[3] = Pack.BE_To_UInt32(input, inOff+12); + + Array.Copy(subKeys, 0, decryptKeys, 0, subKeys.Length); + theta(decryptKeys, nullVector); + + int i; + for (i = GenericSize; i > 0; i--) + { + theta(state, decryptKeys); + state[0] ^= roundConstants[i]; + pi1(state); + gamma(state); + pi2(state); + } + + theta(state, decryptKeys); + state[0] ^= roundConstants[i]; + + Pack.UInt32_To_BE(state[0], output, outOff); + Pack.UInt32_To_BE(state[1], output, outOff+4); + Pack.UInt32_To_BE(state[2], output, outOff+8); + Pack.UInt32_To_BE(state[3], output, outOff+12); + + return GenericSize; + } + + private void gamma(uint[] a) + { + a[1] ^= ~a[3] & ~a[2]; + a[0] ^= a[2] & a[1]; + + uint tmp = a[3]; + a[3] = a[0]; + a[0] = tmp; + a[2] ^= a[0]^a[1]^a[3]; + + a[1] ^= ~a[3] & ~a[2]; + a[0] ^= a[2] & a[1]; + } + + private void theta(uint[] a, uint[] k) + { + uint tmp; + tmp = a[0]^a[2]; + tmp ^= rotl(tmp,8)^rotl(tmp,24); + a[1] ^= tmp; + a[3] ^= tmp; + + for (int i = 0; i < 4; i++) + { + a[i] ^= k[i]; + } + + tmp = a[1]^a[3]; + tmp ^= rotl(tmp,8)^rotl(tmp,24); + a[0] ^= tmp; + a[2] ^= tmp; + } + + private void pi1(uint[] a) + { + a[1] = rotl(a[1], 1); + a[2] = rotl(a[2], 5); + a[3] = rotl(a[3], 2); + } + + private void pi2(uint[] a) + { + a[1] = rotl(a[1], 31); + a[2] = rotl(a[2], 27); + a[3] = rotl(a[3], 30); + } + + // Helpers + + private uint rotl(uint x, int y) + { + return (x << y) | (x >> (32-y)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs.meta new file mode 100644 index 0000000..785162c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/NoekeonEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 89978e6f457d6a546ac5b8c81fa0b9cb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs new file mode 100644 index 0000000..f041530 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs @@ -0,0 +1,315 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of RC2 as described in RFC 2268 + * "A Description of the RC2(r) Encryption Algorithm" R. Rivest. + */ + public class RC2Engine + : IBlockCipher + { + // + // the values we use for key expansion (based on the digits of PI) + // + private static readonly byte[] piTable = + { + (byte)0xd9, (byte)0x78, (byte)0xf9, (byte)0xc4, (byte)0x19, (byte)0xdd, (byte)0xb5, (byte)0xed, + (byte)0x28, (byte)0xe9, (byte)0xfd, (byte)0x79, (byte)0x4a, (byte)0xa0, (byte)0xd8, (byte)0x9d, + (byte)0xc6, (byte)0x7e, (byte)0x37, (byte)0x83, (byte)0x2b, (byte)0x76, (byte)0x53, (byte)0x8e, + (byte)0x62, (byte)0x4c, (byte)0x64, (byte)0x88, (byte)0x44, (byte)0x8b, (byte)0xfb, (byte)0xa2, + (byte)0x17, (byte)0x9a, (byte)0x59, (byte)0xf5, (byte)0x87, (byte)0xb3, (byte)0x4f, (byte)0x13, + (byte)0x61, (byte)0x45, (byte)0x6d, (byte)0x8d, (byte)0x9, (byte)0x81, (byte)0x7d, (byte)0x32, + (byte)0xbd, (byte)0x8f, (byte)0x40, (byte)0xeb, (byte)0x86, (byte)0xb7, (byte)0x7b, (byte)0xb, + (byte)0xf0, (byte)0x95, (byte)0x21, (byte)0x22, (byte)0x5c, (byte)0x6b, (byte)0x4e, (byte)0x82, + (byte)0x54, (byte)0xd6, (byte)0x65, (byte)0x93, (byte)0xce, (byte)0x60, (byte)0xb2, (byte)0x1c, + (byte)0x73, (byte)0x56, (byte)0xc0, (byte)0x14, (byte)0xa7, (byte)0x8c, (byte)0xf1, (byte)0xdc, + (byte)0x12, (byte)0x75, (byte)0xca, (byte)0x1f, (byte)0x3b, (byte)0xbe, (byte)0xe4, (byte)0xd1, + (byte)0x42, (byte)0x3d, (byte)0xd4, (byte)0x30, (byte)0xa3, (byte)0x3c, (byte)0xb6, (byte)0x26, + (byte)0x6f, (byte)0xbf, (byte)0xe, (byte)0xda, (byte)0x46, (byte)0x69, (byte)0x7, (byte)0x57, + (byte)0x27, (byte)0xf2, (byte)0x1d, (byte)0x9b, (byte)0xbc, (byte)0x94, (byte)0x43, (byte)0x3, + (byte)0xf8, (byte)0x11, (byte)0xc7, (byte)0xf6, (byte)0x90, (byte)0xef, (byte)0x3e, (byte)0xe7, + (byte)0x6, (byte)0xc3, (byte)0xd5, (byte)0x2f, (byte)0xc8, (byte)0x66, (byte)0x1e, (byte)0xd7, + (byte)0x8, (byte)0xe8, (byte)0xea, (byte)0xde, (byte)0x80, (byte)0x52, (byte)0xee, (byte)0xf7, + (byte)0x84, (byte)0xaa, (byte)0x72, (byte)0xac, (byte)0x35, (byte)0x4d, (byte)0x6a, (byte)0x2a, + (byte)0x96, (byte)0x1a, (byte)0xd2, (byte)0x71, (byte)0x5a, (byte)0x15, (byte)0x49, (byte)0x74, + (byte)0x4b, (byte)0x9f, (byte)0xd0, (byte)0x5e, (byte)0x4, (byte)0x18, (byte)0xa4, (byte)0xec, + (byte)0xc2, (byte)0xe0, (byte)0x41, (byte)0x6e, (byte)0xf, (byte)0x51, (byte)0xcb, (byte)0xcc, + (byte)0x24, (byte)0x91, (byte)0xaf, (byte)0x50, (byte)0xa1, (byte)0xf4, (byte)0x70, (byte)0x39, + (byte)0x99, (byte)0x7c, (byte)0x3a, (byte)0x85, (byte)0x23, (byte)0xb8, (byte)0xb4, (byte)0x7a, + (byte)0xfc, (byte)0x2, (byte)0x36, (byte)0x5b, (byte)0x25, (byte)0x55, (byte)0x97, (byte)0x31, + (byte)0x2d, (byte)0x5d, (byte)0xfa, (byte)0x98, (byte)0xe3, (byte)0x8a, (byte)0x92, (byte)0xae, + (byte)0x5, (byte)0xdf, (byte)0x29, (byte)0x10, (byte)0x67, (byte)0x6c, (byte)0xba, (byte)0xc9, + (byte)0xd3, (byte)0x0, (byte)0xe6, (byte)0xcf, (byte)0xe1, (byte)0x9e, (byte)0xa8, (byte)0x2c, + (byte)0x63, (byte)0x16, (byte)0x1, (byte)0x3f, (byte)0x58, (byte)0xe2, (byte)0x89, (byte)0xa9, + (byte)0xd, (byte)0x38, (byte)0x34, (byte)0x1b, (byte)0xab, (byte)0x33, (byte)0xff, (byte)0xb0, + (byte)0xbb, (byte)0x48, (byte)0xc, (byte)0x5f, (byte)0xb9, (byte)0xb1, (byte)0xcd, (byte)0x2e, + (byte)0xc5, (byte)0xf3, (byte)0xdb, (byte)0x47, (byte)0xe5, (byte)0xa5, (byte)0x9c, (byte)0x77, + (byte)0xa, (byte)0xa6, (byte)0x20, (byte)0x68, (byte)0xfe, (byte)0x7f, (byte)0xc1, (byte)0xad + }; + + private const int BLOCK_SIZE = 8; + + private int[] workingKey; + private bool encrypting; + + private int[] GenerateWorkingKey( + byte[] key, + int bits) + { + int x; + int[] xKey = new int[128]; + + for (int i = 0; i != key.Length; i++) + { + xKey[i] = key[i] & 0xff; + } + + // Phase 1: Expand input key to 128 bytes + int len = key.Length; + + if (len < 128) + { + int index = 0; + + x = xKey[len - 1]; + + do + { + x = piTable[(x + xKey[index++]) & 255] & 0xff; + xKey[len++] = x; + } + while (len < 128); + } + + // Phase 2 - reduce effective key size to "bits" + len = (bits + 7) >> 3; + x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff; + xKey[128 - len] = x; + + for (int i = 128 - len - 1; i >= 0; i--) + { + x = piTable[x ^ xKey[i + len]] & 0xff; + xKey[i] = x; + } + + // Phase 3 - copy to newKey in little-endian order + int[] newKey = new int[64]; + + for (int i = 0; i != newKey.Length; i++) + { + newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8)); + } + + return newKey; + } + + /** + * initialise a RC2 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + + if (parameters is RC2Parameters) + { + RC2Parameters param = (RC2Parameters) parameters; + + workingKey = GenerateWorkingKey(param.GetKey(), param.EffectiveKeyBits); + } + else if (parameters is KeyParameter) + { + KeyParameter param = (KeyParameter) parameters; + byte[] key = param.GetKey(); + + workingKey = GenerateWorkingKey(key, key.Length * 8); + } + else + { + throw new ArgumentException("invalid parameter passed to RC2 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + } + + public virtual void Reset() + { + } + + public virtual string AlgorithmName + { + get { return "RC2"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("RC2 engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + /** + * return the result rotating the 16 bit number in x left by y + */ + private int RotateWordLeft( + int x, + int y) + { + x &= 0xffff; + return (x << y) | (x >> (16 - y)); + } + + private void EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x76, x54, x32, x10; + + x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff); + x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff); + x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff); + x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff); + + for (int i = 0; i <= 16; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + x10 += workingKey[x76 & 63]; + x32 += workingKey[x10 & 63]; + x54 += workingKey[x32 & 63]; + x76 += workingKey[x54 & 63]; + + for (int i = 20; i <= 40; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + x10 += workingKey[x76 & 63]; + x32 += workingKey[x10 & 63]; + x54 += workingKey[x32 & 63]; + x76 += workingKey[x54 & 63]; + + for (int i = 44; i < 64; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + outBytes[outOff + 0] = (byte)x10; + outBytes[outOff + 1] = (byte)(x10 >> 8); + outBytes[outOff + 2] = (byte)x32; + outBytes[outOff + 3] = (byte)(x32 >> 8); + outBytes[outOff + 4] = (byte)x54; + outBytes[outOff + 5] = (byte)(x54 >> 8); + outBytes[outOff + 6] = (byte)x76; + outBytes[outOff + 7] = (byte)(x76 >> 8); + } + + private void DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x76, x54, x32, x10; + + x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff); + x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff); + x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff); + x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff); + + for (int i = 60; i >= 44; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + x76 -= workingKey[x54 & 63]; + x54 -= workingKey[x32 & 63]; + x32 -= workingKey[x10 & 63]; + x10 -= workingKey[x76 & 63]; + + for (int i = 40; i >= 20; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + x76 -= workingKey[x54 & 63]; + x54 -= workingKey[x32 & 63]; + x32 -= workingKey[x10 & 63]; + x10 -= workingKey[x76 & 63]; + + for (int i = 16; i >= 0; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + outBytes[outOff + 0] = (byte)x10; + outBytes[outOff + 1] = (byte)(x10 >> 8); + outBytes[outOff + 2] = (byte)x32; + outBytes[outOff + 3] = (byte)(x32 >> 8); + outBytes[outOff + 4] = (byte)x54; + outBytes[outOff + 5] = (byte)(x54 >> 8); + outBytes[outOff + 6] = (byte)x76; + outBytes[outOff + 7] = (byte)(x76 >> 8); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs.meta new file mode 100644 index 0000000..efd5dc8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9e2908df73e25da4690be4d9c34ba50c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs new file mode 100644 index 0000000..372f4b7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs @@ -0,0 +1,374 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Wrap keys according to RFC 3217 - RC2 mechanism + */ + public class RC2WrapEngine + : IWrapper + { + /** Field engine */ + private CbcBlockCipher engine; + + /** Field param */ + private ICipherParameters parameters; + + /** Field paramPlusIV */ + private ParametersWithIV paramPlusIV; + + /** Field iv */ + private byte[] iv; + + /** Field forWrapping */ + private bool forWrapping; + + private SecureRandom sr; + + /** Field IV2 */ + private static readonly byte[] IV2 = + { + (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, + (byte) 0x2c, (byte) 0x79, (byte) 0xe8, + (byte) 0x21, (byte) 0x05 + }; + + // + // checksum digest + // + IDigest sha1 = new Sha1Digest(); + byte[] digest = new byte[20]; + + /** + * Method init + * + * @param forWrapping + * @param param + */ + public virtual void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + this.engine = new CbcBlockCipher(new RC2Engine()); + + if (parameters is ParametersWithRandom) + { + ParametersWithRandom pWithR = (ParametersWithRandom)parameters; + sr = pWithR.Random; + parameters = pWithR.Parameters; + } + else + { + sr = new SecureRandom(); + } + + if (parameters is ParametersWithIV) + { + if (!forWrapping) + throw new ArgumentException("You should not supply an IV for unwrapping"); + + this.paramPlusIV = (ParametersWithIV)parameters; + this.iv = this.paramPlusIV.GetIV(); + this.parameters = this.paramPlusIV.Parameters; + + if (this.iv.Length != 8) + throw new ArgumentException("IV is not 8 octets"); + } + else + { + this.parameters = parameters; + + if (this.forWrapping) + { + // Hm, we have no IV but we want to wrap ?!? + // well, then we have to create our own IV. + this.iv = new byte[8]; + sr.NextBytes(iv); + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + } + } + } + + /** + * Method GetAlgorithmName + * + * @return + */ + public virtual string AlgorithmName + { + get { return "RC2"; } + } + + /** + * Method wrap + * + * @param in + * @param inOff + * @param inLen + * @return + */ + public virtual byte[] Wrap( + byte[] input, + int inOff, + int length) + { + if (!forWrapping) + { + throw new InvalidOperationException("Not initialized for wrapping"); + } + + int len = length + 1; + if ((len % 8) != 0) + { + len += 8 - (len % 8); + } + + byte [] keyToBeWrapped = new byte[len]; + + keyToBeWrapped[0] = (byte)length; + Array.Copy(input, inOff, keyToBeWrapped, 1, length); + + byte[] pad = new byte[keyToBeWrapped.Length - length - 1]; + + if (pad.Length > 0) + { + sr.NextBytes(pad); + Array.Copy(pad, 0, keyToBeWrapped, length + 1, pad.Length); + } + + // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. + byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped); + + // Let WKCKS = WK || CKS where || is concatenation. + byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length]; + + Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length); + Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length); + + // Encrypt WKCKS in CBC mode using KEK as the key and IV as the + // initialization vector. Call the results TEMP1. + byte [] TEMP1 = new byte[WKCKS.Length]; + + Array.Copy(WKCKS, 0, TEMP1, 0, WKCKS.Length); + + int noOfBlocks = WKCKS.Length / engine.GetBlockSize(); + int extraBytes = WKCKS.Length % engine.GetBlockSize(); + + if (extraBytes != 0) + { + throw new InvalidOperationException("Not multiple of block length"); + } + + engine.Init(true, paramPlusIV); + + for (int i = 0; i < noOfBlocks; i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP1, currentBytePos, TEMP1, currentBytePos); + } + + // Left TEMP2 = IV || TEMP1. + byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length]; + + Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length); + Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length); + + // Reverse the order of the octets in TEMP2 and call the result TEMP3. + byte[] TEMP3 = new byte[TEMP2.Length]; + + for (int i = 0; i < TEMP2.Length; i++) + { + TEMP3[i] = TEMP2[TEMP2.Length - (i + 1)]; + } + + // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector + // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired + // result. It is 40 octets long if a 168 bit key is being wrapped. + ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); + + this.engine.Init(true, param2); + + for (int i = 0; i < noOfBlocks + 1; i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + return TEMP3; + } + + /** + * Method unwrap + * + * @param in + * @param inOff + * @param inLen + * @return + * @throws InvalidCipherTextException + */ + public virtual byte[] Unwrap( + byte[] input, + int inOff, + int length) + { + if (forWrapping) + { + throw new InvalidOperationException("Not set for unwrapping"); + } + + if (input == null) + { + throw new InvalidCipherTextException("Null pointer as ciphertext"); + } + + if (length % engine.GetBlockSize() != 0) + { + throw new InvalidCipherTextException("Ciphertext not multiple of " + + engine.GetBlockSize()); + } + + /* + // Check if the length of the cipher text is reasonable given the key + // type. It must be 40 bytes for a 168 bit key and either 32, 40, or + // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported + // or inconsistent with the algorithm for which the key is intended, + // return error. + // + // we do not accept 168 bit keys. it has to be 192 bit. + int lengthA = (estimatedKeyLengthInBit / 8) + 16; + int lengthB = estimatedKeyLengthInBit % 8; + + if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) { + throw new XMLSecurityException("empty"); + } + */ + + // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK + // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. + ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); + + this.engine.Init(false, param2); + + byte [] TEMP3 = new byte[length]; + + Array.Copy(input, inOff, TEMP3, 0, length); + + for (int i = 0; i < (TEMP3.Length / engine.GetBlockSize()); i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + // Reverse the order of the octets in TEMP3 and call the result TEMP2. + byte[] TEMP2 = new byte[TEMP3.Length]; + + for (int i = 0; i < TEMP3.Length; i++) + { + TEMP2[i] = TEMP3[TEMP3.Length - (i + 1)]; + } + + // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. + this.iv = new byte[8]; + + byte[] TEMP1 = new byte[TEMP2.Length - 8]; + + Array.Copy(TEMP2, 0, this.iv, 0, 8); + Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8); + + // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV + // found in the previous step. Call the result WKCKS. + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + + this.engine.Init(false, this.paramPlusIV); + + byte[] LCEKPADICV = new byte[TEMP1.Length]; + + Array.Copy(TEMP1, 0, LCEKPADICV, 0, TEMP1.Length); + + for (int i = 0; i < (LCEKPADICV.Length / engine.GetBlockSize()); i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(LCEKPADICV, currentBytePos, LCEKPADICV, currentBytePos); + } + + // Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped key, are + // those octets before the CKS. + byte[] result = new byte[LCEKPADICV.Length - 8]; + byte[] CKStoBeVerified = new byte[8]; + + Array.Copy(LCEKPADICV, 0, result, 0, LCEKPADICV.Length - 8); + Array.Copy(LCEKPADICV, LCEKPADICV.Length - 8, CKStoBeVerified, 0, 8); + + // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare + // with the CKS extracted in the above step. If they are not equal, return error. + if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) + { + throw new InvalidCipherTextException( + "Checksum inside ciphertext is corrupted"); + } + + if ((result.Length - ((result[0] & 0xff) + 1)) > 7) + { + throw new InvalidCipherTextException( + "too many pad bytes (" + (result.Length - ((result[0] & 0xff) + 1)) + ")"); + } + + // CEK is the wrapped key, now extracted for use in data decryption. + byte[] CEK = new byte[result[0]]; + Array.Copy(result, 1, CEK, 0, CEK.Length); + return CEK; + } + + /** + * Some key wrap algorithms make use of the Key Checksum defined + * in CMS [CMS-Algorithms]. This is used to provide an integrity + * check value for the key being wrapped. The algorithm is + * + * - Compute the 20 octet SHA-1 hash on the key being wrapped. + * - Use the first 8 octets of this hash as the checksum value. + * + * @param key + * @return + * @throws Exception + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private byte[] CalculateCmsKeyChecksum( + byte[] key) + { + sha1.BlockUpdate(key, 0, key.Length); + sha1.DoFinal(digest, 0); + + byte[] result = new byte[8]; + Array.Copy(digest, 0, result, 0, 8); + return result; + } + + /** + * @param key + * @param checksum + * @return + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private bool CheckCmsKeyChecksum( + byte[] key, + byte[] checksum) + { + return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs.meta new file mode 100644 index 0000000..5986eff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC2WrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0c68dd7b320ee974c9bf521cec0159e5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs new file mode 100644 index 0000000..fbf37ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs @@ -0,0 +1,143 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class RC4Engine + : IStreamCipher + { + private readonly static int STATE_LENGTH = 256; + + /* + * variables to hold the state of the RC4 engine + * during encryption and decryption + */ + + private byte[] engineState; + private int x; + private int y; + private byte[] workingKey; + + /** + * initialise a RC4 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + /* + * RC4 encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. + */ + workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(workingKey); + + return; + } + + throw new ArgumentException("invalid parameter passed to RC4 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + + public virtual string AlgorithmName + { + get { return "RC4"; } + } + + public virtual byte ReturnByte( + byte input) + { + x = (x + 1) & 0xff; + y = (engineState[x] + y) & 0xff; + + // swap + byte tmp = engineState[x]; + engineState[x] = engineState[y]; + engineState[y] = tmp; + + // xor + return (byte)(input ^ engineState[(engineState[x] + engineState[y]) & 0xff]); + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + Check.DataLength(input, inOff, length, "input buffer too short"); + Check.OutputLength(output, outOff, length, "output buffer too short"); + + for (int i = 0; i < length ; i++) + { + x = (x + 1) & 0xff; + y = (engineState[x] + y) & 0xff; + + // swap + byte tmp = engineState[x]; + engineState[x] = engineState[y]; + engineState[y] = tmp; + + // xor + output[i+outOff] = (byte)(input[i + inOff] + ^ engineState[(engineState[x] + engineState[y]) & 0xff]); + } + } + + public virtual void Reset() + { + SetKey(workingKey); + } + + // Private implementation + + private void SetKey( + byte[] keyBytes) + { + workingKey = keyBytes; + + // System.out.println("the key length is ; "+ workingKey.Length); + + x = 0; + y = 0; + + if (engineState == null) + { + engineState = new byte[STATE_LENGTH]; + } + + // reset the state of the engine + for (int i=0; i < STATE_LENGTH; i++) + { + engineState[i] = (byte)i; + } + + int i1 = 0; + int i2 = 0; + + for (int i=0; i < STATE_LENGTH; i++) + { + i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff; + // do the byte-swap inline + byte tmp = engineState[i]; + engineState[i] = engineState[i2]; + engineState[i2] = tmp; + i1 = (i1+1) % keyBytes.Length; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs.meta new file mode 100644 index 0000000..de4874d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC4Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 068d5429f72b08f45a6b2ecde0991212 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs new file mode 100644 index 0000000..55936ea --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs @@ -0,0 +1,302 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP +using System.TypeFix; +#endif + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The specification for RC5 came from the RC5 Encryption Algorithm + * publication in RSA CryptoBytes, Spring of 1995. + * http://www.rsasecurity.com/rsalabs/cryptobytes. + *

+ * This implementation has a word size of 32 bits.

+ */ + public class RC532Engine + : IBlockCipher + { + /* + * the number of rounds to perform + */ + private int _noRounds; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private int [] _S; + + /* + * our "magic constants" for 32 32 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly int P32 = unchecked((int) 0xb7e15163); + private static readonly int Q32 = unchecked((int) 0x9e3779b9); + + private bool forEncryption; + + /** + * Create an instance of the RC5 encryption algorithm + * and set some defaults + */ + public RC532Engine() + { + _noRounds = 12; // the default +// _S = null; + } + + public virtual string AlgorithmName + { + get { return "RC5-32"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return 2 * 4; + } + + /** + * initialise a RC5-32 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (typeof(RC5Parameters).IsInstanceOfType(parameters)) + { + RC5Parameters p = (RC5Parameters)parameters; + + _noRounds = p.Rounds; + + SetKey(p.GetKey()); + } + else if (typeof(KeyParameter).IsInstanceOfType(parameters)) + { + KeyParameter p = (KeyParameter)parameters; + + SetKey(p.GetKey()); + } + else + { + throw new ArgumentException("invalid parameter passed to RC532 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + + this.forEncryption = forEncryption; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = 32/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + int[] L = new int[(key.Length + (4 - 1)) / 4]; + + for (int i = 0; i != key.Length; i++) + { + L[i / 4] += (key[i] & 0xff) << (8 * (i % 4)); + } + + // + // Phase 2: + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new int[2*(_noRounds + 1)]; + + _S[0] = P32; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q32); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + int A = 0, B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + /** + * Encrypt the given block starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param in in byte buffer containing data to encrypt + * @param inOff offset into src buffer + * @param out out buffer where encrypted data is written + * @param outOff offset into out buffer + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int A = BytesToWord(input, inOff) + _S[0]; + int B = BytesToWord(input, inOff + 4) + _S[1]; + + for (int i = 1; i <= _noRounds; i++) + { + A = RotateLeft(A ^ B, B) + _S[2*i]; + B = RotateLeft(B ^ A, A) + _S[2*i+1]; + } + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + 4); + + return 2 * 4; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + 4); + + for (int i = _noRounds; i >= 1; i--) + { + B = RotateRight(B - _S[2*i+1], A) ^ A; + A = RotateRight(A - _S[2*i], B) ^ B; + } + + WordToBytes(A - _S[0], outBytes, outOff); + WordToBytes(B - _S[1], outBytes, outOff + 4); + + return 2 * 4; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(32) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % 32 + */ + private int RotateLeft(int x, int y) { + return ((int) ( (uint) (x << (y & (32-1))) | + ((uint) x >> (32 - (y & (32-1)))) ) + ); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(32) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % 32 + */ + private int RotateRight(int x, int y) { + return ((int) ( ((uint) x >> (y & (32-1))) | + (uint) (x << (32 - (y & (32-1)))) ) + ); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + return (src[srcOff] & 0xff) | ((src[srcOff + 1] & 0xff) << 8) + | ((src[srcOff + 2] & 0xff) << 16) | ((src[srcOff + 3] & 0xff) << 24); + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + dst[dstOff] = (byte)word; + dst[dstOff + 1] = (byte)(word >> 8); + dst[dstOff + 2] = (byte)(word >> 16); + dst[dstOff + 3] = (byte)(word >> 24); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs.meta new file mode 100644 index 0000000..55f6ba1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC532Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 715d03447094f77489e130fd0ae50f48 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs new file mode 100644 index 0000000..4ead07c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs @@ -0,0 +1,303 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP +using System.TypeFix; +#endif + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The specification for RC5 came from the RC5 Encryption Algorithm + * publication in RSA CryptoBytes, Spring of 1995. + * http://www.rsasecurity.com/rsalabs/cryptobytes. + *

+ * This implementation is set to work with a 64 bit word size.

+ */ + public class RC564Engine + : IBlockCipher + { + private static readonly int wordSize = 64; + private static readonly int bytesPerWord = wordSize / 8; + + /* + * the number of rounds to perform + */ + private int _noRounds; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private long [] _S; + + /* + * our "magic constants" for wordSize 62 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly long P64 = unchecked( (long) 0xb7e151628aed2a6bL); + private static readonly long Q64 = unchecked( (long) 0x9e3779b97f4a7c15L); + + private bool forEncryption; + + /** + * Create an instance of the RC5 encryption algorithm + * and set some defaults + */ + public RC564Engine() + { + _noRounds = 12; +// _S = null; + } + + public virtual string AlgorithmName + { + get { return "RC5-64"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return 2 * bytesPerWord; + } + + /** + * initialise a RC5-64 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(typeof(RC5Parameters).IsInstanceOfType(parameters))) + { + throw new ArgumentException("invalid parameter passed to RC564 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + + RC5Parameters p = (RC5Parameters)parameters; + + this.forEncryption = forEncryption; + + _noRounds = p.Rounds; + + SetKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = wordSize/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + long[] L = new long[(key.Length + (bytesPerWord - 1)) / bytesPerWord]; + + for (int i = 0; i != key.Length; i++) + { + L[i / bytesPerWord] += (long)(key[i] & 0xff) << (8 * (i % bytesPerWord)); + } + + // + // Phase 2: + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new long[2*(_noRounds + 1)]; + + _S[0] = P64; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q64); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + long A = 0, B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + /** + * Encrypt the given block starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param in in byte buffer containing data to encrypt + * @param inOff offset into src buffer + * @param out out buffer where encrypted data is written + * @param outOff offset into out buffer + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + long A = BytesToWord(input, inOff) + _S[0]; + long B = BytesToWord(input, inOff + bytesPerWord) + _S[1]; + + for (int i = 1; i <= _noRounds; i++) + { + A = RotateLeft(A ^ B, B) + _S[2*i]; + B = RotateLeft(B ^ A, A) + _S[2*i+1]; + } + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + + return 2 * bytesPerWord; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + long A = BytesToWord(input, inOff); + long B = BytesToWord(input, inOff + bytesPerWord); + + for (int i = _noRounds; i >= 1; i--) + { + B = RotateRight(B - _S[2*i+1], A) ^ A; + A = RotateRight(A - _S[2*i], B) ^ B; + } + + WordToBytes(A - _S[0], outBytes, outOff); + WordToBytes(B - _S[1], outBytes, outOff + bytesPerWord); + + return 2 * bytesPerWord; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private long RotateLeft(long x, long y) { + return ((long) ( (ulong) (x << (int) (y & (wordSize-1))) | + ((ulong) x >> (int) (wordSize - (y & (wordSize-1))))) + ); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private long RotateRight(long x, long y) { + return ((long) ( ((ulong) x >> (int) (y & (wordSize-1))) | + (ulong) (x << (int) (wordSize - (y & (wordSize-1))))) + ); + } + + private long BytesToWord( + byte[] src, + int srcOff) + { + long word = 0; + + for (int i = bytesPerWord - 1; i >= 0; i--) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void WordToBytes( + long word, + byte[] dst, + int dstOff) + { + for (int i = 0; i < bytesPerWord; i++) + { + dst[i + dstOff] = (byte)word; + word = (long) ((ulong) word >> 8); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs.meta new file mode 100644 index 0000000..accf301 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC564Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e794bc4a420f67d47924b24a7d3e9fd0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs new file mode 100644 index 0000000..2ed9ee8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs @@ -0,0 +1,365 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An RC6 engine. + */ + public class RC6Engine + : IBlockCipher + { + private static readonly int wordSize = 32; + private static readonly int bytesPerWord = wordSize / 8; + + /* + * the number of rounds to perform + */ + private static readonly int _noRounds = 20; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private int [] _S; + + /* + * our "magic constants" for wordSize 32 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly int P32 = unchecked((int) 0xb7e15163); + private static readonly int Q32 = unchecked((int) 0x9e3779b9); + + private static readonly int LGW = 5; // log2(32) + + private bool forEncryption; + + /** + * Create an instance of the RC6 encryption algorithm + * and set some defaults + */ + public RC6Engine() + { +// _S = null; + } + + public virtual string AlgorithmName + { + get { return "RC6"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return 4 * bytesPerWord; + } + + /** + * initialise a RC5-32 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to RC6 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + this.forEncryption = forEncryption; + + KeyParameter p = (KeyParameter)parameters; + SetKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int blockSize = GetBlockSize(); + if (_S == null) + throw new InvalidOperationException("RC6 engine not initialised"); + + Check.DataLength(input, inOff, blockSize, "input buffer too short"); + Check.OutputLength(output, outOff, blockSize, "output buffer too short"); + + return (forEncryption) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param inKey the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = wordSize/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + // compute number of dwords + int c = (key.Length + (bytesPerWord - 1)) / bytesPerWord; + if (c == 0) + { + c = 1; + } + int[] L = new int[(key.Length + bytesPerWord - 1) / bytesPerWord]; + + // load all key bytes into array of key dwords + for (int i = key.Length - 1; i >= 0; i--) + { + L[i / bytesPerWord] = (L[i / bytesPerWord] << 8) + (key[i] & 0xff); + } + + // + // Phase 2: + // Key schedule is placed in a array of 2+2*ROUNDS+2 = 44 dwords. + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new int[2+2*_noRounds+2]; + + _S[0] = P32; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q32); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + int A = 0; + int B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + // load A,B,C and D registers from in. + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + bytesPerWord); + int C = BytesToWord(input, inOff + bytesPerWord*2); + int D = BytesToWord(input, inOff + bytesPerWord*3); + + // Do pseudo-round #0: pre-whitening of B and D + B += _S[0]; + D += _S[1]; + + // perform round #1,#2 ... #ROUNDS of encryption + for (int i = 1; i <= _noRounds; i++) + { + int t = 0,u = 0; + + t = B*(2*B+1); + t = RotateLeft(t,5); + + u = D*(2*D+1); + u = RotateLeft(u,5); + + A ^= t; + A = RotateLeft(A,u); + A += _S[2*i]; + + C ^= u; + C = RotateLeft(C,t); + C += _S[2*i+1]; + + int temp = A; + A = B; + B = C; + C = D; + D = temp; + } + // do pseudo-round #(ROUNDS+1) : post-whitening of A and C + A += _S[2*_noRounds+2]; + C += _S[2*_noRounds+3]; + + // store A, B, C and D registers to out + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + WordToBytes(C, outBytes, outOff + bytesPerWord*2); + WordToBytes(D, outBytes, outOff + bytesPerWord*3); + + return 4 * bytesPerWord; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + // load A,B,C and D registers from out. + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + bytesPerWord); + int C = BytesToWord(input, inOff + bytesPerWord*2); + int D = BytesToWord(input, inOff + bytesPerWord*3); + + // Undo pseudo-round #(ROUNDS+1) : post whitening of A and C + C -= _S[2*_noRounds+3]; + A -= _S[2*_noRounds+2]; + + // Undo round #ROUNDS, .., #2,#1 of encryption + for (int i = _noRounds; i >= 1; i--) + { + int t=0,u = 0; + + int temp = D; + D = C; + C = B; + B = A; + A = temp; + + t = B*(2*B+1); + t = RotateLeft(t, LGW); + + u = D*(2*D+1); + u = RotateLeft(u, LGW); + + C -= _S[2*i+1]; + C = RotateRight(C,t); + C ^= u; + + A -= _S[2*i]; + A = RotateRight(A,u); + A ^= t; + + } + // Undo pseudo-round #0: pre-whitening of B and D + D -= _S[1]; + B -= _S[0]; + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + WordToBytes(C, outBytes, outOff + bytesPerWord*2); + WordToBytes(D, outBytes, outOff + bytesPerWord*3); + + return 4 * bytesPerWord; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private int RotateLeft(int x, int y) + { + return ((int)((uint)(x << (y & (wordSize-1))) + | ((uint) x >> (wordSize - (y & (wordSize-1)))))); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private int RotateRight(int x, int y) + { + return ((int)(((uint) x >> (y & (wordSize-1))) + | (uint)(x << (wordSize - (y & (wordSize-1)))))); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + int word = 0; + + for (int i = bytesPerWord - 1; i >= 0; i--) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + for (int i = 0; i < bytesPerWord; i++) + { + dst[i + dstOff] = (byte)word; + word = (int) ((uint) word >> 8); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs.meta new file mode 100644 index 0000000..27938e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RC6Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2b7585edcc7be3146a7550caa7c8678b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs new file mode 100644 index 0000000..d97de23 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs @@ -0,0 +1,172 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the RFC 3211 Key Wrap + * Specification. + */ + public class Rfc3211WrapEngine + : IWrapper + { + private CbcBlockCipher engine; + private ParametersWithIV param; + private bool forWrapping; + private SecureRandom rand; + + public Rfc3211WrapEngine( + IBlockCipher engine) + { + this.engine = new CbcBlockCipher(engine); + } + + public virtual void Init( + bool forWrapping, + ICipherParameters param) + { + this.forWrapping = forWrapping; + + if (param is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) param; + + this.rand = p.Random; + this.param = (ParametersWithIV) p.Parameters; + } + else + { + if (forWrapping) + { + rand = new SecureRandom(); + } + + this.param = (ParametersWithIV) param; + } + } + + public virtual string AlgorithmName + { + get { return engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap"; } + } + + public virtual byte[] Wrap( + byte[] inBytes, + int inOff, + int inLen) + { + if (!forWrapping) + { + throw new InvalidOperationException("not set for wrapping"); + } + + engine.Init(true, param); + + int blockSize = engine.GetBlockSize(); + byte[] cekBlock; + + if (inLen + 4 < blockSize * 2) + { + cekBlock = new byte[blockSize * 2]; + } + else + { + cekBlock = new byte[(inLen + 4) % blockSize == 0 ? inLen + 4 : ((inLen + 4) / blockSize + 1) * blockSize]; + } + + cekBlock[0] = (byte)inLen; + cekBlock[1] = (byte)~inBytes[inOff]; + cekBlock[2] = (byte)~inBytes[inOff + 1]; + cekBlock[3] = (byte)~inBytes[inOff + 2]; + + Array.Copy(inBytes, inOff, cekBlock, 4, inLen); + + rand.NextBytes(cekBlock, inLen + 4, cekBlock.Length - inLen - 4); + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + return cekBlock; + } + + public virtual byte[] Unwrap( + byte[] inBytes, + int inOff, + int inLen) + { + if (forWrapping) + { + throw new InvalidOperationException("not set for unwrapping"); + } + + int blockSize = engine.GetBlockSize(); + + if (inLen < 2 * blockSize) + { + throw new InvalidCipherTextException("input too short"); + } + + byte[] cekBlock = new byte[inLen]; + byte[] iv = new byte[blockSize]; + + Array.Copy(inBytes, inOff, cekBlock, 0, inLen); + Array.Copy(inBytes, inOff, iv, 0, iv.Length); + + engine.Init(false, new ParametersWithIV(param.Parameters, iv)); + + for (int i = blockSize; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + Array.Copy(cekBlock, cekBlock.Length - iv.Length, iv, 0, iv.Length); + + engine.Init(false, new ParametersWithIV(param.Parameters, iv)); + + engine.ProcessBlock(cekBlock, 0, cekBlock, 0); + + engine.Init(false, param); + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + if ((cekBlock[0] & 0xff) > cekBlock.Length - 4) + { + throw new InvalidCipherTextException("wrapped key corrupted"); + } + + byte[] key = new byte[cekBlock[0] & 0xff]; + + Array.Copy(cekBlock, 4, key, 0, cekBlock[0]); + + // Note: Using constant time comparison + int nonEqual = 0; + for (int i = 0; i != 3; i++) + { + byte check = (byte)~cekBlock[1 + i]; + nonEqual |= (check ^ key[i]); + } + + if (nonEqual != 0) + throw new InvalidCipherTextException("wrapped key fails checksum"); + + return key; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs.meta new file mode 100644 index 0000000..fd03646 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3211WrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e6aba8788322b964490eefbb8c3d6208 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs new file mode 100644 index 0000000..bc670d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs @@ -0,0 +1,182 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the AES Key Wrapper from the NIST Key Wrap + /// Specification as described in RFC 3394. + ///

+ /// For further details see: http://www.ietf.org/rfc/rfc3394.txt + /// and http://csrc.nist.gov/encryption/kms/key-wrap.pdf. + /// + public class Rfc3394WrapEngine + : IWrapper + { + private readonly IBlockCipher engine; + + private KeyParameter param; + private bool forWrapping; + + private byte[] iv = + { + 0xa6, 0xa6, 0xa6, 0xa6, + 0xa6, 0xa6, 0xa6, 0xa6 + }; + + public Rfc3394WrapEngine( + IBlockCipher engine) + { + this.engine = engine; + } + + public virtual void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (parameters is KeyParameter) + { + this.param = (KeyParameter) parameters; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV pIV = (ParametersWithIV) parameters; + byte[] iv = pIV.GetIV(); + + if (iv.Length != 8) + throw new ArgumentException("IV length not equal to 8", "parameters"); + + this.iv = iv; + this.param = (KeyParameter) pIV.Parameters; + } + else + { + // TODO Throw an exception for bad parameters? + } + } + + public virtual string AlgorithmName + { + get { return engine.AlgorithmName; } + } + + public virtual byte[] Wrap( + byte[] input, + int inOff, + int inLen) + { + if (!forWrapping) + { + throw new InvalidOperationException("not set for wrapping"); + } + + int n = inLen / 8; + + if ((n * 8) != inLen) + { + throw new DataLengthException("wrap data must be a multiple of 8 bytes"); + } + + byte[] block = new byte[inLen + iv.Length]; + byte[] buf = new byte[8 + iv.Length]; + + Array.Copy(iv, 0, block, 0, iv.Length); + Array.Copy(input, inOff, block, iv.Length, inLen); + + engine.Init(true, param); + + for (int j = 0; j != 6; j++) + { + for (int i = 1; i <= n; i++) + { + Array.Copy(block, 0, buf, 0, iv.Length); + Array.Copy(block, 8 * i, buf, iv.Length, 8); + engine.ProcessBlock(buf, 0, buf, 0); + + int t = n * j + i; + for (int k = 1; t != 0; k++) + { + byte v = (byte)t; + + buf[iv.Length - k] ^= v; + t = (int) ((uint)t >> 8); + } + + Array.Copy(buf, 0, block, 0, 8); + Array.Copy(buf, 8, block, 8 * i, 8); + } + } + + return block; + } + + public virtual byte[] Unwrap( + byte[] input, + int inOff, + int inLen) + { + if (forWrapping) + { + throw new InvalidOperationException("not set for unwrapping"); + } + + int n = inLen / 8; + + if ((n * 8) != inLen) + { + throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes"); + } + + byte[] block = new byte[inLen - iv.Length]; + byte[] a = new byte[iv.Length]; + byte[] buf = new byte[8 + iv.Length]; + + Array.Copy(input, inOff, a, 0, iv.Length); + Array.Copy(input, inOff + iv.Length, block, 0, inLen - iv.Length); + + engine.Init(false, param); + + n = n - 1; + + for (int j = 5; j >= 0; j--) + { + for (int i = n; i >= 1; i--) + { + Array.Copy(a, 0, buf, 0, iv.Length); + Array.Copy(block, 8 * (i - 1), buf, iv.Length, 8); + + int t = n * j + i; + for (int k = 1; t != 0; k++) + { + byte v = (byte)t; + + buf[iv.Length - k] ^= v; + t = (int) ((uint)t >> 8); + } + + engine.ProcessBlock(buf, 0, buf, 0); + Array.Copy(buf, 0, a, 0, 8); + Array.Copy(buf, 8, block, 8 * (i - 1), 8); + } + } + + if (!Arrays.ConstantTimeAreEqual(a, iv)) + throw new InvalidCipherTextException("checksum failed"); + + return block; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs.meta new file mode 100644 index 0000000..a03e499 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RFC3394WrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7e321866e73515648bfd4569ca4b8573 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs new file mode 100644 index 0000000..fbabf2a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs @@ -0,0 +1,132 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic RSA algorithm with blinding + */ + public class RsaBlindedEngine + : IAsymmetricBlockCipher + { + private readonly RsaCoreEngine core = new RsaCoreEngine(); + private RsaKeyParameters key; + private SecureRandom random; + + public virtual string AlgorithmName + { + get { return "RSA"; } + } + + /** + * initialise the RSA engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary RSA key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters param) + { + core.Init(forEncryption, param); + + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + key = (RsaKeyParameters)rParam.Parameters; + random = rParam.Random; + } + else + { + key = (RsaKeyParameters)param; + random = new SecureRandom(); + } + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + return core.GetInputBlockSize(); + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + return core.GetOutputBlockSize(); + } + + /** + * Process a single block using the basic RSA algorithm. + * + * @param inBuf the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param inLen the length of the data to be processed. + * @return the result of the RSA process. + * @exception DataLengthException the input block is too large. + */ + public virtual byte[] ProcessBlock( + byte[] inBuf, + int inOff, + int inLen) + { + if (key == null) + throw new InvalidOperationException("RSA engine not initialised"); + + BigInteger input = core.ConvertInput(inBuf, inOff, inLen); + + BigInteger result; + if (key is RsaPrivateCrtKeyParameters) + { + RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key; + BigInteger e = k.PublicExponent; + if (e != null) // can't do blinding without a public exponent + { + BigInteger m = k.Modulus; + BigInteger r = BigIntegers.CreateRandomInRange( + BigInteger.One, m.Subtract(BigInteger.One), random); + + BigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m); + BigInteger blindedResult = core.ProcessBlock(blindedInput); + + BigInteger rInv = r.ModInverse(m); + result = blindedResult.Multiply(rInv).Mod(m); + + // defence against Arjen Lenstra’s CRT attack + if (!input.Equals(result.ModPow(e, m))) + throw new InvalidOperationException("RSA engine faulty decryption/signing detected"); + } + else + { + result = core.ProcessBlock(input); + } + } + else + { + result = core.ProcessBlock(input); + } + + return core.ConvertOutput(result); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs.meta new file mode 100644 index 0000000..9bd54bf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSABlindedEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 85f59d14d3e55564aa1645a62950ed19 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs new file mode 100644 index 0000000..025609a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs @@ -0,0 +1,160 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic RSA algorithm. + */ + class RsaCoreEngine + { + private RsaKeyParameters key; + private bool forEncryption; + private int bitSize; + + /** + * initialise the RSA engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary RSA key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (!(parameters is RsaKeyParameters)) + throw new InvalidKeyException("Not an RSA key"); + + this.key = (RsaKeyParameters) parameters; + this.forEncryption = forEncryption; + this.bitSize = key.Modulus.BitLength; + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + if (forEncryption) + { + return (bitSize - 1) / 8; + } + + return (bitSize + 7) / 8; + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + if (forEncryption) + { + return (bitSize + 7) / 8; + } + + return (bitSize - 1) / 8; + } + + public virtual BigInteger ConvertInput( + byte[] inBuf, + int inOff, + int inLen) + { + int maxLength = (bitSize + 7) / 8; + + if (inLen > maxLength) + throw new DataLengthException("input too large for RSA cipher."); + + BigInteger input = new BigInteger(1, inBuf, inOff, inLen); + + if (input.CompareTo(key.Modulus) >= 0) + throw new DataLengthException("input too large for RSA cipher."); + + return input; + } + + public virtual byte[] ConvertOutput( + BigInteger result) + { + byte[] output = result.ToByteArrayUnsigned(); + + if (forEncryption) + { + int outSize = GetOutputBlockSize(); + + // TODO To avoid this, create version of BigInteger.ToByteArray that + // writes to an existing array + if (output.Length < outSize) // have ended up with less bytes than normal, lengthen + { + byte[] tmp = new byte[outSize]; + output.CopyTo(tmp, tmp.Length - output.Length); + output = tmp; + } + } + + return output; + } + + public virtual BigInteger ProcessBlock( + BigInteger input) + { + if (key is RsaPrivateCrtKeyParameters) + { + // + // we have the extra factors, use the Chinese Remainder Theorem - the author + // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for + // advice regarding the expression of this. + // + RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters)key; + + BigInteger p = crtKey.P; + BigInteger q = crtKey.Q; + BigInteger dP = crtKey.DP; + BigInteger dQ = crtKey.DQ; + BigInteger qInv = crtKey.QInv; + + BigInteger mP, mQ, h, m; + + // mP = ((input Mod p) ^ dP)) Mod p + mP = (input.Remainder(p)).ModPow(dP, p); + + // mQ = ((input Mod q) ^ dQ)) Mod q + mQ = (input.Remainder(q)).ModPow(dQ, q); + + // h = qInv * (mP - mQ) Mod p + h = mP.Subtract(mQ); + h = h.Multiply(qInv); + h = h.Mod(p); // Mod (in Java) returns the positive residual + + // m = h * q + mQ + m = h.Multiply(q); + m = m.Add(mQ); + + return m; + } + + return input.ModPow(key.Exponent, key.Modulus); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs.meta new file mode 100644 index 0000000..d658408 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RSACoreEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e5746cae08e3e594fb68d786851c04ea +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs new file mode 100644 index 0000000..025ac64 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs @@ -0,0 +1,746 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP +using System.TypeFix; +#endif + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of Rijndael, based on the documentation and reference implementation + * by Paulo Barreto, Vincent Rijmen, for v2.0 August '99. + *

+ * Note: this implementation is based on information prior to readonly NIST publication. + *

+ */ + public class RijndaelEngine + : IBlockCipher + { + private static readonly int MAXROUNDS = 14; + + private static readonly int MAXKC = (256/4); + + private static readonly byte[] Logtable = + { + 0, 0, 25, 1, 50, 2, 26, 198, + 75, 199, 27, 104, 51, 238, 223, 3, + 100, 4, 224, 14, 52, 141, 129, 239, + 76, 113, 8, 200, 248, 105, 28, 193, + 125, 194, 29, 181, 249, 185, 39, 106, + 77, 228, 166, 114, 154, 201, 9, 120, + 101, 47, 138, 5, 33, 15, 225, 36, + 18, 240, 130, 69, 53, 147, 218, 142, + 150, 143, 219, 189, 54, 208, 206, 148, + 19, 92, 210, 241, 64, 70, 131, 56, + 102, 221, 253, 48, 191, 6, 139, 98, + 179, 37, 226, 152, 34, 136, 145, 16, + 126, 110, 72, 195, 163, 182, 30, 66, + 58, 107, 40, 84, 250, 133, 61, 186, + 43, 121, 10, 21, 155, 159, 94, 202, + 78, 212, 172, 229, 243, 115, 167, 87, + 175, 88, 168, 80, 244, 234, 214, 116, + 79, 174, 233, 213, 231, 230, 173, 232, + 44, 215, 117, 122, 235, 22, 11, 245, + 89, 203, 95, 176, 156, 169, 81, 160, + 127, 12, 246, 111, 23, 196, 73, 236, + 216, 67, 31, 45, 164, 118, 123, 183, + 204, 187, 62, 90, 251, 96, 177, 134, + 59, 82, 161, 108, 170, 85, 41, 157, + 151, 178, 135, 144, 97, 190, 220, 252, + 188, 149, 207, 205, 55, 63, 91, 209, + 83, 57, 132, 60, 65, 162, 109, 71, + 20, 42, 158, 93, 86, 242, 211, 171, + 68, 17, 146, 217, 35, 32, 46, 137, + 180, 124, 184, 38, 119, 153, 227, 165, + 103, 74, 237, 222, 197, 49, 254, 24, + 13, 99, 140, 128, 192, 247, 112, 7 + }; + + private static readonly byte[] Alogtable = + { + 0, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1, + 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1, + }; + + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, + }; + + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125, + }; + + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + static readonly byte[][] shifts0 = new byte [][] + { + new byte[]{ 0, 8, 16, 24 }, + new byte[]{ 0, 8, 16, 24 }, + new byte[]{ 0, 8, 16, 24 }, + new byte[]{ 0, 8, 16, 32 }, + new byte[]{ 0, 8, 24, 32 } + }; + + static readonly byte[][] shifts1 = + { + new byte[]{ 0, 24, 16, 8 }, + new byte[]{ 0, 32, 24, 16 }, + new byte[]{ 0, 40, 32, 24 }, + new byte[]{ 0, 48, 40, 24 }, + new byte[]{ 0, 56, 40, 32 } + }; + + /** + * multiply two elements of GF(2^m) + * needed for MixColumn and InvMixColumn + */ + private byte Mul0x2( + int b) + { + if (b != 0) + { + return Alogtable[25 + (Logtable[b] & 0xff)]; + } + else + { + return 0; + } + } + + private byte Mul0x3( + int b) + { + if (b != 0) + { + return Alogtable[1 + (Logtable[b] & 0xff)]; + } + else + { + return 0; + } + } + + private byte Mul0x9( + int b) + { + if (b >= 0) + { + return Alogtable[199 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xb( + int b) + { + if (b >= 0) + { + return Alogtable[104 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xd( + int b) + { + if (b >= 0) + { + return Alogtable[238 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xe( + int b) + { + if (b >= 0) + { + return Alogtable[223 + b]; + } + else + { + return 0; + } + } + + /** + * xor corresponding text input and round key input bytes + */ + private void KeyAddition( + long[] rk) + { + A0 ^= rk[0]; + A1 ^= rk[1]; + A2 ^= rk[2]; + A3 ^= rk[3]; + } + + private long Shift( + long r, + int shift) + { + //return (((long)((ulong) r >> shift) | (r << (BC - shift)))) & BC_MASK; + + ulong temp = (ulong) r >> shift; + + // NB: This corrects for Mono Bug #79087 (fixed in 1.1.17) + if (shift > 31) + { + temp &= 0xFFFFFFFFUL; + } + + return ((long) temp | (r << (BC - shift))) & BC_MASK; + } + + /** + * Row 0 remains unchanged + * The other three rows are shifted a variable amount + */ + private void ShiftRow( + byte[] shiftsSC) + { + A1 = Shift(A1, shiftsSC[1]); + A2 = Shift(A2, shiftsSC[2]); + A3 = Shift(A3, shiftsSC[3]); + } + + private long ApplyS( + long r, + byte[] box) + { + long res = 0; + + for (int j = 0; j < BC; j += 8) + { + res |= (long)(box[(int)((r >> j) & 0xff)] & 0xff) << j; + } + + return res; + } + + /** + * Replace every byte of the input by the byte at that place + * in the nonlinear S-box + */ + private void Substitution( + byte[] box) + { + A0 = ApplyS(A0, box); + A1 = ApplyS(A1, box); + A2 = ApplyS(A2, box); + A3 = ApplyS(A3, box); + } + + /** + * Mix the bytes of every column in a linear way + */ + private void MixColumn() + { + long r0, r1, r2, r3; + + r0 = r1 = r2 = r3 = 0; + + for (int j = 0; j < BC; j += 8) + { + int a0 = (int)((A0 >> j) & 0xff); + int a1 = (int)((A1 >> j) & 0xff); + int a2 = (int)((A2 >> j) & 0xff); + int a3 = (int)((A3 >> j) & 0xff); + + r0 |= (long)((Mul0x2(a0) ^ Mul0x3(a1) ^ a2 ^ a3) & 0xff) << j; + + r1 |= (long)((Mul0x2(a1) ^ Mul0x3(a2) ^ a3 ^ a0) & 0xff) << j; + + r2 |= (long)((Mul0x2(a2) ^ Mul0x3(a3) ^ a0 ^ a1) & 0xff) << j; + + r3 |= (long)((Mul0x2(a3) ^ Mul0x3(a0) ^ a1 ^ a2) & 0xff) << j; + } + + A0 = r0; + A1 = r1; + A2 = r2; + A3 = r3; + } + + /** + * Mix the bytes of every column in a linear way + * This is the opposite operation of Mixcolumn + */ + private void InvMixColumn() + { + long r0, r1, r2, r3; + + r0 = r1 = r2 = r3 = 0; + for (int j = 0; j < BC; j += 8) + { + int a0 = (int)((A0 >> j) & 0xff); + int a1 = (int)((A1 >> j) & 0xff); + int a2 = (int)((A2 >> j) & 0xff); + int a3 = (int)((A3 >> j) & 0xff); + + // + // pre-lookup the log table + // + a0 = (a0 != 0) ? (Logtable[a0 & 0xff] & 0xff) : -1; + a1 = (a1 != 0) ? (Logtable[a1 & 0xff] & 0xff) : -1; + a2 = (a2 != 0) ? (Logtable[a2 & 0xff] & 0xff) : -1; + a3 = (a3 != 0) ? (Logtable[a3 & 0xff] & 0xff) : -1; + + r0 |= (long)((Mul0xe(a0) ^ Mul0xb(a1) ^ Mul0xd(a2) ^ Mul0x9(a3)) & 0xff) << j; + + r1 |= (long)((Mul0xe(a1) ^ Mul0xb(a2) ^ Mul0xd(a3) ^ Mul0x9(a0)) & 0xff) << j; + + r2 |= (long)((Mul0xe(a2) ^ Mul0xb(a3) ^ Mul0xd(a0) ^ Mul0x9(a1)) & 0xff) << j; + + r3 |= (long)((Mul0xe(a3) ^ Mul0xb(a0) ^ Mul0xd(a1) ^ Mul0x9(a2)) & 0xff) << j; + } + + A0 = r0; + A1 = r1; + A2 = r2; + A3 = r3; + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on keyBits and blockBits + */ + private long[][] GenerateWorkingKey( + byte[] key) + { + int KC; + int t, rconpointer = 0; + int keyBits = key.Length * 8; + byte[,] tk = new byte[4,MAXKC]; + //long[,] W = new long[MAXROUNDS+1,4]; + long[][] W = new long[MAXROUNDS+1][]; + + for (int i = 0; i < MAXROUNDS+1; i++) W[i] = new long[4]; + + switch (keyBits) + { + case 128: + KC = 4; + break; + case 160: + KC = 5; + break; + case 192: + KC = 6; + break; + case 224: + KC = 7; + break; + case 256: + KC = 8; + break; + default : + throw new ArgumentException("Key length not 128/160/192/224/256 bits."); + } + + if (keyBits >= blockBits) + { + ROUNDS = KC + 6; + } + else + { + ROUNDS = (BC / 8) + 6; + } + + // + // copy the key into the processing area + // + int index = 0; + + for (int i = 0; i < key.Length; i++) + { + tk[i % 4,i / 4] = key[index++]; + } + + t = 0; + + // + // copy values into round key array + // + for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC / 8)); j++, t++) + { + for (int i = 0; i < 4; i++) + { + W[t / (BC / 8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % BC); + } + } + + // + // while not enough round key material calculated + // calculate new values + // + while (t < (ROUNDS+1)*(BC/8)) + { + for (int i = 0; i < 4; i++) + { + tk[i,0] ^= S[tk[(i+1)%4,KC-1] & 0xff]; + } + tk[0,0] ^= (byte) rcon[rconpointer++]; + + if (KC <= 6) + { + for (int j = 1; j < KC; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + } + else + { + for (int j = 1; j < 4; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + for (int i = 0; i < 4; i++) + { + tk[i,4] ^= S[tk[i,3] & 0xff]; + } + for (int j = 5; j < KC; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + } + + // + // copy values into round key array + // + for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC/8)); j++, t++) + { + for (int i = 0; i < 4; i++) + { + W[t / (BC/8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % (BC)); + } + } + } + return W; + } + + private int BC; + private long BC_MASK; + private int ROUNDS; + private int blockBits; + private long[][] workingKey; + private long A0, A1, A2, A3; + private bool forEncryption; + private byte[] shifts0SC; + private byte[] shifts1SC; + + /** + * default constructor - 128 bit block size. + */ + public RijndaelEngine() : this(128) {} + + /** + * basic constructor - set the cipher up for a given blocksize + * + * @param blocksize the blocksize in bits, must be 128, 192, or 256. + */ + public RijndaelEngine( + int blockBits) + { + switch (blockBits) + { + case 128: + BC = 32; + BC_MASK = 0xffffffffL; + shifts0SC = shifts0[0]; + shifts1SC = shifts1[0]; + break; + case 160: + BC = 40; + BC_MASK = 0xffffffffffL; + shifts0SC = shifts0[1]; + shifts1SC = shifts1[1]; + break; + case 192: + BC = 48; + BC_MASK = 0xffffffffffffL; + shifts0SC = shifts0[2]; + shifts1SC = shifts1[2]; + break; + case 224: + BC = 56; + BC_MASK = 0xffffffffffffffL; + shifts0SC = shifts0[3]; + shifts1SC = shifts1[3]; + break; + case 256: + BC = 64; + BC_MASK = unchecked( (long)0xffffffffffffffffL); + shifts0SC = shifts0[4]; + shifts1SC = shifts1[4]; + break; + default: + throw new ArgumentException("unknown blocksize to Rijndael"); + } + + this.blockBits = blockBits; + } + + /** + * initialise a Rijndael cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (typeof(KeyParameter).IsInstanceOfType(parameters)) + { + workingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey()); + this.forEncryption = forEncryption; + return; + } + + throw new ArgumentException("invalid parameter passed to Rijndael init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + + public virtual string AlgorithmName + { + get { return "Rijndael"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BC / 2; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Rijndael engine not initialised"); + + Check.DataLength(input, inOff, (BC / 2), "input buffer too short"); + Check.OutputLength(output, outOff, (BC / 2), "output buffer too short"); + + UnPackBlock(input, inOff); + + if (forEncryption) + { + EncryptBlock(workingKey); + } + else + { + DecryptBlock(workingKey); + } + + PackBlock(output, outOff); + + return BC / 2; + } + + public virtual void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + int index = off; + + A0 = (long)(bytes[index++] & 0xff); + A1 = (long)(bytes[index++] & 0xff); + A2 = (long)(bytes[index++] & 0xff); + A3 = (long)(bytes[index++] & 0xff); + + for (int j = 8; j != BC; j += 8) + { + A0 |= (long)(bytes[index++] & 0xff) << j; + A1 |= (long)(bytes[index++] & 0xff) << j; + A2 |= (long)(bytes[index++] & 0xff) << j; + A3 |= (long)(bytes[index++] & 0xff) << j; + } + } + + private void PackBlock( + byte[] bytes, + int off) + { + int index = off; + + for (int j = 0; j != BC; j += 8) + { + bytes[index++] = (byte)(A0 >> j); + bytes[index++] = (byte)(A1 >> j); + bytes[index++] = (byte)(A2 >> j); + bytes[index++] = (byte)(A3 >> j); + } + } + + private void EncryptBlock( + long[][] rk) + { + int r; + + // + // begin with a key addition + // + KeyAddition(rk[0]); + + // + // ROUNDS-1 ordinary rounds + // + for (r = 1; r < ROUNDS; r++) + { + Substitution(S); + ShiftRow(shifts0SC); + MixColumn(); + KeyAddition(rk[r]); + } + + // + // Last round is special: there is no MixColumn + // + Substitution(S); + ShiftRow(shifts0SC); + KeyAddition(rk[ROUNDS]); + } + + private void DecryptBlock( + long[][] rk) + { + int r; + + // To decrypt: apply the inverse operations of the encrypt routine, + // in opposite order + // + // (KeyAddition is an involution: it 's equal to its inverse) + // (the inverse of Substitution with table S is Substitution with the inverse table of S) + // (the inverse of Shiftrow is Shiftrow over a suitable distance) + // + + // First the special round: + // without InvMixColumn + // with extra KeyAddition + // + KeyAddition(rk[ROUNDS]); + Substitution(Si); + ShiftRow(shifts1SC); + + // + // ROUNDS-1 ordinary rounds + // + for (r = ROUNDS-1; r > 0; r--) + { + KeyAddition(rk[r]); + InvMixColumn(); + Substitution(Si); + ShiftRow(shifts1SC); + } + + // + // End with the extra key addition + // + KeyAddition(rk[0]); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs.meta new file mode 100644 index 0000000..be694c2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/RijndaelEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a49117f9f15a0794da51511f5e07a5df +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs new file mode 100644 index 0000000..43ebfa1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs @@ -0,0 +1,364 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Implementation of the SEED algorithm as described in RFC 4009 + */ + public class SeedEngine + : IBlockCipher + { + private const int BlockSize = 16; + + private static readonly uint[] SS0 = + { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298 + }; + + private static readonly uint[] SS1 = + { + 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0, + 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, + 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3, + 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43, + 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, + 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890, + 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3, + 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, + 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83, + 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430, + 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, + 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1, + 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1, + 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171, + 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951, + 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0, + 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, + 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41, + 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62, + 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, + 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303, + 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901, + 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, + 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343, + 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971, + 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, + 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642, + 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1, + 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, + 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, + 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783, + 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3 + }; + + private static readonly uint[] SS2 = + { + + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a + }; + + private static readonly uint[] SS3 = + { + + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437 + }; + + private static readonly uint[] KC = + { + 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, + 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, + 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, + 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b + }; + + private int[] wKey; + private bool forEncryption; + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + wKey = createWorkingKey(((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "SEED"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock( + byte[] inBuf, + int inOff, + byte[] outBuf, + int outOff) + { + if (wKey == null) + throw new InvalidOperationException("SEED engine not initialised"); + + Check.DataLength(inBuf, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(outBuf, outOff, BlockSize, "output buffer too short"); + + long l = bytesToLong(inBuf, inOff + 0); + long r = bytesToLong(inBuf, inOff + 8); + + if (forEncryption) + { + for (int i = 0; i < 16; i++) + { + long nl = r; + + r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); + l = nl; + } + } + else + { + for (int i = 15; i >= 0; i--) + { + long nl = r; + + r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); + l = nl; + } + } + + longToBytes(outBuf, outOff + 0, r); + longToBytes(outBuf, outOff + 8, l); + + return BlockSize; + } + + public virtual void Reset() + { + } + + private int[] createWorkingKey( + byte[] inKey) + { + int[] key = new int[32]; + long lower = bytesToLong(inKey, 0); + long upper = bytesToLong(inKey, 8); + + int key0 = extractW0(lower); + int key1 = extractW1(lower); + int key2 = extractW0(upper); + int key3 = extractW1(upper); + + for (int i = 0; i < 16; i++) + { + key[2 * i] = G(key0 + key2 - (int)KC[i]); + key[2 * i + 1] = G(key1 - key3 + (int)KC[i]); + + if (i % 2 == 0) + { + lower = rotateRight8(lower); + key0 = extractW0(lower); + key1 = extractW1(lower); + } + else + { + upper = rotateLeft8(upper); + key2 = extractW0(upper); + key3 = extractW1(upper); + } + } + + return key; + } + + private int extractW1( + long lVal) + { + return (int)lVal; + } + + private int extractW0( + long lVal) + { + return (int)(lVal >> 32); + } + + private long rotateLeft8( + long x) + { + return (x << 8) | ((long)((ulong) x >> 56)); + } + + private long rotateRight8( + long x) + { + return ((long)((ulong) x >> 8)) | (x << 56); + } + + private long bytesToLong( + byte[] src, + int srcOff) + { + long word = 0; + + for (int i = 0; i <= 7; i++) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void longToBytes( + byte[] dest, + int destOff, + long value) + { + for (int i = 0; i < 8; i++) + { + dest[i + destOff] = (byte)(value >> ((7 - i) * 8)); + } + } + + private int G( + int x) + { + return (int)(SS0[x & 0xff] ^ SS1[(x >> 8) & 0xff] ^ SS2[(x >> 16) & 0xff] ^ SS3[(x >> 24) & 0xff]); + } + + private long F( + int ki0, + int ki1, + long r) + { + int r0 = (int)(r >> 32); + int r1 = (int)r; + int rd1 = phaseCalc2(r0, ki0, r1, ki1); + int rd0 = rd1 + phaseCalc1(r0, ki0, r1, ki1); + + return ((long)rd0 << 32) | (rd1 & 0xffffffffL); + } + + private int phaseCalc1( + int r0, + int ki0, + int r1, + int ki1) + { + return G(G((r0 ^ ki0) ^ (r1 ^ ki1)) + (r0 ^ ki0)); + } + + private int phaseCalc2( + int r0, + int ki0, + int r1, + int ki1) + { + return G(phaseCalc1(r0, ki0, r1, ki1) + G((r0 ^ ki0) ^ (r1 ^ ki1))); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs.meta new file mode 100644 index 0000000..6ac94d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2871544d92435c54787622babc99b141 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs new file mode 100644 index 0000000..330793e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the SEED key wrapper based on RFC 4010/RFC 3394. + ///

+ /// For further details see: http://www.ietf.org/rfc/rfc4010.txt. + /// + public class SeedWrapEngine + : Rfc3394WrapEngine + { + public SeedWrapEngine() + : base(new SeedEngine()) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs.meta new file mode 100644 index 0000000..a885626 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SEEDWrapEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9401520a7aa7c8d41baf502990de084a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs new file mode 100644 index 0000000..77e24ce --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs @@ -0,0 +1,366 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + ///

+ /// Implementation of Daniel J. Bernstein's Salsa20 stream cipher, Snuffle 2005 + /// + public class Salsa20Engine + : IStreamCipher + { + public static readonly int DEFAULT_ROUNDS = 20; + + /** Constants */ + private const int StateSize = 16; // 16, 32 bit ints = 64 bytes + + private readonly static uint[] TAU_SIGMA = Pack.LE_To_UInt32(Strings.ToAsciiByteArray("expand 16-byte k" + "expand 32-byte k"), 0, 8); + + internal void PackTauOrSigma(int keyLength, uint[] state, int stateOffset) + { + int tsOff = (keyLength - 16) / 4; + state[stateOffset] = TAU_SIGMA[tsOff]; + state[stateOffset + 1] = TAU_SIGMA[tsOff + 1]; + state[stateOffset + 2] = TAU_SIGMA[tsOff + 2]; + state[stateOffset + 3] = TAU_SIGMA[tsOff + 3]; + } + + [Obsolete] + protected readonly static byte[] + sigma = Strings.ToAsciiByteArray("expand 32-byte k"), + tau = Strings.ToAsciiByteArray("expand 16-byte k"); + + protected int rounds; + + /* + * variables to hold the state of the engine + * during encryption and decryption + */ + private int index = 0; + internal uint[] engineState = new uint[StateSize]; // state + internal uint[] x = new uint[StateSize]; // internal buffer + private byte[] keyStream = new byte[StateSize * 4]; // expanded state, 64 bytes + private bool initialised = false; + + /* + * internal counter + */ + private uint cW0, cW1, cW2; + + /// + /// Creates a 20 round Salsa20 engine. + /// + public Salsa20Engine() + : this(DEFAULT_ROUNDS) + { + } + + /// + /// Creates a Salsa20 engine with a specific number of rounds. + /// + /// the number of rounds (must be an even number). + public Salsa20Engine(int rounds) + { + if (rounds <= 0 || (rounds & 1) != 0) + { + throw new ArgumentException("'rounds' must be a positive, even number"); + } + + this.rounds = rounds; + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + /* + * Salsa20 encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. (Like 90% of stream ciphers) + */ + + ParametersWithIV ivParams = parameters as ParametersWithIV; + if (ivParams == null) + throw new ArgumentException(AlgorithmName + " Init requires an IV", "parameters"); + + byte[] iv = ivParams.GetIV(); + if (iv == null || iv.Length != NonceSize) + throw new ArgumentException(AlgorithmName + " requires exactly " + NonceSize + " bytes of IV"); + + ICipherParameters keyParam = ivParams.Parameters; + if (keyParam == null) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " KeyParameter can not be null for first initialisation"); + + SetKey(null, iv); + } + else if (keyParam is KeyParameter) + { + SetKey(((KeyParameter)keyParam).GetKey(), iv); + } + else + { + throw new ArgumentException(AlgorithmName + " Init parameters must contain a KeyParameter (or null for re-init)"); + } + + Reset(); + initialised = true; + } + + protected virtual int NonceSize + { + get { return 8; } + } + + public virtual string AlgorithmName + { + get + { + string name = "Salsa20"; + if (rounds != DEFAULT_ROUNDS) + { + name += "/" + rounds; + } + return name; + } + } + + public virtual byte ReturnByte( + byte input) + { + if (LimitExceeded()) + { + throw new MaxBytesExceededException("2^70 byte limit per IV; Change IV"); + } + + if (index == 0) + { + GenerateKeyStream(keyStream); + AdvanceCounter(); + } + + byte output = (byte)(keyStream[index] ^ input); + index = (index + 1) & 63; + + return output; + } + + protected virtual void AdvanceCounter() + { + if (++engineState[8] == 0) + { + ++engineState[9]; + } + } + + public virtual void ProcessBytes( + byte[] inBytes, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + Check.OutputLength(outBytes, outOff, len, "output buffer too short"); + + if (LimitExceeded((uint)len)) + throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV"); + + for (int i = 0; i < len; i++) + { + if (index == 0) + { + GenerateKeyStream(keyStream); + AdvanceCounter(); + } + outBytes[i+outOff] = (byte)(keyStream[index]^inBytes[i+inOff]); + index = (index + 1) & 63; + } + } + + public virtual void Reset() + { + index = 0; + ResetLimitCounter(); + ResetCounter(); + } + + protected virtual void ResetCounter() + { + engineState[8] = engineState[9] = 0; + } + + protected virtual void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes != null) + { + if ((keyBytes.Length != 16) && (keyBytes.Length != 32)) + throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key"); + + int tsOff = (keyBytes.Length - 16) / 4; + engineState[0] = TAU_SIGMA[tsOff]; + engineState[5] = TAU_SIGMA[tsOff + 1]; + engineState[10] = TAU_SIGMA[tsOff + 2]; + engineState[15] = TAU_SIGMA[tsOff + 3]; + + // Key + Pack.LE_To_UInt32(keyBytes, 0, engineState, 1, 4); + Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 11, 4); + } + + // IV + Pack.LE_To_UInt32(ivBytes, 0, engineState, 6, 2); + } + + protected virtual void GenerateKeyStream(byte[] output) + { + SalsaCore(rounds, engineState, x); + Pack.UInt32_To_LE(x, output, 0); + } + + internal static void SalsaCore(int rounds, uint[] input, uint[] x) + { + if (input.Length != 16) + throw new ArgumentException(); + if (x.Length != 16) + throw new ArgumentException(); + if (rounds % 2 != 0) + throw new ArgumentException("Number of rounds must be even"); + + uint x00 = input[ 0]; + uint x01 = input[ 1]; + uint x02 = input[ 2]; + uint x03 = input[ 3]; + uint x04 = input[ 4]; + uint x05 = input[ 5]; + uint x06 = input[ 6]; + uint x07 = input[ 7]; + uint x08 = input[ 8]; + uint x09 = input[ 9]; + uint x10 = input[10]; + uint x11 = input[11]; + uint x12 = input[12]; + uint x13 = input[13]; + uint x14 = input[14]; + uint x15 = input[15]; + + for (int i = rounds; i > 0; i -= 2) + { + x04 ^= R((x00+x12), 7); + x08 ^= R((x04+x00), 9); + x12 ^= R((x08+x04),13); + x00 ^= R((x12+x08),18); + x09 ^= R((x05+x01), 7); + x13 ^= R((x09+x05), 9); + x01 ^= R((x13+x09),13); + x05 ^= R((x01+x13),18); + x14 ^= R((x10+x06), 7); + x02 ^= R((x14+x10), 9); + x06 ^= R((x02+x14),13); + x10 ^= R((x06+x02),18); + x03 ^= R((x15+x11), 7); + x07 ^= R((x03+x15), 9); + x11 ^= R((x07+x03),13); + x15 ^= R((x11+x07),18); + + x01 ^= R((x00+x03), 7); + x02 ^= R((x01+x00), 9); + x03 ^= R((x02+x01),13); + x00 ^= R((x03+x02),18); + x06 ^= R((x05+x04), 7); + x07 ^= R((x06+x05), 9); + x04 ^= R((x07+x06),13); + x05 ^= R((x04+x07),18); + x11 ^= R((x10+x09), 7); + x08 ^= R((x11+x10), 9); + x09 ^= R((x08+x11),13); + x10 ^= R((x09+x08),18); + x12 ^= R((x15+x14), 7); + x13 ^= R((x12+x15), 9); + x14 ^= R((x13+x12),13); + x15 ^= R((x14+x13),18); + } + + x[ 0] = x00 + input[ 0]; + x[ 1] = x01 + input[ 1]; + x[ 2] = x02 + input[ 2]; + x[ 3] = x03 + input[ 3]; + x[ 4] = x04 + input[ 4]; + x[ 5] = x05 + input[ 5]; + x[ 6] = x06 + input[ 6]; + x[ 7] = x07 + input[ 7]; + x[ 8] = x08 + input[ 8]; + x[ 9] = x09 + input[ 9]; + x[10] = x10 + input[10]; + x[11] = x11 + input[11]; + x[12] = x12 + input[12]; + x[13] = x13 + input[13]; + x[14] = x14 + input[14]; + x[15] = x15 + input[15]; + } + + /** + * Rotate left + * + * @param x value to rotate + * @param y amount to rotate x + * + * @return rotated x + */ + internal static uint R(uint x, int y) + { + return (x << y) | (x >> (32 - y)); + } + + private void ResetLimitCounter() + { + cW0 = 0; + cW1 = 0; + cW2 = 0; + } + + private bool LimitExceeded() + { + if (++cW0 == 0) + { + if (++cW1 == 0) + { + return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6) + } + } + + return false; + } + + /* + * this relies on the fact len will always be positive. + */ + private bool LimitExceeded( + uint len) + { + uint old = cW0; + cW0 += len; + if (cW0 < old) + { + if (++cW1 == 0) + { + return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6) + } + } + + return false; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs.meta new file mode 100644 index 0000000..5662ad7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/Salsa20Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e6638eb0b1fe30e45ada9cdca38690cd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs new file mode 100644 index 0000000..269d756 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs @@ -0,0 +1,296 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Serpent is a 128-bit 32-round block cipher with variable key lengths, + * including 128, 192 and 256 bit keys conjectured to be at least as + * secure as three-key triple-DES. + *

+ * Serpent was designed by Ross Anderson, Eli Biham and Lars Knudsen as a + * candidate algorithm for the NIST AES Quest. + *

+ *

+ * For full details see The Serpent home page + *

+ */ + public sealed class SerpentEngine + : SerpentEngineBase + { + /** + * Expand a user-supplied key material into a session key. + * + * @param key The user-key bytes (multiples of 4) to use. + * @exception ArgumentException + */ + protected override int[] MakeWorkingKey(byte[] key) + { + // + // pad key to 256 bits + // + int[] kPad = new int[16]; + int off = 0; + int length = 0; + + for (off = 0; (off + 4) < key.Length; off += 4) + { + kPad[length++] = (int)Pack.LE_To_UInt32(key, off); + } + + if (off % 4 == 0) + { + kPad[length++] = (int)Pack.LE_To_UInt32(key, off); + if (length < 8) + { + kPad[length] = 1; + } + } + else + { + throw new ArgumentException("key must be a multiple of 4 bytes"); + } + + // + // expand the padded key up to 33 x 128 bits of key material + // + int amount = (ROUNDS + 1) * 4; + int[] w = new int[amount]; + + // + // compute w0 to w7 from w-8 to w-1 + // + for (int i = 8; i < 16; i++) + { + kPad[i] = RotateLeft(kPad[i - 8] ^ kPad[i - 5] ^ kPad[i - 3] ^ kPad[i - 1] ^ PHI ^ (i - 8), 11); + } + + Array.Copy(kPad, 8, w, 0, 8); + + // + // compute w8 to w136 + // + for (int i = 8; i < amount; i++) + { + w[i] = RotateLeft(w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); + } + + // + // create the working keys by processing w with the Sbox and IP + // + Sb3(w[0], w[1], w[2], w[3]); + w[0] = X0; w[1] = X1; w[2] = X2; w[3] = X3; + Sb2(w[4], w[5], w[6], w[7]); + w[4] = X0; w[5] = X1; w[6] = X2; w[7] = X3; + Sb1(w[8], w[9], w[10], w[11]); + w[8] = X0; w[9] = X1; w[10] = X2; w[11] = X3; + Sb0(w[12], w[13], w[14], w[15]); + w[12] = X0; w[13] = X1; w[14] = X2; w[15] = X3; + Sb7(w[16], w[17], w[18], w[19]); + w[16] = X0; w[17] = X1; w[18] = X2; w[19] = X3; + Sb6(w[20], w[21], w[22], w[23]); + w[20] = X0; w[21] = X1; w[22] = X2; w[23] = X3; + Sb5(w[24], w[25], w[26], w[27]); + w[24] = X0; w[25] = X1; w[26] = X2; w[27] = X3; + Sb4(w[28], w[29], w[30], w[31]); + w[28] = X0; w[29] = X1; w[30] = X2; w[31] = X3; + Sb3(w[32], w[33], w[34], w[35]); + w[32] = X0; w[33] = X1; w[34] = X2; w[35] = X3; + Sb2(w[36], w[37], w[38], w[39]); + w[36] = X0; w[37] = X1; w[38] = X2; w[39] = X3; + Sb1(w[40], w[41], w[42], w[43]); + w[40] = X0; w[41] = X1; w[42] = X2; w[43] = X3; + Sb0(w[44], w[45], w[46], w[47]); + w[44] = X0; w[45] = X1; w[46] = X2; w[47] = X3; + Sb7(w[48], w[49], w[50], w[51]); + w[48] = X0; w[49] = X1; w[50] = X2; w[51] = X3; + Sb6(w[52], w[53], w[54], w[55]); + w[52] = X0; w[53] = X1; w[54] = X2; w[55] = X3; + Sb5(w[56], w[57], w[58], w[59]); + w[56] = X0; w[57] = X1; w[58] = X2; w[59] = X3; + Sb4(w[60], w[61], w[62], w[63]); + w[60] = X0; w[61] = X1; w[62] = X2; w[63] = X3; + Sb3(w[64], w[65], w[66], w[67]); + w[64] = X0; w[65] = X1; w[66] = X2; w[67] = X3; + Sb2(w[68], w[69], w[70], w[71]); + w[68] = X0; w[69] = X1; w[70] = X2; w[71] = X3; + Sb1(w[72], w[73], w[74], w[75]); + w[72] = X0; w[73] = X1; w[74] = X2; w[75] = X3; + Sb0(w[76], w[77], w[78], w[79]); + w[76] = X0; w[77] = X1; w[78] = X2; w[79] = X3; + Sb7(w[80], w[81], w[82], w[83]); + w[80] = X0; w[81] = X1; w[82] = X2; w[83] = X3; + Sb6(w[84], w[85], w[86], w[87]); + w[84] = X0; w[85] = X1; w[86] = X2; w[87] = X3; + Sb5(w[88], w[89], w[90], w[91]); + w[88] = X0; w[89] = X1; w[90] = X2; w[91] = X3; + Sb4(w[92], w[93], w[94], w[95]); + w[92] = X0; w[93] = X1; w[94] = X2; w[95] = X3; + Sb3(w[96], w[97], w[98], w[99]); + w[96] = X0; w[97] = X1; w[98] = X2; w[99] = X3; + Sb2(w[100], w[101], w[102], w[103]); + w[100] = X0; w[101] = X1; w[102] = X2; w[103] = X3; + Sb1(w[104], w[105], w[106], w[107]); + w[104] = X0; w[105] = X1; w[106] = X2; w[107] = X3; + Sb0(w[108], w[109], w[110], w[111]); + w[108] = X0; w[109] = X1; w[110] = X2; w[111] = X3; + Sb7(w[112], w[113], w[114], w[115]); + w[112] = X0; w[113] = X1; w[114] = X2; w[115] = X3; + Sb6(w[116], w[117], w[118], w[119]); + w[116] = X0; w[117] = X1; w[118] = X2; w[119] = X3; + Sb5(w[120], w[121], w[122], w[123]); + w[120] = X0; w[121] = X1; w[122] = X2; w[123] = X3; + Sb4(w[124], w[125], w[126], w[127]); + w[124] = X0; w[125] = X1; w[126] = X2; w[127] = X3; + Sb3(w[128], w[129], w[130], w[131]); + w[128] = X0; w[129] = X1; w[130] = X2; w[131] = X3; + + return w; + } + + /** + * Encrypt one block of plaintext. + * + * @param input the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param output the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + protected override void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + X0 = (int)Pack.LE_To_UInt32(input, inOff); + X1 = (int)Pack.LE_To_UInt32(input, inOff + 4); + X2 = (int)Pack.LE_To_UInt32(input, inOff + 8); + X3 = (int)Pack.LE_To_UInt32(input, inOff + 12); + + Sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3); LT(); + Sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3); LT(); + Sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3); LT(); + Sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3); LT(); + Sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3); LT(); + Sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3); LT(); + Sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3); LT(); + Sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3); LT(); + Sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3); LT(); + Sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3); LT(); + Sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3); LT(); + Sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3); LT(); + Sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3); LT(); + Sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3); LT(); + Sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3); LT(); + Sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3); LT(); + Sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3); LT(); + Sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3); LT(); + Sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3); LT(); + Sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3); LT(); + Sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3); LT(); + Sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3); LT(); + Sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3); LT(); + Sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3); LT(); + Sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3); LT(); + Sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3); LT(); + Sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3); LT(); + Sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3); LT(); + Sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3); LT(); + Sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3); LT(); + Sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3); LT(); + Sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3); + + Pack.UInt32_To_LE((uint)(wKey[128] ^ X0), output, outOff); + Pack.UInt32_To_LE((uint)(wKey[129] ^ X1), output, outOff + 4); + Pack.UInt32_To_LE((uint)(wKey[130] ^ X2), output, outOff + 8); + Pack.UInt32_To_LE((uint)(wKey[131] ^ X3), output, outOff + 12); + } + + /** + * Decrypt one block of ciphertext. + * + * @param input the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param output the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + protected override void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + X0 = wKey[128] ^ (int)Pack.LE_To_UInt32(input, inOff); + X1 = wKey[129] ^ (int)Pack.LE_To_UInt32(input, inOff + 4); + X2 = wKey[130] ^ (int)Pack.LE_To_UInt32(input, inOff + 8); + X3 = wKey[131] ^ (int)Pack.LE_To_UInt32(input, inOff + 12); + + Ib7(X0, X1, X2, X3); + X0 ^= wKey[124]; X1 ^= wKey[125]; X2 ^= wKey[126]; X3 ^= wKey[127]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[120]; X1 ^= wKey[121]; X2 ^= wKey[122]; X3 ^= wKey[123]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[116]; X1 ^= wKey[117]; X2 ^= wKey[118]; X3 ^= wKey[119]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[112]; X1 ^= wKey[113]; X2 ^= wKey[114]; X3 ^= wKey[115]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[108]; X1 ^= wKey[109]; X2 ^= wKey[110]; X3 ^= wKey[111]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[104]; X1 ^= wKey[105]; X2 ^= wKey[106]; X3 ^= wKey[107]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[100]; X1 ^= wKey[101]; X2 ^= wKey[102]; X3 ^= wKey[103]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[96]; X1 ^= wKey[97]; X2 ^= wKey[98]; X3 ^= wKey[99]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[92]; X1 ^= wKey[93]; X2 ^= wKey[94]; X3 ^= wKey[95]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[88]; X1 ^= wKey[89]; X2 ^= wKey[90]; X3 ^= wKey[91]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[84]; X1 ^= wKey[85]; X2 ^= wKey[86]; X3 ^= wKey[87]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[80]; X1 ^= wKey[81]; X2 ^= wKey[82]; X3 ^= wKey[83]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[76]; X1 ^= wKey[77]; X2 ^= wKey[78]; X3 ^= wKey[79]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[72]; X1 ^= wKey[73]; X2 ^= wKey[74]; X3 ^= wKey[75]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[68]; X1 ^= wKey[69]; X2 ^= wKey[70]; X3 ^= wKey[71]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[64]; X1 ^= wKey[65]; X2 ^= wKey[66]; X3 ^= wKey[67]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[60]; X1 ^= wKey[61]; X2 ^= wKey[62]; X3 ^= wKey[63]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[56]; X1 ^= wKey[57]; X2 ^= wKey[58]; X3 ^= wKey[59]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[52]; X1 ^= wKey[53]; X2 ^= wKey[54]; X3 ^= wKey[55]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[48]; X1 ^= wKey[49]; X2 ^= wKey[50]; X3 ^= wKey[51]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[44]; X1 ^= wKey[45]; X2 ^= wKey[46]; X3 ^= wKey[47]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[40]; X1 ^= wKey[41]; X2 ^= wKey[42]; X3 ^= wKey[43]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[36]; X1 ^= wKey[37]; X2 ^= wKey[38]; X3 ^= wKey[39]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[32]; X1 ^= wKey[33]; X2 ^= wKey[34]; X3 ^= wKey[35]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[28]; X1 ^= wKey[29]; X2 ^= wKey[30]; X3 ^= wKey[31]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[24]; X1 ^= wKey[25]; X2 ^= wKey[26]; X3 ^= wKey[27]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[20]; X1 ^= wKey[21]; X2 ^= wKey[22]; X3 ^= wKey[23]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[16]; X1 ^= wKey[17]; X2 ^= wKey[18]; X3 ^= wKey[19]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[12]; X1 ^= wKey[13]; X2 ^= wKey[14]; X3 ^= wKey[15]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[8]; X1 ^= wKey[9]; X2 ^= wKey[10]; X3 ^= wKey[11]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[4]; X1 ^= wKey[5]; X2 ^= wKey[6]; X3 ^= wKey[7]; + InverseLT(); Ib0(X0, X1, X2, X3); + + Pack.UInt32_To_LE((uint)(X0 ^ wKey[0]), output, outOff); + Pack.UInt32_To_LE((uint)(X1 ^ wKey[1]), output, outOff + 4); + Pack.UInt32_To_LE((uint)(X2 ^ wKey[2]), output, outOff + 8); + Pack.UInt32_To_LE((uint)(X3 ^ wKey[3]), output, outOff + 12); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs.meta new file mode 100644 index 0000000..a6d60fb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 491e4a3043740fb4aa22329380b4cbe4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs new file mode 100644 index 0000000..bf4d723 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs @@ -0,0 +1,473 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public abstract class SerpentEngineBase + : IBlockCipher + { + protected static readonly int BlockSize = 16; + + internal const int ROUNDS = 32; + internal const int PHI = unchecked((int)0x9E3779B9); // (sqrt(5) - 1) * 2**31 + + protected bool encrypting; + protected int[] wKey; + + protected int X0, X1, X2, X3; // registers + + protected SerpentEngineBase() + { + } + + /** + * initialise a Serpent cipher. + * + * @param encrypting whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @throws IllegalArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init(bool encrypting, ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to " + AlgorithmName + " init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + this.encrypting = encrypting; + this.wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "Serpent"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @return the number of bytes processed and produced. + * @throws DataLengthException if there isn't enough data in in, or + * space in out. + * @throws IllegalStateException if the cipher isn't initialised. + */ + public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (wKey == null) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BlockSize; + } + + public virtual void Reset() + { + } + + protected static int RotateLeft(int x, int bits) + { + return ((x << bits) | (int) ((uint)x >> (32 - bits))); + } + + private static int RotateRight(int x, int bits) + { + return ( (int)((uint)x >> bits) | (x << (32 - bits))); + } + + /* + * The sboxes below are based on the work of Brian Gladman and + * Sam Simpson, whose original notice appears below. + *

+ * For further details see: + * http://fp.gladman.plus.com/cryptography_technology/serpent/ + *

+ */ + + /* Partially optimised Serpent S Box boolean functions derived */ + /* using a recursive descent analyser but without a full search */ + /* of all subtrees. This set of S boxes is the result of work */ + /* by Sam Simpson and Brian Gladman using the spare time on a */ + /* cluster of high capacity servers to search for S boxes with */ + /* this customised search engine. There are now an average of */ + /* 15.375 terms per S box. */ + /* */ + /* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */ + /* and Sam Simpson (s.simpson@mia.co.uk) */ + /* 17th December 1998 */ + /* */ + /* We hereby give permission for information in this file to be */ + /* used freely subject only to acknowledgement of its origin. */ + + /* + * S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms. + */ + protected void Sb0(int a, int b, int c, int d) + { + int t1 = a ^ d; + int t3 = c ^ t1; + int t4 = b ^ t3; + X3 = (a & d) ^ t4; + int t7 = a ^ (b & t1); + X2 = t4 ^ (c | t7); + int t12 = X3 & (t3 ^ t7); + X1 = (~t3) ^ t12; + X0 = t12 ^ (~t7); + } + + /** + * InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms. + */ + protected void Ib0(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t4 = d ^ (t1 | t2); + int t5 = c ^ t4; + X2 = t2 ^ t5; + int t8 = t1 ^ (d & t2); + X1 = t4 ^ (X2 & t8); + X3 = (a & t4) ^ (t5 | X1); + X0 = X3 ^ (t5 ^ t8); + } + + /** + * S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms. + */ + protected void Sb1(int a, int b, int c, int d) + { + int t2 = b ^ (~a); + int t5 = c ^ (a | t2); + X2 = d ^ t5; + int t7 = b ^ (d | t2); + int t8 = t2 ^ X2; + X3 = t8 ^ (t5 & t7); + int t11 = t5 ^ t7; + X1 = X3 ^ t11; + X0 = t5 ^ (t8 & t11); + } + + /** + * InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps. + */ + protected void Ib1(int a, int b, int c, int d) + { + int t1 = b ^ d; + int t3 = a ^ (b & t1); + int t4 = t1 ^ t3; + X3 = c ^ t4; + int t7 = b ^ (t1 & t3); + int t8 = X3 | t7; + X1 = t3 ^ t8; + int t10 = ~X1; + int t11 = X3 ^ t7; + X0 = t10 ^ t11; + X2 = t4 ^ (t10 | t11); + } + + /** + * S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms. + */ + protected void Sb2(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = b ^ d; + int t3 = c & t1; + X0 = t2 ^ t3; + int t5 = c ^ t1; + int t6 = c ^ X0; + int t7 = b & t6; + X3 = t5 ^ t7; + X2 = a ^ ((d | t7) & (X0 | t5)); + X1 = (t2 ^ X3) ^ (X2 ^ (d | t1)); + } + + /** + * InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps. + */ + protected void Ib2(int a, int b, int c, int d) + { + int t1 = b ^ d; + int t2 = ~t1; + int t3 = a ^ c; + int t4 = c ^ t1; + int t5 = b & t4; + X0 = t3 ^ t5; + int t7 = a | t2; + int t8 = d ^ t7; + int t9 = t3 | t8; + X3 = t1 ^ t9; + int t11 = ~t4; + int t12 = X0 | X3; + X1 = t11 ^ t12; + X2 = (d & t11) ^ (t3 ^ t12); + } + + /** + * S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms. + */ + protected void Sb3(int a, int b, int c, int d) + { + int t1 = a ^ b; + int t2 = a & c; + int t3 = a | d; + int t4 = c ^ d; + int t5 = t1 & t3; + int t6 = t2 | t5; + X2 = t4 ^ t6; + int t8 = b ^ t3; + int t9 = t6 ^ t8; + int t10 = t4 & t9; + X0 = t1 ^ t10; + int t12 = X2 & X0; + X1 = t9 ^ t12; + X3 = (b | d) ^ (t4 ^ t12); + } + + /** + * InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms + */ + protected void Ib3(int a, int b, int c, int d) + { + int t1 = a | b; + int t2 = b ^ c; + int t3 = b & t2; + int t4 = a ^ t3; + int t5 = c ^ t4; + int t6 = d | t4; + X0 = t2 ^ t6; + int t8 = t2 | t6; + int t9 = d ^ t8; + X2 = t5 ^ t9; + int t11 = t1 ^ t9; + int t12 = X0 & t11; + X3 = t4 ^ t12; + X1 = X3 ^ (X0 ^ t11); + } + + /** + * S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms. + */ + protected void Sb4(int a, int b, int c, int d) + { + int t1 = a ^ d; + int t2 = d & t1; + int t3 = c ^ t2; + int t4 = b | t3; + X3 = t1 ^ t4; + int t6 = ~b; + int t7 = t1 | t6; + X0 = t3 ^ t7; + int t9 = a & X0; + int t10 = t1 ^ t6; + int t11 = t4 & t10; + X2 = t9 ^ t11; + X1 = (a ^ t3) ^ (t10 & X2); + } + + /** + * InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms. + */ + protected void Ib4(int a, int b, int c, int d) + { + int t1 = c | d; + int t2 = a & t1; + int t3 = b ^ t2; + int t4 = a & t3; + int t5 = c ^ t4; + X1 = d ^ t5; + int t7 = ~a; + int t8 = t5 & X1; + X3 = t3 ^ t8; + int t10 = X1 | t7; + int t11 = d ^ t10; + X0 = X3 ^ t11; + X2 = (t3 & t11) ^ (X1 ^ t7); + } + + /** + * S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms. + */ + protected void Sb5(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t3 = a ^ d; + int t4 = c ^ t1; + int t5 = t2 | t3; + X0 = t4 ^ t5; + int t7 = d & X0; + int t8 = t2 ^ X0; + X1 = t7 ^ t8; + int t10 = t1 | X0; + int t11 = t2 | t7; + int t12 = t3 ^ t10; + X2 = t11 ^ t12; + X3 = (b ^ t7) ^ (X1 & t12); + } + + /** + * InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms. + */ + protected void Ib5(int a, int b, int c, int d) + { + int t1 = ~c; + int t2 = b & t1; + int t3 = d ^ t2; + int t4 = a & t3; + int t5 = b ^ t1; + X3 = t4 ^ t5; + int t7 = b | X3; + int t8 = a & t7; + X1 = t3 ^ t8; + int t10 = a | d; + int t11 = t1 ^ t7; + X0 = t10 ^ t11; + X2 = (b & t10) ^ (t4 | (a ^ c)); + } + + /** + * S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms. + */ + protected void Sb6(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ d; + int t3 = b ^ t2; + int t4 = t1 | t2; + int t5 = c ^ t4; + X1 = b ^ t5; + int t7 = t2 | X1; + int t8 = d ^ t7; + int t9 = t5 & t8; + X2 = t3 ^ t9; + int t11 = t5 ^ t8; + X0 = X2 ^ t11; + X3 = (~t5) ^ (t3 & t11); + } + + /** + * InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms. + */ + protected void Ib6(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t3 = c ^ t2; + int t4 = c | t1; + int t5 = d ^ t4; + X1 = t3 ^ t5; + int t7 = t3 & t5; + int t8 = t2 ^ t7; + int t9 = b | t8; + X3 = t5 ^ t9; + int t11 = b | X3; + X0 = t8 ^ t11; + X2 = (d & t1) ^ (t3 ^ t11); + } + + /** + * S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms. + */ + protected void Sb7(int a, int b, int c, int d) + { + int t1 = b ^ c; + int t2 = c & t1; + int t3 = d ^ t2; + int t4 = a ^ t3; + int t5 = d | t1; + int t6 = t4 & t5; + X1 = b ^ t6; + int t8 = t3 | X1; + int t9 = a & t4; + X3 = t1 ^ t9; + int t11 = t4 ^ t8; + int t12 = X3 & t11; + X2 = t3 ^ t12; + X0 = (~t11) ^ (X3 & X2); + } + + /** + * InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms. + */ + protected void Ib7(int a, int b, int c, int d) + { + int t3 = c | (a & b); + int t4 = d & (a | b); + X3 = t3 ^ t4; + int t6 = ~d; + int t7 = b ^ t4; + int t9 = t7 | (X3 ^ t6); + X1 = a ^ t9; + X0 = (c ^ t7) ^ (d | X1); + X2 = (t3 ^ X1) ^ (X0 ^ (a & X3)); + } + + /** + * Apply the linear transformation to the register set. + */ + protected void LT() + { + int x0 = RotateLeft(X0, 13); + int x2 = RotateLeft(X2, 3); + int x1 = X1 ^ x0 ^ x2; + int x3 = X3 ^ x2 ^ x0 << 3; + + X1 = RotateLeft(x1, 1); + X3 = RotateLeft(x3, 7); + X0 = RotateLeft(x0 ^ X1 ^ X3, 5); + X2 = RotateLeft(x2 ^ X3 ^ (X1 << 7), 22); + } + + /** + * Apply the inverse of the linear transformation to the register set. + */ + protected void InverseLT() + { + int x2 = RotateRight(X2, 22) ^ X3 ^ (X1 << 7); + int x0 = RotateRight(X0, 5) ^ X1 ^ X3; + int x3 = RotateRight(X3, 7); + int x1 = RotateRight(X1, 1); + X3 = x3 ^ x2 ^ x0 << 3; + X1 = x1 ^ x0 ^ x2; + X2 = RotateRight(x2, 3); + X0 = RotateRight(x0, 13); + } + + protected abstract int[] MakeWorkingKey(byte[] key); + + protected abstract void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff); + + protected abstract void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs.meta new file mode 100644 index 0000000..2e1ee99 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SerpentEngineBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f164055e1ead4fa418746f4253a72692 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs new file mode 100644 index 0000000..6746b55 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs @@ -0,0 +1,258 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * a class that provides a basic SKIPJACK engine. + */ + public class SkipjackEngine + : IBlockCipher + { + const int BLOCK_SIZE = 8; + + static readonly short [] ftable = + { + 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, + 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, + 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, + 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, + 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, + 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, + 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, + 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, + 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, + 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, + 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, + 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, + 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, + 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, + 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, + 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46 + }; + + private int[] key0, key1, key2, key3; + private bool encrypting; + + /** + * initialise a SKIPJACK cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to SKIPJACK init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + byte[] keyBytes = ((KeyParameter)parameters).GetKey(); + + this.encrypting = forEncryption; + this.key0 = new int[32]; + this.key1 = new int[32]; + this.key2 = new int[32]; + this.key3 = new int[32]; + + // + // expand the key to 128 bytes in 4 parts (saving us a modulo, multiply + // and an addition). + // + for (int i = 0; i < 32; i ++) + { + key0[i] = keyBytes[(i * 4) % 10] & 0xff; + key1[i] = keyBytes[(i * 4 + 1) % 10] & 0xff; + key2[i] = keyBytes[(i * 4 + 2) % 10] & 0xff; + key3[i] = keyBytes[(i * 4 + 3) % 10] & 0xff; + } + } + + public virtual string AlgorithmName + { + get { return "SKIPJACK"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (key1 == null) + throw new InvalidOperationException("SKIPJACK engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + /** + * The G permutation + */ + private int G( + int k, + int w) + { + int g1, g2, g3, g4, g5, g6; + + g1 = (w >> 8) & 0xff; + g2 = w & 0xff; + + g3 = ftable[g2 ^ key0[k]] ^ g1; + g4 = ftable[g3 ^ key1[k]] ^ g2; + g5 = ftable[g4 ^ key2[k]] ^ g3; + g6 = ftable[g5 ^ key3[k]] ^ g4; + + return ((g5 << 8) + g6); + } + + public virtual int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int w1 = (input[inOff + 0] << 8) + (input[inOff + 1] & 0xff); + int w2 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xff); + int w3 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xff); + int w4 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xff); + + int k = 0; + + for (int t = 0; t < 2; t++) + { + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w2; + w2 = G(k, w1); + w1 = w2 ^ tmp ^ (k + 1); + k++; + } + + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w1 ^ w2 ^ (k + 1); + w2 = G(k, w1); + w1 = tmp; + k++; + } + } + + outBytes[outOff + 0] = (byte)((w1 >> 8)); + outBytes[outOff + 1] = (byte)(w1); + outBytes[outOff + 2] = (byte)((w2 >> 8)); + outBytes[outOff + 3] = (byte)(w2); + outBytes[outOff + 4] = (byte)((w3 >> 8)); + outBytes[outOff + 5] = (byte)(w3); + outBytes[outOff + 6] = (byte)((w4 >> 8)); + outBytes[outOff + 7] = (byte)(w4); + + return BLOCK_SIZE; + } + + /** + * the inverse of the G permutation. + */ + private int H( + int k, + int w) + { + int h1, h2, h3, h4, h5, h6; + + h1 = w & 0xff; + h2 = (w >> 8) & 0xff; + + h3 = ftable[h2 ^ key3[k]] ^ h1; + h4 = ftable[h3 ^ key2[k]] ^ h2; + h5 = ftable[h4 ^ key1[k]] ^ h3; + h6 = ftable[h5 ^ key0[k]] ^ h4; + + return ((h6 << 8) + h5); + } + + public virtual int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int w2 = (input[inOff + 0] << 8) + (input[inOff + 1] & 0xff); + int w1 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xff); + int w4 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xff); + int w3 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xff); + + int k = 31; + + for (int t = 0; t < 2; t++) + { + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w2; + w2 = H(k, w1); + w1 = w2 ^ tmp ^ (k + 1); + k--; + } + + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w1 ^ w2 ^ (k + 1); + w2 = H(k, w1); + w1 = tmp; + k--; + } + } + + outBytes[outOff + 0] = (byte)((w2 >> 8)); + outBytes[outOff + 1] = (byte)(w2); + outBytes[outOff + 2] = (byte)((w1 >> 8)); + outBytes[outOff + 3] = (byte)(w1); + outBytes[outOff + 4] = (byte)((w4 >> 8)); + outBytes[outOff + 5] = (byte)(w4); + outBytes[outOff + 6] = (byte)((w3 >> 8)); + outBytes[outOff + 7] = (byte)(w3); + + return BLOCK_SIZE; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs.meta new file mode 100644 index 0000000..e300090 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/SkipjackEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ee50d237d55d7f9409d3850b96c5a875 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs new file mode 100644 index 0000000..e2257e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs @@ -0,0 +1,170 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An TEA engine. + */ + public class TeaEngine + : IBlockCipher + { + private const int + rounds = 32, + block_size = 8; +// key_size = 16, + + private const uint + delta = 0x9E3779B9, + d_sum = 0xC6EF3720; // sum on decrypt + + /* + * the expanded key array of 4 subkeys + */ + private uint _a, _b, _c, _d; + private bool _initialised; + private bool _forEncryption; + + /** + * Create an instance of the TEA encryption algorithm + * and set some defaults + */ + public TeaEngine() + { + _initialised = false; + } + + public virtual string AlgorithmName + { + get { return "TEA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return block_size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + { + throw new ArgumentException("invalid parameter passed to TEA init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(inBytes, inOff, block_size, "input buffer too short"); + Check.OutputLength(outBytes, outOff, block_size, "output buffer too short"); + + return _forEncryption + ? encryptBlock(inBytes, inOff, outBytes, outOff) + : decryptBlock(inBytes, inOff, outBytes, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey( + byte[] key) + { + _a = Pack.BE_To_UInt32(key, 0); + _b = Pack.BE_To_UInt32(key, 4); + _c = Pack.BE_To_UInt32(key, 8); + _d = Pack.BE_To_UInt32(key, 12); + } + + private int encryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + uint sum = 0; + + for (int i = 0; i != rounds; i++) + { + sum += delta; + v0 += ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >> 5) + _b); + v1 += ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >> 5) + _d); + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + + private int decryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + uint sum = d_sum; + + for (int i = 0; i != rounds; i++) + { + v1 -= ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >> 5) + _d); + v0 -= ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >> 5) + _b); + sum -= delta; + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs.meta new file mode 100644 index 0000000..a15b498 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TEAEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 35dd311c76c77164f9dd915b865c17d6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs new file mode 100644 index 0000000..98b75b9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs @@ -0,0 +1,679 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides Twofish encryption operations. + * + * This Java implementation is based on the Java reference + * implementation provided by Bruce Schneier and developed + * by Raif S. Naffah. + */ + public sealed class TwofishEngine + : IBlockCipher + { + private static readonly byte[,] P = { + { // p0 + (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, + (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, + (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, + (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, + (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, + (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, + (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, + (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, + (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, + (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, + (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, + (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, + (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, + (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, + (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, + (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, + (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, + (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, + (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, + (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, + (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, + (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, + (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, + (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, + (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, + (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, + (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, + (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, + (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, + (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, + (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, + (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, + (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, + (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, + (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, + (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, + (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, + (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, + (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, + (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, + (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, + (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, + (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, + (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, + (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, + (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, + (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, + (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, + (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, + (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, + (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, + (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, + (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, + (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, + (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, + (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, + (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, + (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, + (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, + (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, + (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, + (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, + (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, + (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 }, + { // p1 + (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, + (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, + (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, + (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, + (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, + (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, + (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, + (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, + (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, + (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, + (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, + (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, + (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, + (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, + (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, + (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, + (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, + (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, + (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, + (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, + (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, + (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, + (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, + (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, + (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, + (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, + (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, + (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, + (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, + (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, + (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, + (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, + (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, + (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, + (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, + (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, + (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, + (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, + (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, + (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, + (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, + (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, + (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, + (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, + (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, + (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, + (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, + (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, + (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, + (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, + (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, + (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, + (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, + (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, + (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, + (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, + (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, + (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, + (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, + (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, + (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, + (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, + (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, + (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 } + }; + + /** + * Define the fixed p0/p1 permutations used in keyed S-box lookup. + * By changing the following constant definitions, the S-boxes will + * automatically Get changed in the Twofish engine. + */ + private const int P_00 = 1; + private const int P_01 = 0; + private const int P_02 = 0; + private const int P_03 = P_01 ^ 1; + private const int P_04 = 1; + + private const int P_10 = 0; + private const int P_11 = 0; + private const int P_12 = 1; + private const int P_13 = P_11 ^ 1; + private const int P_14 = 0; + + private const int P_20 = 1; + private const int P_21 = 1; + private const int P_22 = 0; + private const int P_23 = P_21 ^ 1; + private const int P_24 = 0; + + private const int P_30 = 0; + private const int P_31 = 1; + private const int P_32 = 1; + private const int P_33 = P_31 ^ 1; + private const int P_34 = 1; + + /* Primitive polynomial for GF(256) */ + private const int GF256_FDBK = 0x169; + private const int GF256_FDBK_2 = GF256_FDBK / 2; + private const int GF256_FDBK_4 = GF256_FDBK / 4; + + private const int RS_GF_FDBK = 0x14D; // field generator + + //==================================== + // Useful constants + //==================================== + + private const int ROUNDS = 16; + private const int MAX_ROUNDS = 16; // bytes = 128 bits + private const int BLOCK_SIZE = 16; // bytes = 128 bits + private const int MAX_KEY_BITS = 256; + + private const int INPUT_WHITEN=0; + private const int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4 + private const int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8 + + private const int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40 + + private const int SK_STEP = 0x02020202; + private const int SK_BUMP = 0x01010101; + private const int SK_ROTL = 9; + + private bool encrypting; + + private int[] gMDS0 = new int[MAX_KEY_BITS]; + private int[] gMDS1 = new int[MAX_KEY_BITS]; + private int[] gMDS2 = new int[MAX_KEY_BITS]; + private int[] gMDS3 = new int[MAX_KEY_BITS]; + + /** + * gSubKeys[] and gSBox[] are eventually used in the + * encryption and decryption methods. + */ + private int[] gSubKeys; + private int[] gSBox; + + private int k64Cnt; + + private byte[] workingKey; + + public TwofishEngine() + { + // calculate the MDS matrix + int[] m1 = new int[2]; + int[] mX = new int[2]; + int[] mY = new int[2]; + int j; + + for (int i=0; i< MAX_KEY_BITS ; i++) + { + j = P[0,i] & 0xff; + m1[0] = j; + mX[0] = Mx_X(j) & 0xff; + mY[0] = Mx_Y(j) & 0xff; + + j = P[1,i] & 0xff; + m1[1] = j; + mX[1] = Mx_X(j) & 0xff; + mY[1] = Mx_Y(j) & 0xff; + + gMDS0[i] = m1[P_00] | mX[P_00] << 8 | + mY[P_00] << 16 | mY[P_00] << 24; + + gMDS1[i] = mY[P_10] | mY[P_10] << 8 | + mX[P_10] << 16 | m1[P_10] << 24; + + gMDS2[i] = mX[P_20] | mY[P_20] << 8 | + m1[P_20] << 16 | mY[P_20] << 24; + + gMDS3[i] = mX[P_30] | m1[P_30] << 8 | + mY[P_30] << 16 | mX[P_30] << 24; + } + } + + /** + * initialise a Twofish cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to Twofish init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + + this.encrypting = forEncryption; + this.workingKey = ((KeyParameter)parameters).GetKey(); + this.k64Cnt = (this.workingKey.Length / 8); // pre-padded ? + SetKey(this.workingKey); + } + + public string AlgorithmName + { + get { return "Twofish"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Twofish not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + if (this.workingKey != null) + { + SetKey(this.workingKey); + } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + private void SetKey(byte[] key) + { + int[] k32e = new int[MAX_KEY_BITS/64]; // 4 + int[] k32o = new int[MAX_KEY_BITS/64]; // 4 + + int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4 + gSubKeys = new int[TOTAL_SUBKEYS]; + + if (k64Cnt < 1) + { + throw new ArgumentException("Key size less than 64 bits"); + } + + if (k64Cnt > 4) + { + throw new ArgumentException("Key size larger than 256 bits"); + } + + /* + * k64Cnt is the number of 8 byte blocks (64 chunks) + * that are in the input key. The input key is a + * maximum of 32 bytes ( 256 bits ), so the range + * for k64Cnt is 1..4 + */ + for (int i=0,p=0; i> 24); + A += B; + gSubKeys[i*2] = A; + A += B; + gSubKeys[i*2 + 1] = A << SK_ROTL | (int)((uint)A >> (32-SK_ROTL)); + } + + /* + * fully expand the table for speed + */ + int k0 = sBoxKeys[0]; + int k1 = sBoxKeys[1]; + int k2 = sBoxKeys[2]; + int k3 = sBoxKeys[3]; + int b0, b1, b2, b3; + gSBox = new int[4*MAX_KEY_BITS]; + for (int i=0; i>1) | x2 << 31; + x3 = (x3 << 1 | (int) ((uint)x3 >> 31)) ^ (t0 + 2*t1 + gSubKeys[k++]); + + t0 = Fe32_0(x2); + t1 = Fe32_3(x3); + x0 ^= t0 + t1 + gSubKeys[k++]; + x0 = (int) ((uint)x0 >>1) | x0 << 31; + x1 = (x1 << 1 | (int)((uint)x1 >> 31)) ^ (t0 + 2*t1 + gSubKeys[k++]); + } + + Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex); + Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4); + Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8); + Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12); + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * The input will be an exact multiple of our blocksize. + */ + private void DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN]; + int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1]; + int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2]; + int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3]; + + int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ; + int t0, t1; + for (int r = 0; r< ROUNDS ; r +=2) + { + t0 = Fe32_0(x2); + t1 = Fe32_3(x3); + x1 ^= t0 + 2*t1 + gSubKeys[k--]; + x0 = (x0 << 1 | (int)((uint) x0 >> 31)) ^ (t0 + t1 + gSubKeys[k--]); + x1 = (int) ((uint)x1 >>1) | x1 << 31; + + t0 = Fe32_0(x0); + t1 = Fe32_3(x1); + x3 ^= t0 + 2*t1 + gSubKeys[k--]; + x2 = (x2 << 1 | (int)((uint)x2 >> 31)) ^ (t0 + t1 + gSubKeys[k--]); + x3 = (int)((uint)x3 >>1) | x3 << 31; + } + + Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex); + Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4); + Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8); + Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12); + } + + /* + * TODO: This can be optimised and made cleaner by combining + * the functionality in this function and applying it appropriately + * to the creation of the subkeys during key setup. + */ + private int F32(int x, int[] k32) + { + int b0 = M_b0(x); + int b1 = M_b1(x); + int b2 = M_b2(x); + int b3 = M_b3(x); + int k0 = k32[0]; + int k1 = k32[1]; + int k2 = k32[2]; + int k3 = k32[3]; + + int result = 0; + switch (k64Cnt & 3) + { + case 1: + result = gMDS0[(P[P_01,b0] & 0xff) ^ M_b0(k0)] ^ + gMDS1[(P[P_11,b1] & 0xff) ^ M_b1(k0)] ^ + gMDS2[(P[P_21,b2] & 0xff) ^ M_b2(k0)] ^ + gMDS3[(P[P_31,b3] & 0xff) ^ M_b3(k0)]; + break; + case 0: /* 256 bits of key */ + b0 = (P[P_04,b0] & 0xff) ^ M_b0(k3); + b1 = (P[P_14,b1] & 0xff) ^ M_b1(k3); + b2 = (P[P_24,b2] & 0xff) ^ M_b2(k3); + b3 = (P[P_34,b3] & 0xff) ^ M_b3(k3); + goto case 3; + case 3: + b0 = (P[P_03,b0] & 0xff) ^ M_b0(k2); + b1 = (P[P_13,b1] & 0xff) ^ M_b1(k2); + b2 = (P[P_23,b2] & 0xff) ^ M_b2(k2); + b3 = (P[P_33,b3] & 0xff) ^ M_b3(k2); + goto case 2; + case 2: + result = + gMDS0[(P[P_01,(P[P_02,b0]&0xff)^M_b0(k1)]&0xff)^M_b0(k0)] ^ + gMDS1[(P[P_11,(P[P_12,b1]&0xff)^M_b1(k1)]&0xff)^M_b1(k0)] ^ + gMDS2[(P[P_21,(P[P_22,b2]&0xff)^M_b2(k1)]&0xff)^M_b2(k0)] ^ + gMDS3[(P[P_31,(P[P_32,b3]&0xff)^M_b3(k1)]&0xff)^M_b3(k0)]; + break; + } + return result; + } + + /** + * Use (12, 8) Reed-Solomon code over GF(256) to produce + * a key S-box 32-bit entity from 2 key material 32-bit + * entities. + * + * @param k0 first 32-bit entity + * @param k1 second 32-bit entity + * @return Remainder polynomial Generated using RS code + */ + private int RS_MDS_Encode(int k0, int k1) + { + int r = k1; + for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time + { + r = RS_rem(r); + } + r ^= k0; + for (int i=0 ; i < 4 ; i++) + { + r = RS_rem(r); + } + + return r; + } + + /** + * Reed-Solomon code parameters: (12,8) reversible code: + *

+ *

+        * G(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
+        * 
+ * where a = primitive root of field generator 0x14D + *

+ */ + private int RS_rem(int x) + { + int b = (int) (((uint)x >> 24) & 0xff); + int g2 = ((b << 1) ^ + ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff; + int g3 = ( (int)((uint)b >> 1) ^ + ((b & 0x01) != 0 ? (int)((uint)RS_GF_FDBK >> 1) : 0)) ^ g2 ; + return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b); + } + + private int LFSR1(int x) + { + return (x >> 1) ^ + (((x & 0x01) != 0) ? GF256_FDBK_2 : 0); + } + + private int LFSR2(int x) + { + return (x >> 2) ^ + (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^ + (((x & 0x01) != 0) ? GF256_FDBK_4 : 0); + } + + private int Mx_X(int x) + { + return x ^ LFSR2(x); + } // 5B + + private int Mx_Y(int x) + { + return x ^ LFSR1(x) ^ LFSR2(x); + } // EF + + private int M_b0(int x) + { + return x & 0xff; + } + + private int M_b1(int x) + { + return (int)((uint)x >> 8) & 0xff; + } + + private int M_b2(int x) + { + return (int)((uint)x >> 16) & 0xff; + } + + private int M_b3(int x) + { + return (int)((uint)x >> 24) & 0xff; + } + + private int Fe32_0(int x) + { + return gSBox[ 0x000 + 2*(x & 0xff) ] ^ + gSBox[ 0x001 + 2*((int)((uint)x >> 8) & 0xff) ] ^ + gSBox[ 0x200 + 2*((int)((uint)x >> 16) & 0xff) ] ^ + gSBox[ 0x201 + 2*((int)((uint)x >> 24) & 0xff) ]; + } + + private int Fe32_3(int x) + { + return gSBox[ 0x000 + 2*((int)((uint)x >> 24) & 0xff) ] ^ + gSBox[ 0x001 + 2*(x & 0xff) ] ^ + gSBox[ 0x200 + 2*((int)((uint)x >> 8) & 0xff) ] ^ + gSBox[ 0x201 + 2*((int)((uint)x >> 16) & 0xff) ]; + } + + private int BytesTo32Bits(byte[] b, int p) + { + return ((b[p] & 0xff) ) | + ((b[p+1] & 0xff) << 8) | + ((b[p+2] & 0xff) << 16) | + ((b[p+3] & 0xff) << 24); + } + + private void Bits32ToBytes(int inData, byte[] b, int offset) + { + b[offset] = (byte)inData; + b[offset + 1] = (byte)(inData >> 8); + b[offset + 2] = (byte)(inData >> 16); + b[offset + 3] = (byte)(inData >> 24); + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs.meta new file mode 100644 index 0000000..c526596 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/TwofishEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 55bc155aecc561841af464c77f3a4cf9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs new file mode 100644 index 0000000..ce0e6ae --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs @@ -0,0 +1,137 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class VmpcEngine + : IStreamCipher + { + /* + * variables to hold the state of the VMPC engine during encryption and + * decryption + */ + protected byte n = 0; + protected byte[] P = null; + protected byte s = 0; + + protected byte[] workingIV; + protected byte[] workingKey; + + public virtual string AlgorithmName + { + get { return "VMPC"; } + } + + /** + * initialise a VMPC cipher. + * + * @param forEncryption + * whether or not we are for encryption. + * @param params + * the parameters required to set up the cipher. + * @exception ArgumentException + * if the params argument is inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("VMPC Init parameters must include an IV"); + + ParametersWithIV ivParams = (ParametersWithIV) parameters; + + if (!(ivParams.Parameters is KeyParameter)) + throw new ArgumentException("VMPC Init parameters must include a key"); + + KeyParameter key = (KeyParameter)ivParams.Parameters; + + this.workingIV = ivParams.GetIV(); + + if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768) + throw new ArgumentException("VMPC requires 1 to 768 bytes of IV"); + + this.workingKey = key.GetKey(); + + InitKey(this.workingKey, this.workingIV); + } + + protected virtual void InitKey( + byte[] keyBytes, + byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + n = 0; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + // encryption + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + + // xor + output[i + outOff] = (byte) (input[i + inOff] ^ z); + } + } + + public virtual void Reset() + { + InitKey(this.workingKey, this.workingIV); + } + + public virtual byte ReturnByte( + byte input) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + // encryption + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + + // xor + return (byte) (input ^ z); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs.meta new file mode 100644 index 0000000..2e2bf36 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c29feaad92e27d4a8e258e0856100ec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs new file mode 100644 index 0000000..eae05c7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs @@ -0,0 +1,55 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class VmpcKsa3Engine + : VmpcEngine + { + public override string AlgorithmName + { + get { return "VMPC-KSA3"; } + } + + protected override void InitKey( + byte[] keyBytes, + byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + n = 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs.meta new file mode 100644 index 0000000..1938e75 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/VMPCKSA3Engine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 05ccf3686014dfd48981280c5cc5b3b9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs new file mode 100644 index 0000000..4df6902 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs @@ -0,0 +1,170 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An XTEA engine. + */ + public class XteaEngine + : IBlockCipher + { + private const int + rounds = 32, + block_size = 8, +// key_size = 16, + delta = unchecked((int) 0x9E3779B9); + + /* + * the expanded key array of 4 subkeys + */ + private uint[] _S = new uint[4], + _sum0 = new uint[32], + _sum1 = new uint[32]; + private bool _initialised, _forEncryption; + + /** + * Create an instance of the TEA encryption algorithm + * and set some defaults + */ + public XteaEngine() + { + _initialised = false; + } + + public virtual string AlgorithmName + { + get { return "XTEA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return block_size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + { + throw new ArgumentException("invalid parameter passed to TEA init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(inBytes, inOff, block_size, "input buffer too short"); + Check.OutputLength(outBytes, outOff, block_size, "output buffer too short"); + + return _forEncryption + ? encryptBlock(inBytes, inOff, outBytes, outOff) + : decryptBlock(inBytes, inOff, outBytes, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey( + byte[] key) + { + int i, j; + for (i = j = 0; i < 4; i++,j+=4) + { + _S[i] = Pack.BE_To_UInt32(key, j); + } + + for (i = j = 0; i < rounds; i++) + { + _sum0[i] = ((uint)j + _S[j & 3]); + j += delta; + _sum1[i] = ((uint)j + _S[j >> 11 & 3]); + } + } + + private int encryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + for (int i = 0; i < rounds; i++) + { + v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i]; + v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i]; + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + + private int decryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + for (int i = rounds-1; i >= 0; i--) + { + v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i]; + v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i]; + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs.meta new file mode 100644 index 0000000..30176cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/engines/XTEAEngine.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6051826ba9ea2a74bbbc2efd92b5d977 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators.meta new file mode 100644 index 0000000..5d64058 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a0959102436299e4eba93aa086cc6f46 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs new file mode 100644 index 0000000..5f87096 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs @@ -0,0 +1,42 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a basic Diffie-Hellman key pair generator. + * + * This generates keys consistent for use with the basic algorithm for + * Diffie-Hellman. + */ + public class DHBasicKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private DHKeyGenerationParameters param; + + public virtual void Init( + KeyGenerationParameters parameters) + { + this.param = (DHKeyGenerationParameters)parameters; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + DHParameters dhp = param.Parameters; + + BigInteger x = helper.CalculatePrivate(dhp, param.Random); + BigInteger y = helper.CalculatePublic(dhp, x); + + return new AsymmetricCipherKeyPair( + new DHPublicKeyParameters(y, dhp), + new DHPrivateKeyParameters(x, dhp)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs.meta new file mode 100644 index 0000000..2c13fd1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHBasicKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b7a4dfca0f6e38241991e7bc666269d0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs new file mode 100644 index 0000000..f79a9d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs @@ -0,0 +1,76 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + class DHKeyGeneratorHelper + { + internal static readonly DHKeyGeneratorHelper Instance = new DHKeyGeneratorHelper(); + + private DHKeyGeneratorHelper() + { + } + + internal BigInteger CalculatePrivate( + DHParameters dhParams, + SecureRandom random) + { + int limit = dhParams.L; + + if (limit != 0) + { + int minWeight = limit >> 2; + for (;;) + { + BigInteger x = new BigInteger(limit, random).SetBit(limit - 1); + if (WNafUtilities.GetNafWeight(x) >= minWeight) + { + return x; + } + } + } + + BigInteger min = BigInteger.Two; + int m = dhParams.M; + if (m != 0) + { + min = BigInteger.One.ShiftLeft(m - 1); + } + + BigInteger q = dhParams.Q; + if (q == null) + { + q = dhParams.P; + } + BigInteger max = q.Subtract(BigInteger.Two); + + { + int minWeight = max.BitLength >> 2; + for (;;) + { + BigInteger x = BigIntegers.CreateRandomInRange(min, max, random); + if (WNafUtilities.GetNafWeight(x) >= minWeight) + { + return x; + } + } + } + } + + internal BigInteger CalculatePublic( + DHParameters dhParams, + BigInteger x) + { + return dhParams.G.ModPow(x, dhParams.P); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs.meta new file mode 100644 index 0000000..4c0b958 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyGeneratorHelper.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 98272963180479a45b4495273799bb5c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs new file mode 100644 index 0000000..f093251 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs @@ -0,0 +1,42 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a Diffie-Hellman key pair generator. + * + * This generates keys consistent for use in the MTI/A0 key agreement protocol + * as described in "Handbook of Applied Cryptography", Pages 516-519. + */ + public class DHKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private DHKeyGenerationParameters param; + + public virtual void Init( + KeyGenerationParameters parameters) + { + this.param = (DHKeyGenerationParameters)parameters; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + DHParameters dhp = param.Parameters; + + BigInteger x = helper.CalculatePrivate(dhp, param.Random); + BigInteger y = helper.CalculatePublic(dhp, x); + + return new AsymmetricCipherKeyPair( + new DHPublicKeyParameters(y, dhp), + new DHPrivateKeyParameters(x, dhp)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs.meta new file mode 100644 index 0000000..639a6cf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c6dd5179b7382f74dbd970c11817e3b8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs new file mode 100644 index 0000000..bc03123 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs @@ -0,0 +1,160 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + internal class DHParametersHelper + { + private static readonly BigInteger Six = BigInteger.ValueOf(6); + + private static readonly int[][] primeLists = BigInteger.primeLists; + private static readonly int[] primeProducts = BigInteger.primeProducts; + private static readonly BigInteger[] BigPrimeProducts = ConstructBigPrimeProducts(primeProducts); + + private static BigInteger[] ConstructBigPrimeProducts(int[] primeProducts) + { + BigInteger[] bpp = new BigInteger[primeProducts.Length]; + for (int i = 0; i < bpp.Length; ++i) + { + bpp[i] = BigInteger.ValueOf(primeProducts[i]); + } + return bpp; + } + + /* + * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} + * + * (see: Handbook of Applied Cryptography 4.86) + */ + internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random) + { + BigInteger p, q; + int qLength = size - 1; + int minWeight = size >> 2; + + if (size <= 32) + { + for (;;) + { + q = new BigInteger(qLength, 2, random); + + p = q.ShiftLeft(1).Add(BigInteger.One); + + if (!p.IsProbablePrime(certainty, true)) + continue; + + if (certainty > 2 && !q.IsProbablePrime(certainty, true)) + continue; + + break; + } + } + else + { + // Note: Modified from Java version for speed + for (;;) + { + q = new BigInteger(qLength, 0, random); + + retry: + for (int i = 0; i < primeLists.Length; ++i) + { + int test = q.Remainder(BigPrimeProducts[i]).IntValue; + + if (i == 0) + { + int rem3 = test % 3; + if (rem3 != 2) + { + int diff = 2 * rem3 + 2; + q = q.Add(BigInteger.ValueOf(diff)); + test = (test + diff) % primeProducts[i]; + } + } + + int[] primeList = primeLists[i]; + for (int j = 0; j < primeList.Length; ++j) + { + int prime = primeList[j]; + int qRem = test % prime; + if (qRem == 0 || qRem == (prime >> 1)) + { + q = q.Add(Six); + goto retry; + } + } + } + + if (q.BitLength != qLength) + continue; + + if (!q.RabinMillerTest(2, random, true)) + continue; + + p = q.ShiftLeft(1).Add(BigInteger.One); + + if (!p.RabinMillerTest(certainty, random, true)) + continue; + + if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random, true)) + continue; + + /* + * Require a minimum weight of the NAF representation, since low-weight primes may be + * weak against a version of the number-field-sieve for the discrete-logarithm-problem. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtilities.GetNafWeight(p) < minWeight) + continue; + + break; + } + } + + return new BigInteger[] { p, q }; + } + + /* + * Select a high order element of the multiplicative group Zp* + * + * p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes) + */ + internal static BigInteger SelectGenerator(BigInteger p, BigInteger q, SecureRandom random) + { + BigInteger pMinusTwo = p.Subtract(BigInteger.Two); + BigInteger g; + + /* + * (see: Handbook of Applied Cryptography 4.80) + */ +// do +// { +// g = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); +// } +// while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One) +// || g.ModPow(q, p).Equals(BigInteger.One)); + + /* + * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81) + */ + do + { + BigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); + + g = h.ModPow(BigInteger.Two, p); + } + while (g.Equals(BigInteger.One)); + + return g; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs.meta new file mode 100644 index 0000000..1454d46 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DHParametersHelper.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d4fdec6c91ff77e41add37910a845fa0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs new file mode 100644 index 0000000..dc49e5b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs @@ -0,0 +1,76 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a DSA key pair generator. + * + * This Generates DSA keys in line with the method described + * in FIPS 186-3 B.1 FFC Key Pair Generation. + */ + public class DsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private static readonly BigInteger One = BigInteger.One; + + private DsaKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + // Note: If we start accepting instances of KeyGenerationParameters, + // must apply constraint checking on strength (see DsaParametersGenerator.Init) + + this.param = (DsaKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DsaParameters dsaParams = param.Parameters; + + BigInteger x = GeneratePrivateKey(dsaParams.Q, param.Random); + BigInteger y = CalculatePublicKey(dsaParams.P, dsaParams.G, x); + + return new AsymmetricCipherKeyPair( + new DsaPublicKeyParameters(y, dsaParams), + new DsaPrivateKeyParameters(x, dsaParams)); + } + + private static BigInteger GeneratePrivateKey(BigInteger q, SecureRandom random) + { + // B.1.2 Key Pair Generation by Testing Candidates + int minWeight = q.BitLength >> 2; + for (;;) + { + // TODO Prefer this method? (change test cases that used fixed random) + // B.1.1 Key Pair Generation Using Extra Random Bits + //BigInteger x = new BigInteger(q.BitLength + 64, random).Mod(q.Subtract(One)).Add(One); + + BigInteger x = BigIntegers.CreateRandomInRange(One, q.Subtract(One), random); + if (WNafUtilities.GetNafWeight(x) >= minWeight) + { + return x; + } + } + } + + private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x) + { + return g.ModPow(x, p); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs.meta new file mode 100644 index 0000000..986a92e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/DsaKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 81ed675e8e1609d468d4e8957e891e0e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs new file mode 100644 index 0000000..b0d3261 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs @@ -0,0 +1,166 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class ECKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private readonly string algorithm; + + private ECDomainParameters parameters; + private DerObjectIdentifier publicKeyParamSet; + private SecureRandom random; + + public ECKeyPairGenerator() + : this("EC") + { + } + + public ECKeyPairGenerator( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + this.algorithm = ECKeyParameters.VerifyAlgorithmName(algorithm); + } + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters is ECKeyGenerationParameters) + { + ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters; + + this.publicKeyParamSet = ecP.PublicKeyParamSet; + this.parameters = ecP.DomainParameters; + } + else + { + DerObjectIdentifier oid; + switch (parameters.Strength) + { + case 192: + oid = X9ObjectIdentifiers.Prime192v1; + break; + case 224: + oid = SecObjectIdentifiers.SecP224r1; + break; + case 239: + oid = X9ObjectIdentifiers.Prime239v1; + break; + case 256: + oid = X9ObjectIdentifiers.Prime256v1; + break; + case 384: + oid = SecObjectIdentifiers.SecP384r1; + break; + case 521: + oid = SecObjectIdentifiers.SecP521r1; + break; + default: + throw new InvalidParameterException("unknown key size."); + } + + X9ECParameters ecps = FindECCurveByOid(oid); + + this.publicKeyParamSet = oid; + this.parameters = new ECDomainParameters( + ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed()); + } + + this.random = parameters.Random; + + if (this.random == null) + { + this.random = new SecureRandom(); + } + } + + /** + * Given the domain parameters this routine generates an EC key + * pair in accordance with X9.62 section 5.2.1 pages 26, 27. + */ + public AsymmetricCipherKeyPair GenerateKeyPair() + { + BigInteger n = parameters.N; + BigInteger d; + int minWeight = n.BitLength >> 2; + + for (;;) + { + d = new BigInteger(n.BitLength, random); + + if (d.CompareTo(BigInteger.Two) < 0 || d.CompareTo(n) >= 0) + continue; + + if (WNafUtilities.GetNafWeight(d) < minWeight) + continue; + + break; + } + + ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d); + + if (publicKeyParamSet != null) + { + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(algorithm, q, publicKeyParamSet), + new ECPrivateKeyParameters(algorithm, d, publicKeyParamSet)); + } + + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(algorithm, q, parameters), + new ECPrivateKeyParameters(algorithm, d, parameters)); + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + + internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid) + { + // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) + + X9ECParameters ecP = CustomNamedCurves.GetByOid(oid); + if (ecP == null) + { + ecP = ECNamedCurveTable.GetByOid(oid); + } + return ecP; + } + + internal static ECPublicKeyParameters GetCorrespondingPublicKey( + ECPrivateKeyParameters privKey) + { + ECDomainParameters ec = privKey.Parameters; + ECPoint q = new FixedPointCombMultiplier().Multiply(ec.G, privKey.D); + + if (privKey.PublicKeyParamSet != null) + { + return new ECPublicKeyParameters(privKey.AlgorithmName, q, privKey.PublicKeyParamSet); + } + + return new ECPublicKeyParameters(privKey.AlgorithmName, q, ec); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs.meta new file mode 100644 index 0000000..6431937 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ECKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dd6193d5b658f3549963a15501652b67 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs new file mode 100644 index 0000000..136c3d9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a ElGamal key pair generator. + *

+ * This Generates keys consistent for use with ElGamal as described in + * page 164 of "Handbook of Applied Cryptography".

+ */ + public class ElGamalKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private ElGamalKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + this.param = (ElGamalKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + ElGamalParameters egp = param.Parameters; + DHParameters dhp = new DHParameters(egp.P, egp.G, null, 0, egp.L); + + BigInteger x = helper.CalculatePrivate(dhp, param.Random); + BigInteger y = helper.CalculatePublic(dhp, x); + + return new AsymmetricCipherKeyPair( + new ElGamalPublicKeyParameters(y, egp), + new ElGamalPrivateKeyParameters(x, egp)); + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs.meta new file mode 100644 index 0000000..6b292db --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/ElGamalKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0d3c646aa86666e4ca77bdb7f900d2df +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs new file mode 100644 index 0000000..a12c11f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs @@ -0,0 +1,120 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /// + /// Generates keys for the Poly1305 MAC. + /// + /// + /// Poly1305 keys are 256 bit keys consisting of a 128 bit secret key used for the underlying block + /// cipher followed by a 128 bit {@code r} value used for the polynomial portion of the Mac.
+ /// The {@code r} value has a specific format with some bits required to be cleared, resulting in an + /// effective 106 bit key.
+ /// A separately generated 256 bit key can be modified to fit the Poly1305 key format by using the + /// {@link #clamp(byte[])} method to clear the required bits. + ///
+ /// + public class Poly1305KeyGenerator + : CipherKeyGenerator + { + private const byte R_MASK_LOW_2 = (byte)0xFC; + private const byte R_MASK_HIGH_4 = (byte)0x0F; + + /// + /// Initialises the key generator. + /// + /// + /// Poly1305 keys are always 256 bits, so the key length in the provided parameters is ignored. + /// + protected override void engineInit(KeyGenerationParameters param) + { + // Poly1305 keys are always 256 bits + this.random = param.Random; + this.strength = 32; + } + + /// + /// Generates a 256 bit key in the format required for Poly1305 - e.g. + /// k[0] ... k[15], r[0] ... r[15] with the required bits in r cleared + /// as per . + /// + protected override byte[] engineGenerateKey() + { + byte[] key = base.engineGenerateKey(); + Clamp(key); + return key; + } + + /// + /// Modifies an existing 32 byte key value to comply with the requirements of the Poly1305 key by + /// clearing required bits in the r (second 16 bytes) portion of the key.
+ /// Specifically: + ///
    + ///
  • r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})
  • + ///
  • r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252})
  • + ///
+ ///
+ /// a 32 byte key value k[0] ... k[15], r[0] ... r[15] + public static void Clamp(byte[] key) + { + /* + * Key is k[0] ... k[15], r[0] ... r[15] as per poly1305_aes_clamp in ref impl. + */ + if (key.Length != 32) + throw new ArgumentException("Poly1305 key must be 256 bits."); + + /* + * r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15}) + */ + key[3] &= R_MASK_HIGH_4; + key[7] &= R_MASK_HIGH_4; + key[11] &= R_MASK_HIGH_4; + key[15] &= R_MASK_HIGH_4; + + /* + * r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252}). + */ + key[4] &= R_MASK_LOW_2; + key[8] &= R_MASK_LOW_2; + key[12] &= R_MASK_LOW_2; + } + + /// + /// Checks a 32 byte key for compliance with the Poly1305 key requirements, e.g. + /// k[0] ... k[15], r[0] ... r[15] with the required bits in r cleared + /// as per . + /// + /// Key. + /// if the key is of the wrong length, or has invalid bits set + /// in the r portion of the key. + public static void CheckKey(byte[] key) + { + if (key.Length != 32) + throw new ArgumentException("Poly1305 key must be 256 bits."); + + CheckMask(key[3], R_MASK_HIGH_4); + CheckMask(key[7], R_MASK_HIGH_4); + CheckMask(key[11], R_MASK_HIGH_4); + CheckMask(key[15], R_MASK_HIGH_4); + + CheckMask(key[4], R_MASK_LOW_2); + CheckMask(key[8], R_MASK_LOW_2); + CheckMask(key[12], R_MASK_LOW_2); + } + + private static void CheckMask(byte b, byte mask) + { + if ((b & (~mask)) != 0) + throw new ArgumentException("Invalid format for r portion of Poly1305 key."); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs.meta new file mode 100644 index 0000000..b683858 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/Poly1305KeyGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5da95a369948e924eaed42d18e10729a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs new file mode 100644 index 0000000..5b2a2cb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs @@ -0,0 +1,167 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * an RSA key pair generator. + */ + public class RsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private static readonly int[] SPECIAL_E_VALUES = new int[]{ 3, 5, 17, 257, 65537 }; + private static readonly int SPECIAL_E_HIGHEST = SPECIAL_E_VALUES[SPECIAL_E_VALUES.Length - 1]; + private static readonly int SPECIAL_E_BITS = BigInteger.ValueOf(SPECIAL_E_HIGHEST).BitLength; + + protected static readonly BigInteger One = BigInteger.One; + protected static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001); + protected const int DefaultTests = 100; + + protected RsaKeyGenerationParameters parameters; + + public virtual void Init( + KeyGenerationParameters parameters) + { + if (parameters is RsaKeyGenerationParameters) + { + this.parameters = (RsaKeyGenerationParameters)parameters; + } + else + { + this.parameters = new RsaKeyGenerationParameters( + DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests); + } + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + for (;;) + { + // + // p and q values should have a length of half the strength in bits + // + int strength = parameters.Strength; + int pBitlength = (strength + 1) / 2; + int qBitlength = strength - pBitlength; + int mindiffbits = strength / 3; + int minWeight = strength >> 2; + + BigInteger e = parameters.PublicExponent; + + // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) + // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") + + BigInteger p = ChooseRandomPrime(pBitlength, e); + BigInteger q, n; + + // + // generate a modulus of the required length + // + for (;;) + { + q = ChooseRandomPrime(qBitlength, e); + + // p and q should not be too close together (or equal!) + BigInteger diff = q.Subtract(p).Abs(); + if (diff.BitLength < mindiffbits) + continue; + + // + // calculate the modulus + // + n = p.Multiply(q); + + if (n.BitLength != strength) + { + // + // if we get here our primes aren't big enough, make the largest + // of the two p and try again + // + p = p.Max(q); + continue; + } + + /* + * Require a minimum weight of the NAF representation, since low-weight composites may + * be weak against a version of the number-field-sieve for factoring. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtilities.GetNafWeight(n) < minWeight) + { + p = ChooseRandomPrime(pBitlength, e); + continue; + } + + break; + } + + if (p.CompareTo(q) < 0) + { + BigInteger tmp = p; + p = q; + q = tmp; + } + + BigInteger pSub1 = p.Subtract(One); + BigInteger qSub1 = q.Subtract(One); + //BigInteger phi = pSub1.Multiply(qSub1); + BigInteger gcd = pSub1.Gcd(qSub1); + BigInteger lcm = pSub1.Divide(gcd).Multiply(qSub1); + + // + // calculate the private exponent + // + BigInteger d = e.ModInverse(lcm); + + if (d.BitLength <= qBitlength) + continue; + + // + // calculate the CRT factors + // + BigInteger dP = d.Remainder(pSub1); + BigInteger dQ = d.Remainder(qSub1); + BigInteger qInv = q.ModInverse(p); + + return new AsymmetricCipherKeyPair( + new RsaKeyParameters(false, n, e), + new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + } + } + + /// Choose a random prime value for use with RSA + /// the bit-length of the returned prime + /// the RSA public exponent + /// a prime p, with (p-1) relatively prime to e + protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e) + { + bool eIsKnownOddPrime = (e.BitLength <= SPECIAL_E_BITS) && Arrays.Contains(SPECIAL_E_VALUES, e.IntValue); + + for (;;) + { + BigInteger p = new BigInteger(bitlength, 1, parameters.Random); + + if (p.Mod(e).Equals(One)) + continue; + + if (!p.IsProbablePrime(parameters.Certainty, true)) + continue; + + if (!eIsKnownOddPrime && !e.Gcd(p.Subtract(One)).Equals(One)) + continue; + + return p; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs.meta new file mode 100644 index 0000000..238a15f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/generators/RsaKeyPairGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d11ab5e345ab24647ab0356dc7f92e64 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs.meta new file mode 100644 index 0000000..ecf3925 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3d929d360f5bba5429128c0fce7c78e9 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs new file mode 100644 index 0000000..6c11ef3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs @@ -0,0 +1,261 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * CMAC - as specified at www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html + *

+ * CMAC is analogous to OMAC1 - see also en.wikipedia.org/wiki/CMAC + *

+ * CMAC is a NIST recomendation - see + * csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf + *

+ * CMAC/OMAC1 is a blockcipher-based message authentication code designed and + * analyzed by Tetsu Iwata and Kaoru Kurosawa. + *

+ * CMAC/OMAC1 is a simple variant of the CBC MAC (Cipher Block Chaining Message + * Authentication Code). OMAC stands for One-Key CBC MAC. + *

+ * It supports 128- or 64-bits block ciphers, with any key size, and returns + * a MAC with dimension less or equal to the block size of the underlying + * cipher. + *

+ */ + public class CMac + : IMac + { + private const byte CONSTANT_128 = (byte)0x87; + private const byte CONSTANT_64 = (byte)0x1b; + + private byte[] ZEROES; + + private byte[] mac; + + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + + private int macSize; + + private byte[] L, Lu, Lu2; + + /** + * create a standard MAC based on a CBC block cipher (64 or 128 bit block). + * This will produce an authentication code the length of the block size + * of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CMac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8 and @lt;= 128. + */ + public CMac( + IBlockCipher cipher, + int macSizeInBits) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (macSizeInBits > (cipher.GetBlockSize() * 8)) + { + throw new ArgumentException( + "MAC size must be less or equal to " + + (cipher.GetBlockSize() * 8)); + } + + if (cipher.GetBlockSize() != 8 && cipher.GetBlockSize() != 16) + { + throw new ArgumentException( + "Block size must be either 64 or 128 bits"); + } + + this.cipher = new CbcBlockCipher(cipher); + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + + buf = new byte[cipher.GetBlockSize()]; + + ZEROES = new byte[cipher.GetBlockSize()]; + + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + private static int ShiftLeft(byte[] block, byte[] output) + { + int i = block.Length; + uint bit = 0; + while (--i >= 0) + { + uint b = block[i]; + output[i] = (byte)((b << 1) | bit); + bit = (b >> 7) & 1; + } + return (int)bit; + } + + private static byte[] DoubleLu(byte[] input) + { + byte[] ret = new byte[input.Length]; + int carry = ShiftLeft(input, ret); + int xor = input.Length == 16 ? CONSTANT_128 : CONSTANT_64; + + /* + * NOTE: This construction is an attempt at a constant-time implementation. + */ + ret[input.Length - 1] ^= (byte)(xor >> ((1 - carry) << 3)); + + return ret; + } + + public void Init( + ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + cipher.Init(true, parameters); + + //initializes the L, Lu, Lu2 numbers + L = new byte[ZEROES.Length]; + cipher.ProcessBlock(ZEROES, 0, L, 0); + Lu = DoubleLu(L); + Lu2 = DoubleLu(Lu); + } + else if (parameters != null) + { + // CMAC mode does not permit IV to underlying CBC mode + throw new ArgumentException("CMac mode only permits key to be set.", "parameters"); + } + + Reset(); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] inBytes, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(inBytes, inOff, buf, bufOff, gapLen); + + cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + cipher.ProcessBlock(inBytes, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(inBytes, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] outBytes, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + byte[] lu; + if (bufOff == blockSize) + { + lu = Lu; + } + else + { + new ISO7816d4Padding().AddPadding(buf, bufOff); + lu = Lu2; + } + + for (int i = 0; i < mac.Length; i++) + { + buf[i] ^= lu[i]; + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + Array.Copy(mac, 0, outBytes, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + /* + * clean the buffer. + */ + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + /* + * Reset the underlying cipher. + */ + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs.meta new file mode 100644 index 0000000..1ee3ef6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 147ba6faf8894394bb4ede3ad60aa6ca +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs new file mode 100644 index 0000000..a058c98 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs @@ -0,0 +1,213 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * standard CBC Block Cipher MAC - if no padding is specified the default of + * pad of zeroes is used. + */ + public class CbcBlockCipherMac + : IMac + { + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + + /** + * create a standard MAC based on a CBC block cipher. This will produce an + * authentication code half the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CbcBlockCipherMac( + IBlockCipher cipher) + : this(cipher, (cipher.GetBlockSize() * 8) / 2, null) + { + } + + /** + * create a standard MAC based on a CBC block cipher. This will produce an + * authentication code half the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used to complete the last block. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, (cipher.GetBlockSize() * 8) / 2, padding) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CBC mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + int macSizeInBits) + : this(cipher, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CBC mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding the padding to be used to complete the last block. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + this.cipher = new CbcBlockCipher(cipher); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + cipher.ProcessBlock(buf, 0, buf, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + cipher.ProcessBlock(input, inOff, buf, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + if (padding == null) + { + // pad with zeroes + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + } + else + { + if (bufOff == blockSize) + { + cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + } + + cipher.ProcessBlock(buf, 0, buf, 0); + + Array.Copy(buf, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + // Clear the buffer. + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + // Reset the underlying cipher. + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs.meta new file mode 100644 index 0000000..09aa786 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CbcBlockCipherMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 85bfc6f3c7c846946b5e385bca692356 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs new file mode 100644 index 0000000..5179128 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs @@ -0,0 +1,372 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. + */ + class MacCFBBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public MacCFBBlockCipher( + IBlockCipher cipher, + int bitBlockSize) + { + this.cipher = cipher; + this.blockSize = bitBlockSize / 8; + + this.IV = new byte[cipher.GetBlockSize()]; + this.cfbV = new byte[cipher.GetBlockSize()]; + this.cfbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(true, parameters); + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + throw new DataLengthException("input buffer too short"); + + if ((outOff + blockSize) > outBytes.Length) + throw new DataLengthException("output buffer too short"); + + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + + // + // XOR the cfbV with the plaintext producing the cipher text + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(outBytes, outOff, cfbV, cfbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + IV.CopyTo(cfbV, 0); + + cipher.Reset(); + } + + public void GetMacBlock( + byte[] mac) + { + cipher.ProcessBlock(cfbV, 0, mac, 0); + } + } + + public class CfbBlockCipherMac + : IMac + { + private byte[] mac; + private byte[] Buffer; + private int bufOff; + private MacCFBBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + + /** + * create a standard MAC based on a CFB block cipher. This will produce an + * authentication code half the length of the block size of the cipher, with + * the CFB mode set to 8 bits. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CfbBlockCipherMac( + IBlockCipher cipher) + : this(cipher, 8, (cipher.GetBlockSize() * 8) / 2, null) + { + } + + /** + * create a standard MAC based on a CFB block cipher. This will produce an + * authentication code half the length of the block size of the cipher, with + * the CFB mode set to 8 bits. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, 8, (cipher.GetBlockSize() * 8) / 2, padding) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CFB mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param cfbBitSize the size of an output block produced by the CFB mode. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + int cfbBitSize, + int macSizeInBits) + : this(cipher, cfbBitSize, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CFB mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param cfbBitSize the size of an output block produced by the CFB mode. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding a padding to be used. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + int cfbBitSize, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + mac = new byte[cipher.GetBlockSize()]; + + this.cipher = new MacCFBBlockCipher(cipher, cfbBitSize); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + Buffer = new byte[this.cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == Buffer.Length) + { + cipher.ProcessBlock(Buffer, 0, mac, 0); + bufOff = 0; + } + + Buffer[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, Buffer, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(Buffer, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, Buffer, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + // pad with zeroes + if (this.padding == null) + { + while (bufOff < blockSize) + { + Buffer[bufOff++] = 0; + } + } + else + { + padding.AddPadding(Buffer, bufOff); + } + + cipher.ProcessBlock(Buffer, 0, mac, 0); + + cipher.GetMacBlock(mac); + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + // Clear the buffer. + Array.Clear(Buffer, 0, Buffer.Length); + bufOff = 0; + + // Reset the underlying cipher. + cipher.Reset(); + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs.meta new file mode 100644 index 0000000..e1801d1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/CfbBlockCipherMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3fc42df051ecc104680ab4efa67051c1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs new file mode 100644 index 0000000..6e124a6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs @@ -0,0 +1,301 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implementation of GOST 28147-89 MAC + */ + public class Gost28147Mac : IMac + { + private const int blockSize = 8; + private const int macSize = 4; + private int bufOff; + private byte[] buf; + private byte[] mac; + private bool firstStep = true; + private int[] workingKey; + + // + // This is default S-box - E_A. + private byte[] S = + { + 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, + 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, + 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, + 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, + 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, + 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, + 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, + 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 + }; + + public Gost28147Mac() + { + mac = new byte[blockSize]; + buf = new byte[blockSize]; + bufOff = 0; + } + + private static int[] generateWorkingKey( + byte[] userKey) + { + if (userKey.Length != 32) + throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); + + int[] key = new int[8]; + for(int i=0; i!=8; i++) + { + key[i] = bytesToint(userKey,i*4); + } + + return key; + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + buf = new byte[blockSize]; + if (parameters is ParametersWithSBox) + { + ParametersWithSBox param = (ParametersWithSBox)parameters; + + // + // Set the S-Box + // + param.GetSBox().CopyTo(this.S, 0); + + // + // set key if there is one + // + if (param.Parameters != null) + { + workingKey = generateWorkingKey(((KeyParameter)param.Parameters).GetKey()); + } + } + else if (parameters is KeyParameter) + { + workingKey = generateWorkingKey(((KeyParameter)parameters).GetKey()); + } + else + { + throw new ArgumentException("invalid parameter passed to Gost28147 init - " + + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters)); + } + } + + public string AlgorithmName + { + get { return "Gost28147Mac"; } + } + + public int GetMacSize() + { + return macSize; + } + + private int gost28147_mainStep(int n1, int key) + { + int cm = (key + n1); // CM1 + + // S-box replacing + + int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); + om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); + om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); + om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); + om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); + om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); + om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); + om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); + +// return om << 11 | om >>> (32-11); // 11-leftshift + int omLeft = om << 11; + int omRight = (int)(((uint) om) >> (32 - 11)); // Note: Casts required to get unsigned bit rotation + + return omLeft | omRight; + } + + private void gost28147MacFunc( + int[] workingKey, + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int N1, N2, tmp; //tmp -> for saving N1 + N1 = bytesToint(input, inOff); + N2 = bytesToint(input, inOff + 4); + + for (int k = 0; k < 2; k++) // 1-16 steps + { + for (int j = 0; j < 8; j++) + { + tmp = N1; + N1 = N2 ^ gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + + intTobytes(N1, output, outOff); + intTobytes(N2, output, outOff + 4); + } + + //array of bytes to type int + private static int bytesToint( + byte[] input, + int inOff) + { + return (int)((input[inOff + 3] << 24) & 0xff000000) + ((input[inOff + 2] << 16) & 0xff0000) + + ((input[inOff + 1] << 8) & 0xff00) + (input[inOff] & 0xff); + } + + //int to array of bytes + private static void intTobytes( + int num, + byte[] output, + int outOff) + { + output[outOff + 3] = (byte)(num >> 24); + output[outOff + 2] = (byte)(num >> 16); + output[outOff + 1] = (byte)(num >> 8); + output[outOff] = (byte)num; + } + + private static byte[] CM5func( + byte[] buf, + int bufOff, + byte[] mac) + { + byte[] sum = new byte[buf.Length - bufOff]; + + Array.Copy(buf, bufOff, sum, 0, mac.Length); + + for (int i = 0; i != mac.Length; i++) + { + sum[i] = (byte)(sum[i] ^ mac[i]); + } + + return sum; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + sumbuf = CM5func(input, inOff, mac); + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + //padding with zero + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + Array.Copy(mac, (mac.Length/2)-macSize, output, outOff, macSize); + + Reset(); + + return macSize; + } + + public void Reset() + { + // Clear the buffer. + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + firstStep = true; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs.meta new file mode 100644 index 0000000..49779e8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/GOST28147Mac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a1a6f75281759774dbe9f4409f241a2b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs new file mode 100644 index 0000000..45c024f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs @@ -0,0 +1,158 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * HMAC implementation based on RFC2104 + * + * H(K XOR opad, H(K XOR ipad, text)) + */ + public class HMac + : IMac + { + private const byte IPAD = (byte)0x36; + private const byte OPAD = (byte)0x5C; + + private readonly IDigest digest; + private readonly int digestSize; + private readonly int blockLength; + private IMemoable ipadState; + private IMemoable opadState; + + private readonly byte[] inputPad; + private readonly byte[] outputBuf; + + public HMac(IDigest digest) + { + this.digest = digest; + this.digestSize = digest.GetDigestSize(); + this.blockLength = digest.GetByteLength(); + this.inputPad = new byte[blockLength]; + this.outputBuf = new byte[blockLength + digestSize]; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "/HMAC"; } + } + + public virtual IDigest GetUnderlyingDigest() + { + return digest; + } + + public virtual void Init(ICipherParameters parameters) + { + digest.Reset(); + + byte[] key = ((KeyParameter)parameters).GetKey(); + int keyLength = key.Length; + + if (keyLength > blockLength) + { + digest.BlockUpdate(key, 0, keyLength); + digest.DoFinal(inputPad, 0); + + keyLength = digestSize; + } + else + { + Array.Copy(key, 0, inputPad, 0, keyLength); + } + + Array.Clear(inputPad, keyLength, blockLength - keyLength); + Array.Copy(inputPad, 0, outputBuf, 0, blockLength); + + XorPad(inputPad, blockLength, IPAD); + XorPad(outputBuf, blockLength, OPAD); + + if (digest is IMemoable) + { + opadState = ((IMemoable)digest).Copy(); + + ((IDigest)opadState).BlockUpdate(outputBuf, 0, blockLength); + } + + digest.BlockUpdate(inputPad, 0, inputPad.Length); + + if (digest is IMemoable) + { + ipadState = ((IMemoable)digest).Copy(); + } + } + + public virtual int GetMacSize() + { + return digestSize; + } + + public virtual void Update(byte input) + { + digest.Update(input); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + digest.BlockUpdate(input, inOff, len); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + digest.DoFinal(outputBuf, blockLength); + + if (opadState != null) + { + ((IMemoable)digest).Reset(opadState); + digest.BlockUpdate(outputBuf, blockLength, digest.GetDigestSize()); + } + else + { + digest.BlockUpdate(outputBuf, 0, outputBuf.Length); + } + + int len = digest.DoFinal(output, outOff); + + Array.Clear(outputBuf, blockLength, digestSize); + + if (ipadState != null) + { + ((IMemoable)digest).Reset(ipadState); + } + else + { + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } + + return len; + } + + /** + * Reset the mac generator. + */ + public virtual void Reset() + { + // Reset underlying digest + digest.Reset(); + + // Initialise the digest + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } + + private static void XorPad(byte[] pad, int len, byte n) + { + for (int i = 0; i < len; ++i) + { + pad[i] ^= n; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs.meta new file mode 100644 index 0000000..0335384 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/HMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ff9c8a587cf6ee843b4bc5fadb67a117 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs new file mode 100644 index 0000000..b34d652 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs @@ -0,0 +1,279 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * DES based CBC Block Cipher MAC according to ISO9797, algorithm 3 (ANSI X9.19 Retail MAC) + * + * This could as well be derived from CBCBlockCipherMac, but then the property mac in the base + * class must be changed to protected + */ + public class ISO9797Alg3Mac : IMac + { + private byte[] mac; + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + private KeyParameter lastKey2; + private KeyParameter lastKey3; + + /** + * create a Retail-MAC based on a CBC block cipher. This will produce an + * authentication code of the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. This must + * be DESEngine. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8, null) + { + } + + /** + * create a Retail-MAC based on a CBC block cipher. This will produce an + * authentication code of the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used to complete the last block. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, cipher.GetBlockSize() * 8, padding) + { + } + + /** + * create a Retail-MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses single DES CBC mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + int macSizeInBits) + : this(cipher, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses single DES CBC mode as the basis for the + * MAC generation. The final block is decrypted and then encrypted using the + * middle and right part of the key. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding the padding to be used to complete the last block. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (!(cipher is DesEngine)) + throw new ArgumentException("cipher must be instance of DesEngine"); + + this.cipher = new CbcBlockCipher(cipher); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return "ISO9797Alg3"; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + if (!(parameters is KeyParameter || parameters is ParametersWithIV)) + throw new ArgumentException("parameters must be an instance of KeyParameter or ParametersWithIV"); + + // KeyParameter must contain a double or triple length DES key, + // however the underlying cipher is a single DES. The middle and + // right key are used only in the final step. + + KeyParameter kp; + if (parameters is KeyParameter) + { + kp = (KeyParameter)parameters; + } + else + { + kp = (KeyParameter)((ParametersWithIV)parameters).Parameters; + } + + KeyParameter key1; + byte[] keyvalue = kp.GetKey(); + + if (keyvalue.Length == 16) + { // Double length DES key + key1 = new KeyParameter(keyvalue, 0, 8); + this.lastKey2 = new KeyParameter(keyvalue, 8, 8); + this.lastKey3 = key1; + } + else if (keyvalue.Length == 24) + { // Triple length DES key + key1 = new KeyParameter(keyvalue, 0, 8); + this.lastKey2 = new KeyParameter(keyvalue, 8, 8); + this.lastKey3 = new KeyParameter(keyvalue, 16, 8); + } + else + { + throw new ArgumentException("Key must be either 112 or 168 bit long"); + } + + if (parameters is ParametersWithIV) + { + cipher.Init(true, new ParametersWithIV(key1, ((ParametersWithIV)parameters).GetIV())); + } + else + { + cipher.Init(true, key1); + } + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + if (padding == null) + { + // pad with zeroes + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + } + else + { + if (bufOff == blockSize) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + // Added to code from base class + DesEngine deseng = new DesEngine(); + + deseng.Init(false, this.lastKey2); + deseng.ProcessBlock(mac, 0, mac, 0); + + deseng.Init(true, this.lastKey3); + deseng.ProcessBlock(mac, 0, mac, 0); + // **** + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + // reset the underlying cipher. + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs.meta new file mode 100644 index 0000000..42a8b6d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/ISO9797Alg3Mac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ba1bf157d949c9a40b850fc633d073cb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs new file mode 100644 index 0000000..d1f855a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs @@ -0,0 +1,299 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + + /// + /// Poly1305 message authentication code, designed by D. J. Bernstein. + /// + /// + /// Poly1305 computes a 128-bit (16 bytes) authenticator, using a 128 bit nonce and a 256 bit key + /// consisting of a 128 bit key applied to an underlying cipher, and a 128 bit key (with 106 + /// effective key bits) used in the authenticator. + /// + /// The polynomial calculation in this implementation is adapted from the public domain poly1305-donna-unrolled C implementation + /// by Andrew M (@floodyberry). + /// + /// + public class Poly1305 + : IMac + { + private const int BlockSize = 16; + + private readonly IBlockCipher cipher; + + private readonly byte[] singleByte = new byte[1]; + + // Initialised state + + /** Polynomial key */ + private uint r0, r1, r2, r3, r4; + + /** Precomputed 5 * r[1..4] */ + private uint s1, s2, s3, s4; + + /** Encrypted nonce */ + private uint k0, k1, k2, k3; + + // Accumulating state + + /** Current block of buffered input */ + private byte[] currentBlock = new byte[BlockSize]; + + /** Current offset in input buffer */ + private int currentBlockOffset = 0; + + /** Polynomial accumulator */ + private uint h0, h1, h2, h3, h4; + + /** + * Constructs a Poly1305 MAC, where the key passed to init() will be used directly. + */ + public Poly1305() + { + this.cipher = null; + } + + /** + * Constructs a Poly1305 MAC, using a 128 bit block cipher. + */ + public Poly1305(IBlockCipher cipher) + { + if (cipher.GetBlockSize() != BlockSize) + { + throw new ArgumentException("Poly1305 requires a 128 bit block cipher."); + } + this.cipher = cipher; + } + + /// + /// Initialises the Poly1305 MAC. + /// + /// a {@link ParametersWithIV} containing a 128 bit nonce and a {@link KeyParameter} with + /// a 256 bit key complying to the {@link Poly1305KeyGenerator Poly1305 key format}. + public void Init(ICipherParameters parameters) + { + byte[] nonce = null; + + if (cipher != null) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("Poly1305 requires an IV when used with a block cipher.", "parameters"); + + ParametersWithIV ivParams = (ParametersWithIV)parameters; + nonce = ivParams.GetIV(); + parameters = ivParams.Parameters; + } + + if (!(parameters is KeyParameter)) + throw new ArgumentException("Poly1305 requires a key."); + + KeyParameter keyParams = (KeyParameter)parameters; + + SetKey(keyParams.GetKey(), nonce); + + Reset(); + } + + private void SetKey(byte[] key, byte[] nonce) + { + if (key.Length != 32) + throw new ArgumentException("Poly1305 key must be 256 bits."); + + if (cipher != null && (nonce == null || nonce.Length != BlockSize)) + throw new ArgumentException("Poly1305 requires a 128 bit IV."); + + // Extract r portion of key (and "clamp" the values) + uint t0 = Pack.LE_To_UInt32(key, 0); + uint t1 = Pack.LE_To_UInt32(key, 4); + uint t2 = Pack.LE_To_UInt32(key, 8); + uint t3 = Pack.LE_To_UInt32(key, 12); + + // NOTE: The masks perform the key "clamping" implicitly + r0 = t0 & 0x03FFFFFFU; + r1 = ((t0 >> 26) | (t1 << 6)) & 0x03FFFF03U; + r2 = ((t1 >> 20) | (t2 << 12)) & 0x03FFC0FFU; + r3 = ((t2 >> 14) | (t3 << 18)) & 0x03F03FFFU; + r4 = (t3 >> 8) & 0x000FFFFFU; + + // Precompute multipliers + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + byte[] kBytes; + int kOff; + + if (cipher == null) + { + kBytes = key; + kOff = BlockSize; + } + else + { + // Compute encrypted nonce + kBytes = new byte[BlockSize]; + kOff = 0; + + cipher.Init(true, new KeyParameter(key, BlockSize, BlockSize)); + cipher.ProcessBlock(nonce, 0, kBytes, 0); + } + + k0 = Pack.LE_To_UInt32(kBytes, kOff + 0); + k1 = Pack.LE_To_UInt32(kBytes, kOff + 4); + k2 = Pack.LE_To_UInt32(kBytes, kOff + 8); + k3 = Pack.LE_To_UInt32(kBytes, kOff + 12); + } + + public string AlgorithmName + { + get { return cipher == null ? "Poly1305" : "Poly1305-" + cipher.AlgorithmName; } + } + + public int GetMacSize() + { + return BlockSize; + } + + public void Update(byte input) + { + singleByte[0] = input; + BlockUpdate(singleByte, 0, 1); + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + int copied = 0; + while (len > copied) + { + if (currentBlockOffset == BlockSize) + { + ProcessBlock(); + currentBlockOffset = 0; + } + + int toCopy = System.Math.Min((len - copied), BlockSize - currentBlockOffset); + Array.Copy(input, copied + inOff, currentBlock, currentBlockOffset, toCopy); + copied += toCopy; + currentBlockOffset += toCopy; + } + + } + + private void ProcessBlock() + { + if (currentBlockOffset < BlockSize) + { + currentBlock[currentBlockOffset] = 1; + for (int i = currentBlockOffset + 1; i < BlockSize; i++) + { + currentBlock[i] = 0; + } + } + + ulong t0 = Pack.LE_To_UInt32(currentBlock, 0); + ulong t1 = Pack.LE_To_UInt32(currentBlock, 4); + ulong t2 = Pack.LE_To_UInt32(currentBlock, 8); + ulong t3 = Pack.LE_To_UInt32(currentBlock, 12); + + h0 += (uint)(t0 & 0x3ffffffU); + h1 += (uint)((((t1 << 32) | t0) >> 26) & 0x3ffffff); + h2 += (uint)((((t2 << 32) | t1) >> 20) & 0x3ffffff); + h3 += (uint)((((t3 << 32) | t2) >> 14) & 0x3ffffff); + h4 += (uint)(t3 >> 8); + + if (currentBlockOffset == BlockSize) + { + h4 += (1 << 24); + } + + ulong tp0 = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1); + ulong tp1 = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2); + ulong tp2 = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3); + ulong tp3 = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4); + ulong tp4 = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0); + + ulong b; + h0 = (uint)tp0 & 0x3ffffff; b = (tp0 >> 26); + tp1 += b; h1 = (uint)tp1 & 0x3ffffff; b = (tp1 >> 26); + tp2 += b; h2 = (uint)tp2 & 0x3ffffff; b = (tp2 >> 26); + tp3 += b; h3 = (uint)tp3 & 0x3ffffff; b = (tp3 >> 26); + tp4 += b; h4 = (uint)tp4 & 0x3ffffff; b = (tp4 >> 26); + h0 += (uint)(b * 5); + } + + public int DoFinal(byte[] output, int outOff) + { + Check.DataLength(output, outOff, BlockSize, "Output buffer is too short."); + + if (currentBlockOffset > 0) + { + // Process padded block + ProcessBlock(); + } + + ulong f0, f1, f2, f3; + + uint b = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += b * 5; + + uint g0, g1, g2, g3, g4; + g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + uint nb = ~b; + h0 = (h0 & nb) | (g0 & b); + h1 = (h1 & nb) | (g1 & b); + h2 = (h2 & nb) | (g2 & b); + h3 = (h3 & nb) | (g3 & b); + h4 = (h4 & nb) | (g4 & b); + + f0 = ((h0 ) | (h1 << 26)) + (ulong)k0; + f1 = ((h1 >> 6 ) | (h2 << 20)) + (ulong)k1; + f2 = ((h2 >> 12) | (h3 << 14)) + (ulong)k2; + f3 = ((h3 >> 18) | (h4 << 8 )) + (ulong)k3; + + Pack.UInt32_To_LE((uint)f0, output, outOff); + f1 += (f0 >> 32); + Pack.UInt32_To_LE((uint)f1, output, outOff + 4); + f2 += (f1 >> 32); + Pack.UInt32_To_LE((uint)f2, output, outOff + 8); + f3 += (f2 >> 32); + Pack.UInt32_To_LE((uint)f3, output, outOff + 12); + + Reset(); + return BlockSize; + } + + public void Reset() + { + currentBlockOffset = 0; + + h0 = h1 = h2 = h3 = h4 = 0; + } + + private static ulong mul32x32_64(uint i1, uint i2) + { + return ((ulong)i1) * i2; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs.meta new file mode 100644 index 0000000..1aa5812 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/Poly1305.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 741547bc11f330d47b607e905832b385 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs new file mode 100644 index 0000000..18c1a75 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs @@ -0,0 +1,203 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /// + /// Implementation of SipHash as specified in "SipHash: a fast short-input PRF", by Jean-Philippe + /// Aumasson and Daniel J. Bernstein (https://131002.net/siphash/siphash.pdf). + /// + /// + /// "SipHash is a family of PRFs SipHash-c-d where the integer parameters c and d are the number of + /// compression rounds and the number of finalization rounds. A compression round is identical to a + /// finalization round and this round function is called SipRound. Given a 128-bit key k and a + /// (possibly empty) byte string m, SipHash-c-d returns a 64-bit value..." + /// + public class SipHash + : IMac + { + protected readonly int c, d; + + protected long k0, k1; + protected long v0, v1, v2, v3; + + protected long m = 0; + protected int wordPos = 0; + protected int wordCount = 0; + + /// SipHash-2-4 + public SipHash() + : this(2, 4) + { + } + + /// SipHash-c-d + /// the number of compression rounds + /// the number of finalization rounds + public SipHash(int c, int d) + { + this.c = c; + this.d = d; + } + + public virtual string AlgorithmName + { + get { return "SipHash-" + c + "-" + d; } + } + + public virtual int GetMacSize() + { + return 8; + } + + public virtual void Init(ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + if (keyParameter == null) + throw new ArgumentException("must be an instance of KeyParameter", "parameters"); + byte[] key = keyParameter.GetKey(); + if (key.Length != 16) + throw new ArgumentException("must be a 128-bit key", "parameters"); + + this.k0 = (long)Pack.LE_To_UInt64(key, 0); + this.k1 = (long)Pack.LE_To_UInt64(key, 8); + + Reset(); + } + + public virtual void Update(byte input) + { + m = (long)(((ulong)m >> 8) | ((ulong)input << 56)); + + if (++wordPos == 8) + { + ProcessMessageWord(); + wordPos = 0; + } + } + + public virtual void BlockUpdate(byte[] input, int offset, int length) + { + int i = 0, fullWords = length & ~7; + if (wordPos == 0) + { + for (; i < fullWords; i += 8) + { + m = (long)Pack.LE_To_UInt64(input, offset + i); + ProcessMessageWord(); + } + for (; i < length; ++i) + { + m = (long)(((ulong)m >> 8) | ((ulong)input[offset + i] << 56)); + } + wordPos = length - fullWords; + } + else + { + int bits = wordPos << 3; + for (; i < fullWords; i += 8) + { + ulong n = Pack.LE_To_UInt64(input, offset + i); + m = (long)((n << bits) | ((ulong)m >> -bits)); + ProcessMessageWord(); + m = (long)n; + } + for (; i < length; ++i) + { + m = (long)(((ulong)m >> 8) | ((ulong)input[offset + i] << 56)); + + if (++wordPos == 8) + { + ProcessMessageWord(); + wordPos = 0; + } + } + } + } + + public virtual long DoFinal() + { + // NOTE: 2 distinct shifts to avoid "64-bit shift" when wordPos == 0 + m = (long)((ulong)m >> ((7 - wordPos) << 3)); + m = (long)((ulong)m >> 8); + m = (long)((ulong)m | ((ulong)((wordCount << 3) + wordPos) << 56)); + + ProcessMessageWord(); + + v2 ^= 0xffL; + + ApplySipRounds(d); + + long result = v0 ^ v1 ^ v2 ^ v3; + + Reset(); + + return result; + } + + public virtual int DoFinal(byte[] output, int outOff) + { + long result = DoFinal(); + Pack.UInt64_To_LE((ulong)result, output, outOff); + return 8; + } + + public virtual void Reset() + { + v0 = k0 ^ 0x736f6d6570736575L; + v1 = k1 ^ 0x646f72616e646f6dL; + v2 = k0 ^ 0x6c7967656e657261L; + v3 = k1 ^ 0x7465646279746573L; + + m = 0; + wordPos = 0; + wordCount = 0; + } + + protected virtual void ProcessMessageWord() + { + ++wordCount; + v3 ^= m; + ApplySipRounds(c); + v0 ^= m; + } + + protected virtual void ApplySipRounds(int n) + { + long r0 = v0, r1 = v1, r2 = v2, r3 = v3; + + for (int r = 0; r < n; ++r) + { + r0 += r1; + r2 += r3; + r1 = RotateLeft(r1, 13); + r3 = RotateLeft(r3, 16); + r1 ^= r0; + r3 ^= r2; + r0 = RotateLeft(r0, 32); + r2 += r1; + r0 += r3; + r1 = RotateLeft(r1, 17); + r3 = RotateLeft(r3, 21); + r1 ^= r2; + r3 ^= r0; + r2 = RotateLeft(r2, 32); + } + + v0 = r0; v1 = r1; v2 = r2; v3 = r3; + } + + protected static long RotateLeft(long x, int n) + { + ulong ux = (ulong)x; + ux = (ux << n) | (ux >> -n); + return (long)ux; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs.meta new file mode 100644 index 0000000..b73bee8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/SipHash.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b0bbbba09da03b8439fc20b05469327b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs new file mode 100644 index 0000000..9c3172a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs @@ -0,0 +1,177 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + public class VmpcMac + : IMac + { + private byte g; + + private byte n = 0; + private byte[] P = null; + private byte s = 0; + + private byte[] T; + private byte[] workingIV; + + private byte[] workingKey; + + private byte x1, x2, x3, x4; + + public virtual int DoFinal(byte[] output, int outOff) + { + // Execute the Post-Processing Phase + for (int r = 1; r < 25; r++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + + x4 = P[(x4 + x3 + r) & 0xff]; + x3 = P[(x3 + x2 + r) & 0xff]; + x2 = P[(x2 + x1 + r) & 0xff]; + x1 = P[(x1 + s + r) & 0xff]; + T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); + T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); + T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); + T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); + g = (byte) ((g + 4) & 0x1f); + + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + + // Input T to the IV-phase of the VMPC KSA + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + // Store 20 new outputs of the VMPC Stream Cipher input table M + byte[] M = new byte[20]; + for (int i = 0; i < 20; i++) + { + s = P[(s + P[i & 0xff]) & 0xff]; + M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + + byte temp = P[i & 0xff]; + P[i & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + Array.Copy(M, 0, output, outOff, M.Length); + Reset(); + + return M.Length; + } + + public virtual string AlgorithmName + { + get { return "VMPC-MAC"; } + } + + public virtual int GetMacSize() + { + return 20; + } + + public virtual void Init(ICipherParameters parameters) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("VMPC-MAC Init parameters must include an IV", "parameters"); + + ParametersWithIV ivParams = (ParametersWithIV) parameters; + KeyParameter key = (KeyParameter) ivParams.Parameters; + + if (!(ivParams.Parameters is KeyParameter)) + throw new ArgumentException("VMPC-MAC Init parameters must include a key", "parameters"); + + this.workingIV = ivParams.GetIV(); + + if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768) + throw new ArgumentException("VMPC-MAC requires 1 to 768 bytes of IV", "parameters"); + + this.workingKey = key.GetKey(); + + Reset(); + + } + + private void initKey(byte[] keyBytes, byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + n = 0; + } + + public virtual void Reset() + { + initKey(this.workingKey, this.workingIV); + g = x1 = x2 = x3 = x4 = n = 0; + T = new byte[32]; + for (int i = 0; i < 32; i++) + { + T[i] = 0; + } + } + + public virtual void Update(byte input) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte c = (byte) (input ^ P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]); + + x4 = P[(x4 + x3) & 0xff]; + x3 = P[(x3 + x2) & 0xff]; + x2 = P[(x2 + x1) & 0xff]; + x1 = P[(x1 + s + c) & 0xff]; + T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); + T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); + T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); + T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); + g = (byte) ((g + 4) & 0x1f); + + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + if ((inOff + len) > input.Length) + throw new DataLengthException("input buffer too short"); + + for (int i = 0; i < len; i++) + { + Update(input[inOff + i]); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs.meta new file mode 100644 index 0000000..3d6cd56 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/macs/VMPCMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4144352b9e83dda43b21e612553bf87c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes.meta new file mode 100644 index 0000000..08f9167 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7290ea1bd4b4b8044b8c839a0f6e38e6 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs new file mode 100644 index 0000000..001c94a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs @@ -0,0 +1,245 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. + */ + public class CbcBlockCipher + : IBlockCipher + { + private byte[] IV, cbcV, cbcNextV; + private int blockSize; + private IBlockCipher cipher; + private bool encrypting; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of chaining. + */ + public CbcBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + + this.IV = new byte[blockSize]; + this.cbcV = new byte[blockSize]; + this.cbcNextV = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + bool oldEncrypting = this.encrypting; + + this.encrypting = forEncryption; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length != blockSize) + { + throw new ArgumentException("initialisation vector must be the same length as block size"); + } + + Array.Copy(iv, 0, IV, 0, iv.Length); + + parameters = ivParam.Parameters; + } + + Reset(); + + // if null it's an IV changed only. + if (parameters != null) + { + cipher.Init(encrypting, parameters); + } + else if (oldEncrypting != encrypting) + { + throw new ArgumentException("cannot change encrypting state without providing key."); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CBC". + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CBC"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + /** + * return the block size of the underlying cipher. + * + * @return the block size of the underlying cipher. + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (encrypting) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, cbcV, 0, IV.Length); + Array.Clear(cbcNextV, 0, cbcNextV.Length); + + cipher.Reset(); + } + + /** + * Do the appropriate chaining step for CBC mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + /* + * XOR the cbcV and the input, + * then encrypt the cbcV + */ + for (int i = 0; i < blockSize; i++) + { + cbcV[i] ^= input[inOff + i]; + } + + int length = cipher.ProcessBlock(cbcV, 0, outBytes, outOff); + + /* + * copy ciphertext to cbcV + */ + Array.Copy(outBytes, outOff, cbcV, 0, cbcV.Length); + + return length; + } + + /** + * Do the appropriate chaining step for CBC mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the decrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + Array.Copy(input, inOff, cbcNextV, 0, blockSize); + + int length = cipher.ProcessBlock(input, inOff, outBytes, outOff); + + /* + * XOR the cbcV and the output + */ + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] ^= cbcV[i]; + } + + /* + * swap the back up buffer into next position + */ + byte[] tmp; + + tmp = cbcV; + cbcV = cbcNextV; + cbcNextV = tmp; + + return length; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs.meta new file mode 100644 index 0000000..bf216fe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CbcBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3831153ecb36bcf4ba6723fbb3b02484 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs new file mode 100644 index 0000000..7c4ed52 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs @@ -0,0 +1,453 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements the Counter with Cipher Block Chaining mode (CCM) detailed in + * NIST Special Publication 800-38C. + *

+ * Note: this mode is a packet mode - it needs all the data up front. + *

+ */ + public class CcmBlockCipher + : IAeadBlockCipher + { + private static readonly int BlockSize = 16; + + private readonly IBlockCipher cipher; + private readonly byte[] macBlock; + private bool forEncryption; + private byte[] nonce; + private byte[] initialAssociatedText; + private int macSize; + private ICipherParameters keyParam; + private readonly MemoryStream associatedText = new MemoryStream(); + private readonly MemoryStream data = new MemoryStream(); + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used. + */ + public CcmBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.macBlock = new byte[BlockSize]; + + if (cipher.GetBlockSize() != BlockSize) + throw new ArgumentException("cipher required with a block size of " + BlockSize + "."); + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + ICipherParameters cipherParameters; + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters) parameters; + + nonce = param.GetNonce(); + initialAssociatedText = param.GetAssociatedText(); + macSize = param.MacSize / 8; + cipherParameters = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV) parameters; + + nonce = param.GetIV(); + initialAssociatedText = null; + macSize = macBlock.Length / 2; + cipherParameters = param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to CCM"); + } + + // NOTE: Very basic support for key re-use, but no performance gain from it + if (cipherParameters != null) + { + keyParam = cipherParameters; + } + + if (nonce == null || nonce.Length < 7 || nonce.Length > 13) + { + throw new ArgumentException("nonce must have length from 7 to 13 octets"); + } + + Reset(); + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/CCM"; } + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual void ProcessAadByte(byte input) + { + associatedText.WriteByte(input); + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + // TODO: Process AAD online + associatedText.Write(inBytes, inOff, len); + } + + public virtual int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + data.WriteByte(input); + + return 0; + } + + public virtual int ProcessBytes( + byte[] inBytes, + int inOff, + int inLen, + byte[] outBytes, + int outOff) + { + Check.DataLength(inBytes, inOff, inLen, "Input buffer too short"); + + data.Write(inBytes, inOff, inLen); + + return 0; + } + + public virtual int DoFinal( + byte[] outBytes, + int outOff) + { +#if PORTABLE || NETFX_CORE + byte[] input = data.ToArray(); + int inLen = input.Length; +#else + byte[] input = data.GetBuffer(); + int inLen = (int)data.Position; +#endif + + int len = ProcessPacket(input, 0, inLen, outBytes, outOff); + + Reset(); + + return len; + } + + public virtual void Reset() + { + cipher.Reset(); + associatedText.SetLength(0); + data.SetLength(0); + } + + /** + * Returns a byte array containing the mac calculated as part of the + * last encrypt or decrypt operation. + * + * @return the last mac calculated. + */ + public virtual byte[] GetMac() + { + return Arrays.CopyOfRange(macBlock, 0, macSize); + } + + public virtual int GetUpdateOutputSize( + int len) + { + return 0; + } + + public virtual int GetOutputSize( + int len) + { + int totalData = (int)data.Length + len; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + /** + * Process a packet of data for either CCM decryption or encryption. + * + * @param in data for processing. + * @param inOff offset at which data starts in the input array. + * @param inLen length of the data in the input array. + * @return a byte array containing the processed input.. + * @throws IllegalStateException if the cipher is not appropriately set up. + * @throws InvalidCipherTextException if the input data is truncated or the mac check fails. + */ + public virtual byte[] ProcessPacket(byte[] input, int inOff, int inLen) + { + byte[] output; + + if (forEncryption) + { + output = new byte[inLen + macSize]; + } + else + { + if (inLen < macSize) + throw new InvalidCipherTextException("data too short"); + + output = new byte[inLen - macSize]; + } + + ProcessPacket(input, inOff, inLen, output, 0); + + return output; + } + + /** + * Process a packet of data for either CCM decryption or encryption. + * + * @param in data for processing. + * @param inOff offset at which data starts in the input array. + * @param inLen length of the data in the input array. + * @param output output array. + * @param outOff offset into output array to start putting processed bytes. + * @return the number of bytes added to output. + * @throws IllegalStateException if the cipher is not appropriately set up. + * @throws InvalidCipherTextException if the input data is truncated or the mac check fails. + * @throws DataLengthException if output buffer too short. + */ + public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff) + { + // TODO: handle null keyParam (e.g. via RepeatedKeySpec) + // Need to keep the CTR and CBC Mac parts around and reset + if (keyParam == null) + throw new InvalidOperationException("CCM cipher unitialized."); + + int n = nonce.Length; + int q = 15 - n; + if (q < 4) + { + int limitLen = 1 << (8 * q); + if (inLen >= limitLen) + throw new InvalidOperationException("CCM packet too large for choice of q."); + } + + byte[] iv = new byte[BlockSize]; + iv[0] = (byte)((q - 1) & 0x7); + nonce.CopyTo(iv, 1); + + IBlockCipher ctrCipher = new SicBlockCipher(cipher); + ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv)); + + int outputLen; + int inIndex = inOff; + int outIndex = outOff; + + if (forEncryption) + { + outputLen = inLen + macSize; + Check.OutputLength(output, outOff, outputLen, "Output buffer too short."); + + CalculateMac(input, inOff, inLen, macBlock); + + byte[] encMac = new byte[BlockSize]; + ctrCipher.ProcessBlock(macBlock, 0, encMac, 0); // S0 + + while (inIndex < (inOff + inLen - BlockSize)) // S1... + { + ctrCipher.ProcessBlock(input, inIndex, output, outIndex); + outIndex += BlockSize; + inIndex += BlockSize; + } + + byte[] block = new byte[BlockSize]; + + Array.Copy(input, inIndex, block, 0, inLen + inOff - inIndex); + + ctrCipher.ProcessBlock(block, 0, block, 0); + + Array.Copy(block, 0, output, outIndex, inLen + inOff - inIndex); + + Array.Copy(encMac, 0, output, outOff + inLen, macSize); + } + else + { + if (inLen < macSize) + throw new InvalidCipherTextException("data too short"); + + outputLen = inLen - macSize; + Check.OutputLength(output, outOff, outputLen, "Output buffer too short."); + + Array.Copy(input, inOff + outputLen, macBlock, 0, macSize); + + ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); + + for (int i = macSize; i != macBlock.Length; i++) + { + macBlock[i] = 0; + } + + while (inIndex < (inOff + outputLen - BlockSize)) + { + ctrCipher.ProcessBlock(input, inIndex, output, outIndex); + outIndex += BlockSize; + inIndex += BlockSize; + } + + byte[] block = new byte[BlockSize]; + + Array.Copy(input, inIndex, block, 0, outputLen - (inIndex - inOff)); + + ctrCipher.ProcessBlock(block, 0, block, 0); + + Array.Copy(block, 0, output, outIndex, outputLen - (inIndex - inOff)); + + byte[] calculatedMacBlock = new byte[BlockSize]; + + CalculateMac(output, outOff, outputLen, calculatedMacBlock); + + if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock)) + throw new InvalidCipherTextException("mac check in CCM failed"); + } + + return outputLen; + } + + private int CalculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) + { + IMac cMac = new CbcBlockCipherMac(cipher, macSize * 8); + + cMac.Init(keyParam); + + // + // build b0 + // + byte[] b0 = new byte[16]; + + if (HasAssociatedText()) + { + b0[0] |= 0x40; + } + + b0[0] |= (byte)((((cMac.GetMacSize() - 2) / 2) & 0x7) << 3); + + b0[0] |= (byte)(((15 - nonce.Length) - 1) & 0x7); + + Array.Copy(nonce, 0, b0, 1, nonce.Length); + + int q = dataLen; + int count = 1; + while (q > 0) + { + b0[b0.Length - count] = (byte)(q & 0xff); + q >>= 8; + count++; + } + + cMac.BlockUpdate(b0, 0, b0.Length); + + // + // process associated text + // + if (HasAssociatedText()) + { + int extra; + + int textLength = GetAssociatedTextLength(); + if (textLength < ((1 << 16) - (1 << 8))) + { + cMac.Update((byte)(textLength >> 8)); + cMac.Update((byte)textLength); + + extra = 2; + } + else // can't go any higher than 2^32 + { + cMac.Update((byte)0xff); + cMac.Update((byte)0xfe); + cMac.Update((byte)(textLength >> 24)); + cMac.Update((byte)(textLength >> 16)); + cMac.Update((byte)(textLength >> 8)); + cMac.Update((byte)textLength); + + extra = 6; + } + + if (initialAssociatedText != null) + { + cMac.BlockUpdate(initialAssociatedText, 0, initialAssociatedText.Length); + } + if (associatedText.Position > 0) + { +#if PORTABLE || NETFX_CORE + byte[] input = associatedText.ToArray(); + int len = input.Length; +#else + byte[] input = associatedText.GetBuffer(); + int len = (int)associatedText.Position; +#endif + + cMac.BlockUpdate(input, 0, len); + } + + extra = (extra + textLength) % 16; + if (extra != 0) + { + for (int i = extra; i < 16; ++i) + { + cMac.Update((byte)0x00); + } + } + } + + // + // add the text + // + cMac.BlockUpdate(data, dataOff, dataLen); + + return cMac.DoFinal(macBlock, 0); + } + + private int GetAssociatedTextLength() + { + return (int)associatedText.Length + ((initialAssociatedText == null) ? 0 : initialAssociatedText.Length); + } + + private bool HasAssociatedText() + { + return GetAssociatedTextLength() > 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs.meta new file mode 100644 index 0000000..fdaf42f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CcmBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e209f184af83f8f4494a19e8b869a055 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs new file mode 100644 index 0000000..8b16533 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs @@ -0,0 +1,228 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. + */ + public class CfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + private bool encrypting; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public CfbBlockCipher( + IBlockCipher cipher, + int bitBlockSize) + { + this.cipher = cipher; + this.blockSize = bitBlockSize / 8; + this.IV = new byte[cipher.GetBlockSize()]; + this.cfbV = new byte[cipher.GetBlockSize()]; + this.cfbOutV = new byte[cipher.GetBlockSize()]; + } + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV) parameters; + byte[] iv = ivParam.GetIV(); + int diff = IV.Length - iv.Length; + Array.Copy(iv, 0, IV, diff, iv.Length); + Array.Clear(IV, 0, diff); + + parameters = ivParam.Parameters; + } + Reset(); + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (encrypting) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + /** + * Do the appropriate processing for CFB mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + // + // XOR the cfbV with the plaintext producing the ciphertext + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(outBytes, outOff, cfbV, cfbV.Length - blockSize, blockSize); + return blockSize; + } + /** + * Do the appropriate processing for CFB mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(input, inOff, cfbV, cfbV.Length - blockSize, blockSize); + // + // XOR the cfbV with the ciphertext producing the plaintext + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + return blockSize; + } + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, cfbV, 0, IV.Length); + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs.meta new file mode 100644 index 0000000..f77da14 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CfbBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c7ff0cbf4f101654b8f34a6112e42ae3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs new file mode 100644 index 0000000..495d563 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs @@ -0,0 +1,257 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to + * be used to produce cipher text which is the same outLength as the plain text. + */ + public class CtsBlockCipher + : BufferedBlockCipher + { + private readonly int blockSize; + + /** + * Create a buffered block cipher that uses Cipher Text Stealing + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public CtsBlockCipher( + IBlockCipher cipher) + { + // TODO Should this test for acceptable ones instead? + if (cipher is OfbBlockCipher || cipher is CfbBlockCipher) + throw new ArgumentException("CtsBlockCipher can only accept ECB, or CBC ciphers"); + + this.cipher = cipher; + + blockSize = cipher.GetBlockSize(); + + buf = new byte[blockSize * 2]; + bufOff = 0; + } + + /** + * return the size of the output buffer required for an update of 'length' bytes. + * + * @param length the outLength of the input. + * @return the space required to accommodate a call to update + * with length bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + return total - buf.Length; + } + + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of length bytes. + * + * @param length the outLength of the input. + * @return the space required to accommodate a call to update and doFinal + * with length bytes of input. + */ + public override int GetOutputSize( + int length) + { + return length + bufOff; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + if (bufOff == buf.Length) + { + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + Debug.Assert(resultLen == blockSize); + + Array.Copy(buf, blockSize, buf, 0, blockSize); + bufOff = blockSize; + } + + buf[bufOff++] = input; + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param length the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 0) + { + throw new ArgumentException("Can't have a negative input outLength!"); + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + if ((outOff + outLength) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + Array.Copy(buf, blockSize, buf, 0, blockSize); + + bufOff = blockSize; + + length -= gapLen; + inOff += gapLen; + + while (length > blockSize) + { + Array.Copy(input, inOff, buf, bufOff, blockSize); + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + Array.Copy(buf, blockSize, buf, 0, blockSize); + + length -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, length); + + bufOff += length; + + return resultLen; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if cipher text decrypts wrongly (in + * case the exception will never Get thrown). + */ + public override int DoFinal( + byte[] output, + int outOff) + { + if (bufOff + outOff > output.Length) + { + throw new DataLengthException("output buffer too small in doFinal"); + } + + int blockSize = cipher.GetBlockSize(); + int length = bufOff - blockSize; + byte[] block = new byte[blockSize]; + + if (forEncryption) + { + cipher.ProcessBlock(buf, 0, block, 0); + + if (bufOff < blockSize) + { + throw new DataLengthException("need at least one block of input for CTS"); + } + + for (int i = bufOff; i != buf.Length; i++) + { + buf[i] = block[i - blockSize]; + } + + for (int i = blockSize; i != bufOff; i++) + { + buf[i] ^= block[i - blockSize]; + } + + IBlockCipher c = (cipher is CbcBlockCipher) + ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() + : cipher; + + c.ProcessBlock(buf, blockSize, output, outOff); + + Array.Copy(block, 0, output, outOff + blockSize, length); + } + else + { + byte[] lastBlock = new byte[blockSize]; + + IBlockCipher c = (cipher is CbcBlockCipher) + ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() + : cipher; + + c.ProcessBlock(buf, 0, block, 0); + + for (int i = blockSize; i != bufOff; i++) + { + lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]); + } + + Array.Copy(buf, blockSize, block, 0, length); + + cipher.ProcessBlock(block, 0, output, outOff); + Array.Copy(lastBlock, 0, output, outOff + blockSize, length); + } + + int offset = bufOff; + + Reset(); + + return offset; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs.meta new file mode 100644 index 0000000..bd1f08d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/CtsBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d853fe439c7b3cd42be0ebc115faebc1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs new file mode 100644 index 0000000..36eef00 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs @@ -0,0 +1,383 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and + * Efficiency - by M. Bellare, P. Rogaway, D. Wagner. + * + * http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf + * + * EAX is an AEAD scheme based on CTR and OMAC1/CMAC, that uses a single block + * cipher to encrypt and authenticate data. It's on-line (the length of a + * message isn't needed to begin processing it), has good performances, it's + * simple and provably secure (provided the underlying block cipher is secure). + * + * Of course, this implementations is NOT thread-safe. + */ + public class EaxBlockCipher + : IAeadBlockCipher + { + private enum Tag : byte { N, H, C }; + + private SicBlockCipher cipher; + + private bool forEncryption; + + private int blockSize; + + private IMac mac; + + private byte[] nonceMac; + private byte[] associatedTextMac; + private byte[] macBlock; + + private int macSize; + private byte[] bufBlock; + private int bufOff; + + private bool cipherInitialized; + private byte[] initialAssociatedText; + + /** + * Constructor that accepts an instance of a block cipher engine. + * + * @param cipher the engine to use + */ + public EaxBlockCipher( + IBlockCipher cipher) + { + blockSize = cipher.GetBlockSize(); + mac = new CMac(cipher); + macBlock = new byte[blockSize]; + associatedTextMac = new byte[mac.GetMacSize()]; + nonceMac = new byte[mac.GetMacSize()]; + this.cipher = new SicBlockCipher(cipher); + } + + public virtual string AlgorithmName + { + get { return cipher.GetUnderlyingCipher().AlgorithmName + "/EAX"; } + } + + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + byte[] nonce; + ICipherParameters keyParam; + + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters) parameters; + + nonce = param.GetNonce(); + initialAssociatedText = param.GetAssociatedText(); + macSize = param.MacSize / 8; + keyParam = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV) parameters; + + nonce = param.GetIV(); + initialAssociatedText = null; + macSize = mac.GetMacSize() / 2; + keyParam = param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to EAX"); + } + + bufBlock = new byte[forEncryption ? blockSize : (blockSize + macSize)]; + + byte[] tag = new byte[blockSize]; + + // Key reuse implemented in CBC mode of underlying CMac + mac.Init(keyParam); + + tag[blockSize - 1] = (byte)Tag.N; + mac.BlockUpdate(tag, 0, blockSize); + mac.BlockUpdate(nonce, 0, nonce.Length); + mac.DoFinal(nonceMac, 0); + + // Same BlockCipher underlies this and the mac, so reuse last key on cipher + cipher.Init(true, new ParametersWithIV(null, nonceMac)); + + Reset(); + } + + private void InitCipher() + { + if (cipherInitialized) + { + return; + } + + cipherInitialized = true; + + mac.DoFinal(associatedTextMac, 0); + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = (byte)Tag.C; + mac.BlockUpdate(tag, 0, blockSize); + } + + private void CalculateMac() + { + byte[] outC = new byte[blockSize]; + mac.DoFinal(outC, 0); + + for (int i = 0; i < macBlock.Length; i++) + { + macBlock[i] = (byte)(nonceMac[i] ^ associatedTextMac[i] ^ outC[i]); + } + } + + public virtual void Reset() + { + Reset(true); + } + + private void Reset( + bool clearMac) + { + cipher.Reset(); // TODO Redundant since the mac will reset it? + mac.Reset(); + + bufOff = 0; + Array.Clear(bufBlock, 0, bufBlock.Length); + + if (clearMac) + { + Array.Clear(macBlock, 0, macBlock.Length); + } + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = (byte)Tag.H; + mac.BlockUpdate(tag, 0, blockSize); + + cipherInitialized = false; + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + public virtual void ProcessAadByte(byte input) + { + if (cipherInitialized) + { + throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun."); + } + mac.Update(input); + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + if (cipherInitialized) + { + throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun."); + } + mac.BlockUpdate(inBytes, inOff, len); + } + + public virtual int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + InitCipher(); + + return Process(input, outBytes, outOff); + } + + public virtual int ProcessBytes( + byte[] inBytes, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + InitCipher(); + + int resultLen = 0; + + for (int i = 0; i != len; i++) + { + resultLen += Process(inBytes[inOff + i], outBytes, outOff + resultLen); + } + + return resultLen; + } + + public virtual int DoFinal( + byte[] outBytes, + int outOff) + { + InitCipher(); + + int extra = bufOff; + byte[] tmp = new byte[bufBlock.Length]; + + bufOff = 0; + + if (forEncryption) + { + Check.OutputLength(outBytes, outOff, extra + macSize, "Output buffer too short"); + + cipher.ProcessBlock(bufBlock, 0, tmp, 0); + + Array.Copy(tmp, 0, outBytes, outOff, extra); + + mac.BlockUpdate(tmp, 0, extra); + + CalculateMac(); + + Array.Copy(macBlock, 0, outBytes, outOff + extra, macSize); + + Reset(false); + + return extra + macSize; + } + else + { + if (extra < macSize) + throw new InvalidCipherTextException("data too short"); + + Check.OutputLength(outBytes, outOff, extra - macSize, "Output buffer too short"); + + if (extra > macSize) + { + mac.BlockUpdate(bufBlock, 0, extra - macSize); + + cipher.ProcessBlock(bufBlock, 0, tmp, 0); + + Array.Copy(tmp, 0, outBytes, outOff, extra - macSize); + } + + CalculateMac(); + + if (!VerifyMac(bufBlock, extra - macSize)) + throw new InvalidCipherTextException("mac check in EAX failed"); + + Reset(false); + + return extra - macSize; + } + } + + public virtual byte[] GetMac() + { + byte[] mac = new byte[macSize]; + + Array.Copy(macBlock, 0, mac, 0, macSize); + + return mac; + } + + public virtual int GetUpdateOutputSize( + int len) + { + int totalData = len + bufOff; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % blockSize; + } + + public virtual int GetOutputSize( + int len) + { + int totalData = len + bufOff; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + private int Process( + byte b, + byte[] outBytes, + int outOff) + { + bufBlock[bufOff++] = b; + + if (bufOff == bufBlock.Length) + { + Check.OutputLength(outBytes, outOff, blockSize, "Output buffer is too short"); + + // TODO Could move the ProcessByte(s) calls to here +// InitCipher(); + + int size; + + if (forEncryption) + { + size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); + + mac.BlockUpdate(outBytes, outOff, blockSize); + } + else + { + mac.BlockUpdate(bufBlock, 0, blockSize); + + size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); + } + + bufOff = 0; + if (!forEncryption) + { + Array.Copy(bufBlock, blockSize, bufBlock, 0, macSize); + bufOff = macSize; + } + + return size; + } + + return 0; + } + + private bool VerifyMac(byte[] mac, int off) + { + int nonEqual = 0; + + for (int i = 0; i < macSize; i++) + { + nonEqual |= (macBlock[i] ^ mac[off + i]); + } + + return nonEqual == 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs.meta new file mode 100644 index 0000000..a747f08 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/EAXBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 56a798d87f3f7d741b9de7bff3c6622e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs new file mode 100644 index 0000000..2f35188 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs @@ -0,0 +1,569 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Modes.Gcm; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /// + /// Implements the Galois/Counter mode (GCM) detailed in + /// NIST Special Publication 800-38D. + /// + public class GcmBlockCipher + : IAeadBlockCipher + { + private const int BlockSize = 16; + + private readonly IBlockCipher cipher; + private readonly IGcmMultiplier multiplier; + private IGcmExponentiator exp; + + // These fields are set by Init and not modified by processing + private bool forEncryption; + private int macSize; + private byte[] nonce; + private byte[] initialAssociatedText; + private byte[] H; + private byte[] J0; + + // These fields are modified during processing + private byte[] bufBlock; + private byte[] macBlock; + private byte[] S, S_at, S_atPre; + private byte[] counter; + private uint blocksRemaining; + private int bufOff; + private ulong totalLength; + private byte[] atBlock; + private int atBlockPos; + private ulong atLength; + private ulong atLengthPre; + + public GcmBlockCipher( + IBlockCipher c) + : this(c, null) + { + } + + public GcmBlockCipher( + IBlockCipher c, + IGcmMultiplier m) + { + if (c.GetBlockSize() != BlockSize) + throw new ArgumentException("cipher required with a block size of " + BlockSize + "."); + + if (m == null) + { + // TODO Consider a static property specifying default multiplier + m = new Tables8kGcmMultiplier(); + } + + this.cipher = c; + this.multiplier = m; + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/GCM"; } + } + + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + /// + /// MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default is 128 bits. + /// Sizes less than 96 are not recommended, but are supported for specialized applications. + /// + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + this.macBlock = null; + + KeyParameter keyParam; + + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters)parameters; + + nonce = param.GetNonce(); + initialAssociatedText = param.GetAssociatedText(); + + int macSizeBits = param.MacSize; + if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) + { + throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); + } + + macSize = macSizeBits / 8; + keyParam = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV)parameters; + + nonce = param.GetIV(); + initialAssociatedText = null; + macSize = 16; + keyParam = (KeyParameter)param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to GCM"); + } + + int bufLength = forEncryption ? BlockSize : (BlockSize + macSize); + this.bufBlock = new byte[bufLength]; + + if (nonce == null || nonce.Length < 1) + { + throw new ArgumentException("IV must be at least 1 byte"); + } + + // TODO Restrict macSize to 16 if nonce length not 12? + + // Cipher always used in forward mode + // if keyParam is null we're reusing the last key. + if (keyParam != null) + { + cipher.Init(true, keyParam); + + this.H = new byte[BlockSize]; + cipher.ProcessBlock(H, 0, H, 0); + + // if keyParam is null we're reusing the last key and the multiplier doesn't need re-init + multiplier.Init(H); + exp = null; + } + else if (this.H == null) + { + throw new ArgumentException("Key must be specified in initial init"); + } + + this.J0 = new byte[BlockSize]; + + if (nonce.Length == 12) + { + Array.Copy(nonce, 0, J0, 0, nonce.Length); + this.J0[BlockSize - 1] = 0x01; + } + else + { + gHASH(J0, nonce, nonce.Length); + byte[] X = new byte[BlockSize]; + Pack.UInt64_To_BE((ulong)nonce.Length * 8UL, X, 8); + gHASHBlock(J0, X); + } + + this.S = new byte[BlockSize]; + this.S_at = new byte[BlockSize]; + this.S_atPre = new byte[BlockSize]; + this.atBlock = new byte[BlockSize]; + this.atBlockPos = 0; + this.atLength = 0; + this.atLengthPre = 0; + this.counter = Arrays.Clone(J0); + this.blocksRemaining = uint.MaxValue - 1; // page 8, len(P) <= 2^39 - 256, 1 block used by tag + this.bufOff = 0; + this.totalLength = 0; + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + public virtual byte[] GetMac() + { + return Arrays.Clone(macBlock); + } + + public virtual int GetOutputSize( + int len) + { + int totalData = len + bufOff; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + public virtual int GetUpdateOutputSize( + int len) + { + int totalData = len + bufOff; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % BlockSize; + } + + public virtual void ProcessAadByte(byte input) + { + atBlock[atBlockPos] = input; + if (++atBlockPos == BlockSize) + { + // Hash each block as it fills + gHASHBlock(S_at, atBlock); + atBlockPos = 0; + atLength += BlockSize; + } + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + for (int i = 0; i < len; ++i) + { + atBlock[atBlockPos] = inBytes[inOff + i]; + if (++atBlockPos == BlockSize) + { + // Hash each block as it fills + gHASHBlock(S_at, atBlock); + atBlockPos = 0; + atLength += BlockSize; + } + } + } + + private void InitCipher() + { + if (atLength > 0) + { + Array.Copy(S_at, 0, S_atPre, 0, BlockSize); + atLengthPre = atLength; + } + + // Finish hash for partial AAD block + if (atBlockPos > 0) + { + gHASHPartial(S_atPre, atBlock, 0, atBlockPos); + atLengthPre += (uint)atBlockPos; + } + + if (atLengthPre > 0) + { + Array.Copy(S_atPre, 0, S, 0, BlockSize); + } + } + + public virtual int ProcessByte( + byte input, + byte[] output, + int outOff) + { + bufBlock[bufOff] = input; + if (++bufOff == bufBlock.Length) + { + OutputBlock(output, outOff); + return BlockSize; + } + return 0; + } + + public virtual int ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (input.Length < (inOff + len)) + throw new DataLengthException("Input buffer too short"); + + int resultLen = 0; + + for (int i = 0; i < len; ++i) + { + bufBlock[bufOff] = input[inOff + i]; + if (++bufOff == bufBlock.Length) + { + OutputBlock(output, outOff + resultLen); + resultLen += BlockSize; + } + } + + return resultLen; + } + + private void OutputBlock(byte[] output, int offset) + { + Check.OutputLength(output, offset, BlockSize, "Output buffer too short"); + if (totalLength == 0) + { + InitCipher(); + } + gCTRBlock(bufBlock, output, offset); + if (forEncryption) + { + bufOff = 0; + } + else + { + Array.Copy(bufBlock, BlockSize, bufBlock, 0, macSize); + bufOff = macSize; + } + } + + public int DoFinal(byte[] output, int outOff) + { + if (totalLength == 0) + { + InitCipher(); + } + + int extra = bufOff; + + if (forEncryption) + { + Check.OutputLength(output, outOff, extra + macSize, "Output buffer too short"); + } + else + { + if (extra < macSize) + throw new InvalidCipherTextException("data too short"); + + extra -= macSize; + + Check.OutputLength(output, outOff, extra, "Output buffer too short"); + } + + if (extra > 0) + { + gCTRPartial(bufBlock, 0, extra, output, outOff); + } + + atLength += (uint)atBlockPos; + + if (atLength > atLengthPre) + { + /* + * Some AAD was sent after the cipher started. We determine the difference b/w the hash value + * we actually used when the cipher started (S_atPre) and the final hash value calculated (S_at). + * Then we carry this difference forward by multiplying by H^c, where c is the number of (full or + * partial) cipher-text blocks produced, and adjust the current hash. + */ + + // Finish hash for partial AAD block + if (atBlockPos > 0) + { + gHASHPartial(S_at, atBlock, 0, atBlockPos); + } + + // Find the difference between the AAD hashes + if (atLengthPre > 0) + { + GcmUtilities.Xor(S_at, S_atPre); + } + + // Number of cipher-text blocks produced + long c = (long)(((totalLength * 8) + 127) >> 7); + + // Calculate the adjustment factor + byte[] H_c = new byte[16]; + if (exp == null) + { + exp = new Tables1kGcmExponentiator(); + exp.Init(H); + } + exp.ExponentiateX(c, H_c); + + // Carry the difference forward + GcmUtilities.Multiply(S_at, H_c); + + // Adjust the current hash + GcmUtilities.Xor(S, S_at); + } + + // Final gHASH + byte[] X = new byte[BlockSize]; + Pack.UInt64_To_BE(atLength * 8UL, X, 0); + Pack.UInt64_To_BE(totalLength * 8UL, X, 8); + + gHASHBlock(S, X); + + // T = MSBt(GCTRk(J0,S)) + byte[] tag = new byte[BlockSize]; + cipher.ProcessBlock(J0, 0, tag, 0); + GcmUtilities.Xor(tag, S); + + int resultLen = extra; + + // We place into macBlock our calculated value for T + this.macBlock = new byte[macSize]; + Array.Copy(tag, 0, macBlock, 0, macSize); + + if (forEncryption) + { + // Append T to the message + Array.Copy(macBlock, 0, output, outOff + bufOff, macSize); + resultLen += macSize; + } + else + { + // Retrieve the T value from the message and compare to calculated one + byte[] msgMac = new byte[macSize]; + Array.Copy(bufBlock, extra, msgMac, 0, macSize); + if (!Arrays.ConstantTimeAreEqual(this.macBlock, msgMac)) + throw new InvalidCipherTextException("mac check in GCM failed"); + } + + Reset(false); + + return resultLen; + } + + public virtual void Reset() + { + Reset(true); + } + + private void Reset( + bool clearMac) + { + cipher.Reset(); + + S = new byte[BlockSize]; + S_at = new byte[BlockSize]; + S_atPre = new byte[BlockSize]; + atBlock = new byte[BlockSize]; + atBlockPos = 0; + atLength = 0; + atLengthPre = 0; + counter = Arrays.Clone(J0); + blocksRemaining = uint.MaxValue - 1; + bufOff = 0; + totalLength = 0; + + if (bufBlock != null) + { + Arrays.Fill(bufBlock, 0); + } + + if (clearMac) + { + macBlock = null; + } + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + private void gCTRBlock(byte[] block, byte[] output, int outOff) + { + byte[] tmp = GetNextCounterBlock(); + + GcmUtilities.Xor(tmp, block); + Array.Copy(tmp, 0, output, outOff, BlockSize); + + gHASHBlock(S, forEncryption ? tmp : block); + + totalLength += BlockSize; + } + + private void gCTRPartial(byte[] buf, int off, int len, byte[] output, int outOff) + { + byte[] tmp = GetNextCounterBlock(); + + GcmUtilities.Xor(tmp, buf, off, len); + Array.Copy(tmp, 0, output, outOff, len); + + gHASHPartial(S, forEncryption ? tmp : buf, 0, len); + + totalLength += (uint)len; + } + + private void gHASH(byte[] Y, byte[] b, int len) + { + for (int pos = 0; pos < len; pos += BlockSize) + { + int num = System.Math.Min(len - pos, BlockSize); + gHASHPartial(Y, b, pos, num); + } + } + + private void gHASHBlock(byte[] Y, byte[] b) + { + GcmUtilities.Xor(Y, b); + multiplier.MultiplyH(Y); + } + + private void gHASHPartial(byte[] Y, byte[] b, int off, int len) + { + GcmUtilities.Xor(Y, b, off, len); + multiplier.MultiplyH(Y); + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + private byte[] GetNextCounterBlock() + { + if (blocksRemaining == 0) + throw new InvalidOperationException("Attempt to process too many blocks"); + + blocksRemaining--; + + uint c = 1; + c += counter[15]; counter[15] = (byte)c; c >>= 8; + c += counter[14]; counter[14] = (byte)c; c >>= 8; + c += counter[13]; counter[13] = (byte)c; c >>= 8; + c += counter[12]; counter[12] = (byte)c; + + byte[] tmp = new byte[BlockSize]; + // TODO Sure would be nice if ciphers could operate on int[] + cipher.ProcessBlock(counter, 0, tmp, 0); + return tmp; + } +#else + byte[] tmpBlock; + private unsafe byte[] GetNextCounterBlock() + { + if (blocksRemaining == 0) + throw new InvalidOperationException("Attempt to process too many blocks"); + + blocksRemaining--; + + uint c = 1; + fixed (byte* pcounter = counter) + { + c += pcounter[15]; pcounter[15] = (byte)c; c >>= 8; + c += pcounter[14]; pcounter[14] = (byte)c; c >>= 8; + c += pcounter[13]; pcounter[13] = (byte)c; c >>= 8; + c += pcounter[12]; pcounter[12] = (byte)c; + } + + if (tmpBlock == null) + tmpBlock = new byte[BlockSize]; + else + //Array.Clear(tmpBlock, 0, tmpBlock.Length); + tmpBlock[0] = tmpBlock[1] = tmpBlock[2] = tmpBlock[3] = tmpBlock[4] = tmpBlock[5] = tmpBlock[6] = tmpBlock[7] = tmpBlock[8] = tmpBlock[9] = tmpBlock[10] = tmpBlock[11] = tmpBlock[12] = tmpBlock[13] = tmpBlock[14] = tmpBlock[15] = 0; + // TODO Sure would be nice if ciphers could operate on int[] + cipher.ProcessBlock(counter, 0, tmpBlock, 0); + return tmpBlock; + } +#endif + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs.meta new file mode 100644 index 0000000..473776e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GCMBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9e700bc931d48247b4b368d48e44803 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs new file mode 100644 index 0000000..a5ef342 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs @@ -0,0 +1,231 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements the GOST 28147 OFB counter mode (GCTR). + */ + public class GOfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] ofbV; + private byte[] ofbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + bool firstStep = true; + int N3; + int N4; + const int C1 = 16843012; //00000001000000010000000100000100 + const int C2 = 16843009; //00000001000000010000000100000001 + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * counter mode (must have a 64 bit block size). + */ + public GOfbBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + + if (blockSize != 8) + { + throw new ArgumentException("GCTR only for 64 bit block ciphers"); + } + + this.IV = new byte[cipher.GetBlockSize()]; + this.ofbV = new byte[cipher.GetBlockSize()]; + this.ofbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param encrypting if true the cipher is initialised for + * encryption, if false for decryption. + * @param parameters the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is inappropriate. + */ + public void Init( + bool forEncryption, //ignored by this CTR mode + ICipherParameters parameters) + { + firstStep = true; + N3 = 0; + N4 = 0; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/GCTR" + * and the block size in bits + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/GCTR"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at (in bytes). + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (firstStep) + { + firstStep = false; + cipher.ProcessBlock(ofbV, 0, ofbOutV, 0); + N3 = bytesToint(ofbOutV, 0); + N4 = bytesToint(ofbOutV, 4); + } + N3 += C2; + N4 += C1; + intTobytes(N3, ofbV, 0); + intTobytes(N4, ofbV, 4); + + cipher.ProcessBlock(ofbV, 0, ofbOutV, 0); + + // + // XOR the ofbV with the plaintext producing the cipher text (and + // the next input block). + // + for (int i = 0; i < blockSize; i++) + { + output[outOff + i] = (byte)(ofbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(ofbV, blockSize, ofbV, 0, ofbV.Length - blockSize); + Array.Copy(ofbOutV, 0, ofbV, ofbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the feedback vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, ofbV, 0, IV.Length); + + cipher.Reset(); + } + + //array of bytes to type int + private int bytesToint( + byte[] inBytes, + int inOff) + { + return (int)((inBytes[inOff + 3] << 24) & 0xff000000) + ((inBytes[inOff + 2] << 16) & 0xff0000) + + ((inBytes[inOff + 1] << 8) & 0xff00) + (inBytes[inOff] & 0xff); + } + + //int to array of bytes + private void intTobytes( + int num, + byte[] outBytes, + int outOff) + { + outBytes[outOff + 3] = (byte)(num >> 24); + outBytes[outOff + 2] = (byte)(num >> 16); + outBytes[outOff + 1] = (byte)(num >> 8); + outBytes[outOff] = (byte)num; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs.meta new file mode 100644 index 0000000..a868e4b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/GOFBBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e3a091d7cad075041a691018998b39de +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs new file mode 100644 index 0000000..4d61bca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs @@ -0,0 +1,109 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /// + /// A block cipher mode that includes authenticated encryption with a streaming mode + /// and optional associated data. + /// + public interface IAeadBlockCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// The block cipher underlying this algorithm. + IBlockCipher GetUnderlyingCipher(); + + /// Initialise the cipher. + /// Parameter can either be an AeadParameters or a ParametersWithIV object. + /// Initialise for encryption if true, for decryption if false. + /// The key or other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + /// The block size for this cipher, in bytes. + int GetBlockSize(); + + /// Add a single byte to the associated data check. + /// If the implementation supports it, this will be an online operation and will not retain the associated data. + /// The byte to be processed. + void ProcessAadByte(byte input); + + /// Add a sequence of bytes to the associated data check. + /// If the implementation supports it, this will be an online operation and will not retain the associated data. + /// The input byte array. + /// The offset into the input array where the data to be processed starts. + /// The number of bytes to be processed. + void ProcessAadBytes(byte[] inBytes, int inOff, int len); + + /** + * Encrypt/decrypt a single byte. + * + * @param input the byte to be processed. + * @param outBytes the output buffer the processed byte goes into. + * @param outOff the offset into the output byte array the processed data starts at. + * @return the number of bytes written to out. + * @exception DataLengthException if the output buffer is too small. + */ + int ProcessByte(byte input, byte[] outBytes, int outOff); + + /** + * Process a block of bytes from in putting the result into out. + * + * @param inBytes the input byte array. + * @param inOff the offset into the in array where the data to be processed starts. + * @param len the number of bytes to be processed. + * @param outBytes the output buffer the processed bytes go into. + * @param outOff the offset into the output byte array the processed data starts at. + * @return the number of bytes written to out. + * @exception DataLengthException if the output buffer is too small. + */ + int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff); + + /** + * Finish the operation either appending or verifying the MAC at the end of the data. + * + * @param outBytes space for any resulting output data. + * @param outOff offset into out to start copying the data at. + * @return number of bytes written into out. + * @throws InvalidOperationException if the cipher is in an inappropriate state. + * @throws InvalidCipherTextException if the MAC fails to match. + */ + int DoFinal(byte[] outBytes, int outOff); + + /** + * Return the value of the MAC associated with the last stream processed. + * + * @return MAC for plaintext data. + */ + byte[] GetMac(); + + /** + * Return the size of the output buffer required for a ProcessBytes + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to ProcessBytes + * with len bytes of input. + */ + int GetUpdateOutputSize(int len); + + /** + * Return the size of the output buffer required for a ProcessBytes plus a + * DoFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to ProcessBytes and DoFinal + * with len bytes of input. + */ + int GetOutputSize(int len); + + /// + /// Reset the cipher to the same state as it was after the last init (if there was one). + /// + void Reset(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs.meta new file mode 100644 index 0000000..053f69f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/IAeadBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 18514e25fcebaa840909a75294f2f1e8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs new file mode 100644 index 0000000..3a78c37 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs @@ -0,0 +1,567 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * An implementation of RFC 7253 on The OCB + * Authenticated-Encryption Algorithm, licensed per: + * + *

License for + * Open-Source Software Implementations of OCB (Jan 9, 2013) - 'License 1'
+ * Under this license, you are authorized to make, use, and distribute open-source software + * implementations of OCB. This license terminates for you if you sue someone over their open-source + * software implementation of OCB claiming that you have a patent covering their implementation. + *

+ * This is a non-binding summary of a legal document (the link above). The parameters of the license + * are specified in the license document and that document is controlling.

+ */ + public class OcbBlockCipher + : IAeadBlockCipher + { + private const int BLOCK_SIZE = 16; + + private readonly IBlockCipher hashCipher; + private readonly IBlockCipher mainCipher; + + /* + * CONFIGURATION + */ + private bool forEncryption; + private int macSize; + private byte[] initialAssociatedText; + + /* + * KEY-DEPENDENT + */ + // NOTE: elements are lazily calculated + private IList L; + private byte[] L_Asterisk, L_Dollar; + + /* + * NONCE-DEPENDENT + */ + private byte[] KtopInput = null; + private byte[] Stretch = new byte[24]; + private byte[] OffsetMAIN_0 = new byte[16]; + + /* + * PER-ENCRYPTION/DECRYPTION + */ + private byte[] hashBlock, mainBlock; + private int hashBlockPos, mainBlockPos; + private long hashBlockCount, mainBlockCount; + private byte[] OffsetHASH; + private byte[] Sum; + private byte[] OffsetMAIN = new byte[16]; + private byte[] Checksum; + + // NOTE: The MAC value is preserved after doFinal + private byte[] macBlock; + + public OcbBlockCipher(IBlockCipher hashCipher, IBlockCipher mainCipher) + { + if (hashCipher == null) + throw new ArgumentNullException("hashCipher"); + if (hashCipher.GetBlockSize() != BLOCK_SIZE) + throw new ArgumentException("must have a block size of " + BLOCK_SIZE, "hashCipher"); + if (mainCipher == null) + throw new ArgumentNullException("mainCipher"); + if (mainCipher.GetBlockSize() != BLOCK_SIZE) + throw new ArgumentException("must have a block size of " + BLOCK_SIZE, "mainCipher"); + + if (!hashCipher.AlgorithmName.Equals(mainCipher.AlgorithmName)) + throw new ArgumentException("'hashCipher' and 'mainCipher' must be the same algorithm"); + + this.hashCipher = hashCipher; + this.mainCipher = mainCipher; + } + + public virtual IBlockCipher GetUnderlyingCipher() + { + return mainCipher; + } + + public virtual string AlgorithmName + { + get { return mainCipher.AlgorithmName + "/OCB"; } + } + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + bool oldForEncryption = this.forEncryption; + this.forEncryption = forEncryption; + this.macBlock = null; + + KeyParameter keyParameter; + + byte[] N; + if (parameters is AeadParameters) + { + AeadParameters aeadParameters = (AeadParameters) parameters; + + N = aeadParameters.GetNonce(); + initialAssociatedText = aeadParameters.GetAssociatedText(); + + int macSizeBits = aeadParameters.MacSize; + if (macSizeBits < 64 || macSizeBits > 128 || macSizeBits % 8 != 0) + throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); + + macSize = macSizeBits / 8; + keyParameter = aeadParameters.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV parametersWithIV = (ParametersWithIV) parameters; + + N = parametersWithIV.GetIV(); + initialAssociatedText = null; + macSize = 16; + keyParameter = (KeyParameter) parametersWithIV.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to OCB"); + } + + this.hashBlock = new byte[16]; + this.mainBlock = new byte[forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize)]; + + if (N == null) + { + N = new byte[0]; + } + + if (N.Length > 15) + { + throw new ArgumentException("IV must be no more than 15 bytes"); + } + + /* + * KEY-DEPENDENT INITIALISATION + */ + + if (keyParameter != null) + { + // hashCipher always used in forward mode + hashCipher.Init(true, keyParameter); + mainCipher.Init(forEncryption, keyParameter); + KtopInput = null; + } + else if (oldForEncryption != forEncryption) + { + throw new ArgumentException("cannot change encrypting state without providing key."); + } + + this.L_Asterisk = new byte[16]; + hashCipher.ProcessBlock(L_Asterisk, 0, L_Asterisk, 0); + + this.L_Dollar = OCB_double(L_Asterisk); + + this.L = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + this.L.Add(OCB_double(L_Dollar)); + + /* + * NONCE-DEPENDENT AND PER-ENCRYPTION/DECRYPTION INITIALISATION + */ + + int bottom = ProcessNonce(N); + + int bits = bottom % 8, bytes = bottom / 8; + if (bits == 0) + { + Array.Copy(Stretch, bytes, OffsetMAIN_0, 0, 16); + } + else + { + for (int i = 0; i < 16; ++i) + { + uint b1 = Stretch[bytes]; + uint b2 = Stretch[++bytes]; + this.OffsetMAIN_0[i] = (byte) ((b1 << bits) | (b2 >> (8 - bits))); + } + } + + this.hashBlockPos = 0; + this.mainBlockPos = 0; + + this.hashBlockCount = 0; + this.mainBlockCount = 0; + + this.OffsetHASH = new byte[16]; + this.Sum = new byte[16]; + Array.Copy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); + this.Checksum = new byte[16]; + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + protected virtual int ProcessNonce(byte[] N) + { + byte[] nonce = new byte[16]; + Array.Copy(N, 0, nonce, nonce.Length - N.Length, N.Length); + nonce[0] = (byte)(macSize << 4); + nonce[15 - N.Length] |= 1; + + int bottom = nonce[15] & 0x3F; + nonce[15] &= 0xC0; + + /* + * When used with incrementing nonces, the cipher is only applied once every 64 inits. + */ + if (KtopInput == null || !Arrays.AreEqual(nonce, KtopInput)) + { + byte[] Ktop = new byte[16]; + KtopInput = nonce; + hashCipher.ProcessBlock(KtopInput, 0, Ktop, 0); + Array.Copy(Ktop, 0, Stretch, 0, 16); + for (int i = 0; i < 8; ++i) + { + Stretch[16 + i] = (byte)(Ktop[i] ^ Ktop[i + 1]); + } + } + + return bottom; + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual byte[] GetMac() + { + return Arrays.Clone(macBlock); + } + + public virtual int GetOutputSize(int len) + { + int totalData = len + mainBlockPos; + if (forEncryption) + { + return totalData + macSize; + } + return totalData < macSize ? 0 : totalData - macSize; + } + + public virtual int GetUpdateOutputSize(int len) + { + int totalData = len + mainBlockPos; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % BLOCK_SIZE; + } + + public virtual void ProcessAadByte(byte input) + { + hashBlock[hashBlockPos] = input; + if (++hashBlockPos == hashBlock.Length) + { + ProcessHashBlock(); + } + } + + public virtual void ProcessAadBytes(byte[] input, int off, int len) + { + for (int i = 0; i < len; ++i) + { + hashBlock[hashBlockPos] = input[off + i]; + if (++hashBlockPos == hashBlock.Length) + { + ProcessHashBlock(); + } + } + } + + public virtual int ProcessByte(byte input, byte[] output, int outOff) + { + mainBlock[mainBlockPos] = input; + if (++mainBlockPos == mainBlock.Length) + { + ProcessMainBlock(output, outOff); + return BLOCK_SIZE; + } + return 0; + } + + public virtual int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + int resultLen = 0; + + for (int i = 0; i < len; ++i) + { + mainBlock[mainBlockPos] = input[inOff + i]; + if (++mainBlockPos == mainBlock.Length) + { + ProcessMainBlock(output, outOff + resultLen); + resultLen += BLOCK_SIZE; + } + } + + return resultLen; + } + + public virtual int DoFinal(byte[] output, int outOff) + { + /* + * For decryption, get the tag from the end of the message + */ + byte[] tag = null; + if (!forEncryption) { + if (mainBlockPos < macSize) + throw new InvalidCipherTextException("data too short"); + + mainBlockPos -= macSize; + tag = new byte[macSize]; + Array.Copy(mainBlock, mainBlockPos, tag, 0, macSize); + } + + /* + * HASH: Process any final partial block; compute final hash value + */ + if (hashBlockPos > 0) + { + OCB_extend(hashBlock, hashBlockPos); + UpdateHASH(L_Asterisk); + } + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Process any final partial block + */ + if (mainBlockPos > 0) + { + if (forEncryption) + { + OCB_extend(mainBlock, mainBlockPos); + Xor(Checksum, mainBlock); + } + + Xor(OffsetMAIN, L_Asterisk); + + byte[] Pad = new byte[16]; + hashCipher.ProcessBlock(OffsetMAIN, 0, Pad, 0); + + Xor(mainBlock, Pad); + + Check.OutputLength(output, outOff, mainBlockPos, "Output buffer too short"); + Array.Copy(mainBlock, 0, output, outOff, mainBlockPos); + + if (!forEncryption) + { + OCB_extend(mainBlock, mainBlockPos); + Xor(Checksum, mainBlock); + } + } + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Compute raw tag + */ + Xor(Checksum, OffsetMAIN); + Xor(Checksum, L_Dollar); + hashCipher.ProcessBlock(Checksum, 0, Checksum, 0); + Xor(Checksum, Sum); + + this.macBlock = new byte[macSize]; + Array.Copy(Checksum, 0, macBlock, 0, macSize); + + /* + * Validate or append tag and reset this cipher for the next run + */ + int resultLen = mainBlockPos; + + if (forEncryption) + { + Check.OutputLength(output, outOff, resultLen + macSize, "Output buffer too short"); + + // Append tag to the message + Array.Copy(macBlock, 0, output, outOff + resultLen, macSize); + resultLen += macSize; + } + else + { + // Compare the tag from the message with the calculated one + if (!Arrays.ConstantTimeAreEqual(macBlock, tag)) + throw new InvalidCipherTextException("mac check in OCB failed"); + } + + Reset(false); + + return resultLen; + } + + public virtual void Reset() + { + Reset(true); + } + + protected virtual void Clear(byte[] bs) + { + if (bs != null) + { + Array.Clear(bs, 0, bs.Length); + } + } + + protected virtual byte[] GetLSub(int n) + { + while (n >= L.Count) + { + L.Add(OCB_double((byte[]) L[L.Count - 1])); + } + return (byte[])L[n]; + } + + protected virtual void ProcessHashBlock() + { + /* + * HASH: Process any whole blocks + */ + UpdateHASH(GetLSub(OCB_ntz(++hashBlockCount))); + hashBlockPos = 0; + } + + protected virtual void ProcessMainBlock(byte[] output, int outOff) + { + Check.DataLength(output, outOff, BLOCK_SIZE, "Output buffer too short"); + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks + */ + + if (forEncryption) + { + Xor(Checksum, mainBlock); + mainBlockPos = 0; + } + + Xor(OffsetMAIN, GetLSub(OCB_ntz(++mainBlockCount))); + + Xor(mainBlock, OffsetMAIN); + mainCipher.ProcessBlock(mainBlock, 0, mainBlock, 0); + Xor(mainBlock, OffsetMAIN); + + Array.Copy(mainBlock, 0, output, outOff, 16); + + if (!forEncryption) + { + Xor(Checksum, mainBlock); + Array.Copy(mainBlock, BLOCK_SIZE, mainBlock, 0, macSize); + mainBlockPos = macSize; + } + } + + protected virtual void Reset(bool clearMac) + { + hashCipher.Reset(); + mainCipher.Reset(); + + Clear(hashBlock); + Clear(mainBlock); + + hashBlockPos = 0; + mainBlockPos = 0; + + hashBlockCount = 0; + mainBlockCount = 0; + + Clear(OffsetHASH); + Clear(Sum); + Array.Copy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); + Clear(Checksum); + + if (clearMac) + { + macBlock = null; + } + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + protected virtual void UpdateHASH(byte[] LSub) + { + Xor(OffsetHASH, LSub); + Xor(hashBlock, OffsetHASH); + hashCipher.ProcessBlock(hashBlock, 0, hashBlock, 0); + Xor(Sum, hashBlock); + } + + protected static byte[] OCB_double(byte[] block) + { + byte[] result = new byte[16]; + int carry = ShiftLeft(block, result); + + /* + * NOTE: This construction is an attempt at a constant-time implementation. + */ + result[15] ^= (byte)(0x87 >> ((1 - carry) << 3)); + + return result; + } + + protected static void OCB_extend(byte[] block, int pos) + { + block[pos] = (byte) 0x80; + while (++pos < 16) + { + block[pos] = 0; + } + } + + protected static int OCB_ntz(long x) + { + if (x == 0) + { + return 64; + } + + int n = 0; + ulong ux = (ulong)x; + while ((ux & 1UL) == 0UL) + { + ++n; + ux >>= 1; + } + return n; + } + + protected static int ShiftLeft(byte[] block, byte[] output) + { + int i = 16; + uint bit = 0; + while (--i >= 0) + { + uint b = block[i]; + output[i] = (byte) ((b << 1) | bit); + bit = (b >> 7) & 1; + } + return (int)bit; + } + + protected static void Xor(byte[] block, byte[] val) + { + for (int i = 15; i >= 0; --i) + { + block[i] ^= val[i]; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs.meta new file mode 100644 index 0000000..c6fdc7a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OCBBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 89052943097a6b3488c0e056459769e9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs new file mode 100644 index 0000000..582ba04 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs @@ -0,0 +1,186 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements a Output-FeedBack (OFB) mode on top of a simple cipher. + */ + public class OfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] ofbV; + private byte[] ofbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public OfbBlockCipher( + IBlockCipher cipher, + int blockSize) + { + this.cipher = cipher; + this.blockSize = blockSize / 8; + + this.IV = new byte[cipher.GetBlockSize()]; + this.ofbV = new byte[cipher.GetBlockSize()]; + this.ofbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, //ignored by this OFB mode + ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/OFB" + * and the block size in bits + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/OFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at (in bytes). + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + cipher.ProcessBlock(ofbV, 0, ofbOutV, 0); + + // + // XOR the ofbV with the plaintext producing the cipher text (and + // the next input block). + // + for (int i = 0; i < blockSize; i++) + { + output[outOff + i] = (byte)(ofbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(ofbV, blockSize, ofbV, 0, ofbV.Length - blockSize); + Array.Copy(ofbOutV, 0, ofbV, ofbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the feedback vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, ofbV, 0, IV.Length); + + cipher.Reset(); + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs.meta new file mode 100644 index 0000000..3b3d7d3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OfbBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71bc36ce7925c074aa3654b21bda3a7f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs new file mode 100644 index 0000000..e935adb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs @@ -0,0 +1,341 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements OpenPGP's rather strange version of Cipher-FeedBack (CFB) mode + * on top of a simple cipher. This class assumes the IV has been prepended + * to the data stream already, and just accomodates the reset after + * (blockSize + 2) bytes have been read. + *

+ * For further info see RFC 2440. + *

+ */ + public class OpenPgpCfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] FR; + private byte[] FRE; + + private readonly IBlockCipher cipher; + private readonly int blockSize; + + private int count; + private bool forEncryption; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + */ + public OpenPgpCfbBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + + this.blockSize = cipher.GetBlockSize(); + this.IV = new byte[blockSize]; + this.FR = new byte[blockSize]; + this.FRE = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/PGPCFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/OpenPGPCFB"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) : DecryptBlock(input, inOff, output, outOff); + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + count = 0; + + Array.Copy(IV, 0, FR, 0, FR.Length); + + cipher.Reset(); + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param parameters the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(true, parameters); + } + + /** + * Encrypt one byte of data according to CFB mode. + * @param data the byte to encrypt + * @param blockOff offset in the current block + * @returns the encrypted byte + */ + private byte EncryptByte(byte data, int blockOff) + { + return (byte)(FRE[blockOff] ^ data); + } + + /** + * Do the appropriate processing for CFB IV mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (count > blockSize) + { + FR[blockSize - 2] = outBytes[outOff] = EncryptByte(input[inOff], blockSize - 2); + FR[blockSize - 1] = outBytes[outOff + 1] = EncryptByte(input[inOff + 1], blockSize - 1); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + FR[n - 2] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + } + else if (count == 0) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 0; n < blockSize; n++) + { + FR[n] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n); + } + + count += blockSize; + } + else if (count == blockSize) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + outBytes[outOff] = EncryptByte(input[inOff], 0); + outBytes[outOff + 1] = EncryptByte(input[inOff + 1], 1); + + // + // do reset + // + Array.Copy(FR, 2, FR, 0, blockSize - 2); + Array.Copy(outBytes, outOff, FR, blockSize - 2, 2); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + FR[n - 2] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + + count += blockSize; + } + + return blockSize; + } + + /** + * Do the appropriate processing for CFB IV mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (count > blockSize) + { + byte inVal = input[inOff]; + FR[blockSize - 2] = inVal; + outBytes[outOff] = EncryptByte(inVal, blockSize - 2); + + inVal = input[inOff + 1]; + FR[blockSize - 1] = inVal; + outBytes[outOff + 1] = EncryptByte(inVal, blockSize - 1); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + inVal = input[inOff + n]; + FR[n - 2] = inVal; + outBytes[outOff + n] = EncryptByte(inVal, n - 2); + } + } + else if (count == 0) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 0; n < blockSize; n++) + { + FR[n] = input[inOff + n]; + outBytes[n] = EncryptByte(input[inOff + n], n); + } + + count += blockSize; + } + else if (count == blockSize) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + byte inVal1 = input[inOff]; + byte inVal2 = input[inOff + 1]; + outBytes[outOff ] = EncryptByte(inVal1, 0); + outBytes[outOff + 1] = EncryptByte(inVal2, 1); + + Array.Copy(FR, 2, FR, 0, blockSize - 2); + + FR[blockSize - 2] = inVal1; + FR[blockSize - 1] = inVal2; + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + byte inVal = input[inOff + n]; + FR[n - 2] = inVal; + outBytes[outOff + n] = EncryptByte(inVal, n - 2); + } + + count += blockSize; + } + + return blockSize; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs.meta new file mode 100644 index 0000000..639e279 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/OpenPgpCfbBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b1ada4d10e1ce0546a797441077dd7a4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs new file mode 100644 index 0000000..20b6c5f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs @@ -0,0 +1,124 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements the Segmented Integer Counter (SIC) mode on top of a simple + * block cipher. + */ + public class SicBlockCipher + : IBlockCipher + { + private readonly IBlockCipher cipher; + private readonly int blockSize; + private readonly byte[] counter; + private readonly byte[] counterOut; + private byte[] IV; + + /** + * Basic constructor. + * + * @param c the block cipher to be used. + */ + public SicBlockCipher(IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + this.counter = new byte[blockSize]; + this.counterOut = new byte[blockSize]; + this.IV = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual void Init( + bool forEncryption, //ignored by this CTR mode + ICipherParameters parameters) + { + ParametersWithIV ivParam = parameters as ParametersWithIV; + if (ivParam == null) + throw new ArgumentException("CTR/SIC mode requires ParametersWithIV", "parameters"); + + this.IV = Arrays.Clone(ivParam.GetIV()); + + if (blockSize < IV.Length) + throw new ArgumentException("CTR/SIC mode requires IV no greater than: " + blockSize + " bytes."); + + int maxCounterSize = System.Math.Min(8, blockSize / 2); + if (blockSize - IV.Length > maxCounterSize) + throw new ArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - maxCounterSize) + " bytes."); + + // if null it's an IV changed only. + if (ivParam.Parameters != null) + { + cipher.Init(true, ivParam.Parameters); + } + + Reset(); + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/SIC"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return true; } + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + cipher.ProcessBlock(counter, 0, counterOut, 0); + + // + // XOR the counterOut with the plaintext producing the cipher text + // + for (int i = 0; i < counterOut.Length; i++) + { + output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]); + } + + // Increment the counter + int j = counter.Length; + while (--j >= 0 && ++counter[j] == 0) + { + } + + return counter.Length; + } + + public virtual void Reset() + { + Arrays.Fill(counter, (byte)0); + Array.Copy(IV, 0, counter, 0, IV.Length); + cipher.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs.meta new file mode 100644 index 0000000..0fd5e69 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/SicBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2296184ee476c384393555a8260b697e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm.meta new file mode 100644 index 0000000..2bc8528 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 25332b96083d377489f73df4e40c17c8 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs new file mode 100644 index 0000000..10f33e5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs @@ -0,0 +1,389 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + internal abstract class GcmUtilities + { + private const uint E1 = 0xe1000000; + private const ulong E1L = (ulong)E1 << 32; + + private static uint[] GenerateLookup() + { + uint[] lookup = new uint[256]; + + for (int c = 0; c < 256; ++c) + { + uint v = 0; + for (int i = 7; i >= 0; --i) + { + if ((c & (1 << i)) != 0) + { + v ^= (E1 >> (7 - i)); + } + } + lookup[c] = v; + } + + return lookup; + } + + private static readonly uint[] LOOKUP = GenerateLookup(); + + internal static byte[] OneAsBytes() + { + byte[] tmp = new byte[16]; + tmp[0] = 0x80; + return tmp; + } + + internal static uint[] OneAsUints() + { + uint[] tmp = new uint[4]; + tmp[0] = 0x80000000; + return tmp; + } + + internal static ulong[] OneAsUlongs() + { + ulong[] tmp = new ulong[2]; + tmp[0] = 1UL << 63; + return tmp; + } + + internal static byte[] AsBytes(uint[] x) + { + return Pack.UInt32_To_BE(x); + } + + internal static void AsBytes(uint[] x, byte[] z) + { + Pack.UInt32_To_BE(x, z, 0); + } + + internal static byte[] AsBytes(ulong[] x) + { + byte[] z = new byte[16]; + Pack.UInt64_To_BE(x, z, 0); + return z; + } + + internal static void AsBytes(ulong[] x, byte[] z) + { + Pack.UInt64_To_BE(x, z, 0); + } + + internal static uint[] AsUints(byte[] bs) + { + uint[] output = new uint[4]; + Pack.BE_To_UInt32(bs, 0, output); + return output; + } + + internal static void AsUints(byte[] bs, uint[] output) + { + Pack.BE_To_UInt32(bs, 0, output); + } + + internal static ulong[] AsUlongs(byte[] x) + { + ulong[] z = new ulong[2]; + Pack.BE_To_UInt64(x, 0, z); + return z; + } + + public static void AsUlongs(byte[] x, ulong[] z) + { + Pack.BE_To_UInt64(x, 0, z); + } + + internal static void Multiply(byte[] x, byte[] y) + { + uint[] t1 = GcmUtilities.AsUints(x); + uint[] t2 = GcmUtilities.AsUints(y); + GcmUtilities.Multiply(t1, t2); + GcmUtilities.AsBytes(t1, x); + } + + internal static void Multiply(uint[] x, uint[] y) + { + uint r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3]; + uint r10 = 0, r11 = 0, r12 = 0, r13 = 0; + + for (int i = 0; i < 4; ++i) + { + int bits = (int)y[i]; + for (int j = 0; j < 32; ++j) + { + uint m1 = (uint)(bits >> 31); bits <<= 1; + r10 ^= (r00 & m1); + r11 ^= (r01 & m1); + r12 ^= (r02 & m1); + r13 ^= (r03 & m1); + + uint m2 = (uint)((int)(r03 << 31) >> 8); + r03 = (r03 >> 1) | (r02 << 31); + r02 = (r02 >> 1) | (r01 << 31); + r01 = (r01 >> 1) | (r00 << 31); + r00 = (r00 >> 1) ^ (m2 & E1); + } + } + + x[0] = r10; + x[1] = r11; + x[2] = r12; + x[3] = r13; + } + + internal static void Multiply(ulong[] x, ulong[] y) + { + ulong r00 = x[0], r01 = x[1], r10 = 0, r11 = 0; + + for (int i = 0; i < 2; ++i) + { + long bits = (long)y[i]; + for (int j = 0; j < 64; ++j) + { + ulong m1 = (ulong)(bits >> 63); bits <<= 1; + r10 ^= (r00 & m1); + r11 ^= (r01 & m1); + + ulong m2 = (ulong)((long)(r01 << 63) >> 8); + r01 = (r01 >> 1) | (r00 << 63); + r00 = (r00 >> 1) ^ (m2 & E1L); + } + } + + x[0] = r10; + x[1] = r11; + } + + // P is the value with only bit i=1 set + internal static void MultiplyP(uint[] x) + { + uint m = (uint)((int)ShiftRight(x) >> 8); + x[0] ^= (m & E1); + } + + internal static void MultiplyP(uint[] x, uint[] z) + { + uint m = (uint)((int)ShiftRight(x, z) >> 8); + z[0] ^= (m & E1); + } + + internal static void MultiplyP8(uint[] x) + { +// for (int i = 8; i != 0; --i) +// { +// MultiplyP(x); +// } + + uint c = ShiftRightN(x, 8); + x[0] ^= LOOKUP[c >> 24]; + } + + internal static void MultiplyP8(uint[] x, uint[] y) + { + uint c = ShiftRightN(x, 8, y); + y[0] ^= LOOKUP[c >> 24]; + } + + internal static uint ShiftRight(uint[] x) + { + uint b = x[0]; + x[0] = b >> 1; + uint c = b << 31; + b = x[1]; + x[1] = (b >> 1) | c; + c = b << 31; + b = x[2]; + x[2] = (b >> 1) | c; + c = b << 31; + b = x[3]; + x[3] = (b >> 1) | c; + return b << 31; + } + + internal static uint ShiftRight(uint[] x, uint[] z) + { + uint b = x[0]; + z[0] = b >> 1; + uint c = b << 31; + b = x[1]; + z[1] = (b >> 1) | c; + c = b << 31; + b = x[2]; + z[2] = (b >> 1) | c; + c = b << 31; + b = x[3]; + z[3] = (b >> 1) | c; + return b << 31; + } + + internal static uint ShiftRightN(uint[] x, int n) + { + uint b = x[0]; int nInv = 32 - n; + x[0] = b >> n; + uint c = b << nInv; + b = x[1]; + x[1] = (b >> n) | c; + c = b << nInv; + b = x[2]; + x[2] = (b >> n) | c; + c = b << nInv; + b = x[3]; + x[3] = (b >> n) | c; + return b << nInv; + } + + internal static uint ShiftRightN(uint[] x, int n, uint[] z) + { + uint b = x[0]; int nInv = 32 - n; + z[0] = b >> n; + uint c = b << nInv; + b = x[1]; + z[1] = (b >> n) | c; + c = b << nInv; + b = x[2]; + z[2] = (b >> n) | c; + c = b << nInv; + b = x[3]; + z[3] = (b >> n) | c; + return b << nInv; + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + internal static void Xor(byte[] x, byte[] y) + { + int i = 0; + do + { + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + } + while (i < 16); + } +#else + internal static unsafe void Xor(byte[] x, byte[] y) + { + //int i = 0; + fixed (byte* px = x) + fixed (byte* py = y) + { + //do + //{ + // px[i] ^= py[i]; ++i; + // px[i] ^= py[i]; ++i; + // px[i] ^= py[i]; ++i; + // px[i] ^= py[i]; ++i; + //} + //while (i < 16); + + px[0] ^= py[0]; + px[1] ^= py[1]; + px[2] ^= py[2]; + px[3] ^= py[3]; + + px[4] ^= py[4]; + px[5] ^= py[5]; + px[6] ^= py[6]; + px[7] ^= py[7]; + + px[8] ^= py[8]; + px[9] ^= py[9]; + px[10] ^= py[10]; + px[11] ^= py[11]; + + px[12] ^= py[12]; + px[13] ^= py[13]; + px[14] ^= py[14]; + px[15] ^= py[15]; + } + } +#endif + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + internal static void Xor(byte[] x, byte[] y, int yOff, int yLen) + { + while (--yLen >= 0) + { + x[yLen] ^= y[yOff + yLen]; + } + } +#else + + internal static unsafe void Xor(byte[] x, byte[] y, int yOff, int yLen) + { + fixed (byte* px = x) + fixed(byte* py = y) + while (--yLen >= 0) + { + px[yLen] ^= py[yOff + yLen]; + } + } +#endif + + internal static void Xor(byte[] x, byte[] y, byte[] z) + { + int i = 0; + do + { + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + } + while (i < 16); + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + internal static void Xor(uint[] x, uint[] y) + { + x[0] ^= y[0]; + x[1] ^= y[1]; + x[2] ^= y[2]; + x[3] ^= y[3]; + } +#else + internal static unsafe void Xor(uint[] x, uint[] y) + { + fixed (uint* px = x) + fixed (uint* py = y) + { + px[0] ^= py[0]; + px[1] ^= py[1]; + px[2] ^= py[2]; + px[3] ^= py[3]; + } + } +#endif + + internal static void Xor(uint[] x, uint[] y, uint[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + internal static void Xor(ulong[] x, ulong[] y) + { + x[0] ^= y[0]; + x[1] ^= y[1]; + } + + internal static void Xor(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs.meta new file mode 100644 index 0000000..7f2cfbc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/GcmUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a537b491bcdd0934aac526f2ac481e5e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs new file mode 100644 index 0000000..015c91f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs @@ -0,0 +1,14 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public interface IGcmExponentiator + { + void Init(byte[] x); + void ExponentiateX(long pow, byte[] output); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs.meta new file mode 100644 index 0000000..69e795c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmExponentiator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2b9360b15af87e1479595647271315ad +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs new file mode 100644 index 0000000..9955dac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs @@ -0,0 +1,14 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public interface IGcmMultiplier + { + void Init(byte[] H); + void MultiplyH(byte[] x); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs.meta new file mode 100644 index 0000000..a659de6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/IGcmMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c18943b1cef80dd40b832574fd4e810e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs new file mode 100644 index 0000000..3fdfca8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs @@ -0,0 +1,63 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class Tables1kGcmExponentiator + : IGcmExponentiator + { + // A lookup table of the power-of-two powers of 'x' + // - lookupPowX2[i] = x^(2^i) + private IList lookupPowX2; + + public void Init(byte[] x) + { + uint[] y = GcmUtilities.AsUints(x); + if (lookupPowX2 != null && Arrays.AreEqual(y, (uint[])lookupPowX2[0])) + return; + + lookupPowX2 = Org.BouncyCastle.Utilities.Platform.CreateArrayList(8); + lookupPowX2.Add(y); + } + + public void ExponentiateX(long pow, byte[] output) + { + uint[] y = GcmUtilities.OneAsUints(); + int bit = 0; + while (pow > 0) + { + if ((pow & 1L) != 0) + { + EnsureAvailable(bit); + GcmUtilities.Multiply(y, (uint[])lookupPowX2[bit]); + } + ++bit; + pow >>= 1; + } + + GcmUtilities.AsBytes(y, output); + } + + private void EnsureAvailable(int bit) + { + int count = lookupPowX2.Count; + if (count <= bit) + { + uint[] tmp = (uint[])lookupPowX2[count - 1]; + do + { + tmp = Arrays.Clone(tmp); + GcmUtilities.Multiply(tmp, tmp); + lookupPowX2.Add(tmp); + } + while (++count <= bit); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta new file mode 100644 index 0000000..9b43d4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fb76a60bca7933e4fa45510eada87774 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs new file mode 100644 index 0000000..77ce0b0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs @@ -0,0 +1,200 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public sealed class Tables8kGcmMultiplier + : IGcmMultiplier + { + private byte[] H; + private uint[][][] M; + + public void Init(byte[] H) + { + if (M == null) + { + M = new uint[32][][]; + } + else if (Arrays.AreEqual(this.H, H)) + { + return; + } + + this.H = Arrays.Clone(H); + + M[0] = new uint[16][]; + M[1] = new uint[16][]; + M[0][0] = new uint[4]; + M[1][0] = new uint[4]; + M[1][8] = GcmUtilities.AsUints(H); + + for (int j = 4; j >= 1; j >>= 1) + { + uint[] tmp = (uint[])M[1][j + j].Clone(); + GcmUtilities.MultiplyP(tmp); + M[1][j] = tmp; + } + + { + uint[] tmp = (uint[])M[1][1].Clone(); + GcmUtilities.MultiplyP(tmp); + M[0][8] = tmp; + } + + for (int j = 4; j >= 1; j >>= 1) + { + uint[] tmp = (uint[])M[0][j + j].Clone(); + GcmUtilities.MultiplyP(tmp); + M[0][j] = tmp; + } + + for (int i = 0; ; ) + { + for (int j = 2; j < 16; j += j) + { + for (int k = 1; k < j; ++k) + { + uint[] tmp = (uint[])M[i][j].Clone(); + GcmUtilities.Xor(tmp, M[i][k]); + M[i][j + k] = tmp; + } + } + + if (++i == 32) return; + + if (i > 1) + { + M[i] = new uint[16][]; + M[i][0] = new uint[4]; + for (int j = 8; j > 0; j >>= 1) + { + uint[] tmp = (uint[])M[i - 2][j].Clone(); + GcmUtilities.MultiplyP8(tmp); + M[i][j] = tmp; + } + } + } + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + public void MultiplyH(byte[] x) + { + uint[] z = new uint[4]; + for (int i = 15; i >= 0; --i) + { + //GcmUtilities.Xor(z, M[i + i][x[i] & 0x0f]); + uint[] m = M[i + i][x[i] & 0x0f]; + z[0] ^= m[0]; + z[1] ^= m[1]; + z[2] ^= m[2]; + z[3] ^= m[3]; + //GcmUtilities.Xor(z, M[i + i + 1][(x[i] & 0xf0) >> 4]); + m = M[i + i + 1][(x[i] & 0xf0) >> 4]; + z[0] ^= m[0]; + z[1] ^= m[1]; + z[2] ^= m[2]; + z[3] ^= m[3]; + } + + Pack.UInt32_To_BE(z, x, 0); + } +#else + uint[] z = new uint[4]; + public unsafe void MultiplyH(byte[] x) + { + //Array.Clear(z, 0, z.Length); + + fixed (byte* px = x) + fixed (uint* pz = z) + { + pz[0] = pz[1] = pz[2] = pz[3] = 0; + + for (int i = 15; i >= 0; --i) + { + //GcmUtilities.Xor(z, M[i + i][x[i] & 0x0f]); + //uint[] m = M[i + i][x[i] & 0x0f]; + //z[0] ^= m[0]; + //z[1] ^= m[1]; + //z[2] ^= m[2]; + //z[3] ^= m[3]; + + fixed (uint* pm = M[i + i][px[i] & 0x0f]) + { + pz[0] ^= pm[0]; + pz[1] ^= pm[1]; + pz[2] ^= pm[2]; + pz[3] ^= pm[3]; + } + + //GcmUtilities.Xor(z, M[i + i + 1][(x[i] & 0xf0) >> 4]); + //m = M[i + i + 1][(x[i] & 0xf0) >> 4]; + //z[0] ^= m[0]; + //z[1] ^= m[1]; + //z[2] ^= m[2]; + //z[3] ^= m[3]; + + fixed (uint* pm = M[i + i + 1][(px[i] & 0xf0) >> 4]) + { + pz[0] ^= pm[0]; + pz[1] ^= pm[1]; + pz[2] ^= pm[2]; + pz[3] ^= pm[3]; + } + } + + //int off = 0; + //for (int i = 0; i < 4; ++i) + //{ + // uint n = pz[i]; + // + // px[off + 0] = (byte)(n >> 24); + // px[off + 1] = (byte)(n >> 16); + // px[off + 2] = (byte)(n >> 8); + // px[off + 3] = (byte)(n); + // + // off += 4; + //} + // i = 0 + uint n = pz[0]; + + px[0] = (byte)(n >> 24); + px[1] = (byte)(n >> 16); + px[2] = (byte)(n >> 8); + px[3] = (byte)(n); + + // i = 1 + n = pz[1]; + + px[4] = (byte)(n >> 24); + px[5] = (byte)(n >> 16); + px[6] = (byte)(n >> 8); + px[7] = (byte)(n); + + // i = 2 + n = pz[2]; + + px[8] = (byte)(n >> 24); + px[9] = (byte)(n >> 16); + px[10] = (byte)(n >> 8); + px[11] = (byte)(n); + + // i = 3 + n = pz[3]; + + px[12] = (byte)(n >> 24); + px[13] = (byte)(n >> 16); + px[14] = (byte)(n >> 8); + px[15] = (byte)(n); + } + + //Pack.UInt32_To_BE(z, x, 0); + } +#endif + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta new file mode 100644 index 0000000..68aade7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d0ed8793a414fb442ad8987957e3d03f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators.meta new file mode 100644 index 0000000..4902e83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 68a42d586834bc5489474f303f2686c1 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs new file mode 100644 index 0000000..e5f20cc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs @@ -0,0 +1,557 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Operators +{ + internal class X509Utilities + { + private static readonly Asn1Null derNull = DerNull.Instance; + + private static readonly IDictionary algorithms = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary exParams = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly ISet noParams = new HashSet(); + + static X509Utilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); + algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + noParams.Add(NistObjectIdentifiers.DsaWithSha384); + noParams.Add(NistObjectIdentifiers.DsaWithSha512); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + + internal static string GetSignatureName(AlgorithmIdentifier sigAlgId) + { + Asn1Encodable parameters = sigAlgId.Parameters; + + if (parameters != null && !derNull.Equals(parameters)) + { + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters); + + return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1"; + } + if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2)) + { + Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters); + + return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA"; + } + } + + return sigAlgId.Algorithm.Id; + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithmName); + + if (algorithms.Contains(algorithmName)) + { + return (DerObjectIdentifier) algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid, + string algorithmName) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + algorithmName = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithmName); + + if (exParams.Contains(algorithmName)) + { + return new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable GetAlgNames() + { + return new EnumerableProxy(algorithms.Keys); + } + } + + internal class SignerBucket + : Stream + { + protected readonly ISigner signer; + + public SignerBucket( + ISigner signer) + { + this.signer = signer; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + throw new NotImplementedException (); + } + + public override int ReadByte() + { + throw new NotImplementedException (); + } + + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (count > 0) + { + signer.BlockUpdate(buffer, offset, count); + } + } + + public override void WriteByte( + byte b) + { + signer.Update(b); + } + + public override bool CanRead + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override long Length + { + get { return 0; } + } + + public override long Position + { + get { throw new NotImplementedException (); } + set { throw new NotImplementedException (); } + } + + public override void Flush() + { + } + + public override long Seek( + long offset, + SeekOrigin origin) + { + throw new NotImplementedException (); + } + + public override void SetLength( + long length) + { + throw new NotImplementedException (); + } + } + + /// + /// Calculator factory class for signature generation in ASN.1 based profiles that use an AlgorithmIdentifier to preserve + /// signature algorithm details. + /// + public class Asn1SignatureFactory: ISignatureFactory + { + private readonly AlgorithmIdentifier algID; + private readonly string algorithm; + private readonly AsymmetricKeyParameter privateKey; + private readonly SecureRandom random; + + /// + /// Base constructor. + /// + /// The name of the signature algorithm to use. + /// The private key to be used in the signing operation. + public Asn1SignatureFactory (string algorithm, AsymmetricKeyParameter privateKey): this(algorithm, privateKey, null) + { + } + + /// + /// Constructor which also specifies a source of randomness to be used if one is required. + /// + /// The name of the signature algorithm to use. + /// The private key to be used in the signing operation. + /// The source of randomness to be used in signature calculation. + public Asn1SignatureFactory (string algorithm, AsymmetricKeyParameter privateKey, SecureRandom random) + { + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid (algorithm); + + this.algorithm = algorithm; + this.privateKey = privateKey; + this.random = random; + this.algID = X509Utilities.GetSigAlgID (sigOid, algorithm); + } + + public Object AlgorithmDetails + { + get { return this.algID; } + } + + public IStreamCalculator CreateCalculator() + { + ISigner sig = SignerUtilities.GetSigner(algorithm); + + if (random != null) + { + sig.Init(true, new ParametersWithRandom(privateKey, random)); + } + else + { + sig.Init(true, privateKey); + } + + return new SigCalculator(sig); + } + + /// + /// Allows enumeration of the signature names supported by the verifier provider. + /// + public static IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } + + internal class SigCalculator : IStreamCalculator + { + private readonly ISigner sig; + private readonly Stream stream; + + internal SigCalculator(ISigner sig) + { + this.sig = sig; + this.stream = new SignerBucket(sig); + } + + public Stream Stream + { + get { return stream; } + } + + public object GetResult() + { + return new SigResult(sig); + } + } + + internal class SigResult : IBlockResult + { + private readonly ISigner sig; + + internal SigResult(ISigner sig) + { + this.sig = sig; + } + + public byte[] Collect() + { + return sig.GenerateSignature(); + } + + public int Collect(byte[] destination, int offset) + { + byte[] signature = Collect(); + + Array.Copy(signature, 0, destination, offset, signature.Length); + + return signature.Length; + } + } + + /// + /// Verifier class for signature verification in ASN.1 based profiles that use an AlgorithmIdentifier to preserve + /// signature algorithm details. + /// + public class Asn1VerifierFactory: IVerifierFactory + { + private readonly AlgorithmIdentifier algID; + private readonly AsymmetricKeyParameter publicKey; + + /// + /// Base constructor. + /// + /// The name of the signature algorithm to use. + /// The public key to be used in the verification operation. + public Asn1VerifierFactory (String algorithm, AsymmetricKeyParameter publicKey) + { + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid (algorithm); + + this.publicKey = publicKey; + this.algID = X509Utilities.GetSigAlgID (sigOid, algorithm); + } + + public Asn1VerifierFactory (AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey) + { + this.publicKey = publicKey; + this.algID = algorithm; + } + + public Object AlgorithmDetails + { + get { return this.algID; } + } + + public IStreamCalculator CreateCalculator() + { + ISigner sig = SignerUtilities.GetSigner(X509Utilities.GetSignatureName(algID)); + + sig.Init(false, publicKey); + + return new VerifierCalculator(sig); + } + } + + internal class VerifierCalculator : IStreamCalculator + { + private readonly ISigner sig; + private readonly Stream stream; + + internal VerifierCalculator(ISigner sig) + { + this.sig = sig; + this.stream = new SignerBucket(sig); + } + + public Stream Stream + { + get { return stream; } + } + + public object GetResult() + { + return new VerifierResult(sig); + } + } + + internal class VerifierResult : IVerifier + { + private readonly ISigner sig; + + internal VerifierResult(ISigner sig) + { + this.sig = sig; + } + + public bool IsVerified(byte[] signature) + { + return sig.VerifySignature(signature); + } + + public bool IsVerified(byte[] signature, int off, int length) + { + byte[] sigBytes = new byte[length]; + + Array.Copy(signature, 0, sigBytes, off, sigBytes.Length); + + return sig.VerifySignature(signature); + } + } + + /// + /// Provider class which supports dynamic creation of signature verifiers. + /// + public class Asn1VerifierFactoryProvider: IVerifierFactoryProvider + { + private readonly AsymmetricKeyParameter publicKey; + + /// + /// Base constructor - specify the public key to be used in verification. + /// + /// The public key to be used in creating verifiers provided by this object. + public Asn1VerifierFactoryProvider(AsymmetricKeyParameter publicKey) + { + this.publicKey = publicKey; + } + + public IVerifierFactory CreateVerifierFactory(Object algorithmDetails) + { + return new Asn1VerifierFactory ((AlgorithmIdentifier)algorithmDetails, publicKey); + } + + /// + /// Allows enumeration of the signature names supported by the verifier provider. + /// + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs.meta new file mode 100644 index 0000000..dcc54de --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/operators/Asn1Signature.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3cfa37c567c69d64e94a320d53944aff +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings.meta new file mode 100644 index 0000000..c2a9d82 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c60458b835ab8c54ba3ae600588beeeb +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs new file mode 100644 index 0000000..52e7572 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs @@ -0,0 +1,47 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * Block cipher padders are expected to conform to this interface + */ + public interface IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param param parameters, if any required. + */ + void Init(SecureRandom random); + //throws ArgumentException; + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + string PaddingName { get; } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + int AddPadding(byte[] input, int inOff); + + /** + * return the number of pad bytes present in the block. + * @exception InvalidCipherTextException if the padding is badly formed + * or invalid. + */ + int PadCount(byte[] input); + //throws InvalidCipherTextException; + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs.meta new file mode 100644 index 0000000..86b29e3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/BlockCipherPadding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4f24f6689dd124343ab88b53bbef3e26 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs new file mode 100644 index 0000000..8172919 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs @@ -0,0 +1,80 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /** + * A padder that adds ISO10126-2 padding to a block. + */ + public class ISO10126d2Padding: IBlockCipherPadding + { + private SecureRandom random; + + /** + * Initialise the padder. + * + * @param random a SecureRandom if available. + */ + public void Init( + SecureRandom random) + //throws ArgumentException + { + this.random = (random != null) ? random : new SecureRandom(); + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "ISO10126-2"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < (input.Length - 1)) + { + input[inOff] = (byte)random.NextInt(); + inOff++; + } + + input[inOff] = code; + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount(byte[] input) + //throws InvalidCipherTextException + { + int count = input[input.Length - 1] & 0xff; + + if (count > input.Length) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs.meta new file mode 100644 index 0000000..5830c39 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO10126d2Padding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 81e4c7d79b217c44da9b2dc55d48fb3d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs new file mode 100644 index 0000000..5a164b5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs @@ -0,0 +1,83 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds the padding according to the scheme referenced in + * ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is 0x80, rest is 0x00 + */ + public class ISO7816d4Padding + : IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param random - a SecureRandom if available. + */ + public void Init( + SecureRandom random) + { + // nothing to do. + } + + /** + * Return the name of the algorithm the padder implements. + * + * @return the name of the algorithm the padder implements. + */ + public string PaddingName + { + get { return "ISO7816-4"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + int added = (input.Length - inOff); + + input[inOff]= (byte) 0x80; + inOff ++; + + while (inOff < input.Length) + { + input[inOff] = (byte) 0; + inOff++; + } + + return added; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + int count = input.Length - 1; + + while (count > 0 && input[count] == 0) + { + count--; + } + + if (input[count] != (byte)0x80) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return input.Length - count; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs.meta new file mode 100644 index 0000000..ada3368 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ISO7816d4Padding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 26e9e3006aa8e5b49939429f343fbea4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs new file mode 100644 index 0000000..6850394 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs @@ -0,0 +1,289 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A wrapper class that allows block ciphers to be used to process data in + * a piecemeal fashion with padding. The PaddedBufferedBlockCipher + * outputs a block only when the buffer is full and more data is being added, + * or on a doFinal (unless the current block in the buffer is a pad block). + * The default padding mechanism used is the one outlined in Pkcs5/Pkcs7. + */ + public class PaddedBufferedBlockCipher + : BufferedBlockCipher + { + private readonly IBlockCipherPadding padding; + + /** + * Create a buffered block cipher with the desired padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + * @param padding the padding type. + */ + public PaddedBufferedBlockCipher( + IBlockCipher cipher, + IBlockCipherPadding padding) + { + this.cipher = cipher; + this.padding = padding; + + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + /** + * Create a buffered block cipher Pkcs7 padding + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public PaddedBufferedBlockCipher( + IBlockCipher cipher) + : this(cipher, new Pkcs7Padding()) { } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + SecureRandom initRandom = null; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom)parameters; + initRandom = p.Random; + parameters = p.Parameters; + } + + Reset(); + padding.Init(initRandom); + cipher.Init(forEncryption, parameters); + } + + /** + * return the minimum size of the output buffer required for an update + * plus a doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + if (forEncryption) + { + return total + buf.Length; + } + + return total; + } + + return total - leftOver + buf.Length; + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + return total - buf.Length; + } + + return total - leftOver; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + if (bufOff == buf.Length) + { + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + } + + buf[bufOff++] = input; + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 0) + { + throw new ArgumentException("Can't have a negative input length!"); + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + Check.OutputLength(output, outOff, outLength, "output buffer too short"); + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + + bufOff = 0; + length -= gapLen; + inOff += gapLen; + + while (length > buf.Length) + { + resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + + length -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, length); + + bufOff += length; + + return resultLen; + } + + /** + * Process the last block in the buffer. If the buffer is currently + * full and padding needs to be added a call to doFinal will produce + * 2 * GetBlockSize() bytes. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output or we are decrypting and the input is not block size aligned. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + + if (forEncryption) + { + if (bufOff == blockSize) + { + if ((outOff + 2 * blockSize) > output.Length) + { + Reset(); + + throw new OutputLengthException("output buffer too short"); + } + + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + + Reset(); + } + else + { + if (bufOff == blockSize) + { + resultLen = cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + else + { + Reset(); + + throw new DataLengthException("last block incomplete in decryption"); + } + + try + { + resultLen -= padding.PadCount(buf); + + Array.Copy(buf, 0, output, outOff, resultLen); + } + finally + { + Reset(); + } + } + + return resultLen; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs.meta new file mode 100644 index 0000000..8aaecf6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/PaddedBufferedBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 65e1994a7e4976f4aa5b7844d08da1d2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs new file mode 100644 index 0000000..b25d730 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs @@ -0,0 +1,80 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds Pkcs7/Pkcs5 padding to a block. + */ + public class Pkcs7Padding + : IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param random - a SecureRandom if available. + */ + public void Init( + SecureRandom random) + { + // nothing to do. + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "PKCS7"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < input.Length) + { + input[inOff] = code; + inOff++; + } + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + byte countAsByte = input[input.Length - 1]; + int count = countAsByte; + + if (count < 1 || count > input.Length) + throw new InvalidCipherTextException("pad block corrupted"); + + for (int i = 2; i <= count; i++) + { + if (input[input.Length - i] != countAsByte) + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs.meta new file mode 100644 index 0000000..c0af49c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/Pkcs7Padding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a987dc3355949814fa1b788c5ba932d6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs new file mode 100644 index 0000000..c30b576 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs @@ -0,0 +1,83 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /// A padder that adds Trailing-Bit-Compliment padding to a block. + ///

+ /// This padding pads the block out compliment of the last bit + /// of the plain text. + ///

+ ///
+ public class TbcPadding + : IBlockCipherPadding + { + /// Return the name of the algorithm the cipher implements. + /// the name of the algorithm the cipher implements. + /// + public string PaddingName + { + get { return "TBC"; } + } + + /// Initialise the padder. + /// - a SecureRandom if available. + /// + public virtual void Init(SecureRandom random) + { + // nothing to do. + } + + /// add the pad bytes to the passed in block, returning the + /// number of bytes added. + ///

+ /// Note: this assumes that the last block of plain text is always + /// passed to it inside in. i.e. if inOff is zero, indicating the + /// entire block is to be overwritten with padding the value of in + /// should be the same as the last block of plain text. + ///

+ ///
+ public virtual int AddPadding(byte[] input, int inOff) + { + int count = input.Length - inOff; + byte code; + + if (inOff > 0) + { + code = (byte)((input[inOff - 1] & 0x01) == 0?0xff:0x00); + } + else + { + code = (byte)((input[input.Length - 1] & 0x01) == 0?0xff:0x00); + } + + while (inOff < input.Length) + { + input[inOff] = code; + inOff++; + } + + return count; + } + + /// return the number of pad bytes present in the block. + public virtual int PadCount(byte[] input) + { + byte code = input[input.Length - 1]; + + int index = input.Length - 1; + while (index > 0 && input[index - 1] == code) + { + index--; + } + + return input.Length - index; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs.meta new file mode 100644 index 0000000..9e4ba7c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/TbcPadding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ee3e7e57e20d50c41b6f9cc4f31b6b69 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs new file mode 100644 index 0000000..e6a0f06 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs @@ -0,0 +1,86 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds X9.23 padding to a block - if a SecureRandom is + * passed in random padding is assumed, otherwise padding with zeros is used. + */ + public class X923Padding + : IBlockCipherPadding + { + private SecureRandom random; + + /** + * Initialise the padder. + * + * @param random a SecureRandom if one is available. + */ + public void Init( + SecureRandom random) + { + this.random = random; + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "X9.23"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < input.Length - 1) + { + if (random == null) + { + input[inOff] = 0; + } + else + { + input[inOff] = (byte)random.NextInt(); + } + inOff++; + } + + input[inOff] = code; + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + int count = input[input.Length - 1] & 0xff; + + if (count > input.Length) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs.meta new file mode 100644 index 0000000..334de26 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/X923Padding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7c0da47832981c243887ec0245c7c943 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs new file mode 100644 index 0000000..3e8ebb5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs @@ -0,0 +1,72 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /// A padder that adds Null byte padding to a block. + public class ZeroBytePadding : IBlockCipherPadding + { + /// Return the name of the algorithm the cipher implements. + /// + /// + /// the name of the algorithm the cipher implements. + /// + public string PaddingName + { + get { return "ZeroBytePadding"; } + } + + /// Initialise the padder. + /// + /// + /// - a SecureRandom if available. + /// + public void Init(SecureRandom random) + { + // nothing to do. + } + + /// add the pad bytes to the passed in block, returning the + /// number of bytes added. + /// + public int AddPadding( + byte[] input, + int inOff) + { + int added = (input.Length - inOff); + + while (inOff < input.Length) + { + input[inOff] = (byte) 0; + inOff++; + } + + return added; + } + + /// return the number of pad bytes present in the block. + public int PadCount( + byte[] input) + { + int count = input.Length; + + while (count > 0) + { + if (input[count - 1] != 0) + { + break; + } + + count--; + } + + return input.Length - count; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs.meta new file mode 100644 index 0000000..0efd3f2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/paddings/ZeroBytePadding.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: efef1293185559b4e9313cbecabb9d7c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters.meta new file mode 100644 index 0000000..46ffb32 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e16c007b18245954f945dea9b529da6f +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs new file mode 100644 index 0000000..3876dce --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs @@ -0,0 +1,69 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class AeadParameters + : ICipherParameters + { + private readonly byte[] associatedText; + private readonly byte[] nonce; + private readonly KeyParameter key; + private readonly int macSize; + + /** + * Base constructor. + * + * @param key key to be used by underlying cipher + * @param macSize macSize in bits + * @param nonce nonce to be used + */ + public AeadParameters(KeyParameter key, int macSize, byte[] nonce) + : this(key, macSize, nonce, null) + { + } + + /** + * Base constructor. + * + * @param key key to be used by underlying cipher + * @param macSize macSize in bits + * @param nonce nonce to be used + * @param associatedText associated text, if any + */ + public AeadParameters( + KeyParameter key, + int macSize, + byte[] nonce, + byte[] associatedText) + { + this.key = key; + this.nonce = nonce; + this.macSize = macSize; + this.associatedText = associatedText; + } + + public virtual KeyParameter Key + { + get { return key; } + } + + public virtual int MacSize + { + get { return macSize; } + } + + public virtual byte[] GetAssociatedText() + { + return associatedText; + } + + public virtual byte[] GetNonce() + { + return nonce; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs.meta new file mode 100644 index 0000000..980ba02 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/AEADParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2ab1e4d400f1fe643a1fc969f83989a6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs new file mode 100644 index 0000000..0f92d13 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs @@ -0,0 +1,35 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHKeyGenerationParameters + : KeyGenerationParameters + { + private readonly DHParameters parameters; + + public DHKeyGenerationParameters( + SecureRandom random, + DHParameters parameters) + : base(random, GetStrength(parameters)) + { + this.parameters = parameters; + } + + public DHParameters Parameters + { + get { return parameters; } + } + + internal static int GetStrength( + DHParameters parameters) + { + return parameters.L != 0 ? parameters.L : parameters.P.BitLength; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..4b2e079 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyGenerationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e3543cbf42d2468469b628ec9921121f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs new file mode 100644 index 0000000..04adbd4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs @@ -0,0 +1,80 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHKeyParameters + : AsymmetricKeyParameter + { + private readonly DHParameters parameters; + private readonly DerObjectIdentifier algorithmOid; + + protected DHKeyParameters( + bool isPrivate, + DHParameters parameters) + : this(isPrivate, parameters, PkcsObjectIdentifiers.DhKeyAgreement) + { + } + + protected DHKeyParameters( + bool isPrivate, + DHParameters parameters, + DerObjectIdentifier algorithmOid) + : base(isPrivate) + { + // TODO Should we allow parameters to be null? + this.parameters = parameters; + this.algorithmOid = algorithmOid; + } + + public DHParameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier AlgorithmOid + { + get { return algorithmOid; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHKeyParameters other = obj as DHKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHKeyParameters other) + { + return Org.BouncyCastle.Utilities.Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs.meta new file mode 100644 index 0000000..e30a92e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b184706d42c626541b7a830e2f1eb396 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs new file mode 100644 index 0000000..e53ac16 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs @@ -0,0 +1,189 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHParameters + : ICipherParameters + { + private const int DefaultMinimumLength = 160; + + private readonly BigInteger p, g, q, j; + private readonly int m, l; + private readonly DHValidationParameters validation; + + private static int GetDefaultMParam( + int lParam) + { + if (lParam == 0) + return DefaultMinimumLength; + + return System.Math.Min(lParam, DefaultMinimumLength); + } + + public DHParameters( + BigInteger p, + BigInteger g) + : this(p, g, null, 0) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q) + : this(p, g, q, 0) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + int l) + : this(p, g, q, GetDefaultMParam(l), l, null, null) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + int m, + int l) + : this(p, g, q, m, l, null, null) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + BigInteger j, + DHValidationParameters validation) + : this(p, g, q, DefaultMinimumLength, 0, j, validation) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + int m, + int l, + BigInteger j, + DHValidationParameters validation) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + if (!p.TestBit(0)) + throw new ArgumentException("field must be an odd prime", "p"); + if (g.CompareTo(BigInteger.Two) < 0 + || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) + throw new ArgumentException("generator must in the range [2, p - 2]", "g"); + if (q != null && q.BitLength >= p.BitLength) + throw new ArgumentException("q too big to be a factor of (p-1)", "q"); + if (m >= p.BitLength) + throw new ArgumentException("m value must be < bitlength of p", "m"); + if (l != 0) + { + // TODO Check this against the Java version, which has 'l > p.BitLength' here + if (l >= p.BitLength) + throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l"); + if (l < m) + throw new ArgumentException("when l value specified, it may not be less than m value", "l"); + } + if (j != null && j.CompareTo(BigInteger.Two) < 0) + throw new ArgumentException("subgroup factor must be >= 2", "j"); + + // TODO If q, j both provided, validate p = jq + 1 ? + + this.p = p; + this.g = g; + this.q = q; + this.m = m; + this.l = l; + this.j = j; + this.validation = validation; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger G + { + get { return g; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger J + { + get { return j; } + } + + /// The minimum bitlength of the private value. + public int M + { + get { return m; } + } + + /// The bitlength of the private value. + public int L + { + get { return l; } + } + + public DHValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHParameters other = obj as DHParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected virtual bool Equals( + DHParameters other) + { + return p.Equals(other.p) + && g.Equals(other.g) + && Org.BouncyCastle.Utilities.Platform.Equals(q, other.q); + } + + public override int GetHashCode() + { + int hc = p.GetHashCode() ^ g.GetHashCode(); + + if (q != null) + { + hc ^= q.GetHashCode(); + } + + return hc; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs.meta new file mode 100644 index 0000000..11d78d8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bf264f19a21f3204cb815a491eaf7891 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs new file mode 100644 index 0000000..3014751 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs @@ -0,0 +1,64 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHPrivateKeyParameters + : DHKeyParameters + { + private readonly BigInteger x; + + public DHPrivateKeyParameters( + BigInteger x, + DHParameters parameters) + : base(true, parameters) + { + this.x = x; + } + + public DHPrivateKeyParameters( + BigInteger x, + DHParameters parameters, + DerObjectIdentifier algorithmOid) + : base(true, parameters, algorithmOid) + { + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHPrivateKeyParameters other = obj as DHPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHPrivateKeyParameters other) + { + return x.Equals(other.x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..58254f7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPrivateKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0fdd4d67cf6500a4bb5dfe324c483f9e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs new file mode 100644 index 0000000..301db7c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs @@ -0,0 +1,70 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHPublicKeyParameters + : DHKeyParameters + { + private readonly BigInteger y; + + public DHPublicKeyParameters( + BigInteger y, + DHParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public DHPublicKeyParameters( + BigInteger y, + DHParameters parameters, + DerObjectIdentifier algorithmOid) + : base(false, parameters, algorithmOid) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHPublicKeyParameters other = obj as DHPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs.meta new file mode 100644 index 0000000..4714fed --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHPublicKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dcdcc5dd36103a347803778660e62bac +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs new file mode 100644 index 0000000..5c1a167 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs @@ -0,0 +1,63 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHValidationParameters + { + private readonly byte[] seed; + private readonly int counter; + + public DHValidationParameters( + byte[] seed, + int counter) + { + if (seed == null) + throw new ArgumentNullException("seed"); + + this.seed = (byte[]) seed.Clone(); + this.counter = counter; + } + + public byte[] GetSeed() + { + return (byte[]) seed.Clone(); + } + + public int Counter + { + get { return counter; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHValidationParameters other = obj as DHValidationParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHValidationParameters other) + { + return counter == other.counter + && Arrays.AreEqual(this.seed, other.seed); + } + + public override int GetHashCode() + { + return counter.GetHashCode() ^ Arrays.GetHashCode(seed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs.meta new file mode 100644 index 0000000..8b5612c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DHValidationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bcfe09e6364f2824ea27955a589ae4b2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs new file mode 100644 index 0000000..03472f8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs @@ -0,0 +1,144 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DesEdeParameters + : DesParameters + { + /* + * DES-EDE Key length in bytes. + */ + public const int DesEdeKeyLength = 24; + + private static byte[] FixKey( + byte[] key, + int keyOff, + int keyLen) + { + byte[] tmp = new byte[24]; + + switch (keyLen) + { + case 16: + Array.Copy(key, keyOff, tmp, 0, 16); + Array.Copy(key, keyOff, tmp, 16, 8); + break; + case 24: + Array.Copy(key, keyOff, tmp, 0, 24); + break; + default: + throw new ArgumentException("Bad length for DESede key: " + keyLen, "keyLen"); + } + + if (IsWeakKey(tmp)) + throw new ArgumentException("attempt to create weak DESede key"); + + return tmp; + } + + public DesEdeParameters( + byte[] key) + : base(FixKey(key, 0, key.Length)) + { + } + + public DesEdeParameters( + byte[] key, + int keyOff, + int keyLen) + : base(FixKey(key, keyOff, keyLen)) + { + } + + /** + * return true if the passed in key is a DES-EDE weak key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + * @param length number of bytes making up the key + */ + public static bool IsWeakKey( + byte[] key, + int offset, + int length) + { + for (int i = offset; i < length; i += DesKeyLength) + { + if (DesParameters.IsWeakKey(key, i)) + { + return true; + } + } + + return false; + } + + /** + * return true if the passed in key is a DES-EDE weak key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static new bool IsWeakKey( + byte[] key, + int offset) + { + return IsWeakKey(key, offset, key.Length - offset); + } + + public static new bool IsWeakKey( + byte[] key) + { + return IsWeakKey(key, 0, key.Length); + } + + /** + * return true if the passed in key is a real 2/3 part DES-EDE key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static bool IsRealEdeKey(byte[] key, int offset) + { + return key.Length == 16 ? IsReal2Key(key, offset) : IsReal3Key(key, offset); + } + + /** + * return true if the passed in key is a real 2 part DES-EDE key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static bool IsReal2Key(byte[] key, int offset) + { + bool isValid = false; + for (int i = offset; i != offset + 8; i++) + { + isValid |= (key[i] != key[i + 8]); + } + return isValid; + } + + /** + * return true if the passed in key is a real 3 part DES-EDE key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static bool IsReal3Key(byte[] key, int offset) + { + bool diff12 = false, diff13 = false, diff23 = false; + for (int i = offset; i != offset + 8; i++) + { + diff12 |= (key[i] != key[i + 8]); + diff13 |= (key[i] != key[i + 16]); + diff23 |= (key[i + 8] != key[i + 16]); + } + return diff12 && diff13 && diff23; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs.meta new file mode 100644 index 0000000..f597e0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesEdeParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4749e39c2006221438acbd5317e3f77c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs new file mode 100644 index 0000000..c671421 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs @@ -0,0 +1,143 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DesParameters + : KeyParameter + { + public DesParameters( + byte[] key) + : base(key) + { + if (IsWeakKey(key)) + throw new ArgumentException("attempt to create weak DES key"); + } + + public DesParameters( + byte[] key, + int keyOff, + int keyLen) + : base(key, keyOff, keyLen) + { + if (IsWeakKey(key, keyOff)) + throw new ArgumentException("attempt to create weak DES key"); + } + + /* + * DES Key Length in bytes. + */ + public const int DesKeyLength = 8; + + /* + * Table of weak and semi-weak keys taken from Schneier pp281 + */ + private const int N_DES_WEAK_KEYS = 16; + + private static readonly byte[] DES_weak_keys = + { + /* weak keys */ + (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, + (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, + (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, + (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, + + /* semi-weak keys */ + (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, + (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, + (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, + (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, + (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, + (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, + (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, + (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, + (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, + (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, + (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, + (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 + }; + + /** + * DES has 16 weak keys. This method will check + * if the given DES key material is weak or semi-weak. + * Key material that is too short is regarded as weak. + *

+ * See "Applied + * Cryptography" by Bruce Schneier for more information. + *

+ * @return true if the given DES key material is weak or semi-weak, + * false otherwise. + */ + public static bool IsWeakKey( + byte[] key, + int offset) + { + if (key.Length - offset < DesKeyLength) + throw new ArgumentException("key material too short."); + + //nextkey: + for (int i = 0; i < N_DES_WEAK_KEYS; i++) + { + bool unmatch = false; + for (int j = 0; j < DesKeyLength; j++) + { + if (key[j + offset] != DES_weak_keys[i * DesKeyLength + j]) + { + //continue nextkey; + unmatch = true; + break; + } + } + + if (!unmatch) + { + return true; + } + } + + return false; + } + + public static bool IsWeakKey( + byte[] key) + { + return IsWeakKey(key, 0); + } + + public static byte SetOddParity(byte b) + { + uint parity = b ^ 1U; + parity ^= (parity >> 4); + parity ^= (parity >> 2); + parity ^= (parity >> 1); + parity &= 1U; + + return (byte)(b ^ parity); + } + + /** + * DES Keys use the LSB as the odd parity bit. This can + * be used to check for corrupt keys. + * + * @param bytes the byte array to set the parity on. + */ + public static void SetOddParity(byte[] bytes) + { + for (int i = 0; i < bytes.Length; i++) + { + bytes[i] = SetOddParity(bytes[i]); + } + } + + public static void SetOddParity(byte[] bytes, int off, int len) + { + for (int i = 0; i < len; i++) + { + bytes[off + i] = SetOddParity(bytes[off + i]); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs.meta new file mode 100644 index 0000000..161f79c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DesParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b00a12c88d7bcc248b4ca2f26e3aa06d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs new file mode 100644 index 0000000..a03f9bc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs @@ -0,0 +1,30 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaKeyGenerationParameters + : KeyGenerationParameters + { + private readonly DsaParameters parameters; + + public DsaKeyGenerationParameters( + SecureRandom random, + DsaParameters parameters) + : base(random, parameters.P.BitLength - 1) + { + this.parameters = parameters; + } + + public DsaParameters Parameters + { + get { return parameters; } + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..e9df618 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyGenerationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 276581811002f3e4c9cb17ec0a51d092 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs new file mode 100644 index 0000000..cd97761 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs @@ -0,0 +1,63 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class DsaKeyParameters + : AsymmetricKeyParameter + { + private readonly DsaParameters parameters; + + protected DsaKeyParameters( + bool isPrivate, + DsaParameters parameters) + : base(isPrivate) + { + // Note: parameters may be null + this.parameters = parameters; + } + + public DsaParameters Parameters + { + get { return parameters; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaKeyParameters other = obj as DsaKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaKeyParameters other) + { + return Org.BouncyCastle.Utilities.Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs.meta new file mode 100644 index 0000000..c678b20 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0f1017d8a70458545aa4e27a696f2df5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs new file mode 100644 index 0000000..825f3b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs @@ -0,0 +1,89 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaParameters + : ICipherParameters + { + private readonly BigInteger p, q , g; + private readonly DsaValidationParameters validation; + + public DsaParameters( + BigInteger p, + BigInteger q, + BigInteger g) + : this(p, q, g, null) + { + } + + public DsaParameters( + BigInteger p, + BigInteger q, + BigInteger g, + DsaValidationParameters parameters) + { + if (p == null) + throw new ArgumentNullException("p"); + if (q == null) + throw new ArgumentNullException("q"); + if (g == null) + throw new ArgumentNullException("g"); + + this.p = p; + this.q = q; + this.g = g; + this.validation = parameters; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger G + { + get { return g; } + } + + public DsaValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaParameters other = obj as DsaParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaParameters other) + { + return p.Equals(other.p) && q.Equals(other.q) && g.Equals(other.g); + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ q.GetHashCode() ^ g.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs.meta new file mode 100644 index 0000000..392cd77 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ee680943739e3ab4abee72f41f4cb6e3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs new file mode 100644 index 0000000..ddc2c65 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs @@ -0,0 +1,57 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaPrivateKeyParameters + : DsaKeyParameters + { + private readonly BigInteger x; + + public DsaPrivateKeyParameters( + BigInteger x, + DsaParameters parameters) + : base(true, parameters) + { + if (x == null) + throw new ArgumentNullException("x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaPrivateKeyParameters other = obj as DsaPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaPrivateKeyParameters other) + { + return x.Equals(other.x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..eeaa981 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPrivateKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d4f0cb0e77323ee4b94fdb6249c169d1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs new file mode 100644 index 0000000..662d557 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs @@ -0,0 +1,56 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaPublicKeyParameters + : DsaKeyParameters + { + private readonly BigInteger y; + + public DsaPublicKeyParameters( + BigInteger y, + DsaParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + DsaPublicKeyParameters other = obj as DsaPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs.meta new file mode 100644 index 0000000..2972506 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaPublicKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1afe3462c21af6a4ca12ef6e3169445f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs new file mode 100644 index 0000000..b3df217 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs @@ -0,0 +1,76 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaValidationParameters + { + private readonly byte[] seed; + private readonly int counter; + private readonly int usageIndex; + + public DsaValidationParameters(byte[] seed, int counter) + : this(seed, counter, -1) + { + } + + public DsaValidationParameters( + byte[] seed, + int counter, + int usageIndex) + { + if (seed == null) + throw new ArgumentNullException("seed"); + + this.seed = (byte[]) seed.Clone(); + this.counter = counter; + this.usageIndex = usageIndex; + } + + public virtual byte[] GetSeed() + { + return (byte[]) seed.Clone(); + } + + public virtual int Counter + { + get { return counter; } + } + + public virtual int UsageIndex + { + get { return usageIndex; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaValidationParameters other = obj as DsaValidationParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected virtual bool Equals( + DsaValidationParameters other) + { + return counter == other.counter + && Arrays.AreEqual(seed, other.seed); + } + + public override int GetHashCode() + { + return counter.GetHashCode() ^ Arrays.GetHashCode(seed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs.meta new file mode 100644 index 0000000..2b3b73f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/DsaValidationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 66dbc197d770cc74da7061f3a853ea1d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs new file mode 100644 index 0000000..c9a3f87 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs @@ -0,0 +1,121 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECDomainParameters + { + internal ECCurve curve; + internal byte[] seed; + internal ECPoint g; + internal BigInteger n; + internal BigInteger h; + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, BigInteger.One) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + if (curve == null) + throw new ArgumentNullException("curve"); + if (g == null) + throw new ArgumentNullException("g"); + if (n == null) + throw new ArgumentNullException("n"); + if (h == null) + throw new ArgumentNullException("h"); + + this.curve = curve; + this.g = g.Normalize(); + this.n = n; + this.h = h; + this.seed = Arrays.Clone(seed); + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get { return h; } + } + + public byte[] GetSeed() + { + return Arrays.Clone(seed); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECDomainParameters other = obj as ECDomainParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected virtual bool Equals( + ECDomainParameters other) + { + return curve.Equals(other.curve) + && g.Equals(other.g) + && n.Equals(other.n) + && h.Equals(other.h); + } + + public override int GetHashCode() + { + int hc = curve.GetHashCode(); + hc *= 37; + hc ^= g.GetHashCode(); + hc *= 37; + hc ^= n.GetHashCode(); + hc *= 37; + hc ^= h.GetHashCode(); + return hc; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs.meta new file mode 100644 index 0000000..eac5f8b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECDomainParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3beb4f5cf7c45294aae379ff966dee7f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs new file mode 100644 index 0000000..e0ac2b0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs @@ -0,0 +1,45 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECKeyGenerationParameters + : KeyGenerationParameters + { + private readonly ECDomainParameters domainParams; + private readonly DerObjectIdentifier publicKeyParamSet; + + public ECKeyGenerationParameters( + ECDomainParameters domainParameters, + SecureRandom random) + : base(random, domainParameters.N.BitLength) + { + this.domainParams = domainParameters; + } + + public ECKeyGenerationParameters( + DerObjectIdentifier publicKeyParamSet, + SecureRandom random) + : this(ECKeyParameters.LookupParameters(publicKeyParamSet), random) + { + this.publicKeyParamSet = publicKeyParamSet; + } + + public ECDomainParameters DomainParameters + { + get { return domainParams; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..8c65276 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyGenerationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ab3ecd7ab43e33a458ea35a383957a07 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs new file mode 100644 index 0000000..bed29f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs @@ -0,0 +1,140 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class ECKeyParameters + : AsymmetricKeyParameter + { + private static readonly string[] algorithms = { "EC", "ECDSA", "ECDH", "ECDHC", "ECGOST3410", "ECMQV" }; + + private readonly string algorithm; + private readonly ECDomainParameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + protected ECKeyParameters( + string algorithm, + bool isPrivate, + ECDomainParameters parameters) + : base(isPrivate) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (parameters == null) + throw new ArgumentNullException("parameters"); + + this.algorithm = VerifyAlgorithmName(algorithm); + this.parameters = parameters; + } + + protected ECKeyParameters( + string algorithm, + bool isPrivate, + DerObjectIdentifier publicKeyParamSet) + : base(isPrivate) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + this.algorithm = VerifyAlgorithmName(algorithm); + this.parameters = LookupParameters(publicKeyParamSet); + this.publicKeyParamSet = publicKeyParamSet; + } + + public string AlgorithmName + { + get { return algorithm; } + } + + public ECDomainParameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECDomainParameters other = obj as ECDomainParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECKeyParameters other) + { + return parameters.Equals(other.parameters) && base.Equals(other); + } + + public override int GetHashCode() + { + return parameters.GetHashCode() ^ base.GetHashCode(); + } + + internal ECKeyGenerationParameters CreateKeyGenerationParameters( + SecureRandom random) + { + if (publicKeyParamSet != null) + { + return new ECKeyGenerationParameters(publicKeyParamSet, random); + } + + return new ECKeyGenerationParameters(parameters, random); + } + + internal static string VerifyAlgorithmName(string algorithm) + { + string upper = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); + if (Array.IndexOf(algorithms, algorithm, 0, algorithms.Length) < 0) + throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm"); + return upper; + } + + internal static ECDomainParameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + ECDomainParameters p = ECGost3410NamedCurves.GetByOid(publicKeyParamSet); + + if (p == null) + { + X9ECParameters x9 = ECKeyPairGenerator.FindECCurveByOid(publicKeyParamSet); + + if (x9 == null) + { + throw new ArgumentException("OID is not a valid public key parameter set", "publicKeyParamSet"); + } + + p = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); + } + + return p; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs.meta new file mode 100644 index 0000000..78f79f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7082d8fbbed75824585e4b8956c19af4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs new file mode 100644 index 0000000..60ae3e3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs @@ -0,0 +1,91 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECPrivateKeyParameters + : ECKeyParameters + { + private readonly BigInteger d; + + public ECPrivateKeyParameters( + BigInteger d, + ECDomainParameters parameters) + : this("EC", d, parameters) + { + } + + [Obsolete("Use version with explicit 'algorithm' parameter")] + public ECPrivateKeyParameters( + BigInteger d, + DerObjectIdentifier publicKeyParamSet) + : base("ECGOST3410", true, publicKeyParamSet) + { + if (d == null) + throw new ArgumentNullException("d"); + + this.d = d; + } + + public ECPrivateKeyParameters( + string algorithm, + BigInteger d, + ECDomainParameters parameters) + : base(algorithm, true, parameters) + { + if (d == null) + throw new ArgumentNullException("d"); + + this.d = d; + } + + public ECPrivateKeyParameters( + string algorithm, + BigInteger d, + DerObjectIdentifier publicKeyParamSet) + : base(algorithm, true, publicKeyParamSet) + { + if (d == null) + throw new ArgumentNullException("d"); + + this.d = d; + } + + public BigInteger D + { + get { return d; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECPrivateKeyParameters other = obj as ECPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECPrivateKeyParameters other) + { + return d.Equals(other.d) && base.Equals(other); + } + + public override int GetHashCode() + { + return d.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..71397cc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPrivateKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8f9d84f447cca6e4080ff2469a3642d2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs new file mode 100644 index 0000000..e3a9bd0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs @@ -0,0 +1,90 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECPublicKeyParameters + : ECKeyParameters + { + private readonly ECPoint q; + + public ECPublicKeyParameters( + ECPoint q, + ECDomainParameters parameters) + : this("EC", q, parameters) + { + } + + [Obsolete("Use version with explicit 'algorithm' parameter")] + public ECPublicKeyParameters( + ECPoint q, + DerObjectIdentifier publicKeyParamSet) + : base("ECGOST3410", false, publicKeyParamSet) + { + if (q == null) + throw new ArgumentNullException("q"); + + this.q = q.Normalize(); + } + + public ECPublicKeyParameters( + string algorithm, + ECPoint q, + ECDomainParameters parameters) + : base(algorithm, false, parameters) + { + if (q == null) + throw new ArgumentNullException("q"); + + this.q = q.Normalize(); + } + + public ECPublicKeyParameters( + string algorithm, + ECPoint q, + DerObjectIdentifier publicKeyParamSet) + : base(algorithm, false, publicKeyParamSet) + { + if (q == null) + throw new ArgumentNullException("q"); + + this.q = q.Normalize(); + } + + public ECPoint Q + { + get { return q; } + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + ECPublicKeyParameters other = obj as ECPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECPublicKeyParameters other) + { + return q.Equals(other.q) && base.Equals(other); + } + + public override int GetHashCode() + { + return q.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs.meta new file mode 100644 index 0000000..b6168a0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ECPublicKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 03c066cb5e3c19d4eb02383352313fd5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs new file mode 100644 index 0000000..eee6af6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs @@ -0,0 +1,35 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalKeyGenerationParameters + : KeyGenerationParameters + { + private readonly ElGamalParameters parameters; + + public ElGamalKeyGenerationParameters( + SecureRandom random, + ElGamalParameters parameters) + : base(random, GetStrength(parameters)) + { + this.parameters = parameters; + } + + public ElGamalParameters Parameters + { + get { return parameters; } + } + + internal static int GetStrength( + ElGamalParameters parameters) + { + return parameters.L != 0 ? parameters.L : parameters.P.BitLength; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..a82d11c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 605fe530d358a834b87bd5618b3592eb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs new file mode 100644 index 0000000..ddc46f8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs @@ -0,0 +1,63 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalKeyParameters + : AsymmetricKeyParameter + { + private readonly ElGamalParameters parameters; + + protected ElGamalKeyParameters( + bool isPrivate, + ElGamalParameters parameters) + : base(isPrivate) + { + // TODO Should we allow 'parameters' to be null? + this.parameters = parameters; + } + + public ElGamalParameters Parameters + { + get { return parameters; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalKeyParameters other = obj as ElGamalKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalKeyParameters other) + { + return Org.BouncyCastle.Utilities.Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs.meta new file mode 100644 index 0000000..17ceb04 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7cf4458861963154489ccdb128696971 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs new file mode 100644 index 0000000..f08956e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs @@ -0,0 +1,85 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalParameters + : ICipherParameters + { + private readonly BigInteger p, g; + private readonly int l; + + public ElGamalParameters( + BigInteger p, + BigInteger g) + : this(p, g, 0) + { + } + + public ElGamalParameters( + BigInteger p, + BigInteger g, + int l) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + + this.p = p; + this.g = g; + this.l = l; + } + + public BigInteger P + { + get { return p; } + } + + /** + * return the generator - g + */ + public BigInteger G + { + get { return g; } + } + + /** + * return private value limit - l + */ + public int L + { + get { return l; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalParameters other = obj as ElGamalParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalParameters other) + { + return p.Equals(other.p) && g.Equals(other.g) && l == other.l; + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ g.GetHashCode() ^ l; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs.meta new file mode 100644 index 0000000..90bc9a7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3e46c9305cb7e5e49a27049f3f2018ae +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs new file mode 100644 index 0000000..a14b99a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs @@ -0,0 +1,57 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalPrivateKeyParameters + : ElGamalKeyParameters + { + private readonly BigInteger x; + + public ElGamalPrivateKeyParameters( + BigInteger x, + ElGamalParameters parameters) + : base(true, parameters) + { + if (x == null) + throw new ArgumentNullException("x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalPrivateKeyParameters other = obj as ElGamalPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalPrivateKeyParameters other) + { + return other.x.Equals(x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..d6724f2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 334db63a79120bd4a8c4f2fa512f5b35 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs new file mode 100644 index 0000000..313f2f3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs @@ -0,0 +1,57 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalPublicKeyParameters + : ElGamalKeyParameters + { + private readonly BigInteger y; + + public ElGamalPublicKeyParameters( + BigInteger y, + ElGamalParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalPublicKeyParameters other = obj as ElGamalPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs.meta new file mode 100644 index 0000000..274f6ac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ElGamalPublicKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 66e505fdb6b021e4f826fcdbac27d43f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs new file mode 100644 index 0000000..113bf23 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs @@ -0,0 +1,62 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class Gost3410KeyParameters + : AsymmetricKeyParameter + { + private readonly Gost3410Parameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + protected Gost3410KeyParameters( + bool isPrivate, + Gost3410Parameters parameters) + : base(isPrivate) + { + this.parameters = parameters; + } + + protected Gost3410KeyParameters( + bool isPrivate, + DerObjectIdentifier publicKeyParamSet) + : base(isPrivate) + { + this.parameters = LookupParameters(publicKeyParamSet); + this.publicKeyParamSet = publicKeyParamSet; + } + + public Gost3410Parameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + // TODO Implement Equals/GetHashCode + + private static Gost3410Parameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + Gost3410ParamSetParameters p = Gost3410NamedParameters.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return new Gost3410Parameters(p.P, p.Q, p.A); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs.meta new file mode 100644 index 0000000..d0e307d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410KeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1dc6988914e81bd46905d8ebc7b82e2a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs new file mode 100644 index 0000000..5ad308d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs @@ -0,0 +1,90 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410Parameters + : ICipherParameters + { + private readonly BigInteger p, q, a; + private readonly Gost3410ValidationParameters validation; + + public Gost3410Parameters( + BigInteger p, + BigInteger q, + BigInteger a) + : this(p, q, a, null) + { + } + + public Gost3410Parameters( + BigInteger p, + BigInteger q, + BigInteger a, + Gost3410ValidationParameters validation) + { + if (p == null) + throw new ArgumentNullException("p"); + if (q == null) + throw new ArgumentNullException("q"); + if (a == null) + throw new ArgumentNullException("a"); + + this.p = p; + this.q = q; + this.a = a; + this.validation = validation; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger A + { + get { return a; } + } + + public Gost3410ValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + Gost3410Parameters other = obj as Gost3410Parameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + Gost3410Parameters other) + { + return p.Equals(other.p) && q.Equals(other.q) && a.Equals(other.a); + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ q.GetHashCode() ^ a.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs.meta new file mode 100644 index 0000000..615e90a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410Parameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5dbdc652c3f5f944f87efef0cff09e1e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs new file mode 100644 index 0000000..5c73a84 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs @@ -0,0 +1,45 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410PrivateKeyParameters + : Gost3410KeyParameters + { + private readonly BigInteger x; + + public Gost3410PrivateKeyParameters( + BigInteger x, + Gost3410Parameters parameters) + : base(true, parameters) + { + if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) + throw new ArgumentException("Invalid x for GOST3410 private key", "x"); + + this.x = x; + } + + public Gost3410PrivateKeyParameters( + BigInteger x, + DerObjectIdentifier publicKeyParamSet) + : base(true, publicKeyParamSet) + { + if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) + throw new ArgumentException("Invalid x for GOST3410 private key", "x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta new file mode 100644 index 0000000..af2bfd5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f6711979a24300844aa8670163e40905 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs new file mode 100644 index 0000000..95cfba6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410PublicKeyParameters + : Gost3410KeyParameters + { + private readonly BigInteger y; + + public Gost3410PublicKeyParameters( + BigInteger y, + Gost3410Parameters parameters) + : base(false, parameters) + { + if (y.SignValue < 1 || y.CompareTo(Parameters.P) >= 0) + throw new ArgumentException("Invalid y for GOST3410 public key", "y"); + + this.y = y; + } + + public Gost3410PublicKeyParameters( + BigInteger y, + DerObjectIdentifier publicKeyParamSet) + : base(false, publicKeyParamSet) + { + if (y.SignValue < 1 || y.CompareTo(Parameters.P) >= 0) + throw new ArgumentException("Invalid y for GOST3410 public key", "y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs.meta new file mode 100644 index 0000000..c6ca9be --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410PublicKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4d46ac587d55b6046a73f3d32ed2c8a0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs new file mode 100644 index 0000000..9a3259b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs @@ -0,0 +1,55 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410ValidationParameters + { + private int x0; + private int c; + private long x0L; + private long cL; + + public Gost3410ValidationParameters( + int x0, + int c) + { + this.x0 = x0; + this.c = c; + } + + public Gost3410ValidationParameters( + long x0L, + long cL) + { + this.x0L = x0L; + this.cL = cL; + } + + public int C { get { return c; } } + public int X0 { get { return x0; } } + public long CL { get { return cL; } } + public long X0L { get { return x0L; } } + + public override bool Equals( + object obj) + { + Gost3410ValidationParameters other = obj as Gost3410ValidationParameters; + + return other != null + && other.c == this.c + && other.x0 == this.x0 + && other.cL == this.cL + && other.x0L == this.x0L; + } + + public override int GetHashCode() + { + return c.GetHashCode() ^ x0.GetHashCode() ^ cL.GetHashCode() ^ x0L.GetHashCode(); + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs.meta new file mode 100644 index 0000000..9c44359 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/GOST3410ValidationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3c64f65e9276e6e4785c41edb30a4d8b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs new file mode 100644 index 0000000..aff71a4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs @@ -0,0 +1,29 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for Key derivation functions for ISO-18033 + */ + public class Iso18033KdfParameters + : IDerivationParameters + { + byte[] seed; + + public Iso18033KdfParameters( + byte[] seed) + { + this.seed = seed; + } + + public byte[] GetSeed() + { + return seed; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs.meta new file mode 100644 index 0000000..3dae6d4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ISO18033KDFParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1841ab6676510b84a9a6154b0c8c6004 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs new file mode 100644 index 0000000..8d4aadc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs @@ -0,0 +1,53 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for using an integrated cipher in stream mode. + */ + public class IesParameters : ICipherParameters + { + private byte[] derivation; + private byte[] encoding; + private int macKeySize; + + /** + * @param derivation the derivation parameter for the KDF function. + * @param encoding the encoding parameter for the KDF function. + * @param macKeySize the size of the MAC key (in bits). + */ + public IesParameters( + byte[] derivation, + byte[] encoding, + int macKeySize) + { + this.derivation = derivation; + this.encoding = encoding; + this.macKeySize = macKeySize; + } + + public byte[] GetDerivationV() + { + return derivation; + } + + public byte[] GetEncodingV() + { + return encoding; + } + + public int MacKeySize + { + get + { + return macKeySize; + } + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs.meta new file mode 100644 index 0000000..dab38d0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7c03aa52286eafd459b8fc92fa4177e8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs new file mode 100644 index 0000000..4d854e1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs @@ -0,0 +1,37 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class IesWithCipherParameters : IesParameters + { + private int cipherKeySize; + + /** + * @param derivation the derivation parameter for the KDF function. + * @param encoding the encoding parameter for the KDF function. + * @param macKeySize the size of the MAC key (in bits). + * @param cipherKeySize the size of the associated Cipher key (in bits). + */ + public IesWithCipherParameters( + byte[] derivation, + byte[] encoding, + int macKeySize, + int cipherKeySize) : base(derivation, encoding, macKeySize) + { + this.cipherKeySize = cipherKeySize; + } + + public int CipherKeySize + { + get + { + return cipherKeySize; + } + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs.meta new file mode 100644 index 0000000..107a337 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/IesWithCipherParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c3413d4030dee0b47a112e722521d66c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs new file mode 100644 index 0000000..27d1528 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs @@ -0,0 +1,37 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for Key derivation functions for IEEE P1363a + */ + public class KdfParameters : IDerivationParameters + { + byte[] iv; + byte[] shared; + + public KdfParameters( + byte[] shared, + byte[] iv) + { + this.shared = shared; + this.iv = iv; + } + + public byte[] GetSharedSecret() + { + return shared; + } + + public byte[] GetIV() + { + return iv; + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs.meta new file mode 100644 index 0000000..1809dcc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KdfParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 26a35bd34dbec4c4c8291c90a9e688d4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs new file mode 100644 index 0000000..09266e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs @@ -0,0 +1,47 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KeyParameter + : ICipherParameters + { + private readonly byte[] key; + + public KeyParameter( + byte[] key) + { + if (key == null) + throw new ArgumentNullException("key"); + + this.key = (byte[]) key.Clone(); + } + + public KeyParameter( + byte[] key, + int keyOff, + int keyLen) + { + if (key == null) + throw new ArgumentNullException("key"); + if (keyOff < 0 || keyOff > key.Length) + throw new ArgumentOutOfRangeException("keyOff"); + if (keyLen < 0 || (keyOff + keyLen) > key.Length) + throw new ArgumentOutOfRangeException("keyLen"); + + this.key = new byte[keyLen]; + Array.Copy(key, keyOff, this.key, 0, keyLen); + } + + public byte[] GetKey() + { + return (byte[]) key.Clone(); + } + } + +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs.meta new file mode 100644 index 0000000..72cb153 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/KeyParameter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fd79ff15a5360d745bdc45b2083e2958 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs new file mode 100644 index 0000000..91288e5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs @@ -0,0 +1,68 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class MqvPrivateParameters + : ICipherParameters + { + private readonly ECPrivateKeyParameters staticPrivateKey; + private readonly ECPrivateKeyParameters ephemeralPrivateKey; + private readonly ECPublicKeyParameters ephemeralPublicKey; + + public MqvPrivateParameters( + ECPrivateKeyParameters staticPrivateKey, + ECPrivateKeyParameters ephemeralPrivateKey) + : this(staticPrivateKey, ephemeralPrivateKey, null) + { + } + + public MqvPrivateParameters( + ECPrivateKeyParameters staticPrivateKey, + ECPrivateKeyParameters ephemeralPrivateKey, + ECPublicKeyParameters ephemeralPublicKey) + { + if (staticPrivateKey == null) + throw new ArgumentNullException("staticPrivateKey"); + if (ephemeralPrivateKey == null) + throw new ArgumentNullException("ephemeralPrivateKey"); + + ECDomainParameters parameters = staticPrivateKey.Parameters; + if (!parameters.Equals(ephemeralPrivateKey.Parameters)) + throw new ArgumentException("Static and ephemeral private keys have different domain parameters"); + + if (ephemeralPublicKey == null) + { + ephemeralPublicKey = new ECPublicKeyParameters( + parameters.G.Multiply(ephemeralPrivateKey.D), + parameters); + } + else if (!parameters.Equals(ephemeralPublicKey.Parameters)) + { + throw new ArgumentException("Ephemeral public key has different domain parameters"); + } + + this.staticPrivateKey = staticPrivateKey; + this.ephemeralPrivateKey = ephemeralPrivateKey; + this.ephemeralPublicKey = ephemeralPublicKey; + } + + public virtual ECPrivateKeyParameters StaticPrivateKey + { + get { return staticPrivateKey; } + } + + public virtual ECPrivateKeyParameters EphemeralPrivateKey + { + get { return ephemeralPrivateKey; } + } + + public virtual ECPublicKeyParameters EphemeralPublicKey + { + get { return ephemeralPublicKey; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs.meta new file mode 100644 index 0000000..2e5f75b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPrivateParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 48e1468458832e9438b4568785726d43 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs new file mode 100644 index 0000000..f60a275 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class MqvPublicParameters + : ICipherParameters + { + private readonly ECPublicKeyParameters staticPublicKey; + private readonly ECPublicKeyParameters ephemeralPublicKey; + + public MqvPublicParameters( + ECPublicKeyParameters staticPublicKey, + ECPublicKeyParameters ephemeralPublicKey) + { + if (staticPublicKey == null) + throw new ArgumentNullException("staticPublicKey"); + if (ephemeralPublicKey == null) + throw new ArgumentNullException("ephemeralPublicKey"); + if (!staticPublicKey.Parameters.Equals(ephemeralPublicKey.Parameters)) + throw new ArgumentException("Static and ephemeral public keys have different domain parameters"); + + this.staticPublicKey = staticPublicKey; + this.ephemeralPublicKey = ephemeralPublicKey; + } + + public virtual ECPublicKeyParameters StaticPublicKey + { + get { return staticPublicKey; } + } + + public virtual ECPublicKeyParameters EphemeralPublicKey + { + get { return ephemeralPublicKey; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs.meta new file mode 100644 index 0000000..257e152 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/MqvPublicParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e50ff85b1ca76d8428cde7f72e9d9d34 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs new file mode 100644 index 0000000..99e33b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs @@ -0,0 +1,47 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithIV + : ICipherParameters + { + private readonly ICipherParameters parameters; + private readonly byte[] iv; + + public ParametersWithIV( + ICipherParameters parameters, + byte[] iv) + : this(parameters, iv, 0, iv.Length) + { + } + + public ParametersWithIV( + ICipherParameters parameters, + byte[] iv, + int ivOff, + int ivLen) + { + // NOTE: 'parameters' may be null to imply key re-use + if (iv == null) + throw new ArgumentNullException("iv"); + + this.parameters = parameters; + this.iv = new byte[ivLen]; + Array.Copy(iv, ivOff, this.iv, 0, ivLen); + } + + public byte[] GetIV() + { + return (byte[]) iv.Clone(); + } + + public ICipherParameters Parameters + { + get { return parameters; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs.meta new file mode 100644 index 0000000..0232b66 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithIV.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 68fc549489833994d859f97f7f947591 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs new file mode 100644 index 0000000..43e5b0b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs @@ -0,0 +1,52 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithRandom + : ICipherParameters + { + private readonly ICipherParameters parameters; + private readonly SecureRandom random; + + public ParametersWithRandom( + ICipherParameters parameters, + SecureRandom random) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + if (random == null) + throw new ArgumentNullException("random"); + + this.parameters = parameters; + this.random = random; + } + + public ParametersWithRandom( + ICipherParameters parameters) + : this(parameters, new SecureRandom()) + { + } + + [Obsolete("Use Random property instead")] + public SecureRandom GetRandom() + { + return Random; + } + + public SecureRandom Random + { + get { return random; } + } + + public ICipherParameters Parameters + { + get { return parameters; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs.meta new file mode 100644 index 0000000..e7a8ae6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithRandom.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9ce4f2340d8a7d944a7ea4678b7c69ff +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs new file mode 100644 index 0000000..ff40790 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithSBox : ICipherParameters + { + private ICipherParameters parameters; + private byte[] sBox; + + public ParametersWithSBox( + ICipherParameters parameters, + byte[] sBox) + { + this.parameters = parameters; + this.sBox = sBox; + } + + public byte[] GetSBox() { return sBox; } + + public ICipherParameters Parameters { get { return parameters; } } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs.meta new file mode 100644 index 0000000..c137cf7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSBox.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 638195a3abd1d6a46b904b329c8245af +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs new file mode 100644 index 0000000..e705fd3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs @@ -0,0 +1,43 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + + /// Cipher parameters with a fixed salt value associated with them. + public class ParametersWithSalt : ICipherParameters + { + private byte[] salt; + private ICipherParameters parameters; + + public ParametersWithSalt(ICipherParameters parameters, byte[] salt):this(parameters, salt, 0, salt.Length) + { + } + + public ParametersWithSalt(ICipherParameters parameters, byte[] salt, int saltOff, int saltLen) + { + this.salt = new byte[saltLen]; + this.parameters = parameters; + + Array.Copy(salt, saltOff, this.salt, 0, saltLen); + } + + public byte[] GetSalt() + { + return salt; + } + + public ICipherParameters Parameters + { + get + { + return parameters; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs.meta new file mode 100644 index 0000000..ad57271 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/ParametersWithSalt.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 46fe3e74d88b9a94892a247fbc85f040 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs new file mode 100644 index 0000000..8bb88e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs @@ -0,0 +1,51 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RC2Parameters + : KeyParameter + { + private readonly int bits; + + public RC2Parameters( + byte[] key) + : this(key, (key.Length > 128) ? 1024 : (key.Length * 8)) + { + } + + public RC2Parameters( + byte[] key, + int keyOff, + int keyLen) + : this(key, keyOff, keyLen, (keyLen > 128) ? 1024 : (keyLen * 8)) + { + } + + public RC2Parameters( + byte[] key, + int bits) + : base(key) + { + this.bits = bits; + } + + public RC2Parameters( + byte[] key, + int keyOff, + int keyLen, + int bits) + : base(key, keyOff, keyLen) + { + this.bits = bits; + } + + public int EffectiveKeyBits + { + get { return bits; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs.meta new file mode 100644 index 0000000..aa35585 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC2Parameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 383dd2f6afb5c064e937be5dd2cb7ec8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs new file mode 100644 index 0000000..3af41b5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs @@ -0,0 +1,31 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RC5Parameters + : KeyParameter + { + private readonly int rounds; + + public RC5Parameters( + byte[] key, + int rounds) + : base(key) + { + if (key.Length > 255) + throw new ArgumentException("RC5 key length can be no greater than 255"); + + this.rounds = rounds; + } + + public int Rounds + { + get { return rounds; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs.meta new file mode 100644 index 0000000..5e5c2e3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RC5Parameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71a86e01a87befa429932b5ce00b9fa6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs new file mode 100644 index 0000000..34dab35 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs @@ -0,0 +1,38 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaBlindingParameters + : ICipherParameters + { + private readonly RsaKeyParameters publicKey; + private readonly BigInteger blindingFactor; + + public RsaBlindingParameters( + RsaKeyParameters publicKey, + BigInteger blindingFactor) + { + if (publicKey.IsPrivate) + throw new ArgumentException("RSA parameters should be for a public key"); + + this.publicKey = publicKey; + this.blindingFactor = blindingFactor; + } + + public RsaKeyParameters PublicKey + { + get { return publicKey; } + } + + public BigInteger BlindingFactor + { + get { return blindingFactor; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs.meta new file mode 100644 index 0000000..fe46609 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RSABlindingParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 64139b13faf91484d84de884824f3b4f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs new file mode 100644 index 0000000..0b1913e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs @@ -0,0 +1,59 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaKeyGenerationParameters + : KeyGenerationParameters + { + private readonly BigInteger publicExponent; + private readonly int certainty; + + public RsaKeyGenerationParameters( + BigInteger publicExponent, + SecureRandom random, + int strength, + int certainty) + : base(random, strength) + { + this.publicExponent = publicExponent; + this.certainty = certainty; + } + + public BigInteger PublicExponent + { + get { return publicExponent; } + } + + public int Certainty + { + get { return certainty; } + } + + public override bool Equals( + object obj) + { + RsaKeyGenerationParameters other = obj as RsaKeyGenerationParameters; + + if (other == null) + { + return false; + } + + return certainty == other.certainty + && publicExponent.Equals(other.publicExponent); + } + + public override int GetHashCode() + { + return certainty.GetHashCode() ^ publicExponent.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..d059434 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyGenerationParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2dfb8ecda9194534ebe72fd378a0a6ba +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs new file mode 100644 index 0000000..5295a24 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs @@ -0,0 +1,67 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaKeyParameters + : AsymmetricKeyParameter + { + private readonly BigInteger modulus; + private readonly BigInteger exponent; + + public RsaKeyParameters( + bool isPrivate, + BigInteger modulus, + BigInteger exponent) + : base(isPrivate) + { + if (modulus == null) + throw new ArgumentNullException("modulus"); + if (exponent == null) + throw new ArgumentNullException("exponent"); + if (modulus.SignValue <= 0) + throw new ArgumentException("Not a valid RSA modulus", "modulus"); + if (exponent.SignValue <= 0) + throw new ArgumentException("Not a valid RSA exponent", "exponent"); + + this.modulus = modulus; + this.exponent = exponent; + } + + public BigInteger Modulus + { + get { return modulus; } + } + + public BigInteger Exponent + { + get { return exponent; } + } + + public override bool Equals( + object obj) + { + RsaKeyParameters kp = obj as RsaKeyParameters; + + if (kp == null) + { + return false; + } + + return kp.IsPrivate == this.IsPrivate + && kp.Modulus.Equals(this.modulus) + && kp.Exponent.Equals(this.exponent); + } + + public override int GetHashCode() + { + return modulus.GetHashCode() ^ exponent.GetHashCode() ^ IsPrivate.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs.meta new file mode 100644 index 0000000..40baaff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8fbdd0c93dcb1ea49b65b46b26c2d1db +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs new file mode 100644 index 0000000..99fb968 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaPrivateCrtKeyParameters + : RsaKeyParameters + { + private readonly BigInteger e, p, q, dP, dQ, qInv; + + public RsaPrivateCrtKeyParameters( + BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger p, + BigInteger q, + BigInteger dP, + BigInteger dQ, + BigInteger qInv) + : base(true, modulus, privateExponent) + { + ValidateValue(publicExponent, "publicExponent", "exponent"); + ValidateValue(p, "p", "P value"); + ValidateValue(q, "q", "Q value"); + ValidateValue(dP, "dP", "DP value"); + ValidateValue(dQ, "dQ", "DQ value"); + ValidateValue(qInv, "qInv", "InverseQ value"); + + this.e = publicExponent; + this.p = p; + this.q = q; + this.dP = dP; + this.dQ = dQ; + this.qInv = qInv; + } + + public BigInteger PublicExponent + { + get { return e; } + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger DP + { + get { return dP; } + } + + public BigInteger DQ + { + get { return dQ; } + } + + public BigInteger QInv + { + get { return qInv; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + RsaPrivateCrtKeyParameters kp = obj as RsaPrivateCrtKeyParameters; + + if (kp == null) + return false; + + return kp.DP.Equals(dP) + && kp.DQ.Equals(dQ) + && kp.Exponent.Equals(this.Exponent) + && kp.Modulus.Equals(this.Modulus) + && kp.P.Equals(p) + && kp.Q.Equals(q) + && kp.PublicExponent.Equals(e) + && kp.QInv.Equals(qInv); + } + + public override int GetHashCode() + { + return DP.GetHashCode() ^ DQ.GetHashCode() ^ Exponent.GetHashCode() ^ Modulus.GetHashCode() + ^ P.GetHashCode() ^ Q.GetHashCode() ^ PublicExponent.GetHashCode() ^ QInv.GetHashCode(); + } + + private static void ValidateValue(BigInteger x, string name, string desc) + { + if (x == null) + throw new ArgumentNullException(name); + if (x.SignValue <= 0) + throw new ArgumentException("Not a valid RSA " + desc, name); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta new file mode 100644 index 0000000..1c67bb1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b78b91bb256c288459bcb8c8aeb11f63 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng.meta new file mode 100644 index 0000000..addb8c3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0a4df581a93a3a246848f91de3e20edf +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs new file mode 100644 index 0000000..548a5dc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs @@ -0,0 +1,94 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +#if !(NETCF_1_0 || PORTABLE) + +using System; + +#if NETFX_CORE + using Windows.Security.Cryptography; +#else + using System.Security.Cryptography; +#endif + +namespace Org.BouncyCastle.Crypto.Prng +{ + /// + /// Uses Microsoft's RNGCryptoServiceProvider + /// + public class CryptoApiRandomGenerator + : IRandomGenerator + { +#if !NETFX_CORE + private readonly RandomNumberGenerator rndProv; +#endif + + public CryptoApiRandomGenerator() +#if !NETFX_CORE + : this(new RNGCryptoServiceProvider()) +#endif + { + } + +#if !NETFX_CORE + public CryptoApiRandomGenerator(RandomNumberGenerator rng) + { + this.rndProv = rng; + } +#endif + + #region IRandomGenerator Members + + public virtual void AddSeedMaterial(byte[] seed) + { + // We don't care about the seed + } + + public virtual void AddSeedMaterial(long seed) + { + // We don't care about the seed + } + + public virtual void NextBytes(byte[] bytes) + { +#if NETFX_CORE + var buffer = CryptographicBuffer.GenerateRandom((uint)bytes.Length); + byte[] finalBytes = null; + CryptographicBuffer.CopyToByteArray(buffer, out finalBytes); + finalBytes.CopyTo(bytes, 0); +#else + rndProv.GetBytes(bytes); +#endif + } + + public virtual void NextBytes(byte[] bytes, int start, int len) + { + if (start < 0) + throw new ArgumentException("Start offset cannot be negative", "start"); + if (bytes.Length < (start + len)) + throw new ArgumentException("Byte array too small for requested offset and length"); + + if (bytes.Length == len && start == 0) + { + NextBytes(bytes); + } + else + { +#if NETFX_CORE + byte[] tmpBuf = null; + var buffer = CryptographicBuffer.GenerateRandom((uint)bytes.Length); + CryptographicBuffer.CopyToByteArray(buffer, out tmpBuf); +#else + byte[] tmpBuf = new byte[len]; + NextBytes(tmpBuf); +#endif + Array.Copy(tmpBuf, 0, bytes, start, len); + } + } + + #endregion + } +} + +#endif + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs.meta new file mode 100644 index 0000000..899e9e2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/CryptoApiRandomGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ccbe3ba15c23a8a4d94f9d684f23a748 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs new file mode 100644 index 0000000..c6c0bd6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs @@ -0,0 +1,131 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * Random generation based on the digest with counter. Calling AddSeedMaterial will + * always increase the entropy of the hash. + *

+ * Internal access to the digest is synchronized so a single one of these can be shared. + *

+ */ + public class DigestRandomGenerator + : IRandomGenerator + { + private const long CYCLE_COUNT = 10; + + private long stateCounter; + private long seedCounter; + private IDigest digest; + private byte[] state; + private byte[] seed; + + public DigestRandomGenerator( + IDigest digest) + { + this.digest = digest; + + this.seed = new byte[digest.GetDigestSize()]; + this.seedCounter = 1; + + this.state = new byte[digest.GetDigestSize()]; + this.stateCounter = 1; + } + + public void AddSeedMaterial( + byte[] inSeed) + { + lock (this) + { + DigestUpdate(inSeed); + DigestUpdate(seed); + DigestDoFinal(seed); + } + } + + public void AddSeedMaterial( + long rSeed) + { + lock (this) + { + DigestAddCounter(rSeed); + DigestUpdate(seed); + DigestDoFinal(seed); + } + } + + public void NextBytes( + byte[] bytes) + { + NextBytes(bytes, 0, bytes.Length); + } + + public void NextBytes( + byte[] bytes, + int start, + int len) + { + lock (this) + { + int stateOff = 0; + + GenerateState(); + + int end = start + len; + for (int i = start; i < end; ++i) + { + if (stateOff == state.Length) + { + GenerateState(); + stateOff = 0; + } + bytes[i] = state[stateOff++]; + } + } + } + + private void CycleSeed() + { + DigestUpdate(seed); + DigestAddCounter(seedCounter++); + DigestDoFinal(seed); + } + + private void GenerateState() + { + DigestAddCounter(stateCounter++); + DigestUpdate(state); + DigestUpdate(seed); + DigestDoFinal(state); + + if ((stateCounter % CYCLE_COUNT) == 0) + { + CycleSeed(); + } + } + + private void DigestAddCounter(long seedVal) + { + byte[] bytes = new byte[8]; + Pack.UInt64_To_LE((ulong)seedVal, bytes); + digest.BlockUpdate(bytes, 0, bytes.Length); + } + + private void DigestUpdate(byte[] inSeed) + { + digest.BlockUpdate(inSeed, 0, inSeed.Length); + } + + private void DigestDoFinal(byte[] result) + { + digest.DoFinal(result, 0); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs.meta new file mode 100644 index 0000000..8f3bd72 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/DigestRandomGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7979612bf0f2722478158ecadb846f1d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs new file mode 100644 index 0000000..3d9364a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs @@ -0,0 +1,30 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /// Generic interface for objects generating random bytes. + public interface IRandomGenerator + { + /// Add more seed material to the generator. + /// A byte array to be mixed into the generator's state. + void AddSeedMaterial(byte[] seed); + + /// Add more seed material to the generator. + /// A long value to be mixed into the generator's state. + void AddSeedMaterial(long seed); + + /// Fill byte array with random values. + /// Array to be filled. + void NextBytes(byte[] bytes); + + /// Fill byte array with random values. + /// Array to receive bytes. + /// Index to start filling at. + /// Length of segment to fill. + void NextBytes(byte[] bytes, int start, int len); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs.meta new file mode 100644 index 0000000..167535b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/prng/IRandomGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4455377f4c3b6cf4fb000aca48c08ab8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers.meta new file mode 100644 index 0000000..8aa1e48 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 962655b8d2a40294bad978e6d458a24e +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs new file mode 100644 index 0000000..f08655f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs @@ -0,0 +1,149 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class DsaDigestSigner + : ISigner + { + private readonly IDigest digest; + private readonly IDsa dsaSigner; + private bool forSigning; + + public DsaDigestSigner( + IDsa signer, + IDigest digest) + { + this.digest = digest; + this.dsaSigner = signer; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + throw new InvalidKeyException("Signing Requires Private Key."); + + if (!forSigning && k.IsPrivate) + throw new InvalidKeyException("Verification Requires Public Key."); + + Reset(); + + dsaSigner.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update( + byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("DSADigestSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + BigInteger[] sig = dsaSigner.GenerateSignature(hash); + + return DerEncode(sig[0], sig[1]); + } + + /// true if the internal state represents the signature described in the passed in array. + public virtual bool VerifySignature( + byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("DSADigestSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + BigInteger[] sig = DerDecode(signature); + return dsaSigner.VerifySignature(hash, sig[0], sig[1]); + } + catch (IOException) + { + return false; + } + } + + /// Reset the internal state + public virtual void Reset() + { + digest.Reset(); + } + + private byte[] DerEncode( + BigInteger r, + BigInteger s) + { + return new DerSequence(new DerInteger(r), new DerInteger(s)).GetDerEncoded(); + } + + private BigInteger[] DerDecode( + byte[] encoding) + { + Asn1Sequence s = (Asn1Sequence) Asn1Object.FromByteArray(encoding); + + return new BigInteger[] + { + ((DerInteger) s[0]).Value, + ((DerInteger) s[1]).Value + }; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs.meta new file mode 100644 index 0000000..47dac0e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaDigestSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c9905792014e74d4f8a532ab18084ac5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs new file mode 100644 index 0000000..50363e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs @@ -0,0 +1,160 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * The Digital Signature Algorithm - as described in "Handbook of Applied + * Cryptography", pages 452 - 453. + */ + public class DsaSigner + : IDsa + { + protected readonly IDsaKCalculator kCalculator; + + protected DsaKeyParameters key = null; + protected SecureRandom random = null; + + /** + * Default configuration, random K values. + */ + public DsaSigner() + { + this.kCalculator = new RandomDsaKCalculator(); + } + + /** + * Configuration with an alternate, possibly deterministic calculator of K. + * + * @param kCalculator a K value calculator. + */ + public DsaSigner(IDsaKCalculator kCalculator) + { + this.kCalculator = kCalculator; + } + + public virtual string AlgorithmName + { + get { return "DSA"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + SecureRandom providedRandom = null; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + providedRandom = rParam.Random; + parameters = rParam.Parameters; + } + + if (!(parameters is DsaPrivateKeyParameters)) + throw new InvalidKeyException("DSA private key required for signing"); + + this.key = (DsaPrivateKeyParameters)parameters; + } + else + { + if (!(parameters is DsaPublicKeyParameters)) + throw new InvalidKeyException("DSA public key required for verification"); + + this.key = (DsaPublicKeyParameters)parameters; + } + + this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom); + } + + /** + * Generate a signature for the given message using the key we were + * initialised with. For conventional DSA the message should be a SHA-1 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature(byte[] message) + { + DsaParameters parameters = key.Parameters; + BigInteger q = parameters.Q; + BigInteger m = CalculateE(q, message); + BigInteger x = ((DsaPrivateKeyParameters)key).X; + + if (kCalculator.IsDeterministic) + { + kCalculator.Init(q, x, message); + } + else + { + kCalculator.Init(q, random); + } + + BigInteger k = kCalculator.NextK(); + + BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q); + + k = k.ModInverse(q).Multiply(m.Add(x.Multiply(r))); + + BigInteger s = k.Mod(q); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a DSA signature for + * the passed in message for standard DSA the message should be a + * SHA-1 hash of the real message to be verified. + */ + public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) + { + DsaParameters parameters = key.Parameters; + BigInteger q = parameters.Q; + BigInteger m = CalculateE(q, message); + + if (r.SignValue <= 0 || q.CompareTo(r) <= 0) + { + return false; + } + + if (s.SignValue <= 0 || q.CompareTo(s) <= 0) + { + return false; + } + + BigInteger w = s.ModInverse(q); + + BigInteger u1 = m.Multiply(w).Mod(q); + BigInteger u2 = r.Multiply(w).Mod(q); + + BigInteger p = parameters.P; + u1 = parameters.G.ModPow(u1, p); + u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p); + + BigInteger v = u1.Multiply(u2).Mod(p).Mod(q); + + return v.Equals(r); + } + + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) + { + int length = System.Math.Min(message.Length, n.BitLength / 8); + + return new BigInteger(1, message, 0, length); + } + + protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) + { + return !needed ? null : (provided != null) ? provided : new SecureRandom(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs.meta new file mode 100644 index 0000000..2967acf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/DsaSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5b22a4699dfabe048aca470ec8820c46 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs new file mode 100644 index 0000000..ab66b83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs @@ -0,0 +1,244 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * EC-DSA as described in X9.62 + */ + public class ECDsaSigner + : IDsa + { + private static readonly BigInteger Eight = BigInteger.ValueOf(8); + + protected readonly IDsaKCalculator kCalculator; + + protected ECKeyParameters key = null; + protected SecureRandom random = null; + + /** + * Default configuration, random K values. + */ + public ECDsaSigner() + { + this.kCalculator = new RandomDsaKCalculator(); + } + + /** + * Configuration with an alternate, possibly deterministic calculator of K. + * + * @param kCalculator a K value calculator. + */ + public ECDsaSigner(IDsaKCalculator kCalculator) + { + this.kCalculator = kCalculator; + } + + public virtual string AlgorithmName + { + get { return "ECDSA"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + SecureRandom providedRandom = null; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + providedRandom = rParam.Random; + parameters = rParam.Parameters; + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters)parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters)parameters; + } + + this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom); + } + + // 5.3 pg 28 + /** + * Generate a signature for the given message using the key we were + * initialised with. For conventional DSA the message should be a SHA-1 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature(byte[] message) + { + ECDomainParameters ec = key.Parameters; + BigInteger n = ec.N; + BigInteger e = CalculateE(n, message); + BigInteger d = ((ECPrivateKeyParameters)key).D; + + if (kCalculator.IsDeterministic) + { + kCalculator.Init(n, d, message); + } + else + { + kCalculator.Init(n, random); + } + + BigInteger r, s; + + ECMultiplier basePointMultiplier = CreateBasePointMultiplier(); + + // 5.3.2 + do // Generate s + { + BigInteger k; + do // Generate r + { + k = kCalculator.NextK(); + + ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize(); + + // 5.3.3 + r = p.AffineXCoord.ToBigInteger().Mod(n); + } + while (r.SignValue == 0); + + s = k.ModInverse(n).Multiply(e.Add(d.Multiply(r))).Mod(n); + } + while (s.SignValue == 0); + + return new BigInteger[]{ r, s }; + } + + // 5.4 pg 29 + /** + * return true if the value r and s represent a DSA signature for + * the passed in message (for standard DSA the message should be + * a SHA-1 hash of the real message to be verified). + */ + public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) + { + BigInteger n = key.Parameters.N; + + // r and s should both in the range [1,n-1] + if (r.SignValue < 1 || s.SignValue < 1 + || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) + { + return false; + } + + BigInteger e = CalculateE(n, message); + BigInteger c = s.ModInverse(n); + + BigInteger u1 = e.Multiply(c).Mod(n); + BigInteger u2 = r.Multiply(c).Mod(n); + + ECPoint G = key.Parameters.G; + ECPoint Q = ((ECPublicKeyParameters) key).Q; + + ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); + + if (point.IsInfinity) + return false; + + /* + * If possible, avoid normalizing the point (to save a modular inversion in the curve field). + * + * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. + * If the cofactor is known and small, we generate those possible field values and project each + * of them to the same "denominator" (depending on the particular projective coordinates in use) + * as the calculated point.X. If any of the projected values matches point.X, then we have: + * (point.X / Denominator mod p) mod n == r + * as required, and verification succeeds. + * + * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in + * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). + */ + ECCurve curve = point.Curve; + if (curve != null) + { + BigInteger cofactor = curve.Cofactor; + if (cofactor != null && cofactor.CompareTo(Eight) <= 0) + { + ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); + if (D != null && !D.IsZero) + { + ECFieldElement X = point.XCoord; + while (curve.IsValidFieldElement(r)) + { + ECFieldElement R = curve.FromBigInteger(r).Multiply(D); + if (R.Equals(X)) + { + return true; + } + r = r.Add(n); + } + return false; + } + } + } + + BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n); + return v.Equals(r); + } + + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) + { + int messageBitLength = message.Length * 8; + BigInteger trunc = new BigInteger(1, message); + + if (n.BitLength < messageBitLength) + { + trunc = trunc.ShiftRight(messageBitLength - n.BitLength); + } + + return trunc; + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + + protected virtual ECFieldElement GetDenominator(int coordinateSystem, ECPoint p) + { + switch (coordinateSystem) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + case ECCurve.COORD_SKEWED: + return p.GetZCoord(0); + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + return p.GetZCoord(0).Square(); + default: + return null; + } + } + + protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) + { + return !needed ? null : (provided != null) ? provided : new SecureRandom(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs.meta new file mode 100644 index 0000000..f4fc119 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECDsaSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2aeec19b82b60784b857139153cf8807 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs new file mode 100644 index 0000000..93e3f73 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs @@ -0,0 +1,166 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * GOST R 34.10-2001 Signature Algorithm + */ + public class ECGost3410Signer + : IDsa + { + private ECKeyParameters key; + private SecureRandom random; + + public virtual string AlgorithmName + { + get { return "ECGOST3410"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters) parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters)parameters; + } + } + + /** + * generate a signature for the given message using the key we were + * initialised with. For conventional GOST3410 the message should be a GOST3411 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature( + byte[] message) + { + byte[] mRev = new byte[message.Length]; // conversion is little-endian + for (int i = 0; i != mRev.Length; i++) + { + mRev[i] = message[mRev.Length - 1 - i]; + } + + BigInteger e = new BigInteger(1, mRev); + + ECDomainParameters ec = key.Parameters; + BigInteger n = ec.N; + BigInteger d = ((ECPrivateKeyParameters)key).D; + + BigInteger r, s = null; + + ECMultiplier basePointMultiplier = CreateBasePointMultiplier(); + + do // generate s + { + BigInteger k; + do // generate r + { + do + { + k = new BigInteger(n.BitLength, random); + } + while (k.SignValue == 0); + + ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize(); + + r = p.AffineXCoord.ToBigInteger().Mod(n); + } + while (r.SignValue == 0); + + s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n); + } + while (s.SignValue == 0); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a GOST3410 signature for + * the passed in message (for standard GOST3410 the message should be + * a GOST3411 hash of the real message to be verified). + */ + public virtual bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + byte[] mRev = new byte[message.Length]; // conversion is little-endian + for (int i = 0; i != mRev.Length; i++) + { + mRev[i] = message[mRev.Length - 1 - i]; + } + + BigInteger e = new BigInteger(1, mRev); + BigInteger n = key.Parameters.N; + + // r in the range [1,n-1] + if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) + { + return false; + } + + // s in the range [1,n-1] + if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) + { + return false; + } + + BigInteger v = e.ModInverse(n); + + BigInteger z1 = s.Multiply(v).Mod(n); + BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); + + ECPoint G = key.Parameters.G; // P + ECPoint Q = ((ECPublicKeyParameters)key).Q; + + ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize(); + + if (point.IsInfinity) + return false; + + BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n); + + return R.Equals(r); + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs.meta new file mode 100644 index 0000000..b00b619 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECGOST3410Signer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c0fa6c431f2efb54c89b5784adc45bd7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs new file mode 100644 index 0000000..2c6acab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs @@ -0,0 +1,192 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * EC-NR as described in IEEE 1363-2000 + */ + public class ECNRSigner + : IDsa + { + private bool forSigning; + private ECKeyParameters key; + private SecureRandom random; + + public virtual string AlgorithmName + { + get { return "ECNR"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom) parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters) parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters) parameters; + } + } + + // Section 7.2.5 ECSP-NR, pg 34 + /** + * generate a signature for the given message using the key we were + * initialised with. Generally, the order of the curve should be at + * least as long as the hash of the message of interest, and with + * ECNR it *must* be at least as long. + * + * @param digest the digest to be signed. + * @exception DataLengthException if the digest is longer than the key allows + */ + public virtual BigInteger[] GenerateSignature( + byte[] message) + { + if (!this.forSigning) + { + // not properly initilaized... deal with it + throw new InvalidOperationException("not initialised for signing"); + } + + BigInteger n = ((ECPrivateKeyParameters) this.key).Parameters.N; + int nBitLength = n.BitLength; + + BigInteger e = new BigInteger(1, message); + int eBitLength = e.BitLength; + + ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key; + + if (eBitLength > nBitLength) + { + throw new DataLengthException("input too large for ECNR key."); + } + + BigInteger r = null; + BigInteger s = null; + + AsymmetricCipherKeyPair tempPair; + do // generate r + { + // generate another, but very temporary, key pair using + // the same EC parameters + ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); + + keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random)); + + tempPair = keyGen.GenerateKeyPair(); + + // BigInteger Vx = tempPair.getPublic().getW().getAffineX(); + ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key + BigInteger Vx = V.Q.AffineXCoord.ToBigInteger(); // get the point's x coordinate + + r = Vx.Add(e).Mod(n); + } + while (r.SignValue == 0); + + // generate s + BigInteger x = privKey.D; // private key value + BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value + s = u.Subtract(r.Multiply(x)).Mod(n); + + return new BigInteger[]{ r, s }; + } + + // Section 7.2.6 ECVP-NR, pg 35 + /** + * return true if the value r and s represent a signature for the + * message passed in. Generally, the order of the curve should be at + * least as long as the hash of the message of interest, and with + * ECNR, it *must* be at least as long. But just in case the signer + * applied mod(n) to the longer digest, this implementation will + * apply mod(n) during verification. + * + * @param digest the digest to be verified. + * @param r the r value of the signature. + * @param s the s value of the signature. + * @exception DataLengthException if the digest is longer than the key allows + */ + public virtual bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + if (this.forSigning) + { + // not properly initilaized... deal with it + throw new InvalidOperationException("not initialised for verifying"); + } + + ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; + BigInteger n = pubKey.Parameters.N; + int nBitLength = n.BitLength; + + BigInteger e = new BigInteger(1, message); + int eBitLength = e.BitLength; + + if (eBitLength > nBitLength) + { + throw new DataLengthException("input too large for ECNR key."); + } + + // r in the range [1,n-1] + if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) + { + return false; + } + + // s in the range [0,n-1] NB: ECNR spec says 0 + if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0) + { + return false; + } + + // compute P = sG + rW + + ECPoint G = pubKey.Parameters.G; + ECPoint W = pubKey.Q; + // calculate P using Bouncy math + ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize(); + + if (P.IsInfinity) + return false; + + BigInteger x = P.AffineXCoord.ToBigInteger(); + BigInteger t = r.Subtract(x).Mod(n); + + return t.Equals(e); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs.meta new file mode 100644 index 0000000..33a5b6d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/ECNRSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7b65a3f5dbbb4a340bbc3407aa2a1316 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs new file mode 100644 index 0000000..9b165e5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs @@ -0,0 +1,149 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Gost3410DigestSigner + : ISigner + { + private readonly IDigest digest; + private readonly IDsa dsaSigner; + private bool forSigning; + + public Gost3410DigestSigner( + IDsa signer, + IDigest digest) + { + this.dsaSigner = signer; + this.digest = digest; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + { + throw new InvalidKeyException("Signing Requires Private Key."); + } + + if (!forSigning && k.IsPrivate) + { + throw new InvalidKeyException("Verification Requires Public Key."); + } + + Reset(); + + dsaSigner.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update( + byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + BigInteger[] sig = dsaSigner.GenerateSignature(hash); + byte[] sigBytes = new byte[64]; + + // TODO Add methods to allow writing BigInteger to existing byte array? + byte[] r = sig[0].ToByteArrayUnsigned(); + byte[] s = sig[1].ToByteArrayUnsigned(); + s.CopyTo(sigBytes, 32 - s.Length); + r.CopyTo(sigBytes, 64 - r.Length); + return sigBytes; + } + catch (Exception e) + { + throw new SignatureException(e.Message, e); + } + } + + /// true if the internal state represents the signature described in the passed in array. + public virtual bool VerifySignature( + byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("DSADigestSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + BigInteger R, S; + try + { + R = new BigInteger(1, signature, 32, 32); + S = new BigInteger(1, signature, 0, 32); + } + catch (Exception e) + { + throw new SignatureException("error decoding signature bytes.", e); + } + + return dsaSigner.VerifySignature(hash, R, S); + } + + /// Reset the internal state + public virtual void Reset() + { + digest.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs.meta new file mode 100644 index 0000000..e405fed --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410DigestSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e49e35369e72fe545b2a1fddbaa3603a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs new file mode 100644 index 0000000..1a9f6ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs @@ -0,0 +1,136 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * Gost R 34.10-94 Signature Algorithm + */ + public class Gost3410Signer + : IDsa + { + private Gost3410KeyParameters key; + private SecureRandom random; + + public virtual string AlgorithmName + { + get { return "GOST3410"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is Gost3410PrivateKeyParameters)) + throw new InvalidKeyException("GOST3410 private key required for signing"); + + this.key = (Gost3410PrivateKeyParameters) parameters; + } + else + { + if (!(parameters is Gost3410PublicKeyParameters)) + throw new InvalidKeyException("GOST3410 public key required for signing"); + + this.key = (Gost3410PublicKeyParameters) parameters; + } + } + + /** + * generate a signature for the given message using the key we were + * initialised with. For conventional Gost3410 the message should be a Gost3411 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature( + byte[] message) + { + byte[] mRev = new byte[message.Length]; // conversion is little-endian + for (int i = 0; i != mRev.Length; i++) + { + mRev[i] = message[mRev.Length - 1 - i]; + } + + BigInteger m = new BigInteger(1, mRev); + Gost3410Parameters parameters = key.Parameters; + BigInteger k; + + do + { + k = new BigInteger(parameters.Q.BitLength, random); + } + while (k.CompareTo(parameters.Q) >= 0); + + BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q); + + BigInteger s = k.Multiply(m). + Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)). + Mod(parameters.Q); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a Gost3410 signature for + * the passed in message for standard Gost3410 the message should be a + * Gost3411 hash of the real message to be verified. + */ + public virtual bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + byte[] mRev = new byte[message.Length]; // conversion is little-endian + for (int i = 0; i != mRev.Length; i++) + { + mRev[i] = message[mRev.Length - 1 - i]; + } + + BigInteger m = new BigInteger(1, mRev); + Gost3410Parameters parameters = key.Parameters; + + if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0) + { + return false; + } + + if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0) + { + return false; + } + + BigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q); + + BigInteger z1 = s.Multiply(v).Mod(parameters.Q); + BigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q); + + z1 = parameters.A.ModPow(z1, parameters.P); + z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P); + + BigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q); + + return u.Equals(r); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs.meta new file mode 100644 index 0000000..e736fe7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GOST3410Signer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 675f660b7066e3842bfd94bc6c5ea723 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs new file mode 100644 index 0000000..3bf387a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs @@ -0,0 +1,134 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class GenericSigner + : ISigner + { + private readonly IAsymmetricBlockCipher engine; + private readonly IDigest digest; + private bool forSigning; + + public GenericSigner( + IAsymmetricBlockCipher engine, + IDigest digest) + { + this.engine = engine; + this.digest = digest; + } + + public virtual string AlgorithmName + { + get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; } + } + + /** + * initialise the signer for signing or verification. + * + * @param forSigning + * true if for signing, false otherwise + * @param parameters + * necessary parameters. + */ + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + throw new InvalidKeyException("Signing requires private key."); + + if (!forSigning && k.IsPrivate) + throw new InvalidKeyException("Verification requires public key."); + + Reset(); + + engine.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update(byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate(byte[] input, int inOff, int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using the key + * we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("GenericSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + return engine.ProcessBlock(hash, 0, hash.Length); + } + + /** + * return true if the internal state represents the signature described in + * the passed in array. + */ + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("GenericSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + byte[] sig = engine.ProcessBlock(signature, 0, signature.Length); + + // Extend with leading zeroes to match the digest size, if necessary. + if (sig.Length < hash.Length) + { + byte[] tmp = new byte[hash.Length]; + Array.Copy(sig, 0, tmp, tmp.Length - sig.Length, sig.Length); + sig = tmp; + } + + return Arrays.ConstantTimeAreEqual(sig, hash); + } + catch (Exception) + { + return false; + } + } + + public virtual void Reset() + { + digest.Reset(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs.meta new file mode 100644 index 0000000..82bcf71 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/GenericSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c33281fcbe5fc2448a481ded39da05c4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs new file mode 100644 index 0000000..310b36b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs @@ -0,0 +1,154 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979. + */ + public class HMacDsaKCalculator + : IDsaKCalculator + { + private readonly HMac hMac; + private readonly byte[] K; + private readonly byte[] V; + + private BigInteger n; + + /** + * Base constructor. + * + * @param digest digest to build the HMAC on. + */ + public HMacDsaKCalculator(IDigest digest) + { + this.hMac = new HMac(digest); + this.V = new byte[hMac.GetMacSize()]; + this.K = new byte[hMac.GetMacSize()]; + } + + public virtual bool IsDeterministic + { + get { return true; } + } + + public virtual void Init(BigInteger n, SecureRandom random) + { + throw new InvalidOperationException("Operation not supported"); + } + + public void Init(BigInteger n, BigInteger d, byte[] message) + { + this.n = n; + + Arrays.Fill(V, (byte)0x01); + Arrays.Fill(K, (byte)0); + + byte[] x = new byte[(n.BitLength + 7) / 8]; + byte[] dVal = BigIntegers.AsUnsignedByteArray(d); + + Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length); + + byte[] m = new byte[(n.BitLength + 7) / 8]; + + BigInteger mInt = BitsToInt(message); + + if (mInt.CompareTo(n) >= 0) + { + mInt = mInt.Subtract(n); + } + + byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt); + + Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + hMac.Update((byte)0x00); + hMac.BlockUpdate(x, 0, x.Length); + hMac.BlockUpdate(m, 0, m.Length); + + hMac.DoFinal(K, 0); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + + hMac.BlockUpdate(V, 0, V.Length); + hMac.Update((byte)0x01); + hMac.BlockUpdate(x, 0, x.Length); + hMac.BlockUpdate(m, 0, m.Length); + + hMac.DoFinal(K, 0); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + } + + public virtual BigInteger NextK() + { + byte[] t = new byte[((n.BitLength + 7) / 8)]; + + for (;;) + { + int tOff = 0; + + while (tOff < t.Length) + { + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + + int len = System.Math.Min(t.Length - tOff, V.Length); + Array.Copy(V, 0, t, tOff, len); + tOff += len; + } + + BigInteger k = BitsToInt(t); + + if (k.SignValue > 0 && k.CompareTo(n) < 0) + { + return k; + } + + hMac.BlockUpdate(V, 0, V.Length); + hMac.Update((byte)0x00); + + hMac.DoFinal(K, 0); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + } + } + + private BigInteger BitsToInt(byte[] t) + { + BigInteger v = new BigInteger(1, t); + + if (t.Length * 8 > n.BitLength) + { + v = v.ShiftRight(t.Length * 8 - n.BitLength); + } + + return v; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs.meta new file mode 100644 index 0000000..ccf591e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/HMacDsaKCalculator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 78e1027b4769aa54ba1097aeccbdf881 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs new file mode 100644 index 0000000..03ea3bf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * Interface define calculators of K values for DSA/ECDSA. + */ + public interface IDsaKCalculator + { + /** + * Return true if this calculator is deterministic, false otherwise. + * + * @return true if deterministic, otherwise false. + */ + bool IsDeterministic { get; } + + /** + * Non-deterministic initialiser. + * + * @param n the order of the DSA group. + * @param random a source of randomness. + */ + void Init(BigInteger n, SecureRandom random); + + /** + * Deterministic initialiser. + * + * @param n the order of the DSA group. + * @param d the DSA private value. + * @param message the message being signed. + */ + void Init(BigInteger n, BigInteger d, byte[] message); + + /** + * Return the next valid value of K. + * + * @return a K value. + */ + BigInteger NextK(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs.meta new file mode 100644 index 0000000..6cfb30c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IDsaKCalculator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b6b2ca8e130099946a1565068a5b5929 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs new file mode 100644 index 0000000..c41016b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs @@ -0,0 +1,554 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// ISO9796-2 - mechanism using a hash function with recovery (scheme 1) + public class Iso9796d2Signer : ISignerWithRecovery + { + /// + /// Return a reference to the recoveredMessage message. + /// + /// The full/partial recoveredMessage message. + /// + public byte[] GetRecoveredMessage() + { + return recoveredMessage; + } + + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerImplicit = 0xBC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerRipeMD160 = 0x31CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerRipeMD128 = 0x32CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha1 = 0x33CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha256 = 0x34CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha512 = 0x35CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha384 = 0x36CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerWhirlpool = 0x37CC; + + private IDigest digest; + private IAsymmetricBlockCipher cipher; + + private int trailer; + private int keyBits; + private byte[] block; + private byte[] mBuf; + private int messageLength; + private bool fullMessage; + private byte[] recoveredMessage; + + private byte[] preSig; + private byte[] preBlock; + + /// + /// Generate a signer with either implicit or explicit trailers for ISO9796-2. + /// + /// base cipher to use for signature creation/verification + /// digest to use. + /// whether or not the trailer is implicit or gives the hash. + public Iso9796d2Signer( + IAsymmetricBlockCipher cipher, + IDigest digest, + bool isImplicit) + { + this.cipher = cipher; + this.digest = digest; + + if (isImplicit) + { + trailer = IsoTrailers.TRAILER_IMPLICIT; + } + else if (IsoTrailers.NoTrailerAvailable(digest)) + { + throw new ArgumentException("no valid trailer", "digest"); + } + else + { + trailer = IsoTrailers.GetTrailer(digest); + } + } + + /// Constructor for a signer with an explicit digest trailer. + /// + /// + /// cipher to use. + /// + /// digest to sign with. + /// + public Iso9796d2Signer(IAsymmetricBlockCipher cipher, IDigest digest) + : this(cipher, digest, false) + { + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + "ISO9796-2S1"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + RsaKeyParameters kParam = (RsaKeyParameters) parameters; + + cipher.Init(forSigning, kParam); + + keyBits = kParam.Modulus.BitLength; + + block = new byte[(keyBits + 7) / 8]; + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + mBuf = new byte[block.Length - digest.GetDigestSize() - 2]; + } + else + { + mBuf = new byte[block.Length - digest.GetDigestSize() - 3]; + } + + Reset(); + } + + /// compare two byte arrays - constant time. + private bool IsSameAs(byte[] a, byte[] b) + { + int checkLen; + if (messageLength > mBuf.Length) + { + if (mBuf.Length > b.Length) + { + return false; + } + + checkLen = mBuf.Length; + } + else + { + if (messageLength != b.Length) + { + return false; + } + + checkLen = b.Length; + } + + bool isOkay = true; + + for (int i = 0; i != checkLen; i++) + { + if (a[i] != b[i]) + { + isOkay = false; + } + } + + return isOkay; + } + + /// clear possible sensitive data + private void ClearBlock( + byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + public virtual void UpdateWithRecoveredMessage( + byte[] signature) + { + byte[] block = cipher.ProcessBlock(signature, 0, signature.Length); + + if (((block[0] & 0xC0) ^ 0x40) != 0) + throw new InvalidCipherTextException("malformed signature"); + + if (((block[block.Length - 1] & 0xF) ^ 0xC) != 0) + throw new InvalidCipherTextException("malformed signature"); + + int delta = 0; + + if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0) + { + delta = 1; + } + else + { + int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF); + + if (IsoTrailers.NoTrailerAvailable(digest)) + throw new ArgumentException("unrecognised hash in signature"); + + if (sigTrail != IsoTrailers.GetTrailer(digest)) + throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail); + + delta = 2; + } + + // + // find out how much padding we've got + // + int mStart = 0; + + for (mStart = 0; mStart != block.Length; mStart++) + { + if (((block[mStart] & 0x0f) ^ 0x0a) == 0) + break; + } + + mStart++; + + int off = block.Length - delta - digest.GetDigestSize(); + + // + // there must be at least one byte of message string + // + if ((off - mStart) <= 0) + throw new InvalidCipherTextException("malformed block"); + + // + // if we contain the whole message as well, check the hash of that. + // + if ((block[0] & 0x20) == 0) + { + fullMessage = true; + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + else + { + fullMessage = false; + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + + preSig = signature; + preBlock = block; + + digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length); + messageLength = recoveredMessage.Length; + recoveredMessage.CopyTo(mBuf, 0); + } + + /// update the internal digest with the byte b + public virtual void Update( + byte input) + { + digest.Update(input); + + if (messageLength < mBuf.Length) + { + mBuf[messageLength] = input; + } + + messageLength++; + } + + /// update the internal digest with the byte array in + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + while (length > 0 && messageLength < mBuf.Length) + { + //for (int i = 0; i < length && (i + messageLength) < mBuf.Length; i++) + //{ + // mBuf[messageLength + i] = input[inOff + i]; + //} + this.Update(input[inOff]); + inOff++; + length--; + } + + digest.BlockUpdate(input, inOff, length); + messageLength += length; + } + + /// reset the internal state + public virtual void Reset() + { + digest.Reset(); + messageLength = 0; + ClearBlock(mBuf); + + if (recoveredMessage != null) + { + ClearBlock(recoveredMessage); + } + + recoveredMessage = null; + fullMessage = false; + + if (preSig != null) + { + preSig = null; + ClearBlock(preBlock); + preBlock = null; + } + } + + /// Generate a signature for the loaded message using the key we were + /// initialised with. + /// + public virtual byte[] GenerateSignature() + { + int digSize = digest.GetDigestSize(); + + int t = 0; + int delta = 0; + + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + t = 8; + delta = block.Length - digSize - 1; + digest.DoFinal(block, delta); + block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT; + } + else + { + t = 16; + delta = block.Length - digSize - 2; + digest.DoFinal(block, delta); + block[block.Length - 2] = (byte) ((uint)trailer >> 8); + block[block.Length - 1] = (byte) trailer; + } + + byte header = 0; + int x = (digSize + messageLength) * 8 + t + 4 - keyBits; + + if (x > 0) + { + int mR = messageLength - ((x + 7) / 8); + header = (byte) (0x60); + + delta -= mR; + + Array.Copy(mBuf, 0, block, delta, mR); + } + else + { + header = (byte) (0x40); + delta -= messageLength; + + Array.Copy(mBuf, 0, block, delta, messageLength); + } + + if ((delta - 1) > 0) + { + for (int i = delta - 1; i != 0; i--) + { + block[i] = (byte) 0xbb; + } + block[delta - 1] ^= (byte) 0x01; + block[0] = (byte) 0x0b; + block[0] |= header; + } + else + { + block[0] = (byte) 0x0a; + block[0] |= header; + } + + byte[] b = cipher.ProcessBlock(block, 0, block.Length); + + ClearBlock(mBuf); + ClearBlock(block); + + return b; + } + + /// return true if the signature represents a ISO9796-2 signature + /// for the passed in message. + /// + public virtual bool VerifySignature(byte[] signature) + { + byte[] block; + + if (preSig == null) + { + try + { + block = cipher.ProcessBlock(signature, 0, signature.Length); + } + catch (Exception) + { + return false; + } + } + else + { + if (!Arrays.AreEqual(preSig, signature)) + throw new InvalidOperationException("updateWithRecoveredMessage called on different signature"); + + block = preBlock; + + preSig = null; + preBlock = null; + } + + if (((block[0] & 0xC0) ^ 0x40) != 0) + return ReturnFalse(block); + + if (((block[block.Length - 1] & 0xF) ^ 0xC) != 0) + return ReturnFalse(block); + + int delta = 0; + + if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0) + { + delta = 1; + } + else + { + int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF); + + if (IsoTrailers.NoTrailerAvailable(digest)) + throw new ArgumentException("unrecognised hash in signature"); + + if (sigTrail != IsoTrailers.GetTrailer(digest)) + throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail); + + delta = 2; + } + + // + // find out how much padding we've got + // + int mStart = 0; + for (; mStart != block.Length; mStart++) + { + if (((block[mStart] & 0x0f) ^ 0x0a) == 0) + { + break; + } + } + + mStart++; + + // + // check the hashes + // + byte[] hash = new byte[digest.GetDigestSize()]; + + int off = block.Length - delta - hash.Length; + + // + // there must be at least one byte of message string + // + if ((off - mStart) <= 0) + { + return ReturnFalse(block); + } + + // + // if we contain the whole message as well, check the hash of that. + // + if ((block[0] & 0x20) == 0) + { + fullMessage = true; + + // check right number of bytes passed in. + if (messageLength > off - mStart) + { + return ReturnFalse(block); + } + + digest.Reset(); + digest.BlockUpdate(block, mStart, off - mStart); + digest.DoFinal(hash, 0); + + bool isOkay = true; + + for (int i = 0; i != hash.Length; i++) + { + block[off + i] ^= hash[i]; + if (block[off + i] != 0) + { + isOkay = false; + } + } + + if (!isOkay) + { + return ReturnFalse(block); + } + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + else + { + fullMessage = false; + + digest.DoFinal(hash, 0); + + bool isOkay = true; + + for (int i = 0; i != hash.Length; i++) + { + block[off + i] ^= hash[i]; + if (block[off + i] != 0) + { + isOkay = false; + } + } + + if (!isOkay) + { + return ReturnFalse(block); + } + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + + // + // if they've input a message check what we've recovered against + // what was input. + // + if (messageLength != 0) + { + if (!IsSameAs(mBuf, recoveredMessage)) + { + return ReturnFalse(block); + } + } + + ClearBlock(mBuf); + ClearBlock(block); + + return true; + } + + private bool ReturnFalse(byte[] block) + { + ClearBlock(mBuf); + ClearBlock(block); + + return false; + } + + /// + /// Return true if the full message was recoveredMessage. + /// + /// true on full message recovery, false otherwise. + /// + public virtual bool HasFullMessage() + { + return fullMessage; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs.meta new file mode 100644 index 0000000..362439a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/Iso9796d2Signer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 87ac94cff478bb34ba55e541d2971b29 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs new file mode 100644 index 0000000..cb3940c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs @@ -0,0 +1,60 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class IsoTrailers + { + public const int TRAILER_IMPLICIT = 0xBC; + public const int TRAILER_RIPEMD160 = 0x31CC; + public const int TRAILER_RIPEMD128 = 0x32CC; + public const int TRAILER_SHA1 = 0x33CC; + public const int TRAILER_SHA256 = 0x34CC; + public const int TRAILER_SHA512 = 0x35CC; + public const int TRAILER_SHA384 = 0x36CC; + public const int TRAILER_WHIRLPOOL = 0x37CC; + public const int TRAILER_SHA224 = 0x38CC; + public const int TRAILER_SHA512_224 = 0x39CC; + public const int TRAILER_SHA512_256 = 0x40CC; + + private static IDictionary CreateTrailerMap() + { + IDictionary trailers = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + trailers.Add("RIPEMD128", TRAILER_RIPEMD128); + trailers.Add("RIPEMD160", TRAILER_RIPEMD160); + + trailers.Add("SHA-1", TRAILER_SHA1); + trailers.Add("SHA-224", TRAILER_SHA224); + trailers.Add("SHA-256", TRAILER_SHA256); + trailers.Add("SHA-384", TRAILER_SHA384); + trailers.Add("SHA-512", TRAILER_SHA512); + trailers.Add("SHA-512/224", TRAILER_SHA512_224); + trailers.Add("SHA-512/256", TRAILER_SHA512_256); + + trailers.Add("Whirlpool", TRAILER_WHIRLPOOL); + + return CollectionUtilities.ReadOnly(trailers); + } + + // IDictionary is (string -> Int32) + private static readonly IDictionary trailerMap = CreateTrailerMap(); + + public static int GetTrailer(IDigest digest) + { + return (int)trailerMap[digest.AlgorithmName]; + } + + public static bool NoTrailerAvailable(IDigest digest) + { + return !trailerMap.Contains(digest.AlgorithmName); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs.meta new file mode 100644 index 0000000..210bd4b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/IsoTrailers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a5fd009acb42ef44a8b900072b16221b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs new file mode 100644 index 0000000..2d90db4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs @@ -0,0 +1,390 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// RSA-PSS as described in Pkcs# 1 v 2.1. + ///

+ /// Note: the usual value for the salt length is the number of + /// bytes in the hash function.

+ ///
+ public class PssSigner + : ISigner + { + public const byte TrailerImplicit = (byte)0xBC; + + private readonly IDigest contentDigest1, contentDigest2; + private readonly IDigest mgfDigest; + private readonly IAsymmetricBlockCipher cipher; + + private SecureRandom random; + + private int hLen; + private int mgfhLen; + private int sLen; + private bool sSet; + private int emBits; + private byte[] salt; + private byte[] mDash; + private byte[] block; + private byte trailer; + + public static PssSigner CreateRawSigner( + IAsymmetricBlockCipher cipher, + IDigest digest) + { + return new PssSigner(cipher, new NullDigest(), digest, digest, digest.GetDigestSize(), null, TrailerImplicit); + } + + public static PssSigner CreateRawSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + int saltLen, + byte trailer) + { + return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, saltLen, null, trailer); + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest) + : this(cipher, digest, digest.GetDigestSize()) + { + } + + /// Basic constructor + /// the asymmetric cipher to use. + /// the digest to use. + /// the length of the salt to use (in bytes). + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + int saltLen) + : this(cipher, digest, saltLen, TrailerImplicit) + { + } + + /// Basic constructor + /// the asymmetric cipher to use. + /// the digest to use. + /// the fixed salt to be used. + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + byte[] salt) + : this(cipher, digest, digest, digest, salt.Length, salt, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + int saltLen) + : this(cipher, contentDigest, mgfDigest, saltLen, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + byte[] salt) + : this(cipher, contentDigest, contentDigest, mgfDigest, salt.Length, salt, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + int saltLen, + byte trailer) + : this(cipher, digest, digest, saltLen, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + int saltLen, + byte trailer) + : this(cipher, contentDigest, contentDigest, mgfDigest, saltLen, null, trailer) + { + } + + private PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest1, + IDigest contentDigest2, + IDigest mgfDigest, + int saltLen, + byte[] salt, + byte trailer) + { + this.cipher = cipher; + this.contentDigest1 = contentDigest1; + this.contentDigest2 = contentDigest2; + this.mgfDigest = mgfDigest; + this.hLen = contentDigest2.GetDigestSize(); + this.mgfhLen = mgfDigest.GetDigestSize(); + this.sLen = saltLen; + this.sSet = salt != null; + if (sSet) + { + this.salt = salt; + } + else + { + this.salt = new byte[saltLen]; + } + this.mDash = new byte[8 + saltLen + hLen]; + this.trailer = trailer; + } + + public virtual string AlgorithmName + { + get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) parameters; + + parameters = p.Parameters; + random = p.Random; + } + else + { + if (forSigning) + { + random = new SecureRandom(); + } + } + + cipher.Init(forSigning, parameters); + + RsaKeyParameters kParam; + if (parameters is RsaBlindingParameters) + { + kParam = ((RsaBlindingParameters) parameters).PublicKey; + } + else + { + kParam = (RsaKeyParameters) parameters; + } + + emBits = kParam.Modulus.BitLength - 1; + + if (emBits < (8 * hLen + 8 * sLen + 9)) + throw new ArgumentException("key too small for specified hash and salt lengths"); + + block = new byte[(emBits + 7) / 8]; + } + + /// clear possible sensitive data + private void ClearBlock( + byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + /// update the internal digest with the byte b + public virtual void Update( + byte input) + { + contentDigest1.Update(input); + } + + /// update the internal digest with the byte array in + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + contentDigest1.BlockUpdate(input, inOff, length); + } + + /// reset the internal state + public virtual void Reset() + { + contentDigest1.Reset(); + } + + /// Generate a signature for the message we've been loaded with using + /// the key we were initialised with. + /// + public virtual byte[] GenerateSignature() + { + contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); + + if (sLen != 0) + { + if (!sSet) + { + random.NextBytes(salt); + } + salt.CopyTo(mDash, mDash.Length - sLen); + } + + byte[] h = new byte[hLen]; + + contentDigest2.BlockUpdate(mDash, 0, mDash.Length); + + contentDigest2.DoFinal(h, 0); + + block[block.Length - sLen - 1 - hLen - 1] = (byte) (0x01); + salt.CopyTo(block, block.Length - sLen - hLen - 1); + + byte[] dbMask = MaskGeneratorFunction1(h, 0, h.Length, block.Length - hLen - 1); + for (int i = 0; i != dbMask.Length; i++) + { + block[i] ^= dbMask[i]; + } + + block[0] &= (byte) ((0xff >> ((block.Length * 8) - emBits))); + + h.CopyTo(block, block.Length - hLen - 1); + + block[block.Length - 1] = trailer; + + byte[] b = cipher.ProcessBlock(block, 0, block.Length); + + ClearBlock(block); + + return b; + } + + /// return true if the internal state represents the signature described + /// in the passed in array. + /// + public virtual bool VerifySignature( + byte[] signature) + { + contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); + + byte[] b = cipher.ProcessBlock(signature, 0, signature.Length); + b.CopyTo(block, block.Length - b.Length); + + if (block[block.Length - 1] != trailer) + { + ClearBlock(block); + return false; + } + + byte[] dbMask = MaskGeneratorFunction1(block, block.Length - hLen - 1, hLen, block.Length - hLen - 1); + + for (int i = 0; i != dbMask.Length; i++) + { + block[i] ^= dbMask[i]; + } + + block[0] &= (byte) ((0xff >> ((block.Length * 8) - emBits))); + + for (int i = 0; i != block.Length - hLen - sLen - 2; i++) + { + if (block[i] != 0) + { + ClearBlock(block); + return false; + } + } + + if (block[block.Length - hLen - sLen - 2] != 0x01) + { + ClearBlock(block); + return false; + } + + if (sSet) + { + Array.Copy(salt, 0, mDash, mDash.Length - sLen, sLen); + } + else + { + Array.Copy(block, block.Length - sLen - hLen - 1, mDash, mDash.Length - sLen, sLen); + } + + contentDigest2.BlockUpdate(mDash, 0, mDash.Length); + contentDigest2.DoFinal(mDash, mDash.Length - hLen); + + for (int i = block.Length - hLen - 1, j = mDash.Length - hLen; j != mDash.Length; i++, j++) + { + if ((block[i] ^ mDash[j]) != 0) + { + ClearBlock(mDash); + ClearBlock(block); + return false; + } + } + + ClearBlock(mDash); + ClearBlock(block); + + return true; + } + + /// int to octet string. + private void ItoOSP( + int i, + byte[] sp) + { + sp[0] = (byte)((uint) i >> 24); + sp[1] = (byte)((uint) i >> 16); + sp[2] = (byte)((uint) i >> 8); + sp[3] = (byte)((uint) i >> 0); + } + + /// mask generator function, as described in Pkcs1v2. + private byte[] MaskGeneratorFunction1( + byte[] Z, + int zOff, + int zLen, + int length) + { + byte[] mask = new byte[length]; + byte[] hashBuf = new byte[mgfhLen]; + byte[] C = new byte[4]; + int counter = 0; + + mgfDigest.Reset(); + + while (counter < (length / mgfhLen)) + { + ItoOSP(counter, C); + + mgfDigest.BlockUpdate(Z, zOff, zLen); + mgfDigest.BlockUpdate(C, 0, C.Length); + mgfDigest.DoFinal(hashBuf, 0); + + hashBuf.CopyTo(mask, counter * mgfhLen); + ++counter; + } + + if ((counter * mgfhLen) < length) + { + ItoOSP(counter, C); + + mgfDigest.BlockUpdate(Z, zOff, zLen); + mgfDigest.BlockUpdate(C, 0, C.Length); + mgfDigest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * mgfhLen, mask.Length - (counter * mgfhLen)); + } + + return mask; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs.meta new file mode 100644 index 0000000..2831c5b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/PssSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 29735d3087c8c97469fcd65a9be64767 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs new file mode 100644 index 0000000..65b7513 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class RandomDsaKCalculator + : IDsaKCalculator + { + private BigInteger q; + private SecureRandom random; + + public virtual bool IsDeterministic + { + get { return false; } + } + + public virtual void Init(BigInteger n, SecureRandom random) + { + this.q = n; + this.random = random; + } + + public virtual void Init(BigInteger n, BigInteger d, byte[] message) + { + throw new InvalidOperationException("Operation not supported"); + } + + public virtual BigInteger NextK() + { + int qBitLength = q.BitLength; + + BigInteger k; + do + { + k = new BigInteger(qBitLength, random); + } + while (k.SignValue < 1 || k.CompareTo(q) >= 0); + + return k; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs.meta new file mode 100644 index 0000000..b742f6c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RandomDsaKCalculator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c1bb646c95a66c04787462b6a62bd3cc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs new file mode 100644 index 0000000..8af32d1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs @@ -0,0 +1,221 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class RsaDigestSigner + : ISigner + { + private readonly IAsymmetricBlockCipher rsaEngine = new Pkcs1Encoding(new RsaBlindedEngine()); + private readonly AlgorithmIdentifier algId; + private readonly IDigest digest; + private bool forSigning; + + private static readonly IDictionary oidMap = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + /// + /// Load oid table. + /// + static RsaDigestSigner() + { + oidMap["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128; + oidMap["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160; + oidMap["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256; + + oidMap["SHA-1"] = X509ObjectIdentifiers.IdSha1; + oidMap["SHA-224"] = NistObjectIdentifiers.IdSha224; + oidMap["SHA-256"] = NistObjectIdentifiers.IdSha256; + oidMap["SHA-384"] = NistObjectIdentifiers.IdSha384; + oidMap["SHA-512"] = NistObjectIdentifiers.IdSha512; + + oidMap["MD2"] = PkcsObjectIdentifiers.MD2; + oidMap["MD4"] = PkcsObjectIdentifiers.MD4; + oidMap["MD5"] = PkcsObjectIdentifiers.MD5; + } + + public RsaDigestSigner(IDigest digest) + : this(digest, (DerObjectIdentifier)oidMap[digest.AlgorithmName]) + { + } + + public RsaDigestSigner(IDigest digest, DerObjectIdentifier digestOid) + : this(digest, new AlgorithmIdentifier(digestOid, DerNull.Instance)) + { + } + + public RsaDigestSigner(IDigest digest, AlgorithmIdentifier algId) + { + this.digest = digest; + this.algId = algId; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "withRSA"; } + } + + /** + * Initialise the signer for signing or verification. + * + * @param forSigning true if for signing, false otherwise + * @param param necessary parameters. + */ + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + AsymmetricKeyParameter k; + + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + throw new InvalidKeyException("Signing requires private key."); + + if (!forSigning && k.IsPrivate) + throw new InvalidKeyException("Verification requires public key."); + + Reset(); + + rsaEngine.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update( + byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + byte[] data = DerEncode(hash); + return rsaEngine.ProcessBlock(data, 0, data.Length); + } + + /** + * return true if the internal state represents the signature described + * in the passed in array. + */ + public virtual bool VerifySignature( + byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("RsaDigestSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + byte[] sig; + byte[] expected; + + try + { + sig = rsaEngine.ProcessBlock(signature, 0, signature.Length); + expected = DerEncode(hash); + } + catch (Exception) + { + return false; + } + + if (sig.Length == expected.Length) + { + return Arrays.ConstantTimeAreEqual(sig, expected); + } + else if (sig.Length == expected.Length - 2) // NULL left out + { + int sigOffset = sig.Length - hash.Length - 2; + int expectedOffset = expected.Length - hash.Length - 2; + + expected[1] -= 2; // adjust lengths + expected[3] -= 2; + + int nonEqual = 0; + + for (int i = 0; i < hash.Length; i++) + { + nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]); + } + + for (int i = 0; i < sigOffset; i++) + { + nonEqual |= (sig[i] ^ expected[i]); // check header less NULL + } + + return nonEqual == 0; + } + else + { + return false; + } + } + + public virtual void Reset() + { + digest.Reset(); + } + + private byte[] DerEncode(byte[] hash) + { + if (algId == null) + { + // For raw RSA, the DigestInfo must be prepared externally + return hash; + } + + DigestInfo dInfo = new DigestInfo(algId, hash); + + return dInfo.GetDerEncoded(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs.meta new file mode 100644 index 0000000..994edea --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/RsaDigestSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0a1d2191580cc304e9dd7fb6a78629ad +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs new file mode 100644 index 0000000..fcb955b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs @@ -0,0 +1,229 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * X9.31-1998 - signing using a hash. + *

+ * The message digest hash, H, is encapsulated to form a byte string as follows + *

+ *
+     * EB = 06 || PS || 0xBA || H || TRAILER
+     * 
+ * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number† for the digest. The byte string, EB, is converted to an integer value, the message representative, f. + */ + public class X931Signer + : ISigner + { + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_IMPLICIT = 0xBC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_RIPEMD160 = 0x31CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_RIPEMD128 = 0x32CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA1 = 0x33CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA256 = 0x34CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA512 = 0x35CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA384 = 0x36CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_WHIRLPOOL = 0x37CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA224 = 0x38CC; + + private IDigest digest; + private IAsymmetricBlockCipher cipher; + private RsaKeyParameters kParam; + + private int trailer; + private int keyBits; + private byte[] block; + + /** + * Generate a signer with either implicit or explicit trailers for X9.31. + * + * @param cipher base cipher to use for signature creation/verification + * @param digest digest to use. + * @param implicit whether or not the trailer is implicit or gives the hash. + */ + public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit) + { + this.cipher = cipher; + this.digest = digest; + + if (isImplicit) + { + trailer = IsoTrailers.TRAILER_IMPLICIT; + } + else if (IsoTrailers.NoTrailerAvailable(digest)) + { + throw new ArgumentException("no valid trailer", "digest"); + } + else + { + trailer = IsoTrailers.GetTrailer(digest); + } + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; } + } + + /** + * Constructor for a signer with an explicit digest trailer. + * + * @param cipher cipher to use. + * @param digest digest to sign with. + */ + public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest) + : this(cipher, digest, false) + { + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + kParam = (RsaKeyParameters)parameters; + + cipher.Init(forSigning, kParam); + + keyBits = kParam.Modulus.BitLength; + + block = new byte[(keyBits + 7) / 8]; + + Reset(); + } + + /// clear possible sensitive data + private void ClearBlock(byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update(byte b) + { + digest.Update(b); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate(byte[] input, int off, int len) + { + digest.BlockUpdate(input, off, len); + } + + /** + * reset the internal state + */ + public virtual void Reset() + { + digest.Reset(); + } + + /** + * generate a signature for the loaded message using the key we were + * initialised with. + */ + public virtual byte[] GenerateSignature() + { + CreateSignatureBlock(); + + BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length)); + ClearBlock(block); + + t = t.Min(kParam.Modulus.Subtract(t)); + + return BigIntegers.AsUnsignedByteArray((kParam.Modulus.BitLength + 7) / 8, t); + } + + private void CreateSignatureBlock() + { + int digSize = digest.GetDigestSize(); + + int delta; + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + delta = block.Length - digSize - 1; + digest.DoFinal(block, delta); + block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT; + } + else + { + delta = block.Length - digSize - 2; + digest.DoFinal(block, delta); + block[block.Length - 2] = (byte)(trailer >> 8); + block[block.Length - 1] = (byte)trailer; + } + + block[0] = 0x6b; + for (int i = delta - 2; i != 0; i--) + { + block[i] = (byte)0xbb; + } + block[delta - 1] = (byte)0xba; + } + + /** + * return true if the signature represents a ISO9796-2 signature + * for the passed in message. + */ + public virtual bool VerifySignature(byte[] signature) + { + try + { + block = cipher.ProcessBlock(signature, 0, signature.Length); + } + catch (Exception) + { + return false; + } + + BigInteger t = new BigInteger(1, block); + BigInteger f; + + if ((t.IntValue & 15) == 12) + { + f = t; + } + else + { + t = kParam.Modulus.Subtract(t); + if ((t.IntValue & 15) == 12) + { + f = t; + } + else + { + return false; + } + } + + CreateSignatureBlock(); + + byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f); + + bool rv = Arrays.ConstantTimeAreEqual(block, fBlock); + + ClearBlock(block); + ClearBlock(fBlock); + + return rv; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs.meta new file mode 100644 index 0000000..68b5a0d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/signers/X931Signer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a4d003e3a33c78049a002e2b2f4da98d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls.meta new file mode 100644 index 0000000..1e74706 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 377c62a7a08191a46babb9e0f98c238c +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs new file mode 100644 index 0000000..08dbd18 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsAgreementCredentials + : AbstractTlsCredentials, TlsAgreementCredentials + { + /// + public abstract byte[] GenerateAgreement(AsymmetricKeyParameter peerPublicKey); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs.meta new file mode 100644 index 0000000..8b59222 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsAgreementCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 883690e221f19a6418e8bc624f2e9a08 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs new file mode 100644 index 0000000..76b6adc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs @@ -0,0 +1,19 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class AbstractTlsCipherFactory + : TlsCipherFactory + { + /// + public virtual TlsCipher CreateCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs.meta new file mode 100644 index 0000000..3ecfb6f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCipherFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f22405f313bf66a449f14a07c843bc2f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs new file mode 100644 index 0000000..aeba82b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs @@ -0,0 +1,272 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsClient + : AbstractTlsPeer, TlsClient + { + protected TlsCipherFactory mCipherFactory; + + protected TlsClientContext mContext; + + protected IList mSupportedSignatureAlgorithms; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected int mSelectedCipherSuite; + protected short mSelectedCompressionMethod; + + public System.Collections.Generic.List HostNames { get; set; } + + public AbstractTlsClient() + : this(new DefaultTlsCipherFactory()) + { + } + + public AbstractTlsClient(TlsCipherFactory cipherFactory) + { + this.mCipherFactory = cipherFactory; + } + + protected virtual bool AllowUnexpectedServerExtension(int extensionType, byte[] extensionData) + { + switch (extensionType) + { + case ExtensionType.elliptic_curves: + /* + * Exception added based on field reports that some servers do send this, although the + * Supported Elliptic Curves Extension is clearly intended to be client-only. If + * present, we still require that it is a valid EllipticCurveList. + */ + TlsEccUtilities.ReadSupportedEllipticCurvesExtension(extensionData); + return true; + default: + return false; + } + } + + protected virtual void CheckForUnexpectedServerExtension(IDictionary serverExtensions, int extensionType) + { + byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType); + if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + public virtual void Init(TlsClientContext context) + { + this.mContext = context; + } + + public virtual TlsSession GetSessionToResume() + { + return null; + } + + public virtual ProtocolVersion ClientHelloRecordLayerVersion + { + get + { + // "{03,00}" + //return ProtocolVersion.SSLv3; + + // "the lowest version number supported by the client" + //return MinimumVersion; + + // "the value of ClientHello.client_version" + return ClientVersion; + } + } + + public virtual ProtocolVersion ClientVersion + { + get { return ProtocolVersion.TLSv12; } + } + + public virtual bool IsFallback + { + /* + * RFC 7507 4. The TLS_FALLBACK_SCSV cipher suite value is meant for use by clients that + * repeat a connection attempt with a downgraded protocol (perform a "fallback retry") in + * order to work around interoperability problems with legacy servers. + */ + get { return false; } + } + + public virtual IDictionary GetClientExtensions() + { + IDictionary clientExtensions = null; + + ProtocolVersion clientVersion = mContext.ClientVersion; + + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior to 1.2. + * Clients MUST NOT offer it if they are offering prior versions. + */ + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion)) + { + // TODO Provide a way for the user to specify the acceptable hash/signature algorithms. + + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); + + clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(clientExtensions); + + TlsUtilities.AddSignatureAlgorithmsExtension(clientExtensions, mSupportedSignatureAlgorithms); + } + + if (TlsEccUtilities.ContainsEccCipherSuites(GetCipherSuites())) + { + /* + * RFC 4492 5.1. A client that proposes ECC cipher suites in its ClientHello message + * appends these extensions (along with any others), enumerating the curves it supports + * and the point formats it can parse. Clients SHOULD send both the Supported Elliptic + * Curves Extension and the Supported Point Formats Extension. + */ + /* + * TODO Could just add all the curves since we support them all, but users may not want + * to use unnecessarily large fields. Need configuration options. + */ + this.mNamedCurves = new int[]{ NamedCurve.secp256r1, NamedCurve.secp384r1 }; + this.mClientECPointFormats = new byte[]{ ECPointFormat.uncompressed, + ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, }; + + clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(clientExtensions); + + TlsEccUtilities.AddSupportedEllipticCurvesExtension(clientExtensions, mNamedCurves); + TlsEccUtilities.AddSupportedPointFormatsExtension(clientExtensions, mClientECPointFormats); + } + + if (this.HostNames != null && this.HostNames.Count > 0) + { + var list = new System.Collections.Generic.List(this.HostNames.Count); + + for (int i = 0; i < this.HostNames.Count; ++i) + list.Add(new ServerName(Tls.NameType.host_name, this.HostNames[i])); + + TlsExtensionsUtilities.AddServerNameExtension(clientExtensions, new ServerNameList(list)); + } + + return clientExtensions; + } + + public virtual ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv10; } + } + + public virtual void NotifyServerVersion(ProtocolVersion serverVersion) + { + if (!MinimumVersion.IsEqualOrEarlierVersionOf(serverVersion)) + throw new TlsFatalAlert(AlertDescription.protocol_version); + } + + public abstract int[] GetCipherSuites(); + + public virtual byte[] GetCompressionMethods() + { + return new byte[]{ CompressionMethod.cls_null }; + } + + public virtual void NotifySessionID(byte[] sessionID) + { + // Currently ignored + } + + public virtual void NotifySelectedCipherSuite(int selectedCipherSuite) + { + this.mSelectedCipherSuite = selectedCipherSuite; + } + + public virtual void NotifySelectedCompressionMethod(byte selectedCompressionMethod) + { + this.mSelectedCompressionMethod = selectedCompressionMethod; + } + + public virtual void ProcessServerExtensions(IDictionary serverExtensions) + { + /* + * TlsProtocol implementation validates that any server extensions received correspond to + * client extensions sent. By default, we don't send any, and this method is not called. + */ + if (serverExtensions != null) + { + /* + * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms); + + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.elliptic_curves); + + if (TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite)) + { + this.mServerECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(serverExtensions); + } + else + { + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats); + } + + /* + * RFC 7685 3. The server MUST NOT echo the extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.padding); + } + } + + public virtual void ProcessServerSupplementalData(IList serverSupplementalData) + { + if (serverSupplementalData != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public abstract TlsKeyExchange GetKeyExchange(); + + public abstract TlsAuthentication GetAuthentication(); + + public virtual IList GetClientSupplementalData() + { + return null; + } + + public override TlsCompression GetCompression() + { + switch (mSelectedCompressionMethod) + { + case CompressionMethod.cls_null: + return new TlsNullCompression(); + + case CompressionMethod.DEFLATE: + return new TlsDeflateCompression(); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected compression method was in the list of client-offered compression + * methods, so if we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsCipher GetCipher() + { + int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite); + int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite); + + return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm); + } + + public virtual void NotifyNewSessionTicket(NewSessionTicket newSessionTicket) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs.meta new file mode 100644 index 0000000..a465b05 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsClient.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c301d56f352233b47bd13d7a3142a95a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs new file mode 100644 index 0000000..af9fd58 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs @@ -0,0 +1,156 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Threading; + +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal abstract class AbstractTlsContext + : TlsContext + { + private static long counter = Times.NanoTime(); + +#if NETCF_1_0 + private static object counterLock = new object(); + private static long NextCounterValue() + { + lock (counterLock) + { + return ++counter; + } + } +#else + private static long NextCounterValue() + { + return Interlocked.Increment(ref counter); + } +#endif + + private readonly IRandomGenerator mNonceRandom; + private readonly SecureRandom mSecureRandom; + private readonly SecurityParameters mSecurityParameters; + + private ProtocolVersion mClientVersion = null; + private ProtocolVersion mServerVersion = null; + private TlsSession mSession = null; + private object mUserObject = null; + + internal AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) + { + IDigest d = TlsUtilities.CreateHash(HashAlgorithm.sha256); + byte[] seed = new byte[d.GetDigestSize()]; + secureRandom.NextBytes(seed); + + this.mNonceRandom = new DigestRandomGenerator(d); + mNonceRandom.AddSeedMaterial(NextCounterValue()); + mNonceRandom.AddSeedMaterial(Times.NanoTime()); + mNonceRandom.AddSeedMaterial(seed); + + this.mSecureRandom = secureRandom; + this.mSecurityParameters = securityParameters; + } + + public virtual IRandomGenerator NonceRandomGenerator + { + get { return mNonceRandom; } + } + + public virtual SecureRandom SecureRandom + { + get { return mSecureRandom; } + } + + public virtual SecurityParameters SecurityParameters + { + get { return mSecurityParameters; } + } + + public abstract bool IsServer { get; } + + public virtual ProtocolVersion ClientVersion + { + get { return mClientVersion; } + } + + internal virtual void SetClientVersion(ProtocolVersion clientVersion) + { + this.mClientVersion = clientVersion; + } + + public virtual ProtocolVersion ServerVersion + { + get { return mServerVersion; } + } + + internal virtual void SetServerVersion(ProtocolVersion serverVersion) + { + this.mServerVersion = serverVersion; + } + + public virtual TlsSession ResumableSession + { + get { return mSession; } + } + + internal virtual void SetResumableSession(TlsSession session) + { + this.mSession = session; + } + + public virtual object UserObject + { + get { return mUserObject; } + set { this.mUserObject = value; } + } + + public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length) + { + /* + * TODO[session-hash] + * + * draft-ietf-tls-session-hash-04 5.4. If a client or server chooses to continue with a full + * handshake without the extended master secret extension, [..] the client or server MUST + * NOT export any key material based on the new master secret for any subsequent + * application-level authentication. In particular, it MUST disable [RFC5705] [..]. + */ + + if (context_value != null && !TlsUtilities.IsValidUint16(context_value.Length)) + throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value"); + + SecurityParameters sp = SecurityParameters; + byte[] cr = sp.ClientRandom, sr = sp.ServerRandom; + + int seedLength = cr.Length + sr.Length; + if (context_value != null) + { + seedLength += (2 + context_value.Length); + } + + byte[] seed = new byte[seedLength]; + int seedPos = 0; + + Array.Copy(cr, 0, seed, seedPos, cr.Length); + seedPos += cr.Length; + Array.Copy(sr, 0, seed, seedPos, sr.Length); + seedPos += sr.Length; + if (context_value != null) + { + TlsUtilities.WriteUint16(context_value.Length, seed, seedPos); + seedPos += 2; + Array.Copy(context_value, 0, seed, seedPos, context_value.Length); + seedPos += context_value.Length; + } + + if (seedPos != seedLength) + throw new InvalidOperationException("error in calculation of seed for export"); + + return TlsUtilities.PRF(this, sp.MasterSecret, asciiLabel, seed, length); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs.meta new file mode 100644 index 0000000..84e4e6c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsContext.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ae1694ad34c5af748804e7e441781e6e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs new file mode 100644 index 0000000..831605e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs @@ -0,0 +1,14 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsCredentials + : TlsCredentials + { + public abstract Certificate Certificate { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs.meta new file mode 100644 index 0000000..46bc923 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 45b44747a83f28d4a8d737abb08516fb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs new file mode 100644 index 0000000..3e1d4e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsEncryptionCredentials + : AbstractTlsCredentials, TlsEncryptionCredentials + { + /// + public abstract byte[] DecryptPreMasterSecret(byte[] encryptedPreMasterSecret); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta new file mode 100644 index 0000000..c1838e3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 55bf10e0f1cbfca47b598d52fb8cdd7a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs new file mode 100644 index 0000000..db62165 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs @@ -0,0 +1,181 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsKeyExchange + : TlsKeyExchange + { + protected readonly int mKeyExchange; + protected IList mSupportedSignatureAlgorithms; + + protected TlsContext mContext; + + protected AbstractTlsKeyExchange(int keyExchange, IList supportedSignatureAlgorithms) + { + this.mKeyExchange = keyExchange; + this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms; + } + + protected virtual DigitallySigned ParseSignature(Stream input) + { + DigitallySigned signature = DigitallySigned.Parse(mContext, input); + SignatureAndHashAlgorithm signatureAlgorithm = signature.Algorithm; + if (signatureAlgorithm != null) + { + TlsUtilities.VerifySupportedSignatureAlgorithm(mSupportedSignatureAlgorithms, signatureAlgorithm); + } + return signature; + } + + public virtual void Init(TlsContext context) + { + this.mContext = context; + + ProtocolVersion clientVersion = context.ClientVersion; + + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion)) + { + /* + * RFC 5264 7.4.1.4.1. If the client does not send the signature_algorithms extension, + * the server MUST do the following: + * + * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK, + * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}. + * + * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if + * the client had sent the value {sha1,dsa}. + * + * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA), + * behave as if the client had sent value {sha1,ecdsa}. + */ + if (this.mSupportedSignatureAlgorithms == null) + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.SRP_DSS: + { + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultDssSignatureAlgorithms(); + break; + } + + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + { + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); + break; + } + + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.RSA: + case KeyExchangeAlgorithm.RSA_PSK: + case KeyExchangeAlgorithm.SRP_RSA: + { + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultRsaSignatureAlgorithms(); + break; + } + + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.SRP: + break; + + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + } + + } + else if (this.mSupportedSignatureAlgorithms != null) + { + throw new InvalidOperationException("supported_signature_algorithms not allowed for " + clientVersion); + } + } + + public abstract void SkipServerCredentials(); + + public virtual void ProcessServerCertificate(Certificate serverCertificate) + { + if (mSupportedSignatureAlgorithms == null) + { + /* + * TODO RFC 2264 7.4.2. Unless otherwise specified, the signing algorithm for the + * certificate must be the same as the algorithm for the certificate key. + */ + } + else + { + /* + * TODO RFC 5264 7.4.2. If the client provided a "signature_algorithms" extension, then + * all certificates provided by the server MUST be signed by a hash/signature algorithm + * pair that appears in that extension. + */ + } + } + + public virtual void ProcessServerCredentials(TlsCredentials serverCredentials) + { + ProcessServerCertificate(serverCredentials.Certificate); + } + + public virtual bool RequiresServerKeyExchange + { + get { return false; } + } + + public virtual byte[] GenerateServerKeyExchange() + { + if (RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return null; + } + + public virtual void SkipServerKeyExchange() + { + if (RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual void ProcessServerKeyExchange(Stream input) + { + if (!RequiresServerKeyExchange) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + public abstract void ValidateCertificateRequest(CertificateRequest certificateRequest); + + public virtual void SkipClientCredentials() + { + } + + public abstract void ProcessClientCredentials(TlsCredentials clientCredentials); + + public virtual void ProcessClientCertificate(Certificate clientCertificate) + { + } + + public abstract void GenerateClientKeyExchange(Stream output); + + public virtual void ProcessClientKeyExchange(Stream input) + { + // Key exchange implementation MUST support client key exchange + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public abstract byte[] GeneratePremasterSecret(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs.meta new file mode 100644 index 0000000..8bb7fe6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e3f8816144989924494adb4d63ab573e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs new file mode 100644 index 0000000..992d5bb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs @@ -0,0 +1,52 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsPeer + : TlsPeer + { + public virtual bool ShouldUseGmtUnixTime() + { + /* + * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that + * TLS implementors MUST by default set the entire value the ClientHello.Random and + * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random + * sequence. + */ + return false; + } + + public virtual void NotifySecureRenegotiation(bool secureRenegotiation) + { + if (!secureRenegotiation) + { + /* + * RFC 5746 3.4/3.6. In this case, some clients/servers may want to terminate the handshake instead + * of continuing; see Section 4.1/4.3 for discussion. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + public abstract TlsCompression GetCompression(); + + public abstract TlsCipher GetCipher(); + + public virtual void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + } + + public virtual void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + } + + public virtual void NotifyHandshakeComplete() + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs.meta new file mode 100644 index 0000000..8260427 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsPeer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 630d4642ce55ac74fb84bdf9d0244397 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs new file mode 100644 index 0000000..5ddf795 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs @@ -0,0 +1,353 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsServer + : AbstractTlsPeer, TlsServer + { + protected TlsCipherFactory mCipherFactory; + + protected TlsServerContext mContext; + + protected ProtocolVersion mClientVersion; + protected int[] mOfferedCipherSuites; + protected byte[] mOfferedCompressionMethods; + protected IDictionary mClientExtensions; + + protected bool mEncryptThenMacOffered; + protected short mMaxFragmentLengthOffered; + protected bool mTruncatedHMacOffered; + protected IList mSupportedSignatureAlgorithms; + protected bool mEccCipherSuitesOffered; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected ProtocolVersion mServerVersion; + protected int mSelectedCipherSuite; + protected byte mSelectedCompressionMethod; + protected IDictionary mServerExtensions; + + public AbstractTlsServer() + : this(new DefaultTlsCipherFactory()) + { + } + + public AbstractTlsServer(TlsCipherFactory cipherFactory) + { + this.mCipherFactory = cipherFactory; + } + + protected virtual bool AllowEncryptThenMac + { + get { return true; } + } + + protected virtual bool AllowTruncatedHMac + { + get { return false; } + } + + protected virtual IDictionary CheckServerExtensions() + { + return this.mServerExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(this.mServerExtensions); + } + + protected abstract int[] GetCipherSuites(); + + protected byte[] GetCompressionMethods() + { + return new byte[] { CompressionMethod.cls_null }; + } + + protected virtual ProtocolVersion MaximumVersion + { + get { return ProtocolVersion.TLSv11; } + } + + protected virtual ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv10; } + } + + protected virtual bool SupportsClientEccCapabilities(int[] namedCurves, byte[] ecPointFormats) + { + // NOTE: BC supports all the current set of point formats so we don't check them here + + if (namedCurves == null) + { + /* + * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these + * extensions. In this case, the server is free to choose any one of the elliptic curves + * or point formats [...]. + */ + return TlsEccUtilities.HasAnySupportedNamedCurves(); + } + + for (int i = 0; i < namedCurves.Length; ++i) + { + int namedCurve = namedCurves[i]; + if (NamedCurve.IsValid(namedCurve) + && (!NamedCurve.RefersToASpecificNamedCurve(namedCurve) || TlsEccUtilities.IsSupportedNamedCurve(namedCurve))) + { + return true; + } + } + + return false; + } + + public virtual void Init(TlsServerContext context) + { + this.mContext = context; + } + + public virtual void NotifyClientVersion(ProtocolVersion clientVersion) + { + this.mClientVersion = clientVersion; + } + + public virtual void NotifyFallback(bool isFallback) + { + /* + * RFC 7507 3. If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest + * protocol version supported by the server is higher than the version indicated in + * ClientHello.client_version, the server MUST respond with a fatal inappropriate_fallback + * alert [..]. + */ + if (isFallback && MaximumVersion.IsLaterVersionOf(mClientVersion)) + throw new TlsFatalAlert(AlertDescription.inappropriate_fallback); + } + + public virtual void NotifyOfferedCipherSuites(int[] offeredCipherSuites) + { + this.mOfferedCipherSuites = offeredCipherSuites; + this.mEccCipherSuitesOffered = TlsEccUtilities.ContainsEccCipherSuites(this.mOfferedCipherSuites); + } + + public virtual void NotifyOfferedCompressionMethods(byte[] offeredCompressionMethods) + { + this.mOfferedCompressionMethods = offeredCompressionMethods; + } + + public virtual void ProcessClientExtensions(IDictionary clientExtensions) + { + this.mClientExtensions = clientExtensions; + + if (clientExtensions != null) + { + this.mEncryptThenMacOffered = TlsExtensionsUtilities.HasEncryptThenMacExtension(clientExtensions); + + this.mMaxFragmentLengthOffered = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions); + if (mMaxFragmentLengthOffered >= 0 && !MaxFragmentLength.IsValid((byte)mMaxFragmentLengthOffered)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mTruncatedHMacOffered = TlsExtensionsUtilities.HasTruncatedHMacExtension(clientExtensions); + + this.mSupportedSignatureAlgorithms = TlsUtilities.GetSignatureAlgorithmsExtension(clientExtensions); + if (this.mSupportedSignatureAlgorithms != null) + { + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior + * to 1.2. Clients MUST NOT offer it if they are offering prior versions. + */ + if (!TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mClientVersion)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + this.mNamedCurves = TlsEccUtilities.GetSupportedEllipticCurvesExtension(clientExtensions); + this.mClientECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(clientExtensions); + } + + /* + * RFC 4429 4. The client MUST NOT include these extensions in the ClientHello message if it + * does not propose any ECC cipher suites. + * + * NOTE: This was overly strict as there may be ECC cipher suites that we don't recognize. + * Also, draft-ietf-tls-negotiated-ff-dhe will be overloading the 'elliptic_curves' + * extension to explicitly allow FFDHE (i.e. non-ECC) groups. + */ + //if (!this.mEccCipherSuitesOffered && (this.mNamedCurves != null || this.mClientECPointFormats != null)) + // throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + public virtual ProtocolVersion GetServerVersion() + { + if (MinimumVersion.IsEqualOrEarlierVersionOf(mClientVersion)) + { + ProtocolVersion maximumVersion = MaximumVersion; + if (mClientVersion.IsEqualOrEarlierVersionOf(maximumVersion)) + { + return mServerVersion = mClientVersion; + } + if (mClientVersion.IsLaterVersionOf(maximumVersion)) + { + return mServerVersion = maximumVersion; + } + } + throw new TlsFatalAlert(AlertDescription.protocol_version); + } + + public virtual int GetSelectedCipherSuite() + { + /* + * TODO RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate + * cipher suites against the "signature_algorithms" extension before selecting them. This is + * somewhat inelegant but is a compromise designed to minimize changes to the original + * cipher suite design. + */ + + /* + * RFC 4429 5.1. A server that receives a ClientHello containing one or both of these + * extensions MUST use the client's enumerated capabilities to guide its selection of an + * appropriate cipher suite. One of the proposed ECC cipher suites must be negotiated only + * if the server can successfully complete the handshake while using the curves and point + * formats supported by the client [...]. + */ + bool eccCipherSuitesEnabled = SupportsClientEccCapabilities(this.mNamedCurves, this.mClientECPointFormats); + + int[] cipherSuites = GetCipherSuites(); + for (int i = 0; i < cipherSuites.Length; ++i) + { + int cipherSuite = cipherSuites[i]; + + if (Arrays.Contains(this.mOfferedCipherSuites, cipherSuite) + && (eccCipherSuitesEnabled || !TlsEccUtilities.IsEccCipherSuite(cipherSuite)) + && TlsUtilities.IsValidCipherSuiteForVersion(cipherSuite, mServerVersion)) + { + return this.mSelectedCipherSuite = cipherSuite; + } + } + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + public virtual byte GetSelectedCompressionMethod() + { + byte[] compressionMethods = GetCompressionMethods(); + for (int i = 0; i < compressionMethods.Length; ++i) + { + if (Arrays.Contains(mOfferedCompressionMethods, compressionMethods[i])) + { + return this.mSelectedCompressionMethod = compressionMethods[i]; + } + } + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + // IDictionary is (Int32 -> byte[]) + public virtual IDictionary GetServerExtensions() + { + if (this.mEncryptThenMacOffered && AllowEncryptThenMac) + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + if (TlsUtilities.IsBlockCipherSuite(this.mSelectedCipherSuite)) + { + TlsExtensionsUtilities.AddEncryptThenMacExtension(CheckServerExtensions()); + } + } + + if (this.mMaxFragmentLengthOffered >= 0 + && TlsUtilities.IsValidUint8(mMaxFragmentLengthOffered) + && MaxFragmentLength.IsValid((byte)mMaxFragmentLengthOffered)) + { + TlsExtensionsUtilities.AddMaxFragmentLengthExtension(CheckServerExtensions(), (byte)mMaxFragmentLengthOffered); + } + + if (this.mTruncatedHMacOffered && AllowTruncatedHMac) + { + TlsExtensionsUtilities.AddTruncatedHMacExtension(CheckServerExtensions()); + } + + if (this.mClientECPointFormats != null && TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite)) + { + /* + * RFC 4492 5.2. A server that selects an ECC cipher suite in response to a ClientHello + * message including a Supported Point Formats Extension appends this extension (along + * with others) to its ServerHello message, enumerating the point formats it can parse. + */ + this.mServerECPointFormats = new byte[]{ ECPointFormat.uncompressed, + ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, }; + + TlsEccUtilities.AddSupportedPointFormatsExtension(CheckServerExtensions(), mServerECPointFormats); + } + + return mServerExtensions; + } + + public virtual IList GetServerSupplementalData() + { + return null; + } + + public abstract TlsCredentials GetCredentials(); + + public virtual CertificateStatus GetCertificateStatus() + { + return null; + } + + public abstract TlsKeyExchange GetKeyExchange(); + + public virtual CertificateRequest GetCertificateRequest() + { + return null; + } + + public virtual void ProcessClientSupplementalData(IList clientSupplementalData) + { + if (clientSupplementalData != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual void NotifyClientCertificate(Certificate clientCertificate) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override TlsCompression GetCompression() + { + switch (mSelectedCompressionMethod) + { + case CompressionMethod.cls_null: + return new TlsNullCompression(); + + default: + /* + * Note: internal error here; we selected the compression method, so if we now can't + * produce an implementation, we shouldn't have chosen it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsCipher GetCipher() + { + int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite); + int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite); + + return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm); + } + + public virtual NewSessionTicket GetNewSessionTicket() + { + /* + * RFC 5077 3.3. If the server determines that it does not want to include a ticket after it + * has included the SessionTicket extension in the ServerHello, then it sends a zero-length + * ticket in the NewSessionTicket handshake message. + */ + return new NewSessionTicket(0L, TlsUtilities.EmptyBytes); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs.meta new file mode 100644 index 0000000..6579c75 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsServer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: faff47b25a0d7154f8ff18e0ab6843ed +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs new file mode 100644 index 0000000..d733710 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs @@ -0,0 +1,54 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsSigner + : TlsSigner + { + protected TlsContext mContext; + + public virtual void Init(TlsContext context) + { + this.mContext = context; + } + + public virtual byte[] GenerateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) + { + return GenerateRawSignature(null, privateKey, md5AndSha1); + } + + public abstract byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash); + + public virtual bool VerifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) + { + return VerifyRawSignature(null, sigBytes, publicKey, md5AndSha1); + } + + public abstract bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash); + + public virtual ISigner CreateSigner(AsymmetricKeyParameter privateKey) + { + return CreateSigner(null, privateKey); + } + + public abstract ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey); + + public virtual ISigner CreateVerifyer(AsymmetricKeyParameter publicKey) + { + return CreateVerifyer(null, publicKey); + } + + public abstract ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey); + + public abstract bool IsValidPublicKey(AsymmetricKeyParameter publicKey); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs.meta new file mode 100644 index 0000000..3eda33a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0d7986fd51deb2444927d8eb012464dd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs new file mode 100644 index 0000000..b4f8316 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsSignerCredentials + : AbstractTlsCredentials, TlsSignerCredentials + { + /// + public abstract byte[] GenerateCertificateSignature(byte[] hash); + + public virtual SignatureAndHashAlgorithm SignatureAndHashAlgorithm + { + get + { + throw new InvalidOperationException("TlsSignerCredentials implementation does not support (D)TLS 1.2+"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs.meta new file mode 100644 index 0000000..32f3b76 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AbstractTlsSignerCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c1498aa1db4f844e9473a971d4efbd2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs new file mode 100644 index 0000000..25b034f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs @@ -0,0 +1,308 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 5246 7.2 + /// + public abstract class AlertDescription + { + /** + * This message notifies the recipient that the sender will not send any more messages on this + * connection. Note that as of TLS 1.1, failure to properly close a connection no longer + * requires that a session not be resumed. This is a change from TLS 1.0 ("The session becomes + * unresumable if any connection is terminated without proper close_notify messages with level + * equal to warning.") to conform with widespread implementation practice. + */ + public const byte close_notify = 0; + + /** + * An inappropriate message was received. This alert is always fatal and should never be + * observed in communication between proper implementations. + */ + public const byte unexpected_message = 10; + + /** + * This alert is returned if a record is received with an incorrect MAC. This alert also MUST be + * returned if an alert is sent because a TLSCiphertext decrypted in an invalid way: either it + * wasn't an even multiple of the block length, or its padding values, when checked, weren't + * correct. This message is always fatal and should never be observed in communication between + * proper implementations (except when messages were corrupted in the network). + */ + public const byte bad_record_mac = 20; + + /** + * This alert was used in some earlier versions of TLS, and may have permitted certain attacks + * against the CBC mode [CBCATT]. It MUST NOT be sent by compliant implementations. + */ + public const byte decryption_failed = 21; + + /** + * A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record + * decrypted to a TLSCompressed record with more than 2^14+1024 bytes. This message is always + * fatal and should never be observed in communication between proper implementations (except + * when messages were corrupted in the network). + */ + public const byte record_overflow = 22; + + /** + * The decompression function received improper input (e.g., data that would expand to excessive + * length). This message is always fatal and should never be observed in communication between + * proper implementations. + */ + public const byte decompression_failure = 30; + + /** + * Reception of a handshake_failure alert message indicates that the sender was unable to + * negotiate an acceptable set of security parameters given the options available. This is a + * fatal error. + */ + public const byte handshake_failure = 40; + + /** + * This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant + * implementations. + */ + public const byte no_certificate = 41; + + /** + * A certificate was corrupt, contained signatures that did not verify correctly, etc. + */ + public const byte bad_certificate = 42; + + /** + * A certificate was of an unsupported type. + */ + public const byte unsupported_certificate = 43; + + /** + * A certificate was revoked by its signer. + */ + public const byte certificate_revoked = 44; + + /** + * A certificate has expired or is not currently valid. + */ + public const byte certificate_expired = 45; + + /** + * Some other (unspecified) issue arose in processing the certificate, rendering it + * unacceptable. + */ + public const byte certificate_unknown = 46; + + /** + * A field in the handshake was out of range or inconsistent with other fields. This message is + * always fatal. + */ + public const byte illegal_parameter = 47; + + /** + * A valid certificate chain or partial chain was received, but the certificate was not accepted + * because the CA certificate could not be located or couldn't be matched with a known, trusted + * CA. This message is always fatal. + */ + public const byte unknown_ca = 48; + + /** + * A valid certificate was received, but when access control was applied, the sender decided not + * to proceed with negotiation. This message is always fatal. + */ + public const byte access_denied = 49; + + /** + * A message could not be decoded because some field was out of the specified range or the + * length of the message was incorrect. This message is always fatal and should never be + * observed in communication between proper implementations (except when messages were corrupted + * in the network). + */ + public const byte decode_error = 50; + + /** + * A handshake cryptographic operation failed, including being unable to correctly verify a + * signature or validate a Finished message. This message is always fatal. + */ + public const byte decrypt_error = 51; + + /** + * This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant + * implementations. + */ + public const byte export_restriction = 60; + + /** + * The protocol version the client has attempted to negotiate is recognized but not supported. + * (For example, old protocol versions might be avoided for security reasons.) This message is + * always fatal. + */ + public const byte protocol_version = 70; + + /** + * Returned instead of handshake_failure when a negotiation has failed specifically because the + * server requires ciphers more secure than those supported by the client. This message is + * always fatal. + */ + public const byte insufficient_security = 71; + + /** + * An internal error unrelated to the peer or the correctness of the protocol (such as a memory + * allocation failure) makes it impossible to continue. This message is always fatal. + */ + public const byte internal_error = 80; + + /** + * This handshake is being canceled for some reason unrelated to a protocol failure. If the user + * cancels an operation after the handshake is complete, just closing the connection by sending + * a close_notify is more appropriate. This alert should be followed by a close_notify. This + * message is generally a warning. + */ + public const byte user_canceled = 90; + + /** + * Sent by the client in response to a hello request or by the server in response to a client + * hello after initial handshaking. Either of these would normally lead to renegotiation; when + * that is not appropriate, the recipient should respond with this alert. At that point, the + * original requester can decide whether to proceed with the connection. One case where this + * would be appropriate is where a server has spawned a process to satisfy a request; the + * process might receive security parameters (key length, authentication, etc.) at startup, and + * it might be difficult to communicate changes to these parameters after that point. This + * message is always a warning. + */ + public const byte no_renegotiation = 100; + + /** + * Sent by clients that receive an extended server hello containing an extension that they did + * not put in the corresponding client hello. This message is always fatal. + */ + public const byte unsupported_extension = 110; + + /* + * RFC 3546 + */ + + /** + * This alert is sent by servers who are unable to retrieve a certificate chain from the URL + * supplied by the client (see Section 3.3). This message MAY be fatal - for example if client + * authentication is required by the server for the handshake to continue and the server is + * unable to retrieve the certificate chain, it may send a fatal alert. + */ + public const byte certificate_unobtainable = 111; + + /** + * This alert is sent by servers that receive a server_name extension request, but do not + * recognize the server name. This message MAY be fatal. + */ + public const byte unrecognized_name = 112; + + /** + * This alert is sent by clients that receive an invalid certificate status response (see + * Section 3.6). This message is always fatal. + */ + public const byte bad_certificate_status_response = 113; + + /** + * This alert is sent by servers when a certificate hash does not match a client provided + * certificate_hash. This message is always fatal. + */ + public const byte bad_certificate_hash_value = 114; + + /* + * RFC 4279 + */ + + /** + * If the server does not recognize the PSK identity, it MAY respond with an + * "unknown_psk_identity" alert message. + */ + public const byte unknown_psk_identity = 115; + + /* + * RFC 7507 + */ + + /** + * If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest protocol version + * supported by the server is higher than the version indicated in ClientHello.client_version, + * the server MUST respond with a fatal inappropriate_fallback alert [..]. + */ + public const byte inappropriate_fallback = 86; + + public static string GetName(byte alertDescription) + { + switch (alertDescription) + { + case close_notify: + return "close_notify"; + case unexpected_message: + return "unexpected_message"; + case bad_record_mac: + return "bad_record_mac"; + case decryption_failed: + return "decryption_failed"; + case record_overflow: + return "record_overflow"; + case decompression_failure: + return "decompression_failure"; + case handshake_failure: + return "handshake_failure"; + case no_certificate: + return "no_certificate"; + case bad_certificate: + return "bad_certificate"; + case unsupported_certificate: + return "unsupported_certificate"; + case certificate_revoked: + return "certificate_revoked"; + case certificate_expired: + return "certificate_expired"; + case certificate_unknown: + return "certificate_unknown"; + case illegal_parameter: + return "illegal_parameter"; + case unknown_ca: + return "unknown_ca"; + case access_denied: + return "access_denied"; + case decode_error: + return "decode_error"; + case decrypt_error: + return "decrypt_error"; + case export_restriction: + return "export_restriction"; + case protocol_version: + return "protocol_version"; + case insufficient_security: + return "insufficient_security"; + case internal_error: + return "internal_error"; + case user_canceled: + return "user_canceled"; + case no_renegotiation: + return "no_renegotiation"; + case unsupported_extension: + return "unsupported_extension"; + case certificate_unobtainable: + return "certificate_unobtainable"; + case unrecognized_name: + return "unrecognized_name"; + case bad_certificate_status_response: + return "bad_certificate_status_response"; + case bad_certificate_hash_value: + return "bad_certificate_hash_value"; + case unknown_psk_identity: + return "unknown_psk_identity"; + case inappropriate_fallback: + return "inappropriate_fallback"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(byte alertDescription) + { + return GetName(alertDescription) + "(" + alertDescription + ")"; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs.meta new file mode 100644 index 0000000..01af0bc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertDescription.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0e83bdd3959fac74eb57e28a1ffd3fe0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs new file mode 100644 index 0000000..8f84d41 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 5246 7.2 + /// + public abstract class AlertLevel + { + public const byte warning = 1; + public const byte fatal = 2; + + public static string GetName(byte alertDescription) + { + switch (alertDescription) + { + case warning: + return "warning"; + case fatal: + return "fatal"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(byte alertDescription) + { + return GetName(alertDescription) + "(" + alertDescription + ")"; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs.meta new file mode 100644 index 0000000..366f0ff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlertLevel.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f5a7ce7fd31dd384680237a5e4538758 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs new file mode 100644 index 0000000..e9df3ef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs @@ -0,0 +1,26 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A certificate verifyer, that will always return true. + ///
+	/// DO NOT USE THIS FILE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING.
+	/// 
+ ///
+ //[Obsolete("Perform certificate verification in TlsAuthentication implementation")] + public class AlwaysValidVerifyer : ICertificateVerifyer + { + /// Return true. + public bool IsValid(Uri targetUri, X509CertificateStructure[] certs) + { + return true; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs.meta new file mode 100644 index 0000000..daed75d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/AlwaysValidVerifyer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8610127981226aa40958ac0b45d51cf5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs new file mode 100644 index 0000000..ce433c4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs @@ -0,0 +1,151 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A queue for bytes. + ///

+ /// This file could be more optimized. + ///

+ ///
+ public class ByteQueue + { + /// The smallest number which can be written as 2^x which is bigger than i. + public static int NextTwoPow( + int i) + { + /* + * This code is based of a lot of code I found on the Internet + * which mostly referenced a book called "Hacking delight". + * + */ + i |= (i >> 1); + i |= (i >> 2); + i |= (i >> 4); + i |= (i >> 8); + i |= (i >> 16); + return i + 1; + } + + /** + * The initial size for our buffer. + */ + private const int DefaultCapacity = 1024; + + /** + * The buffer where we store our data. + */ + private byte[] databuf; + + /** + * How many bytes at the beginning of the buffer are skipped. + */ + private int skipped = 0; + + /** + * How many bytes in the buffer are valid data. + */ + private int available = 0; + + public ByteQueue() + : this(DefaultCapacity) + { + } + + public ByteQueue(int capacity) + { + this.databuf = new byte[capacity]; + } + + /// Read data from the buffer. + /// The buffer where the read data will be copied to. + /// How many bytes to skip at the beginning of buf. + /// How many bytes to read at all. + /// How many bytes from our data to skip. + public void Read( + byte[] buf, + int offset, + int len, + int skip) + { + if ((buf.Length - offset) < len) + { + throw new ArgumentException("Buffer size of " + buf.Length + " is too small for a read of " + len + " bytes"); + } + if ((available - skip) < len) + { + throw new InvalidOperationException("Not enough data to read"); + } + Array.Copy(databuf, skipped + skip, buf, offset, len); + } + + /// Add some data to our buffer. + /// A byte-array to read data from. + /// How many bytes to skip at the beginning of the array. + /// How many bytes to read from the array. + public void AddData( + byte[] data, + int offset, + int len) + { + if ((skipped + available + len) > databuf.Length) + { + int desiredSize = ByteQueue.NextTwoPow(available + len); + if (desiredSize > databuf.Length) + { + byte[] tmp = new byte[desiredSize]; + Array.Copy(databuf, skipped, tmp, 0, available); + databuf = tmp; + } + else + { + Array.Copy(databuf, skipped, databuf, 0, available); + } + skipped = 0; + } + + Array.Copy(data, offset, databuf, skipped + available, len); + available += len; + } + + /// Remove some bytes from our data from the beginning. + /// How many bytes to remove. + public void RemoveData( + int i) + { + if (i > available) + { + throw new InvalidOperationException("Cannot remove " + i + " bytes, only got " + available); + } + + /* + * Skip the data. + */ + available -= i; + skipped += i; + } + + public void RemoveData(byte[] buf, int off, int len, int skip) + { + Read(buf, off, len, skip); + RemoveData(skip + len); + } + + public byte[] RemoveData(int len, int skip) + { + byte[] buf = new byte[len]; + RemoveData(buf, 0, len, skip); + return buf; + } + + /// The number of bytes which are available in this buffer. + public int Available + { + get { return available; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs.meta new file mode 100644 index 0000000..34ef4de --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueue.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e0b6d03f89d72e64da9242c29d55083d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs new file mode 100644 index 0000000..bb2a946 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs @@ -0,0 +1,114 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ByteQueueStream + : Stream + { + private readonly ByteQueue buffer; + + public ByteQueueStream() + { + this.buffer = new ByteQueue(); + } + + public virtual int Available + { + get { return buffer.Available; } + } + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override void Flush() + { + } + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public virtual int Peek(byte[] buf) + { + int bytesToRead = System.Math.Min(buffer.Available, buf.Length); + buffer.Read(buf, 0, bytesToRead, 0); + return bytesToRead; + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public virtual int Read(byte[] buf) + { + return Read(buf, 0, buf.Length); + } + + public override int Read(byte[] buf, int off, int len) + { + int bytesToRead = System.Math.Min(buffer.Available, len); + buffer.RemoveData(buf, off, bytesToRead, 0); + return bytesToRead; + } + + public override int ReadByte() + { + if (buffer.Available == 0) + return -1; + + return buffer.RemoveData(1, 0)[0] & 0xFF; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public virtual int Skip(int n) + { + int bytesToSkip = System.Math.Min(buffer.Available, n); + buffer.RemoveData(bytesToSkip); + return bytesToSkip; + } + + public virtual void Write(byte[] buf) + { + buffer.AddData(buf, 0, buf.Length); + } + + public override void Write(byte[] buf, int off, int len) + { + buffer.AddData(buf, off, len); + } + + public override void WriteByte(byte b) + { + buffer.AddData(new byte[]{ b }, 0, 1); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs.meta new file mode 100644 index 0000000..8f9b51d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ByteQueueStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fec5e2d706f06ac4eacec774c074001a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs new file mode 100644 index 0000000..214ad92 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs @@ -0,0 +1,22 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 3546 3.3. + */ + public abstract class CertChainType + { + public const byte individual_certs = 0; + public const byte pkipath = 1; + + public static bool IsValid(byte certChainType) + { + return certChainType >= individual_certs && certChainType <= pkipath; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs.meta new file mode 100644 index 0000000..151467d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertChainType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8bc6b0ebc7686e944b7bb9ab70a50f50 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs new file mode 100644 index 0000000..11353bd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs @@ -0,0 +1,140 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * Parsing and encoding of a Certificate struct from RFC 4346. + *

+ *

+     * opaque ASN.1Cert<2^24-1>;
+     *
+     * struct {
+     *     ASN.1Cert certificate_list<0..2^24-1>;
+     * } Certificate;
+     * 
+ * + * @see Org.BouncyCastle.Asn1.X509.X509CertificateStructure + */ + public class Certificate + { + public static readonly Certificate EmptyChain = new Certificate(new X509CertificateStructure[0]); + + /** + * The certificates. + */ + protected readonly X509CertificateStructure[] mCertificateList; + + public Certificate(X509CertificateStructure[] certificateList) + { + if (certificateList == null) + throw new ArgumentNullException("certificateList"); + + this.mCertificateList = certificateList; + } + + /** + * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate + * chain. + */ + public virtual X509CertificateStructure[] GetCertificateList() + { + return CloneCertificateList(); + } + + public virtual X509CertificateStructure GetCertificateAt(int index) + { + return mCertificateList[index]; + } + + public virtual int Length + { + get { return mCertificateList.Length; } + } + + /** + * @return true if this certificate chain contains no certificates, or + * false otherwise. + */ + public virtual bool IsEmpty + { + get { return mCertificateList.Length == 0; } + } + + /** + * Encode this {@link Certificate} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + IList derEncodings = Org.BouncyCastle.Utilities.Platform.CreateArrayList(mCertificateList.Length); + + int totalLength = 0; + foreach (Asn1Encodable asn1Cert in mCertificateList) + { + byte[] derEncoding = asn1Cert.GetEncoded(Asn1Encodable.Der); + derEncodings.Add(derEncoding); + totalLength += derEncoding.Length + 3; + } + + TlsUtilities.CheckUint24(totalLength); + TlsUtilities.WriteUint24(totalLength, output); + + foreach (byte[] derEncoding in derEncodings) + { + TlsUtilities.WriteOpaque24(derEncoding, output); + } + } + + /** + * Parse a {@link Certificate} from a {@link Stream}. + * + * @param input the {@link Stream} to parse from. + * @return a {@link Certificate} object. + * @throws IOException + */ + public static Certificate Parse(Stream input) + { + int totalLength = TlsUtilities.ReadUint24(input); + if (totalLength == 0) + { + return EmptyChain; + } + + byte[] certListData = TlsUtilities.ReadFully(totalLength, input); + + MemoryStream buf = new MemoryStream(certListData, false); + + IList certificate_list = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + byte[] derEncoding = TlsUtilities.ReadOpaque24(buf); + Asn1Object asn1Cert = TlsUtilities.ReadDerObject(derEncoding); + certificate_list.Add(X509CertificateStructure.GetInstance(asn1Cert)); + } + + X509CertificateStructure[] certificateList = new X509CertificateStructure[certificate_list.Count]; + for (int i = 0; i < certificate_list.Count; ++i) + { + certificateList[i] = (X509CertificateStructure)certificate_list[i]; + } + return new Certificate(certificateList); + } + + protected virtual X509CertificateStructure[] CloneCertificateList() + { + return (X509CertificateStructure[])mCertificateList.Clone(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs.meta new file mode 100644 index 0000000..bc49d5d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Certificate.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 04e2a7ee7d3bba041bea0b7d394a2fcb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs new file mode 100644 index 0000000..da7aba1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs @@ -0,0 +1,160 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * Parsing and encoding of a CertificateRequest struct from RFC 4346. + *

+ *

+     * struct {
+     *     ClientCertificateType certificate_types<1..2^8-1>;
+     *     DistinguishedName certificate_authorities<3..2^16-1>
+     * } CertificateRequest;
+     * 
+ * + * @see ClientCertificateType + * @see X509Name + */ + public class CertificateRequest + { + protected readonly byte[] mCertificateTypes; + protected readonly IList mSupportedSignatureAlgorithms; + protected readonly IList mCertificateAuthorities; + + /** + * @param certificateTypes see {@link ClientCertificateType} for valid constants. + * @param certificateAuthorities an {@link IList} of {@link X509Name}. + */ + public CertificateRequest(byte[] certificateTypes, IList supportedSignatureAlgorithms, + IList certificateAuthorities) + { + this.mCertificateTypes = certificateTypes; + this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms; + this.mCertificateAuthorities = certificateAuthorities; + } + + /** + * @return an array of certificate types + * @see {@link ClientCertificateType} + */ + public virtual byte[] CertificateTypes + { + get { return mCertificateTypes; } + } + + /** + * @return an {@link IList} of {@link SignatureAndHashAlgorithm} (or null before TLS 1.2). + */ + public virtual IList SupportedSignatureAlgorithms + { + get { return mSupportedSignatureAlgorithms; } + } + + /** + * @return an {@link IList} of {@link X509Name} + */ + public virtual IList CertificateAuthorities + { + get { return mCertificateAuthorities; } + } + + /** + * Encode this {@link CertificateRequest} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + if (mCertificateTypes == null || mCertificateTypes.Length == 0) + { + TlsUtilities.WriteUint8(0, output); + } + else + { + TlsUtilities.WriteUint8ArrayWithUint8Length(mCertificateTypes, output); + } + + if (mSupportedSignatureAlgorithms != null) + { + // TODO Check whether SignatureAlgorithm.anonymous is allowed here + TlsUtilities.EncodeSupportedSignatureAlgorithms(mSupportedSignatureAlgorithms, false, output); + } + + if (mCertificateAuthorities == null || mCertificateAuthorities.Count < 1) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + IList derEncodings = Org.BouncyCastle.Utilities.Platform.CreateArrayList(mCertificateAuthorities.Count); + + int totalLength = 0; + foreach (Asn1Encodable certificateAuthority in mCertificateAuthorities) + { + byte[] derEncoding = certificateAuthority.GetEncoded(Asn1Encodable.Der); + derEncodings.Add(derEncoding); + totalLength += derEncoding.Length + 2; + } + + TlsUtilities.CheckUint16(totalLength); + TlsUtilities.WriteUint16(totalLength, output); + + foreach (byte[] derEncoding in derEncodings) + { + TlsUtilities.WriteOpaque16(derEncoding, output); + } + } + } + + /** + * Parse a {@link CertificateRequest} from a {@link Stream}. + * + * @param context + * the {@link TlsContext} of the current connection. + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateRequest} object. + * @throws IOException + */ + public static CertificateRequest Parse(TlsContext context, Stream input) + { + int numTypes = TlsUtilities.ReadUint8(input); + byte[] certificateTypes = new byte[numTypes]; + for (int i = 0; i < numTypes; ++i) + { + certificateTypes[i] = TlsUtilities.ReadUint8(input); + } + + IList supportedSignatureAlgorithms = null; + if (TlsUtilities.IsTlsV12(context)) + { + // TODO Check whether SignatureAlgorithm.anonymous is allowed here + supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(false, input); + } + + IList certificateAuthorities = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + byte[] certAuthData = TlsUtilities.ReadOpaque16(input); + MemoryStream bis = new MemoryStream(certAuthData, false); + while (bis.Position < bis.Length) + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(bis); + Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding); + // TODO Switch to X500Name when available + certificateAuthorities.Add(X509Name.GetInstance(asn1)); + } + + return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs.meta new file mode 100644 index 0000000..2d9e288 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateRequest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c6de822998d2e9a409cce2db7a032dcd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs new file mode 100644 index 0000000..f3e4a4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs @@ -0,0 +1,106 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class CertificateStatus + { + protected readonly byte mStatusType; + protected readonly object mResponse; + + public CertificateStatus(byte statusType, object response) + { + if (!IsCorrectType(statusType, response)) + throw new ArgumentException("not an instance of the correct type", "response"); + + this.mStatusType = statusType; + this.mResponse = response; + } + + public virtual byte StatusType + { + get { return mStatusType; } + } + + public virtual object Response + { + get { return mResponse; } + } + + public virtual OcspResponse GetOcspResponse() + { + if (!IsCorrectType(CertificateStatusType.ocsp, mResponse)) + throw new InvalidOperationException("'response' is not an OcspResponse"); + + return (OcspResponse)mResponse; + } + + /** + * Encode this {@link CertificateStatus} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mStatusType, output); + + switch (mStatusType) + { + case CertificateStatusType.ocsp: + byte[] derEncoding = ((OcspResponse)mResponse).GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque24(derEncoding, output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /** + * Parse a {@link CertificateStatus} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateStatus} object. + * @throws IOException + */ + public static CertificateStatus Parse(Stream input) + { + byte status_type = TlsUtilities.ReadUint8(input); + object response; + + switch (status_type) + { + case CertificateStatusType.ocsp: + { + byte[] derEncoding = TlsUtilities.ReadOpaque24(input); + response = OcspResponse.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new CertificateStatus(status_type, response); + } + + protected static bool IsCorrectType(byte statusType, object response) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + return response is OcspResponse; + default: + throw new ArgumentException("unsupported value", "statusType"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs.meta new file mode 100644 index 0000000..a240db8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatus.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ef5cccf2d49a9184fa820ad3b0bbf784 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs new file mode 100644 index 0000000..8e93c63 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs @@ -0,0 +1,99 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class CertificateStatusRequest + { + protected readonly byte mStatusType; + protected readonly object mRequest; + + public CertificateStatusRequest(byte statusType, Object request) + { + if (!IsCorrectType(statusType, request)) + throw new ArgumentException("not an instance of the correct type", "request"); + + this.mStatusType = statusType; + this.mRequest = request; + } + + public virtual byte StatusType + { + get { return mStatusType; } + } + + public virtual object Request + { + get { return mRequest; } + } + + public virtual OcspStatusRequest GetOcspStatusRequest() + { + if (!IsCorrectType(CertificateStatusType.ocsp, mRequest)) + throw new InvalidOperationException("'request' is not an OCSPStatusRequest"); + + return (OcspStatusRequest)mRequest; + } + + /** + * Encode this {@link CertificateStatusRequest} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mStatusType, output); + + switch (mStatusType) + { + case CertificateStatusType.ocsp: + ((OcspStatusRequest)mRequest).Encode(output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /** + * Parse a {@link CertificateStatusRequest} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateStatusRequest} object. + * @throws IOException + */ + public static CertificateStatusRequest Parse(Stream input) + { + byte status_type = TlsUtilities.ReadUint8(input); + object result; + + switch (status_type) + { + case CertificateStatusType.ocsp: + result = OcspStatusRequest.Parse(input); + break; + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new CertificateStatusRequest(status_type, result); + } + + protected static bool IsCorrectType(byte statusType, object request) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + return request is OcspStatusRequest; + default: + throw new ArgumentException("unsupported value", "statusType"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs.meta new file mode 100644 index 0000000..2c87da9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusRequest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 323d128a88127984889c78f89508470b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs new file mode 100644 index 0000000..69e5e14 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class CertificateStatusType + { + /* + * RFC 3546 3.6 + */ + public const byte ocsp = 1; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs.meta new file mode 100644 index 0000000..313775f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CertificateStatusType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2e75533986ca52349be91292aa2eb6a3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs new file mode 100644 index 0000000..352758a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs @@ -0,0 +1,203 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * draft-ietf-tls-chacha20-poly1305-04 + */ + public class Chacha20Poly1305 + : TlsCipher + { + private static readonly byte[] Zeroes = new byte[15]; + + protected readonly TlsContext context; + + protected readonly ChaCha7539Engine encryptCipher, decryptCipher; + protected readonly byte[] encryptIV, decryptIV; + + /// + public Chacha20Poly1305(TlsContext context) + { + if (!TlsUtilities.IsTlsV12(context)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.context = context; + + int cipherKeySize = 32; + // TODO SecurityParameters.fixed_iv_length + int fixed_iv_length = 12; + // TODO SecurityParameters.record_iv_length = 0 + + int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length); + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + + if (offset != key_block_size) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.encryptCipher = new ChaCha7539Engine(); + this.decryptCipher = new ChaCha7539Engine(); + + KeyParameter encryptKey, decryptKey; + if (context.IsServer) + { + encryptKey = server_write_key; + decryptKey = client_write_key; + this.encryptIV = server_write_IV; + this.decryptIV = client_write_IV; + } + else + { + encryptKey = client_write_key; + decryptKey = server_write_key; + this.encryptIV = client_write_IV; + this.decryptIV = server_write_IV; + } + + this.encryptCipher.Init(true, new ParametersWithIV(encryptKey, encryptIV)); + this.decryptCipher.Init(false, new ParametersWithIV(decryptKey, decryptIV)); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit - 16; + } + + /// + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + KeyParameter macKey = InitRecord(encryptCipher, true, seqNo, encryptIV); + + byte[] output = new byte[len + 16]; + encryptCipher.ProcessBytes(plaintext, offset, len, output, 0); + + byte[] additionalData = GetAdditionalData(seqNo, type, len); + byte[] mac = CalculateRecordMac(macKey, additionalData, output, 0, len); + Array.Copy(mac, 0, output, len, mac.Length); + + return output; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (GetPlaintextLimit(len) < 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + KeyParameter macKey = InitRecord(decryptCipher, false, seqNo, decryptIV); + + int plaintextLength = len - 16; + + byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); + byte[] calculatedMac = CalculateRecordMac(macKey, additionalData, ciphertext, offset, plaintextLength); + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, offset + plaintextLength, offset + len); + + if (!Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac)) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + byte[] output = new byte[plaintextLength]; + decryptCipher.ProcessBytes(ciphertext, offset, plaintextLength, output, 0); + return output; + } + + protected virtual KeyParameter InitRecord(IStreamCipher cipher, bool forEncryption, long seqNo, byte[] iv) + { + byte[] nonce = CalculateNonce(seqNo, iv); + cipher.Init(forEncryption, new ParametersWithIV(null, nonce)); + return GenerateRecordMacKey(cipher); + } + + protected virtual byte[] CalculateNonce(long seqNo, byte[] iv) + { + byte[] nonce = new byte[12]; + TlsUtilities.WriteUint64(seqNo, nonce, 4); + + for (int i = 0; i < 12; ++i) + { + nonce[i] ^= iv[i]; + } + + return nonce; + } + + protected virtual KeyParameter GenerateRecordMacKey(IStreamCipher cipher) + { + byte[] firstBlock = new byte[64]; + cipher.ProcessBytes(firstBlock, 0, firstBlock.Length, firstBlock, 0); + + KeyParameter macKey = new KeyParameter(firstBlock, 0, 32); + Arrays.Fill(firstBlock, (byte)0); + return macKey; + } + + protected virtual byte[] CalculateRecordMac(KeyParameter macKey, byte[] additionalData, byte[] buf, int off, int len) + { + IMac mac = new Poly1305(); + mac.Init(macKey); + + UpdateRecordMacText(mac, additionalData, 0, additionalData.Length); + UpdateRecordMacText(mac, buf, off, len); + UpdateRecordMacLength(mac, additionalData.Length); + UpdateRecordMacLength(mac, len); + + return MacUtilities.DoFinal(mac); + } + + protected virtual void UpdateRecordMacLength(IMac mac, int len) + { + byte[] longLen = Pack.UInt64_To_LE((ulong)len); + mac.BlockUpdate(longLen, 0, longLen.Length); + } + + protected virtual void UpdateRecordMacText(IMac mac, byte[] buf, int off, int len) + { + mac.BlockUpdate(buf, off, len); + + int partial = len % 16; + if (partial != 0) + { + mac.BlockUpdate(Zeroes, 0, 16 - partial); + } + } + + /// + protected virtual byte[] GetAdditionalData(long seqNo, byte type, int len) + { + /* + * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + + * TLSCompressed.length + */ + byte[] additional_data = new byte[13]; + TlsUtilities.WriteUint64(seqNo, additional_data, 0); + TlsUtilities.WriteUint8(type, additional_data, 8); + TlsUtilities.WriteVersion(context.ServerVersion, additional_data, 9); + TlsUtilities.WriteUint16(len, additional_data, 11); + + return additional_data; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs.meta new file mode 100644 index 0000000..2fdf073 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Chacha20Poly1305.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 564a63c16dc8afd4a83fd19e4682a540 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs new file mode 100644 index 0000000..2ac8552 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ChangeCipherSpec + { + public const byte change_cipher_spec = 1; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs.meta new file mode 100644 index 0000000..695bff4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ChangeCipherSpec.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 94c6cbdf3e6636d4cab39f225441e580 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs new file mode 100644 index 0000000..40c4758 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs @@ -0,0 +1,381 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 2246 A.5 + /// + public abstract class CipherSuite + { + public const int TLS_NULL_WITH_NULL_NULL = 0x0000; + public const int TLS_RSA_WITH_NULL_MD5 = 0x0001; + public const int TLS_RSA_WITH_NULL_SHA = 0x0002; + public const int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003; + public const int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; + public const int TLS_RSA_WITH_RC4_128_SHA = 0x0005; + public const int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006; + public const int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007; + public const int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008; + public const int TLS_RSA_WITH_DES_CBC_SHA = 0x0009; + public const int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; + public const int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B; + public const int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C; + public const int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D; + public const int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E; + public const int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F; + public const int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; + public const int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011; + public const int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; + public const int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; + public const int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014; + public const int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; + public const int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; + public const int TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017; + public const int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018; + public const int TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019; + public const int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A; + public const int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B; + + /* + * Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid + * collision with Fortezza-based cipher suites in SSL 3. + */ + + /* + * RFC 3268 + */ + public const int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; + public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; + public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; + public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; + public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; + public const int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034; + public const int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; + public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; + public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; + public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; + public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; + public const int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A; + + /* + * RFC 5932 + */ + public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045; + public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046; + + public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088; + public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089; + + public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE; + public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF; + + public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4; + public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5; + + /* + * RFC 4162 + */ + public const int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096; + public const int TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097; + public const int TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098; + public const int TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099; + public const int TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A; + public const int TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B; + + /* + * RFC 4279 + */ + public const int TLS_PSK_WITH_RC4_128_SHA = 0x008A; + public const int TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B; + public const int TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; + public const int TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; + public const int TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E; + public const int TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F; + public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090; + public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091; + public const int TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092; + public const int TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093; + public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094; + public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095; + + /* + * RFC 4492 + */ + public const int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001; + public const int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002; + public const int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003; + public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004; + public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005; + public const int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006; + public const int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007; + public const int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; + public const int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B; + public const int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C; + public const int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D; + public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E; + public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F; + public const int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010; + public const int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011; + public const int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012; + public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; + public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; + public const int TLS_ECDH_anon_WITH_NULL_SHA = 0xC015; + public const int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016; + public const int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017; + public const int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018; + public const int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019; + + /* + * RFC 4785 + */ + public const int TLS_PSK_WITH_NULL_SHA = 0x002C; + public const int TLS_DHE_PSK_WITH_NULL_SHA = 0x002D; + public const int TLS_RSA_PSK_WITH_NULL_SHA = 0x002E; + + /* + * RFC 5054 + */ + public const int TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A; + public const int TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B; + public const int TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C; + public const int TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D; + public const int TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E; + public const int TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F; + public const int TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020; + public const int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021; + public const int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022; + + /* + * RFC 5246 + */ + public const int TLS_RSA_WITH_NULL_SHA256 = 0x003B; + public const int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; + public const int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; + public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E; + public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; + public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; + public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; + public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068; + public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069; + public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; + public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; + public const int TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C; + public const int TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D; + + /* + * RFC 5288 + */ + public const int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; + public const int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; + public const int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; + public const int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; + public const int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0; + public const int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1; + public const int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; + public const int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; + public const int TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4; + public const int TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5; + public const int TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6; + public const int TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7; + + /* + * RFC 5289 + */ + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024; + public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025; + public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026; + public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027; + public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028; + public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029; + public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; + public const int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D; + public const int TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E; + public const int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; + public const int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; + public const int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031; + public const int TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032; + + /* + * RFC 5487 + */ + public const int TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8; + public const int TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9; + public const int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA; + public const int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB; + public const int TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC; + public const int TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD; + public const int TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE; + public const int TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF; + public const int TLS_PSK_WITH_NULL_SHA256 = 0x00B0; + public const int TLS_PSK_WITH_NULL_SHA384 = 0x00B1; + public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2; + public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3; + public const int TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4; + public const int TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5; + public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6; + public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7; + public const int TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8; + public const int TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9; + + /* + * RFC 5489 + */ + public const int TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033; + public const int TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034; + public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035; + public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036; + public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037; + public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B; + + /* + * RFC 5746 + */ + public const int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; + + /* + * RFC 6367 + */ + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079; + + public const int TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A; + public const int TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083; + public const int TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084; + public const int TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D; + + public const int TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E; + public const int TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F; + public const int TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090; + public const int TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091; + public const int TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092; + public const int TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093; + public const int TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094; + public const int TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095; + public const int TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096; + public const int TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097; + public const int TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098; + public const int TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099; + public const int TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A; + public const int TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B; + + /* + * RFC 6655 + */ + public const int TLS_RSA_WITH_AES_128_CCM = 0xC09C; + public const int TLS_RSA_WITH_AES_256_CCM = 0xC09D; + public const int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E; + public const int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F; + public const int TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0; + public const int TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1; + public const int TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2; + public const int TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3; + public const int TLS_PSK_WITH_AES_128_CCM = 0xC0A4; + public const int TLS_PSK_WITH_AES_256_CCM = 0xC0A5; + public const int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6; + public const int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7; + public const int TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8; + public const int TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9; + public const int TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA; + public const int TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB; + + /* + * RFC 7251 + */ + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF; + + /* + * RFC 7507 + */ + public const int TLS_FALLBACK_SCSV = 0x5600; + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + public const int DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; + public const int DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; + public const int DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA; + public const int DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB; + public const int DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; + public const int DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD; + public const int DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE; + + /* + * draft-zauner-tls-aes-ocb-04 (code points TBD) + */ + public const int DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB = 0xFF00; + public const int DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB = 0xFF01; + public const int DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB = 0xFF02; + public const int DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB = 0xFF03; + public const int DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB = 0xFF04; + public const int DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB = 0xFF05; + public const int DRAFT_TLS_PSK_WITH_AES_128_OCB = 0xFF10; + public const int DRAFT_TLS_PSK_WITH_AES_256_OCB = 0xFF11; + public const int DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB = 0xFF12; + public const int DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB = 0xFF13; + public const int DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB = 0xFF14; + public const int DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB = 0xFF15; + + public static bool IsScsv(int cipherSuite) + { + switch (cipherSuite) + { + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + case TLS_FALLBACK_SCSV: + return true; + default: + return false; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs.meta new file mode 100644 index 0000000..f148272 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherSuite.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c73b6efb7aba3f8488ad1b3db36e743f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs new file mode 100644 index 0000000..d1b1645 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class CipherType + { + public const int stream = 0; + public const int block = 1; + + /* + * RFC 5246 + */ + public const int aead = 2; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs.meta new file mode 100644 index 0000000..c3a6e06 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CipherType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f1306d0e5036e1b40b6f5b7e9879f53d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs new file mode 100644 index 0000000..8848f08 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ClientCertificateType + { + /* + * RFC 4346 7.4.4 + */ + public const byte rsa_sign = 1; + public const byte dss_sign = 2; + public const byte rsa_fixed_dh = 3; + public const byte dss_fixed_dh = 4; + public const byte rsa_ephemeral_dh_RESERVED = 5; + public const byte dss_ephemeral_dh_RESERVED = 6; + public const byte fortezza_dms_RESERVED = 20; + + /* + * RFC 4492 5.5 + */ + public const byte ecdsa_sign = 64; + public const byte rsa_fixed_ecdh = 65; + public const byte ecdsa_fixed_ecdh = 66; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs.meta new file mode 100644 index 0000000..2e1e1f5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ClientCertificateType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0196ebd3420ed1f41a477463bfbd322a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs new file mode 100644 index 0000000..a340c51 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs @@ -0,0 +1,137 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * A combined hash, which implements md5(m) || sha1(m). + */ + internal class CombinedHash + : TlsHandshakeHash + { + protected TlsContext mContext; + protected IDigest mMd5; + protected IDigest mSha1; + + internal CombinedHash() + { + this.mMd5 = TlsUtilities.CreateHash(HashAlgorithm.md5); + this.mSha1 = TlsUtilities.CreateHash(HashAlgorithm.sha1); + } + + internal CombinedHash(CombinedHash t) + { + this.mContext = t.mContext; + this.mMd5 = TlsUtilities.CloneHash(HashAlgorithm.md5, t.mMd5); + this.mSha1 = TlsUtilities.CloneHash(HashAlgorithm.sha1, t.mSha1); + } + + public virtual void Init(TlsContext context) + { + this.mContext = context; + } + + public virtual TlsHandshakeHash NotifyPrfDetermined() + { + return this; + } + + public virtual void TrackHashAlgorithm(byte hashAlgorithm) + { + throw new InvalidOperationException("CombinedHash only supports calculating the legacy PRF for handshake hash"); + } + + public virtual void SealHashAlgorithms() + { + } + + public virtual TlsHandshakeHash StopTracking() + { + return new CombinedHash(this); + } + + public virtual IDigest ForkPrfHash() + { + return new CombinedHash(this); + } + + public virtual byte[] GetFinalHash(byte hashAlgorithm) + { + throw new InvalidOperationException("CombinedHash doesn't support multiple hashes"); + } + + public virtual string AlgorithmName + { + get { return mMd5.AlgorithmName + " and " + mSha1.AlgorithmName; } + } + + public virtual int GetByteLength() + { + return System.Math.Max(mMd5.GetByteLength(), mSha1.GetByteLength()); + } + + public virtual int GetDigestSize() + { + return mMd5.GetDigestSize() + mSha1.GetDigestSize(); + } + + public virtual void Update(byte input) + { + mMd5.Update(input); + mSha1.Update(input); + } + + /** + * @see org.bouncycastle.crypto.Digest#update(byte[], int, int) + */ + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + mMd5.BlockUpdate(input, inOff, len); + mSha1.BlockUpdate(input, inOff, len); + } + + /** + * @see org.bouncycastle.crypto.Digest#doFinal(byte[], int) + */ + public virtual int DoFinal(byte[] output, int outOff) + { + if (mContext != null && TlsUtilities.IsSsl(mContext)) + { + Ssl3Complete(mMd5, Ssl3Mac.IPAD, Ssl3Mac.OPAD, 48); + Ssl3Complete(mSha1, Ssl3Mac.IPAD, Ssl3Mac.OPAD, 40); + } + + int i1 = mMd5.DoFinal(output, outOff); + int i2 = mSha1.DoFinal(output, outOff + i1); + return i1 + i2; + } + + /** + * @see org.bouncycastle.crypto.Digest#reset() + */ + public virtual void Reset() + { + mMd5.Reset(); + mSha1.Reset(); + } + + protected virtual void Ssl3Complete(IDigest d, byte[] ipad, byte[] opad, int padLength) + { + byte[] master_secret = mContext.SecurityParameters.masterSecret; + + d.BlockUpdate(master_secret, 0, master_secret.Length); + d.BlockUpdate(ipad, 0, padLength); + + byte[] tmp = DigestUtilities.DoFinal(d); + + d.BlockUpdate(master_secret, 0, master_secret.Length); + d.BlockUpdate(opad, 0, padLength); + d.BlockUpdate(tmp, 0, tmp.Length); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs.meta new file mode 100644 index 0000000..9db2749 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CombinedHash.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: af3c6c47834d645488de7375ddc01158 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs new file mode 100644 index 0000000..88b0ec8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs @@ -0,0 +1,26 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 2246 6.1 + /// + public abstract class CompressionMethod + { + public const byte cls_null = 0; + + /* + * RFC 3749 2 + */ + public const byte DEFLATE = 1; + + /* + * Values from 224 decimal (0xE0) through 255 decimal (0xFF) + * inclusive are reserved for private use. + */ + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs.meta new file mode 100644 index 0000000..ac230f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/CompressionMethod.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b73c28d0fbb64c74086bc3db3142c50c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs new file mode 100644 index 0000000..e252bb7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs @@ -0,0 +1,19 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class ConnectionEnd + { + public const int server = 0; + public const int client = 1; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs.meta new file mode 100644 index 0000000..f363cbd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ConnectionEnd.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 450461823377efe458859c00c62dfb7d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs new file mode 100644 index 0000000..d99ba0f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 2246 6.2.1 + */ + public abstract class ContentType + { + public const byte change_cipher_spec = 20; + public const byte alert = 21; + public const byte handshake = 22; + public const byte application_data = 23; + public const byte heartbeat = 24; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs.meta new file mode 100644 index 0000000..675687a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ContentType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e4a759488b194124ebfdb4f5c4185365 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs new file mode 100644 index 0000000..42bf137 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs @@ -0,0 +1,27 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface DatagramTransport + { + /// + int GetReceiveLimit(); + + /// + int GetSendLimit(); + + /// + int Receive(byte[] buf, int off, int len, int waitMillis); + + /// + void Send(byte[] buf, int off, int len); + + /// + void Close(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs.meta new file mode 100644 index 0000000..3e18be9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DatagramTransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 67e21ffc6e4bfae49b08ede38bb9d801 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs new file mode 100644 index 0000000..924ee14 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs @@ -0,0 +1,231 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsCipherFactory + : AbstractTlsCipherFactory + { + /// + public override TlsCipher CreateCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) + { + switch (encryptionAlgorithm) + { + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + return CreateDesEdeCipher(context, macAlgorithm); + case EncryptionAlgorithm.AES_128_CBC: + return CreateAESCipher(context, 16, macAlgorithm); + case EncryptionAlgorithm.AES_128_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 16, 16); + case EncryptionAlgorithm.AES_128_CCM_8: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 16, 8); + case EncryptionAlgorithm.AES_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Gcm(context, 16, 16); + case EncryptionAlgorithm.AES_128_OCB_TAGLEN96: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ocb(context, 16, 12); + case EncryptionAlgorithm.AES_256_CBC: + return CreateAESCipher(context, 32, macAlgorithm); + case EncryptionAlgorithm.AES_256_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 32, 16); + case EncryptionAlgorithm.AES_256_CCM_8: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 32, 8); + case EncryptionAlgorithm.AES_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Gcm(context, 32, 16); + case EncryptionAlgorithm.AES_256_OCB_TAGLEN96: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ocb(context, 32, 12); + case EncryptionAlgorithm.CAMELLIA_128_CBC: + return CreateCamelliaCipher(context, 16, macAlgorithm); + case EncryptionAlgorithm.CAMELLIA_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Camellia_Gcm(context, 16, 16); + case EncryptionAlgorithm.CAMELLIA_256_CBC: + return CreateCamelliaCipher(context, 32, macAlgorithm); + case EncryptionAlgorithm.CAMELLIA_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Camellia_Gcm(context, 32, 16); + case EncryptionAlgorithm.CHACHA20_POLY1305: + // NOTE: Ignores macAlgorithm + return CreateChaCha20Poly1305(context); + case EncryptionAlgorithm.NULL: + return CreateNullCipher(context, macAlgorithm); + case EncryptionAlgorithm.RC4_128: + return CreateRC4Cipher(context, 16, macAlgorithm); + case EncryptionAlgorithm.SEED_CBC: + return CreateSeedCipher(context, macAlgorithm); + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// + protected virtual TlsBlockCipher CreateAESCipher(TlsContext context, int cipherKeySize, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateAesBlockCipher(), CreateAesBlockCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), cipherKeySize); + } + + /// + protected virtual TlsBlockCipher CreateCamelliaCipher(TlsContext context, int cipherKeySize, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateCamelliaBlockCipher(), + CreateCamelliaBlockCipher(), CreateHMacDigest(macAlgorithm), + CreateHMacDigest(macAlgorithm), cipherKeySize); + } + + /// + protected virtual TlsCipher CreateChaCha20Poly1305(TlsContext context) + { + return new Chacha20Poly1305(context); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Aes_Ccm(), + CreateAeadBlockCipher_Aes_Ccm(), cipherKeySize, macSize); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Aes_Gcm(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Aes_Gcm(), + CreateAeadBlockCipher_Aes_Gcm(), cipherKeySize, macSize); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Aes_Ocb(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Aes_Ocb(), + CreateAeadBlockCipher_Aes_Ocb(), cipherKeySize, macSize, TlsAeadCipher.NONCE_DRAFT_CHACHA20_POLY1305); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Camellia_Gcm(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Camellia_Gcm(), + CreateAeadBlockCipher_Camellia_Gcm(), cipherKeySize, macSize); + } + + /// + protected virtual TlsBlockCipher CreateDesEdeCipher(TlsContext context, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateDesEdeBlockCipher(), CreateDesEdeBlockCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), 24); + } + + /// + protected virtual TlsNullCipher CreateNullCipher(TlsContext context, int macAlgorithm) + { + return new TlsNullCipher(context, CreateHMacDigest(macAlgorithm), + CreateHMacDigest(macAlgorithm)); + } + + /// + protected virtual TlsStreamCipher CreateRC4Cipher(TlsContext context, int cipherKeySize, int macAlgorithm) + { + return new TlsStreamCipher(context, CreateRC4StreamCipher(), CreateRC4StreamCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), cipherKeySize, false); + } + + /// + protected virtual TlsBlockCipher CreateSeedCipher(TlsContext context, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateSeedBlockCipher(), CreateSeedBlockCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), 16); + } + + protected virtual IBlockCipher CreateAesEngine() + { + return new AesFastEngine(); + } + + protected virtual IBlockCipher CreateCamelliaEngine() + { + return new CamelliaEngine(); + } + + protected virtual IBlockCipher CreateAesBlockCipher() + { + return new CbcBlockCipher(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Ccm() + { + return new CcmBlockCipher(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Gcm() + { + // TODO Consider allowing custom configuration of multiplier + return new GcmBlockCipher(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Ocb() + { + return new OcbBlockCipher(CreateAesEngine(), CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Camellia_Gcm() + { + // TODO Consider allowing custom configuration of multiplier + return new GcmBlockCipher(CreateCamelliaEngine()); + } + + protected virtual IBlockCipher CreateCamelliaBlockCipher() + { + return new CbcBlockCipher(CreateCamelliaEngine()); + } + + protected virtual IBlockCipher CreateDesEdeBlockCipher() + { + return new CbcBlockCipher(new DesEdeEngine()); + } + + protected virtual IStreamCipher CreateRC4StreamCipher() + { + return new RC4Engine(); + } + + protected virtual IBlockCipher CreateSeedBlockCipher() + { + return new CbcBlockCipher(new SeedEngine()); + } + + /// + protected virtual IDigest CreateHMacDigest(int macAlgorithm) + { + switch (macAlgorithm) + { + case MacAlgorithm.cls_null: + return null; + case MacAlgorithm.hmac_md5: + return TlsUtilities.CreateHash(HashAlgorithm.md5); + case MacAlgorithm.hmac_sha1: + return TlsUtilities.CreateHash(HashAlgorithm.sha1); + case MacAlgorithm.hmac_sha256: + return TlsUtilities.CreateHash(HashAlgorithm.sha256); + case MacAlgorithm.hmac_sha384: + return TlsUtilities.CreateHash(HashAlgorithm.sha384); + case MacAlgorithm.hmac_sha512: + return TlsUtilities.CreateHash(HashAlgorithm.sha512); + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs.meta new file mode 100644 index 0000000..76ccce2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsCipherFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ddaf894bcaa2d914892b1950de5107a9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs new file mode 100644 index 0000000..74d9df7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs @@ -0,0 +1,116 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class DefaultTlsClient + : AbstractTlsClient + { + public DefaultTlsClient() + : base() + { + } + + public DefaultTlsClient(TlsCipherFactory cipherFactory) + : base(cipherFactory) + { + } + + public override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, + }; + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + return CreateDHKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return CreateDheKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + return CreateECDHKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return CreateECDheKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.RSA: + return CreateRsaKeyExchange(); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange) + { + return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null); + } + + protected virtual TlsKeyExchange CreateDheKeyExchange(int keyExchange) + { + return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null); + } + + protected virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange) + { + return new TlsECDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats, + mServerECPointFormats); + } + + protected virtual TlsKeyExchange CreateECDheKeyExchange(int keyExchange) + { + return new TlsECDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats, + mServerECPointFormats); + } + + protected virtual TlsKeyExchange CreateRsaKeyExchange() + { + return new TlsRsaKeyExchange(mSupportedSignatureAlgorithms); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs.meta new file mode 100644 index 0000000..eb5db48 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DefaultTlsClient.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 407646f18e94e0e4ebd018e992aa5fc3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs new file mode 100644 index 0000000..afc94fd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs @@ -0,0 +1,205 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * Buffers input until the hash algorithm is determined. + */ + internal class DeferredHash + : TlsHandshakeHash + { + protected const int BUFFERING_HASH_LIMIT = 4; + + protected TlsContext mContext; + + private DigestInputBuffer mBuf; + private IDictionary mHashes; + private int mPrfHashAlgorithm; + + internal DeferredHash() + { + this.mBuf = new DigestInputBuffer(); + this.mHashes = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + this.mPrfHashAlgorithm = -1; + } + + private DeferredHash(byte prfHashAlgorithm, IDigest prfHash) + { + this.mBuf = null; + this.mHashes = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + this.mPrfHashAlgorithm = prfHashAlgorithm; + mHashes[prfHashAlgorithm] = prfHash; + } + + public virtual void Init(TlsContext context) + { + this.mContext = context; + } + + public virtual TlsHandshakeHash NotifyPrfDetermined() + { + int prfAlgorithm = mContext.SecurityParameters.PrfAlgorithm; + if (prfAlgorithm == PrfAlgorithm.tls_prf_legacy) + { + CombinedHash legacyHash = new CombinedHash(); + legacyHash.Init(mContext); + mBuf.UpdateDigest(legacyHash); + return legacyHash.NotifyPrfDetermined(); + } + + this.mPrfHashAlgorithm = TlsUtilities.GetHashAlgorithmForPrfAlgorithm(prfAlgorithm); + + CheckTrackingHash((byte)mPrfHashAlgorithm); + + return this; + } + + public virtual void TrackHashAlgorithm(byte hashAlgorithm) + { + if (mBuf == null) + throw new InvalidOperationException("Too late to track more hash algorithms"); + + CheckTrackingHash(hashAlgorithm); + } + + public virtual void SealHashAlgorithms() + { + CheckStopBuffering(); + } + + public virtual TlsHandshakeHash StopTracking() + { + byte prfHashAlgorithm = (byte)mPrfHashAlgorithm; + IDigest prfHash = TlsUtilities.CloneHash(prfHashAlgorithm, (IDigest)mHashes[prfHashAlgorithm]); + if (mBuf != null) + { + mBuf.UpdateDigest(prfHash); + } + DeferredHash result = new DeferredHash(prfHashAlgorithm, prfHash); + result.Init(mContext); + return result; + } + + public virtual IDigest ForkPrfHash() + { + CheckStopBuffering(); + + byte prfHashAlgorithm = (byte)mPrfHashAlgorithm; + if (mBuf != null) + { + IDigest prfHash = TlsUtilities.CreateHash(prfHashAlgorithm); + mBuf.UpdateDigest(prfHash); + return prfHash; + } + + return TlsUtilities.CloneHash(prfHashAlgorithm, (IDigest)mHashes[prfHashAlgorithm]); + } + + public virtual byte[] GetFinalHash(byte hashAlgorithm) + { + IDigest d = (IDigest)mHashes[hashAlgorithm]; + if (d == null) + throw new InvalidOperationException("HashAlgorithm." + HashAlgorithm.GetText(hashAlgorithm) + " is not being tracked"); + + d = TlsUtilities.CloneHash(hashAlgorithm, d); + if (mBuf != null) + { + mBuf.UpdateDigest(d); + } + + return DigestUtilities.DoFinal(d); + } + + public virtual string AlgorithmName + { + get { throw new InvalidOperationException("Use Fork() to get a definite IDigest"); } + } + + public virtual int GetByteLength() + { + throw new InvalidOperationException("Use Fork() to get a definite IDigest"); + } + + public virtual int GetDigestSize() + { + throw new InvalidOperationException("Use Fork() to get a definite IDigest"); + } + + public virtual void Update(byte input) + { + if (mBuf != null) + { + mBuf.WriteByte(input); + return; + } + + foreach (IDigest hash in mHashes.Values) + { + hash.Update(input); + } + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + if (mBuf != null) + { + mBuf.Write(input, inOff, len); + return; + } + + foreach (IDigest hash in mHashes.Values) + { + hash.BlockUpdate(input, inOff, len); + } + } + + public virtual int DoFinal(byte[] output, int outOff) + { + throw new InvalidOperationException("Use Fork() to get a definite IDigest"); + } + + public virtual void Reset() + { + if (mBuf != null) + { + mBuf.SetLength(0); + return; + } + + foreach (IDigest hash in mHashes.Values) + { + hash.Reset(); + } + } + + protected virtual void CheckStopBuffering() + { + if (mBuf != null && mHashes.Count <= BUFFERING_HASH_LIMIT) + { + foreach (IDigest hash in mHashes.Values) + { + mBuf.UpdateDigest(hash); + } + + this.mBuf = null; + } + } + + protected virtual void CheckTrackingHash(byte hashAlgorithm) + { + if (!mHashes.Contains(hashAlgorithm)) + { + IDigest hash = TlsUtilities.CreateHash(hashAlgorithm); + mHashes[hashAlgorithm] = hash; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs.meta new file mode 100644 index 0000000..59e8b90 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DeferredHash.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 35244b3409862df4fb244db83d469188 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs new file mode 100644 index 0000000..463b24b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class DigestInputBuffer + : MemoryStream + { + internal void UpdateDigest(IDigest d) + { + WriteTo(new DigStream(d)); + } + + private class DigStream + : BaseOutputStream + { + private readonly IDigest d; + + internal DigStream(IDigest d) + { + this.d = d; + } + + public override void WriteByte(byte b) + { + d.Update(b); + } + + public override void Write(byte[] buf, int off, int len) + { + d.BlockUpdate(buf, off, len); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs.meta new file mode 100644 index 0000000..e956f6f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigestInputBuffer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7407d2712d4fe2c489e6c3374c52d797 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs new file mode 100644 index 0000000..2588d71 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs @@ -0,0 +1,74 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DigitallySigned + { + protected readonly SignatureAndHashAlgorithm mAlgorithm; + protected readonly byte[] mSignature; + + public DigitallySigned(SignatureAndHashAlgorithm algorithm, byte[] signature) + { + if (signature == null) + throw new ArgumentNullException("signature"); + + this.mAlgorithm = algorithm; + this.mSignature = signature; + } + + /** + * @return a {@link SignatureAndHashAlgorithm} (or null before TLS 1.2). + */ + public virtual SignatureAndHashAlgorithm Algorithm + { + get { return mAlgorithm; } + } + + public virtual byte[] Signature + { + get { return mSignature; } + } + + /** + * Encode this {@link DigitallySigned} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + if (mAlgorithm != null) + { + mAlgorithm.Encode(output); + } + TlsUtilities.WriteOpaque16(mSignature, output); + } + + /** + * Parse a {@link DigitallySigned} from a {@link Stream}. + * + * @param context + * the {@link TlsContext} of the current connection. + * @param input + * the {@link Stream} to parse from. + * @return a {@link DigitallySigned} object. + * @throws IOException + */ + public static DigitallySigned Parse(TlsContext context, Stream input) + { + SignatureAndHashAlgorithm algorithm = null; + if (TlsUtilities.IsTlsV12(context)) + { + algorithm = SignatureAndHashAlgorithm.Parse(input); + } + byte[] signature = TlsUtilities.ReadOpaque16(input); + return new DigitallySigned(algorithm, signature); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs.meta new file mode 100644 index 0000000..20d1205 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/DigitallySigned.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b20d78f9aa88ca2469189563d7403921 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs new file mode 100644 index 0000000..90b848d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 4492 5.4. (Errata ID: 2389) + public abstract class ECBasisType + { + public const byte ec_basis_trinomial = 1; + public const byte ec_basis_pentanomial = 2; + + public static bool IsValid(byte ecBasisType) + { + return ecBasisType >= ec_basis_trinomial && ecBasisType <= ec_basis_pentanomial; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs.meta new file mode 100644 index 0000000..75b8ec8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECBasisType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1b1a05facdad16f4a94480843b47056f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs new file mode 100644 index 0000000..496688d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 4492 5.4 + /// + public abstract class ECCurveType + { + /** + * Indicates the elliptic curve domain parameters are conveyed verbosely, and the + * underlying finite field is a prime field. + */ + public const byte explicit_prime = 1; + + /** + * Indicates the elliptic curve domain parameters are conveyed verbosely, and the + * underlying finite field is a characteristic-2 field. + */ + public const byte explicit_char2 = 2; + + /** + * Indicates that a named curve is used. This option SHOULD be used when applicable. + */ + public const byte named_curve = 3; + + /* + * Values 248 through 255 are reserved for private use. + */ + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs.meta new file mode 100644 index 0000000..c2fde26 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECCurveType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9b54ca1f2b1231a41b6c9e4a87e85d40 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs new file mode 100644 index 0000000..f52e475 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 4492 5.1.2 + /// + public abstract class ECPointFormat + { + public const byte uncompressed = 0; + public const byte ansiX962_compressed_prime = 1; + public const byte ansiX962_compressed_char2 = 2; + + /* + * reserved (248..255) + */ + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs.meta new file mode 100644 index 0000000..fa63487 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ECPointFormat.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fc8629ffdb3eafc41b5f8070a55e0bfe +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs new file mode 100644 index 0000000..d6889f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs @@ -0,0 +1,74 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class EncryptionAlgorithm + { + public const int NULL = 0; + public const int RC4_40 = 1; + public const int RC4_128 = 2; + public const int RC2_CBC_40 = 3; + public const int IDEA_CBC = 4; + public const int DES40_CBC = 5; + public const int DES_CBC = 6; + public const int cls_3DES_EDE_CBC = 7; + + /* + * RFC 3268 + */ + public const int AES_128_CBC = 8; + public const int AES_256_CBC = 9; + + /* + * RFC 5289 + */ + public const int AES_128_GCM = 10; + public const int AES_256_GCM = 11; + + /* + * RFC 4132 + */ + public const int CAMELLIA_128_CBC = 12; + public const int CAMELLIA_256_CBC = 13; + + /* + * RFC 4162 + */ + public const int SEED_CBC = 14; + + /* + * RFC 6655 + */ + public const int AES_128_CCM = 15; + public const int AES_128_CCM_8 = 16; + public const int AES_256_CCM = 17; + public const int AES_256_CCM_8 = 18; + + /* + * RFC 6367 + */ + public const int CAMELLIA_128_GCM = 19; + public const int CAMELLIA_256_GCM = 20; + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + public const int CHACHA20_POLY1305 = 102; + [Obsolete] public const int AEAD_CHACHA20_POLY1305 = CHACHA20_POLY1305; + + /* + * draft-zauner-tls-aes-ocb-04 + */ + public const int AES_128_OCB_TAGLEN96 = 103; + public const int AES_256_OCB_TAGLEN96 = 104; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs.meta new file mode 100644 index 0000000..d47eed0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/EncryptionAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9e20fa3a265e9c24392f009daf9ecae0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs new file mode 100644 index 0000000..a2b1027 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs @@ -0,0 +1,41 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 5705 + public abstract class ExporterLabel + { + /* + * RFC 5246 + */ + public const string client_finished = "client finished"; + public const string server_finished = "server finished"; + public const string master_secret = "master secret"; + public const string key_expansion = "key expansion"; + + /* + * RFC 5216 + */ + public const string client_EAP_encryption = "client EAP encryption"; + + /* + * RFC 5281 + */ + public const string ttls_keying_material = "ttls keying material"; + public const string ttls_challenge = "ttls challenge"; + + /* + * RFC 5764 + */ + public const string dtls_srtp = "EXTRACTOR-dtls_srtp"; + + /* + * draft-ietf-tls-session-hash-04 + */ + public static readonly string extended_master_secret = "extended master secret"; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs.meta new file mode 100644 index 0000000..62d3f38 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExporterLabel.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 34fbb70e28322eb4b9250222336ef88b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs new file mode 100644 index 0000000..1093c5c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs @@ -0,0 +1,121 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ExtensionType + { + /* + * RFC 2546 2.3. + */ + public const int server_name = 0; + public const int max_fragment_length = 1; + public const int client_certificate_url = 2; + public const int trusted_ca_keys = 3; + public const int truncated_hmac = 4; + public const int status_request = 5; + + /* + * RFC 4681 + */ + public const int user_mapping = 6; + + /* + * RFC 5878 + */ + public const int client_authz = 7; + public const int server_authz = 8; + + /* + * RFC RFC6091 + */ + public const int cert_type = 9; + + /* + * draft-ietf-tls-negotiated-ff-dhe-10 + */ + public const int supported_groups = 10; + + /* + * RFC 4492 5.1. + */ + public const int elliptic_curves = supported_groups; + public const int ec_point_formats = 11; + + /* + * RFC 5054 2.8.1. + */ + public const int srp = 12; + + /* + * RFC 5246 7.4.1.4. + */ + public const int signature_algorithms = 13; + + /* + * RFC 5764 9. + */ + public const int use_srtp = 14; + + /* + * RFC 6520 6. + */ + public const int heartbeat = 15; + + /* + * RFC 7301 + */ + public const int application_layer_protocol_negotiation = 16; + + /* + * RFC 6961 + */ + public const int status_request_v2 = 17; + + /* + * RFC 6962 + */ + public const int signed_certificate_timestamp = 18; + + /* + * RFC 7250 + */ + public const int client_certificate_type = 19; + public const int server_certificate_type = 20; + + /* + * RFC 7685 + */ + public const int padding = 21; + + /* + * RFC 7366 + */ + public const int encrypt_then_mac = 22; + + /* + * RFC 7627 + */ + public const int extended_master_secret = 23; + + /* + * RFC 5077 7. + */ + public const int session_ticket = 35; + + /* + * draft-ietf-tls-negotiated-ff-dhe-01 + * + * WARNING: Placeholder value; the real value is TBA + */ + public static readonly int negotiated_ff_dhe_groups = 101; + + /* + * RFC 5746 3.2. + */ + public const int renegotiation_info = 0xff01; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs.meta new file mode 100644 index 0000000..10dc1a6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ExtensionType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7df2068c8808c2f4a800c4c052ca8475 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs new file mode 100644 index 0000000..7a3d722 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs @@ -0,0 +1,25 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * draft-ietf-tls-negotiated-ff-dhe-01 + */ + public abstract class FiniteFieldDheGroup + { + public const byte ffdhe2432 = 0; + public const byte ffdhe3072 = 1; + public const byte ffdhe4096 = 2; + public const byte ffdhe6144 = 3; + public const byte ffdhe8192 = 4; + + public static bool IsValid(byte group) + { + return group >= ffdhe2432 && group <= ffdhe8192; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs.meta new file mode 100644 index 0000000..ef6bac3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/FiniteFieldDheGroup.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 09266df25d9c9be45ba30131f8aa1fa6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs new file mode 100644 index 0000000..3b855b1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class HandshakeType + { + /* + * RFC 2246 7.4 + */ + public const byte hello_request = 0; + public const byte client_hello = 1; + public const byte server_hello = 2; + public const byte certificate = 11; + public const byte server_key_exchange = 12; + public const byte certificate_request = 13; + public const byte server_hello_done = 14; + public const byte certificate_verify = 15; + public const byte client_key_exchange = 16; + public const byte finished = 20; + + /* + * RFC 3546 2.4 + */ + public const byte certificate_url = 21; + public const byte certificate_status = 22; + + /* + * (DTLS) RFC 4347 4.3.2 + */ + public const byte hello_verify_request = 3; + + /* + * RFC 4680 + */ + public const byte supplemental_data = 23; + + /* + * RFC 5077 + */ + public const byte session_ticket = 4; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs.meta new file mode 100644 index 0000000..d4040b3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HandshakeType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 632f3a4fb7f86914b9b9f4aa22501b69 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs new file mode 100644 index 0000000..f6b62d9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs @@ -0,0 +1,53 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 5246 7.4.1.4.1 + public abstract class HashAlgorithm + { + public const byte none = 0; + public const byte md5 = 1; + public const byte sha1 = 2; + public const byte sha224 = 3; + public const byte sha256 = 4; + public const byte sha384 = 5; + public const byte sha512 = 6; + + public static string GetName(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case none: + return "none"; + case md5: + return "md5"; + case sha1: + return "sha1"; + case sha224: + return "sha224"; + case sha256: + return "sha256"; + case sha384: + return "sha384"; + case sha512: + return "sha512"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(byte hashAlgorithm) + { + return GetName(hashAlgorithm) + "(" + hashAlgorithm + ")"; + } + + public static bool IsPrivate(byte hashAlgorithm) + { + return 224 <= hashAlgorithm && hashAlgorithm <= 255; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs.meta new file mode 100644 index 0000000..5669b71 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HashAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 677ef3b9d573f1a47b3ba5afe6247d04 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs new file mode 100644 index 0000000..2e67b73 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs @@ -0,0 +1,56 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class HeartbeatExtension + { + protected readonly byte mMode; + + public HeartbeatExtension(byte mode) + { + if (!HeartbeatMode.IsValid(mode)) + throw new ArgumentException("not a valid HeartbeatMode value", "mode"); + + this.mMode = mode; + } + + public virtual byte Mode + { + get { return mMode; } + } + + /** + * Encode this {@link HeartbeatExtension} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mMode, output); + } + + /** + * Parse a {@link HeartbeatExtension} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link HeartbeatExtension} object. + * @throws IOException + */ + public static HeartbeatExtension Parse(Stream input) + { + byte mode = TlsUtilities.ReadUint8(input); + if (!HeartbeatMode.IsValid(mode)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return new HeartbeatExtension(mode); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs.meta new file mode 100644 index 0000000..ad14c48 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatExtension.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 475dad59ffa979641afb6ad8d395452b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs new file mode 100644 index 0000000..1f65754 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs @@ -0,0 +1,22 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 6520 3. + */ + public abstract class HeartbeatMessageType + { + public const byte heartbeat_request = 1; + public const byte heartbeat_response = 2; + + public static bool IsValid(byte heartbeatMessageType) + { + return heartbeatMessageType >= heartbeat_request && heartbeatMessageType <= heartbeat_response; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs.meta new file mode 100644 index 0000000..2a6dd3c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMessageType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f965165b59c150647a20d1f184e4bf13 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs new file mode 100644 index 0000000..c4fe8c3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs @@ -0,0 +1,22 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 6520 + */ + public abstract class HeartbeatMode + { + public const byte peer_allowed_to_send = 1; + public const byte peer_not_allowed_to_send = 2; + + public static bool IsValid(byte heartbeatMode) + { + return heartbeatMode >= peer_allowed_to_send && heartbeatMode <= peer_not_allowed_to_send; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs.meta new file mode 100644 index 0000000..3f5f9b4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/HeartbeatMode.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6eeaea474b6dc2e489b340a6094c6303 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs new file mode 100644 index 0000000..6e43c81 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs @@ -0,0 +1,23 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// This should be implemented by any class which can find out, if a given + /// certificate chain is being accepted by an client. + /// + //[Obsolete("Perform certificate verification in TlsAuthentication implementation")] + public interface ICertificateVerifyer + { + /// The certs, which are part of the chain. + /// + /// True, if the chain is accepted, false otherwise + bool IsValid(Uri targetUri, X509CertificateStructure[] certs); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs.meta new file mode 100644 index 0000000..079052d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ICertificateVerifyer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 465a068f75e92f548888150b2f6eb745 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs new file mode 100644 index 0000000..7de4756 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs @@ -0,0 +1,58 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class KeyExchangeAlgorithm + { + public const int NULL = 0; + public const int RSA = 1; + public const int RSA_EXPORT = 2; + public const int DHE_DSS = 3; + public const int DHE_DSS_EXPORT = 4; + public const int DHE_RSA = 5; + public const int DHE_RSA_EXPORT = 6; + public const int DH_DSS = 7; + public const int DH_DSS_EXPORT = 8; + public const int DH_RSA = 9; + public const int DH_RSA_EXPORT = 10; + public const int DH_anon = 11; + public const int DH_anon_EXPORT = 12; + + /* + * RFC 4279 + */ + public const int PSK = 13; + public const int DHE_PSK = 14; + public const int RSA_PSK = 15; + + /* + * RFC 4429 + */ + public const int ECDH_ECDSA = 16; + public const int ECDHE_ECDSA = 17; + public const int ECDH_RSA = 18; + public const int ECDHE_RSA = 19; + public const int ECDH_anon = 20; + + /* + * RFC 5054 + */ + public const int SRP = 21; + public const int SRP_DSS = 22; + public const int SRP_RSA = 23; + + /* + * RFC 5489 + */ + public const int ECDHE_PSK = 24; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs.meta new file mode 100644 index 0000000..02e752b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/KeyExchangeAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3ec31da934849f4459d2c54c67c5f005 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs new file mode 100644 index 0000000..970d39d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs @@ -0,0 +1,41 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface IClientCredentialsProvider + { + TlsCredentials GetClientCredentials(TlsContext context, CertificateRequest certificateRequest); + } + + /// + /// A temporary class to wrap old CertificateVerifyer stuff for new TlsAuthentication. + /// + public class LegacyTlsAuthentication : TlsAuthentication + { + protected ICertificateVerifyer verifyer; + protected IClientCredentialsProvider credProvider; + protected Uri TargetUri; + + public LegacyTlsAuthentication(Uri targetUri, ICertificateVerifyer verifyer, IClientCredentialsProvider prov) + { + this.TargetUri = targetUri; + this.verifyer = verifyer; + this.credProvider = prov; + } + + public virtual void NotifyServerCertificate(Certificate serverCertificate) + { + if (!this.verifyer.IsValid(this.TargetUri, serverCertificate.GetCertificateList())) + throw new TlsFatalAlert(AlertDescription.user_canceled); + } + + public virtual TlsCredentials GetClientCredentials(TlsContext context, CertificateRequest certificateRequest) + { + return credProvider == null ? null : credProvider.GetClientCredentials(context, certificateRequest); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs.meta new file mode 100644 index 0000000..960ae11 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsAuthentication.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 29f19780ecc147b438fce5295a3e33e3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs new file mode 100644 index 0000000..758b1b0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs @@ -0,0 +1,31 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A temporary class to use LegacyTlsAuthentication + /// + public sealed class LegacyTlsClient : DefaultTlsClient + { + private readonly Uri TargetUri; + private readonly ICertificateVerifyer verifyer; + private readonly IClientCredentialsProvider credProvider; + + public LegacyTlsClient(Uri targetUri, ICertificateVerifyer verifyer, IClientCredentialsProvider prov, System.Collections.Generic.List hostNames) + { + this.TargetUri = targetUri; + this.verifyer = verifyer; + this.credProvider = prov; + this.HostNames = hostNames; + } + + public override TlsAuthentication GetAuthentication() + { + return new LegacyTlsAuthentication(this.TargetUri, verifyer, credProvider); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs.meta new file mode 100644 index 0000000..f1446c8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/LegacyTlsClient.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4bf15149a6a8caa41b57915a4adbea21 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs new file mode 100644 index 0000000..836dbba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs @@ -0,0 +1,29 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class MacAlgorithm + { + public const int cls_null = 0; + public const int md5 = 1; + public const int sha = 2; + + /* + * RFC 5246 + */ + public const int hmac_md5 = md5; + public const int hmac_sha1 = sha; + public const int hmac_sha256 = 3; + public const int hmac_sha384 = 4; + public const int hmac_sha512 = 5; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs.meta new file mode 100644 index 0000000..9bdf1ff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MacAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0097a03fc57753c40931a7c115b2df0e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs new file mode 100644 index 0000000..7efb2dd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class MaxFragmentLength + { + /* + * RFC 3546 3.2. + */ + public const byte pow2_9 = 1; + public const byte pow2_10 = 2; + public const byte pow2_11 = 3; + public const byte pow2_12 = 4; + + public static bool IsValid(byte maxFragmentLength) + { + return maxFragmentLength >= pow2_9 && maxFragmentLength <= pow2_12; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs.meta new file mode 100644 index 0000000..4055859 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/MaxFragmentLength.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8fe16c772a3380242beabd576ef7e256 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs new file mode 100644 index 0000000..d6f7caf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class NameType + { + /* + * RFC 3546 3.1. + */ + public const byte host_name = 0; + + public static bool IsValid(byte nameType) + { + return nameType == host_name; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs.meta new file mode 100644 index 0000000..9c13e22 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NameType.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f309541f5f97b9d4fbf72b2311ffbd25 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs new file mode 100644 index 0000000..ed32891 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 4492 5.1.1 + /// The named curves defined here are those specified in SEC 2 [13]. Note that many of + /// these curves are also recommended in ANSI X9.62 [7] and FIPS 186-2 [11]. Values 0xFE00 + /// through 0xFEFF are reserved for private use. Values 0xFF01 and 0xFF02 indicate that the + /// client supports arbitrary prime and characteristic-2 curves, respectively (the curve + /// parameters must be encoded explicitly in ECParameters). + /// + public abstract class NamedCurve + { + public const int sect163k1 = 1; + public const int sect163r1 = 2; + public const int sect163r2 = 3; + public const int sect193r1 = 4; + public const int sect193r2 = 5; + public const int sect233k1 = 6; + public const int sect233r1 = 7; + public const int sect239k1 = 8; + public const int sect283k1 = 9; + public const int sect283r1 = 10; + public const int sect409k1 = 11; + public const int sect409r1 = 12; + public const int sect571k1 = 13; + public const int sect571r1 = 14; + public const int secp160k1 = 15; + public const int secp160r1 = 16; + public const int secp160r2 = 17; + public const int secp192k1 = 18; + public const int secp192r1 = 19; + public const int secp224k1 = 20; + public const int secp224r1 = 21; + public const int secp256k1 = 22; + public const int secp256r1 = 23; + public const int secp384r1 = 24; + public const int secp521r1 = 25; + + /* + * RFC 7027 + */ + public const int brainpoolP256r1 = 26; + public const int brainpoolP384r1 = 27; + public const int brainpoolP512r1 = 28; + + /* + * reserved (0xFE00..0xFEFF) + */ + + public const int arbitrary_explicit_prime_curves = 0xFF01; + public const int arbitrary_explicit_char2_curves = 0xFF02; + + public static bool IsValid(int namedCurve) + { + return (namedCurve >= sect163k1 && namedCurve <= brainpoolP512r1) + || (namedCurve >= arbitrary_explicit_prime_curves && namedCurve <= arbitrary_explicit_char2_curves); + } + + public static bool RefersToASpecificNamedCurve(int namedCurve) + { + switch (namedCurve) + { + case arbitrary_explicit_prime_curves: + case arbitrary_explicit_char2_curves: + return false; + default: + return true; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs.meta new file mode 100644 index 0000000..7b38c54 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NamedCurve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ea610a144bac59e4692df166bac37dd8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs new file mode 100644 index 0000000..644dabb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs @@ -0,0 +1,57 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class NewSessionTicket + { + protected readonly long mTicketLifetimeHint; + protected readonly byte[] mTicket; + + public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) + { + this.mTicketLifetimeHint = ticketLifetimeHint; + this.mTicket = ticket; + } + + public virtual long TicketLifetimeHint + { + get { return mTicketLifetimeHint; } + } + + public virtual byte[] Ticket + { + get { return mTicket; } + } + + /** + * Encode this {@link NewSessionTicket} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint32(mTicketLifetimeHint, output); + TlsUtilities.WriteOpaque16(mTicket, output); + } + + /** + * Parse a {@link NewSessionTicket} from a {@link Stream}. + * + * @param input the {@link Stream} to parse from. + * @return a {@link NewSessionTicket} object. + * @throws IOException + */ + public static NewSessionTicket Parse(Stream input) + { + long ticketLifetimeHint = TlsUtilities.ReadUint32(input); + byte[] ticket = TlsUtilities.ReadOpaque16(input); + return new NewSessionTicket(ticketLifetimeHint, ticket); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs.meta new file mode 100644 index 0000000..0237e6b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/NewSessionTicket.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 93abceb59e82eb9418fd94289540c1bf +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs new file mode 100644 index 0000000..d66763a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs @@ -0,0 +1,134 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 3546 3.6 + */ + public class OcspStatusRequest + { + protected readonly IList mResponderIDList; + protected readonly X509Extensions mRequestExtensions; + + /** + * @param responderIDList + * an {@link IList} of {@link ResponderID}, specifying the list of trusted OCSP + * responders. An empty list has the special meaning that the responders are + * implicitly known to the server - e.g., by prior arrangement. + * @param requestExtensions + * OCSP request extensions. A null value means that there are no extensions. + */ + public OcspStatusRequest(IList responderIDList, X509Extensions requestExtensions) + { + this.mResponderIDList = responderIDList; + this.mRequestExtensions = requestExtensions; + } + + /** + * @return an {@link IList} of {@link ResponderID} + */ + public virtual IList ResponderIDList + { + get { return mResponderIDList; } + } + + /** + * @return OCSP request extensions + */ + public virtual X509Extensions RequestExtensions + { + get { return mRequestExtensions; } + } + + /** + * Encode this {@link OcspStatusRequest} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + if (mResponderIDList == null || mResponderIDList.Count < 1) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + MemoryStream buf = new MemoryStream(); + for (int i = 0; i < mResponderIDList.Count; ++i) + { + ResponderID responderID = (ResponderID)mResponderIDList[i]; + byte[] derEncoding = responderID.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque16(derEncoding, buf); + } + TlsUtilities.CheckUint16(buf.Length); + TlsUtilities.WriteUint16((int)buf.Length, output); + buf.WriteTo(output); + } + + if (mRequestExtensions == null) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + byte[] derEncoding = mRequestExtensions.GetEncoded(Asn1Encodable.Der); + TlsUtilities.CheckUint16(derEncoding.Length); + TlsUtilities.WriteUint16(derEncoding.Length, output); + output.Write(derEncoding, 0, derEncoding.Length); + } + } + + /** + * Parse a {@link OcspStatusRequest} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return an {@link OcspStatusRequest} object. + * @throws IOException + */ + public static OcspStatusRequest Parse(Stream input) + { + IList responderIDList = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + { + int length = TlsUtilities.ReadUint16(input); + if (length > 0) + { + byte[] data = TlsUtilities.ReadFully(length, input); + MemoryStream buf = new MemoryStream(data, false); + do + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(buf); + ResponderID responderID = ResponderID.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + responderIDList.Add(responderID); + } + while (buf.Position < buf.Length); + } + } + + X509Extensions requestExtensions = null; + { + int length = TlsUtilities.ReadUint16(input); + if (length > 0) + { + byte[] derEncoding = TlsUtilities.ReadFully(length, input); + requestExtensions = X509Extensions.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + } + } + + return new OcspStatusRequest(responderIDList, requestExtensions); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs.meta new file mode 100644 index 0000000..97f97ad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/OcspStatusRequest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2eb26ad027843b746b3453768e6c5ac5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs new file mode 100644 index 0000000..b6f92f9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 5246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class PrfAlgorithm + { + /* + * Placeholder to refer to the legacy TLS algorithm + */ + public const int tls_prf_legacy = 0; + + public const int tls_prf_sha256 = 1; + + /* + * Implied by RFC 5288 + */ + public const int tls_prf_sha384 = 2; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs.meta new file mode 100644 index 0000000..3f6d092 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/PrfAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a3a280a86cd18384c9650c60935f3f4f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs new file mode 100644 index 0000000..8be29fc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs @@ -0,0 +1,163 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public sealed class ProtocolVersion + { + public static readonly ProtocolVersion SSLv3 = new ProtocolVersion(0x0300, "SSL 3.0"); + public static readonly ProtocolVersion TLSv10 = new ProtocolVersion(0x0301, "TLS 1.0"); + public static readonly ProtocolVersion TLSv11 = new ProtocolVersion(0x0302, "TLS 1.1"); + public static readonly ProtocolVersion TLSv12 = new ProtocolVersion(0x0303, "TLS 1.2"); + public static readonly ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0"); + public static readonly ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2"); + + private readonly int version; + private readonly String name; + + private ProtocolVersion(int v, String name) + { + this.version = v & 0xffff; + this.name = name; + } + + public int FullVersion + { + get { return version; } + } + + public int MajorVersion + { + get { return version >> 8; } + } + + public int MinorVersion + { + get { return version & 0xff; } + } + + public bool IsDtls + { + get { return MajorVersion == 0xFE; } + } + + public bool IsSsl + { + get { return this == SSLv3; } + } + + public bool IsTls + { + get { return MajorVersion == 0x03; } + } + + public ProtocolVersion GetEquivalentTLSVersion() + { + if (!IsDtls) + { + return this; + } + if (this == DTLSv10) + { + return TLSv11; + } + return TLSv12; + } + + public bool IsEqualOrEarlierVersionOf(ProtocolVersion version) + { + if (MajorVersion != version.MajorVersion) + { + return false; + } + int diffMinorVersion = version.MinorVersion - MinorVersion; + return IsDtls ? diffMinorVersion <= 0 : diffMinorVersion >= 0; + } + + public bool IsLaterVersionOf(ProtocolVersion version) + { + if (MajorVersion != version.MajorVersion) + { + return false; + } + int diffMinorVersion = version.MinorVersion - MinorVersion; + return IsDtls ? diffMinorVersion > 0 : diffMinorVersion < 0; + } + + public override bool Equals(object other) + { + return this == other || (other is ProtocolVersion && Equals((ProtocolVersion)other)); + } + + public bool Equals(ProtocolVersion other) + { + return other != null && this.version == other.version; + } + + public override int GetHashCode() + { + return version; + } + + /// + public static ProtocolVersion Get(int major, int minor) + { + switch (major) + { + case 0x03: + { + switch (minor) + { + case 0x00: + return SSLv3; + case 0x01: + return TLSv10; + case 0x02: + return TLSv11; + case 0x03: + return TLSv12; + } + return GetUnknownVersion(major, minor, "TLS"); + } + case 0xFE: + { + switch (minor) + { + case 0xFF: + return DTLSv10; + case 0xFE: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + case 0xFD: + return DTLSv12; + } + return GetUnknownVersion(major, minor, "DTLS"); + } + default: + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override string ToString() + { + return name; + } + + private static ProtocolVersion GetUnknownVersion(int major, int minor, string prefix) + { + TlsUtilities.CheckUint8(major); + TlsUtilities.CheckUint8(minor); + + int v = (major << 8) | minor; + String hex = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(Convert.ToString(0x10000 | v, 16).Substring(1)); + return new ProtocolVersion(v, prefix + " 0x" + hex); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs.meta new file mode 100644 index 0000000..cde879e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ProtocolVersion.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b6379f9b46678ef4b942095480ee3e36 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs new file mode 100644 index 0000000..746ed2c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs @@ -0,0 +1,344 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// An implementation of the TLS 1.0/1.1/1.2 record layer, allowing downgrade to SSLv3. + internal class RecordStream + { + private const int DEFAULT_PLAINTEXT_LIMIT = (1 << 14); + + internal const int TLS_HEADER_SIZE = 5; + internal const int TLS_HEADER_TYPE_OFFSET = 0; + internal const int TLS_HEADER_VERSION_OFFSET = 1; + internal const int TLS_HEADER_LENGTH_OFFSET = 3; + + private TlsProtocol mHandler; + private Stream mInput; + private Stream mOutput; + private TlsCompression mPendingCompression = null, mReadCompression = null, mWriteCompression = null; + private TlsCipher mPendingCipher = null, mReadCipher = null, mWriteCipher = null; + private long mReadSeqNo = 0, mWriteSeqNo = 0; + private MemoryStream mBuffer = new MemoryStream(); + + private TlsHandshakeHash mHandshakeHash = null; + + private ProtocolVersion mReadVersion = null, mWriteVersion = null; + private bool mRestrictReadVersion = true; + + private int mPlaintextLimit, mCompressedLimit, mCiphertextLimit; + + internal RecordStream(TlsProtocol handler, Stream input, Stream output) + { + this.mHandler = handler; + this.mInput = input; + this.mOutput = output; + this.mReadCompression = new TlsNullCompression(); + this.mWriteCompression = this.mReadCompression; + } + + internal virtual void Init(TlsContext context) + { + this.mReadCipher = new TlsNullCipher(context); + this.mWriteCipher = this.mReadCipher; + this.mHandshakeHash = new DeferredHash(); + this.mHandshakeHash.Init(context); + + SetPlaintextLimit(DEFAULT_PLAINTEXT_LIMIT); + } + + internal virtual int GetPlaintextLimit() + { + return mPlaintextLimit; + } + + internal virtual void SetPlaintextLimit(int plaintextLimit) + { + this.mPlaintextLimit = plaintextLimit; + this.mCompressedLimit = this.mPlaintextLimit + 1024; + this.mCiphertextLimit = this.mCompressedLimit + 1024; + } + + internal virtual ProtocolVersion ReadVersion + { + get { return mReadVersion; } + set { this.mReadVersion = value; } + } + + internal virtual void SetWriteVersion(ProtocolVersion writeVersion) + { + this.mWriteVersion = writeVersion; + } + + /** + * RFC 5246 E.1. "Earlier versions of the TLS specification were not fully clear on what the + * record layer version number (TLSPlaintext.version) should contain when sending ClientHello + * (i.e., before it is known which version of the protocol will be employed). Thus, TLS servers + * compliant with this specification MUST accept any value {03,XX} as the record layer version + * number for ClientHello." + */ + internal virtual void SetRestrictReadVersion(bool enabled) + { + this.mRestrictReadVersion = enabled; + } + + internal virtual void SetPendingConnectionState(TlsCompression tlsCompression, TlsCipher tlsCipher) + { + this.mPendingCompression = tlsCompression; + this.mPendingCipher = tlsCipher; + } + + internal virtual void SentWriteCipherSpec() + { + if (mPendingCompression == null || mPendingCipher == null) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + this.mWriteCompression = this.mPendingCompression; + this.mWriteCipher = this.mPendingCipher; + this.mWriteSeqNo = 0; + } + + internal virtual void ReceivedReadCipherSpec() + { + if (mPendingCompression == null || mPendingCipher == null) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + this.mReadCompression = this.mPendingCompression; + this.mReadCipher = this.mPendingCipher; + this.mReadSeqNo = 0; + } + + internal virtual void FinaliseHandshake() + { + if (mReadCompression != mPendingCompression || mWriteCompression != mPendingCompression + || mReadCipher != mPendingCipher || mWriteCipher != mPendingCipher) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + this.mPendingCompression = null; + this.mPendingCipher = null; + } + + internal virtual bool ReadRecord() + { + byte[] recordHeader = TlsUtilities.ReadAllOrNothing(TLS_HEADER_SIZE, mInput); + if (recordHeader == null) + return false; + + byte type = TlsUtilities.ReadUint8(recordHeader, TLS_HEADER_TYPE_OFFSET); + + /* + * RFC 5246 6. If a TLS implementation receives an unexpected record type, it MUST send an + * unexpected_message alert. + */ + CheckType(type, AlertDescription.unexpected_message); + + if (!mRestrictReadVersion) + { + int version = TlsUtilities.ReadVersionRaw(recordHeader, TLS_HEADER_VERSION_OFFSET); + if ((version & 0xffffff00) != 0x0300) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + else + { + ProtocolVersion version = TlsUtilities.ReadVersion(recordHeader, TLS_HEADER_VERSION_OFFSET); + if (mReadVersion == null) + { + mReadVersion = version; + } + else if (!version.Equals(mReadVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + int length = TlsUtilities.ReadUint16(recordHeader, TLS_HEADER_LENGTH_OFFSET); + byte[] plaintext = DecodeAndVerify(type, mInput, length); + mHandler.ProcessRecord(type, plaintext, 0, plaintext.Length); + return true; + } + + internal virtual byte[] DecodeAndVerify(byte type, Stream input, int len) + { + CheckLength(len, mCiphertextLimit, AlertDescription.record_overflow); + + byte[] buf = TlsUtilities.ReadFully(len, input); + byte[] decoded = mReadCipher.DecodeCiphertext(mReadSeqNo++, type, buf, 0, buf.Length); + + CheckLength(decoded.Length, mCompressedLimit, AlertDescription.record_overflow); + + /* + * TODO RFC5264 6.2.2. Implementation note: Decompression functions are responsible for + * ensuring that messages cannot cause internal buffer overflows. + */ + Stream cOut = mReadCompression.Decompress(mBuffer); + if (cOut != mBuffer) + { + cOut.Write(decoded, 0, decoded.Length); + cOut.Flush(); + decoded = GetBufferContents(); + } + + /* + * RFC 5264 6.2.2. If the decompression function encounters a TLSCompressed.fragment that + * would decompress to a length in excess of 2^14 bytes, it should report a fatal + * decompression failure error. + */ + CheckLength(decoded.Length, mPlaintextLimit, AlertDescription.decompression_failure); + + /* + * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (decoded.Length < 1 && type != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return decoded; + } + + internal virtual void WriteRecord(byte type, byte[] plaintext, int plaintextOffset, int plaintextLength) + { + // Never send anything until a valid ClientHello has been received + if (mWriteVersion == null) + return; + + /* + * RFC 5264 6. Implementations MUST NOT send record types not defined in this document + * unless negotiated by some extension. + */ + CheckType(type, AlertDescription.internal_error); + + /* + * RFC 5264 6.2.1 The length should not exceed 2^14. + */ + CheckLength(plaintextLength, mPlaintextLimit, AlertDescription.internal_error); + + /* + * RFC 5264 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (plaintextLength < 1 && type != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (type == ContentType.handshake) + { + UpdateHandshakeData(plaintext, plaintextOffset, plaintextLength); + } + + Stream cOut = mWriteCompression.Compress(mBuffer); + + byte[] ciphertext; + if (cOut == mBuffer) + { + ciphertext = mWriteCipher.EncodePlaintext(mWriteSeqNo++, type, plaintext, plaintextOffset, plaintextLength); + } + else + { + cOut.Write(plaintext, plaintextOffset, plaintextLength); + cOut.Flush(); + byte[] compressed = GetBufferContents(); + + /* + * RFC5264 6.2.2. Compression must be lossless and may not increase the content length + * by more than 1024 bytes. + */ + CheckLength(compressed.Length, plaintextLength + 1024, AlertDescription.internal_error); + + ciphertext = mWriteCipher.EncodePlaintext(mWriteSeqNo++, type, compressed, 0, compressed.Length); + } + + /* + * RFC 5264 6.2.3. The length may not exceed 2^14 + 2048. + */ + CheckLength(ciphertext.Length, mCiphertextLimit, AlertDescription.internal_error); + + byte[] record = new byte[ciphertext.Length + TLS_HEADER_SIZE]; + TlsUtilities.WriteUint8(type, record, TLS_HEADER_TYPE_OFFSET); + TlsUtilities.WriteVersion(mWriteVersion, record, TLS_HEADER_VERSION_OFFSET); + TlsUtilities.WriteUint16(ciphertext.Length, record, TLS_HEADER_LENGTH_OFFSET); + Array.Copy(ciphertext, 0, record, TLS_HEADER_SIZE, ciphertext.Length); + mOutput.Write(record, 0, record.Length); + mOutput.Flush(); + } + + internal virtual void NotifyHelloComplete() + { + this.mHandshakeHash = mHandshakeHash.NotifyPrfDetermined(); + } + + internal virtual TlsHandshakeHash HandshakeHash + { + get { return mHandshakeHash; } + } + + internal virtual TlsHandshakeHash PrepareToFinish() + { + TlsHandshakeHash result = mHandshakeHash; + this.mHandshakeHash = mHandshakeHash.StopTracking(); + return result; + } + + internal virtual void UpdateHandshakeData(byte[] message, int offset, int len) + { + mHandshakeHash.BlockUpdate(message, offset, len); + } + + internal virtual void SafeClose() + { + try + { + Org.BouncyCastle.Utilities.Platform.Dispose(mInput); + } + catch (IOException) + { + } + + try + { + Org.BouncyCastle.Utilities.Platform.Dispose(mOutput); + } + catch (IOException) + { + } + } + + internal virtual void Flush() + { + mOutput.Flush(); + } + + private byte[] GetBufferContents() + { + byte[] contents = mBuffer.ToArray(); + mBuffer.SetLength(0); + return contents; + } + + private static void CheckType(byte type, byte alertDescription) + { + switch (type) + { + case ContentType.application_data: + case ContentType.alert: + case ContentType.change_cipher_spec: + case ContentType.handshake: + case ContentType.heartbeat: + break; + default: + throw new TlsFatalAlert(alertDescription); + } + } + + private static void CheckLength(int length, int limit, byte alertDescription) + { + if (length > limit) + throw new TlsFatalAlert(alertDescription); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs.meta new file mode 100644 index 0000000..3772ab6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 31e36fd85b9d4fd4a99eb864a0ef112e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs new file mode 100644 index 0000000..fe7531e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs @@ -0,0 +1,107 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class SecurityParameters + { + internal int entity = -1; + internal int cipherSuite = -1; + internal byte compressionAlgorithm = CompressionMethod.cls_null; + internal int prfAlgorithm = -1; + internal int verifyDataLength = -1; + internal byte[] masterSecret = null; + internal byte[] clientRandom = null; + internal byte[] serverRandom = null; + internal byte[] sessionHash = null; + internal byte[] pskIdentity = null; + internal byte[] srpIdentity = null; + + // TODO Keep these internal, since it's maybe not the ideal place for them + internal short maxFragmentLength = -1; + internal bool truncatedHMac = false; + internal bool encryptThenMac = false; + internal bool extendedMasterSecret = false; + + internal virtual void Clear() + { + if (this.masterSecret != null) + { + Arrays.Fill(this.masterSecret, (byte)0); + this.masterSecret = null; + } + } + + /** + * @return {@link ConnectionEnd} + */ + public virtual int Entity + { + get { return entity; } + } + + /** + * @return {@link CipherSuite} + */ + public virtual int CipherSuite + { + get { return cipherSuite; } + } + + /** + * @return {@link CompressionMethod} + */ + public byte CompressionAlgorithm + { + get { return compressionAlgorithm; } + } + + /** + * @return {@link PRFAlgorithm} + */ + public virtual int PrfAlgorithm + { + get { return prfAlgorithm; } + } + + public virtual int VerifyDataLength + { + get { return verifyDataLength; } + } + + public virtual byte[] MasterSecret + { + get { return masterSecret; } + } + + public virtual byte[] ClientRandom + { + get { return clientRandom; } + } + + public virtual byte[] ServerRandom + { + get { return serverRandom; } + } + + public virtual byte[] SessionHash + { + get { return sessionHash; } + } + + public virtual byte[] PskIdentity + { + get { return pskIdentity; } + } + + public virtual byte[] SrpIdentity + { + get { return srpIdentity; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs.meta new file mode 100644 index 0000000..7608ca6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SecurityParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 052c0351b35336f4fbebef23e845bb71 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs new file mode 100644 index 0000000..ce62df9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs @@ -0,0 +1,65 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ServerDHParams + { + protected readonly DHPublicKeyParameters mPublicKey; + + public ServerDHParams(DHPublicKeyParameters publicKey) + { + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + + this.mPublicKey = publicKey; + } + + public virtual DHPublicKeyParameters PublicKey + { + get { return mPublicKey; } + } + + /** + * Encode this {@link ServerDHParams} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + DHParameters dhParameters = mPublicKey.Parameters; + BigInteger Ys = mPublicKey.Y; + + TlsDHUtilities.WriteDHParameter(dhParameters.P, output); + TlsDHUtilities.WriteDHParameter(dhParameters.G, output); + TlsDHUtilities.WriteDHParameter(Ys, output); + } + + /** + * Parse a {@link ServerDHParams} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link ServerDHParams} object. + * @throws IOException + */ + public static ServerDHParams Parse(Stream input) + { + BigInteger p = TlsDHUtilities.ReadDHParameter(input); + BigInteger g = TlsDHUtilities.ReadDHParameter(input); + BigInteger Ys = TlsDHUtilities.ReadDHParameter(input); + + return new ServerDHParams( + TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Ys, new DHParameters(p, g)))); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs.meta new file mode 100644 index 0000000..68f5308 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerDHParams.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 024e601395e71fd42adce6fab9995524 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs new file mode 100644 index 0000000..26451a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs @@ -0,0 +1,109 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ServerName + { + protected readonly byte mNameType; + protected readonly object mName; + + public ServerName(byte nameType, object name) + { + if (!IsCorrectType(nameType, name)) + throw new ArgumentException("not an instance of the correct type", "name"); + + this.mNameType = nameType; + this.mName = name; + } + + public virtual byte NameType + { + get { return mNameType; } + } + + public virtual object Name + { + get { return mName; } + } + + public virtual string GetHostName() + { + if (!IsCorrectType(Tls.NameType.host_name, mName)) + throw new InvalidOperationException("'name' is not a HostName string"); + + return (string)mName; + } + + /** + * Encode this {@link ServerName} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mNameType, output); + + switch (mNameType) + { + case Tls.NameType.host_name: + byte[] asciiEncoding = Strings.ToAsciiByteArray((string)mName); + if (asciiEncoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + TlsUtilities.WriteOpaque16(asciiEncoding, output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /** + * Parse a {@link ServerName} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link ServerName} object. + * @throws IOException + */ + public static ServerName Parse(Stream input) + { + byte name_type = TlsUtilities.ReadUint8(input); + object name; + + switch (name_type) + { + case Tls.NameType.host_name: + { + byte[] asciiEncoding = TlsUtilities.ReadOpaque16(input); + if (asciiEncoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + name = Strings.FromAsciiByteArray(asciiEncoding); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new ServerName(name_type, name); + } + + protected static bool IsCorrectType(byte nameType, object name) + { + switch (nameType) + { + case Tls.NameType.host_name: + return name is string; + default: + throw new ArgumentException("unsupported value", "name"); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs.meta new file mode 100644 index 0000000..a1f10b2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerName.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3df32b0fc4d3c734aa5301dd1b86ba0c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs new file mode 100644 index 0000000..aec7fea --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ServerNameList + { + protected readonly IList mServerNameList; + + /** + * @param serverNameList an {@link IList} of {@link ServerName}. + */ + public ServerNameList(IList serverNameList) + { + if (serverNameList == null) + throw new ArgumentNullException("serverNameList"); + + this.mServerNameList = serverNameList; + } + + /** + * @return an {@link IList} of {@link ServerName}. + */ + public virtual IList ServerNames + { + get { return mServerNameList; } + } + + /** + * Encode this {@link ServerNameList} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + MemoryStream buf = new MemoryStream(); + + byte[] nameTypesSeen = TlsUtilities.EmptyBytes; + foreach (ServerName entry in ServerNames) + { + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (nameTypesSeen == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + entry.Encode(buf); + } + + TlsUtilities.CheckUint16(buf.Length); + TlsUtilities.WriteUint16((int)buf.Length, output); + buf.WriteTo(output); + } + + /** + * Parse a {@link ServerNameList} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link ServerNameList} object. + * @throws IOException + */ + public static ServerNameList Parse(Stream input) + { + int length = TlsUtilities.ReadUint16(input); + if (length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] data = TlsUtilities.ReadFully(length, input); + + MemoryStream buf = new MemoryStream(data, false); + + byte[] nameTypesSeen = TlsUtilities.EmptyBytes; + IList server_name_list = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + ServerName entry = ServerName.Parse(buf); + + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (nameTypesSeen == null) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + server_name_list.Add(entry); + } + + return new ServerNameList(server_name_list); + } + + private static byte[] CheckNameType(byte[] nameTypesSeen, byte nameType) + { + /* + * RFC 6066 3. The ServerNameList MUST NOT contain more than one name of the same + * name_type. + */ + if (!NameType.IsValid(nameType) || Arrays.Contains(nameTypesSeen, nameType)) + return null; + + return Arrays.Append(nameTypesSeen, nameType); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs.meta new file mode 100644 index 0000000..aabad7c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/ServerNameList.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f1d3abc4e8e4859489773087e2c8f99a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs new file mode 100644 index 0000000..85536bf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs @@ -0,0 +1,169 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public sealed class SessionParameters + { + public sealed class Builder + { + private int mCipherSuite = -1; + private short mCompressionAlgorithm = -1; + private byte[] mMasterSecret = null; + private Certificate mPeerCertificate = null; + private byte[] mPskIdentity = null; + private byte[] mSrpIdentity = null; + private byte[] mEncodedServerExtensions = null; + + public Builder() + { + } + + public SessionParameters Build() + { + Validate(this.mCipherSuite >= 0, "cipherSuite"); + Validate(this.mCompressionAlgorithm >= 0, "compressionAlgorithm"); + Validate(this.mMasterSecret != null, "masterSecret"); + return new SessionParameters(mCipherSuite, (byte)mCompressionAlgorithm, mMasterSecret, mPeerCertificate, + mPskIdentity, mSrpIdentity, mEncodedServerExtensions); + } + + public Builder SetCipherSuite(int cipherSuite) + { + this.mCipherSuite = cipherSuite; + return this; + } + + public Builder SetCompressionAlgorithm(byte compressionAlgorithm) + { + this.mCompressionAlgorithm = compressionAlgorithm; + return this; + } + + public Builder SetMasterSecret(byte[] masterSecret) + { + this.mMasterSecret = masterSecret; + return this; + } + + public Builder SetPeerCertificate(Certificate peerCertificate) + { + this.mPeerCertificate = peerCertificate; + return this; + } + + public Builder SetPskIdentity(byte[] pskIdentity) + { + this.mPskIdentity = pskIdentity; + return this; + } + + public Builder SetSrpIdentity(byte[] srpIdentity) + { + this.mSrpIdentity = srpIdentity; + return this; + } + + public Builder SetServerExtensions(IDictionary serverExtensions) + { + if (serverExtensions == null) + { + mEncodedServerExtensions = null; + } + else + { + MemoryStream buf = new MemoryStream(); + TlsProtocol.WriteExtensions(buf, serverExtensions); + mEncodedServerExtensions = buf.ToArray(); + } + return this; + } + + private void Validate(bool condition, string parameter) + { + if (!condition) + throw new InvalidOperationException("Required session parameter '" + parameter + "' not configured"); + } + } + + private int mCipherSuite; + private byte mCompressionAlgorithm; + private byte[] mMasterSecret; + private Certificate mPeerCertificate; + private byte[] mPskIdentity; + private byte[] mSrpIdentity; + private byte[] mEncodedServerExtensions; + + private SessionParameters(int cipherSuite, byte compressionAlgorithm, byte[] masterSecret, + Certificate peerCertificate, byte[] pskIdentity, byte[] srpIdentity, byte[] encodedServerExtensions) + { + this.mCipherSuite = cipherSuite; + this.mCompressionAlgorithm = compressionAlgorithm; + this.mMasterSecret = Arrays.Clone(masterSecret); + this.mPeerCertificate = peerCertificate; + this.mPskIdentity = Arrays.Clone(pskIdentity); + this.mSrpIdentity = Arrays.Clone(srpIdentity); + this.mEncodedServerExtensions = encodedServerExtensions; + } + + public void Clear() + { + if (this.mMasterSecret != null) + { + Arrays.Fill(this.mMasterSecret, (byte)0); + } + } + + public SessionParameters Copy() + { + return new SessionParameters(mCipherSuite, mCompressionAlgorithm, mMasterSecret, mPeerCertificate, + mPskIdentity, mSrpIdentity, mEncodedServerExtensions); + } + + public int CipherSuite + { + get { return mCipherSuite; } + } + + public byte CompressionAlgorithm + { + get { return mCompressionAlgorithm; } + } + + public byte[] MasterSecret + { + get { return mMasterSecret; } + } + + public Certificate PeerCertificate + { + get { return mPeerCertificate; } + } + + public byte[] PskIdentity + { + get { return mPskIdentity; } + } + + public byte[] SrpIdentity + { + get { return mSrpIdentity; } + } + + public IDictionary ReadServerExtensions() + { + if (mEncodedServerExtensions == null) + return null; + + MemoryStream buf = new MemoryStream(mEncodedServerExtensions, false); + return TlsProtocol.ReadExtensions(buf); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs.meta new file mode 100644 index 0000000..cf4d05d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SessionParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bbc6009270152664498342e5a67289f0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs new file mode 100644 index 0000000..f5ccc54 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs @@ -0,0 +1,19 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) + */ + public abstract class SignatureAlgorithm + { + public const byte anonymous = 0; + public const byte rsa = 1; + public const byte dsa = 2; + public const byte ecdsa = 3; + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs.meta new file mode 100644 index 0000000..627d6f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fe1e468e29a65364e967c9c43ec97ac0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs new file mode 100644 index 0000000..f8b1812 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs @@ -0,0 +1,98 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5246 7.4.1.4.1 + */ + public class SignatureAndHashAlgorithm + { + protected readonly byte mHash; + protected readonly byte mSignature; + + /** + * @param hash {@link HashAlgorithm} + * @param signature {@link SignatureAlgorithm} + */ + public SignatureAndHashAlgorithm(byte hash, byte signature) + { + if (!TlsUtilities.IsValidUint8(hash)) + { + throw new ArgumentException("should be a uint8", "hash"); + } + if (!TlsUtilities.IsValidUint8(signature)) + { + throw new ArgumentException("should be a uint8", "signature"); + } + if (signature == SignatureAlgorithm.anonymous) + { + throw new ArgumentException("MUST NOT be \"anonymous\"", "signature"); + } + + this.mHash = hash; + this.mSignature = signature; + } + + /** + * @return {@link HashAlgorithm} + */ + public virtual byte Hash + { + get { return mHash; } + } + + /** + * @return {@link SignatureAlgorithm} + */ + public virtual byte Signature + { + get { return mSignature; } + } + + public override bool Equals(object obj) + { + if (!(obj is SignatureAndHashAlgorithm)) + { + return false; + } + SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj; + return other.Hash == Hash && other.Signature == Signature; + } + + public override int GetHashCode() + { + return ((int)Hash << 16) | (int)Signature; + } + + /** + * Encode this {@link SignatureAndHashAlgorithm} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(Hash, output); + TlsUtilities.WriteUint8(Signature, output); + } + + /** + * Parse a {@link SignatureAndHashAlgorithm} from a {@link Stream}. + * + * @param input the {@link Stream} to parse from. + * @return a {@link SignatureAndHashAlgorithm} object. + * @throws IOException + */ + public static SignatureAndHashAlgorithm Parse(Stream input) + { + byte hash = TlsUtilities.ReadUint8(input); + byte signature = TlsUtilities.ReadUint8(input); + return new SignatureAndHashAlgorithm(hash, signature); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs.meta new file mode 100644 index 0000000..1162efe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignatureAndHashAlgorithm.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 51e114f319dd0f14ba74e6d415a6fb4b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs new file mode 100644 index 0000000..1e4145a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class SignerInputBuffer + : MemoryStream + { + internal void UpdateSigner(ISigner s) + { + WriteTo(new SigStream(s)); + } + + private class SigStream + : BaseOutputStream + { + private readonly ISigner s; + + internal SigStream(ISigner s) + { + this.s = s; + } + + public override void WriteByte(byte b) + { + s.Update(b); + } + + public override void Write(byte[] buf, int off, int len) + { + s.BlockUpdate(buf, off, len); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs.meta new file mode 100644 index 0000000..d6184e2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SignerInputBuffer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ede9b2816a63d104bba0b2d60c28a180 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs new file mode 100644 index 0000000..5a55fb2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs @@ -0,0 +1,114 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * HMAC implementation based on original internet draft for HMAC (RFC 2104) + * + * The difference is that padding is concatentated versus XORed with the key + * + * H(K + opad, H(K + ipad, text)) + */ + public class Ssl3Mac + : IMac + { + private const byte IPAD_BYTE = 0x36; + private const byte OPAD_BYTE = 0x5C; + + internal static readonly byte[] IPAD = GenPad(IPAD_BYTE, 48); + internal static readonly byte[] OPAD = GenPad(OPAD_BYTE, 48); + + private readonly IDigest digest; + private readonly int padLength; + + private byte[] secret; + + /** + * Base constructor for one of the standard digest algorithms that the byteLength of + * the algorithm is know for. Behaviour is undefined for digests other than MD5 or SHA1. + * + * @param digest the digest. + */ + public Ssl3Mac(IDigest digest) + { + this.digest = digest; + + if (digest.GetDigestSize() == 20) + { + this.padLength = 40; + } + else + { + this.padLength = 48; + } + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "/SSL3MAC"; } + } + + public virtual void Init(ICipherParameters parameters) + { + secret = Arrays.Clone(((KeyParameter)parameters).GetKey()); + + Reset(); + } + + public virtual int GetMacSize() + { + return digest.GetDigestSize(); + } + + public virtual void Update(byte input) + { + digest.Update(input); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + digest.BlockUpdate(input, inOff, len); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + byte[] tmp = new byte[digest.GetDigestSize()]; + digest.DoFinal(tmp, 0); + + digest.BlockUpdate(secret, 0, secret.Length); + digest.BlockUpdate(OPAD, 0, padLength); + digest.BlockUpdate(tmp, 0, tmp.Length); + + int len = digest.DoFinal(output, outOff); + + Reset(); + + return len; + } + + /** + * Reset the mac generator. + */ + public virtual void Reset() + { + digest.Reset(); + digest.BlockUpdate(secret, 0, secret.Length); + digest.BlockUpdate(IPAD, 0, padLength); + } + + private static byte[] GenPad(byte b, int count) + { + byte[] padding = new byte[count]; + Arrays.Fill(padding, b); + return padding; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs.meta new file mode 100644 index 0000000..90c0ad2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/Ssl3Mac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8efb8ed745b4b2141b65fe1efdc9d92c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs new file mode 100644 index 0000000..143653e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs @@ -0,0 +1,30 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class SupplementalDataEntry + { + protected readonly int mDataType; + protected readonly byte[] mData; + + public SupplementalDataEntry(int dataType, byte[] data) + { + this.mDataType = dataType; + this.mData = data; + } + + public virtual int DataType + { + get { return mDataType; } + } + + public virtual byte[] Data + { + get { return mData; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs.meta new file mode 100644 index 0000000..bf18bca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/SupplementalDataEntry.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7756b340729452241aeb7d6f4fdb93d5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs new file mode 100644 index 0000000..259c9e8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs @@ -0,0 +1,253 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsAeadCipher + : TlsCipher + { + // TODO[draft-zauner-tls-aes-ocb-04] Apply data volume limit described in section 8.4 + + public const int NONCE_RFC5288 = 1; + + /* + * draft-zauner-tls-aes-ocb-04 specifies the nonce construction from draft-ietf-tls-chacha20-poly1305-04 + */ + internal const int NONCE_DRAFT_CHACHA20_POLY1305 = 2; + + protected readonly TlsContext context; + protected readonly int macSize; + // TODO SecurityParameters.record_iv_length + protected readonly int record_iv_length; + + protected readonly IAeadBlockCipher encryptCipher; + protected readonly IAeadBlockCipher decryptCipher; + + protected readonly byte[] encryptImplicitNonce, decryptImplicitNonce; + + protected readonly int nonceMode; + + /// + public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, + int cipherKeySize, int macSize) + : this(context, clientWriteCipher, serverWriteCipher, cipherKeySize, macSize, NONCE_RFC5288) + { + } + + /// + internal TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, + int cipherKeySize, int macSize, int nonceMode) + { + if (!TlsUtilities.IsTlsV12(context)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.nonceMode = nonceMode; + + // TODO SecurityParameters.fixed_iv_length + int fixed_iv_length; + + switch (nonceMode) + { + case NONCE_RFC5288: + fixed_iv_length = 4; + this.record_iv_length = 8; + break; + case NONCE_DRAFT_CHACHA20_POLY1305: + fixed_iv_length = 12; + this.record_iv_length = 0; + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + this.context = context; + this.macSize = macSize; + + int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length); + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + + if (offset != key_block_size) + throw new TlsFatalAlert(AlertDescription.internal_error); + + KeyParameter encryptKey, decryptKey; + if (context.IsServer) + { + this.encryptCipher = serverWriteCipher; + this.decryptCipher = clientWriteCipher; + this.encryptImplicitNonce = server_write_IV; + this.decryptImplicitNonce = client_write_IV; + encryptKey = server_write_key; + decryptKey = client_write_key; + } + else + { + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + this.encryptImplicitNonce = client_write_IV; + this.decryptImplicitNonce = server_write_IV; + encryptKey = client_write_key; + decryptKey = server_write_key; + } + + byte[] dummyNonce = new byte[fixed_iv_length + record_iv_length]; + + this.encryptCipher.Init(true, new AeadParameters(encryptKey, 8 * macSize, dummyNonce)); + this.decryptCipher.Init(false, new AeadParameters(decryptKey, 8 * macSize, dummyNonce)); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + // TODO We ought to be able to ask the decryptCipher (independently of it's current state!) + return ciphertextLimit - macSize - record_iv_length; + } + + /// + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + byte[] nonce = new byte[encryptImplicitNonce.Length + record_iv_length]; + + switch (nonceMode) + { + case NONCE_RFC5288: + Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length); + // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number. + TlsUtilities.WriteUint64(seqNo, nonce, encryptImplicitNonce.Length); + break; + case NONCE_DRAFT_CHACHA20_POLY1305: + TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8); + for (int i = 0; i < encryptImplicitNonce.Length; ++i) + { + nonce[i] ^= encryptImplicitNonce[i]; + } + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int plaintextOffset = offset; + int plaintextLength = len; + int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength); + + byte[] output = new byte[record_iv_length + ciphertextLength]; + if (record_iv_length != 0) + { + Array.Copy(nonce, nonce.Length - record_iv_length, output, 0, record_iv_length); + } + int outputPos = record_iv_length; + + byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); + AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData); + + try + { + encryptCipher.Init(true, parameters); + outputPos += encryptCipher.ProcessBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos); + outputPos += encryptCipher.DoFinal(output, outputPos); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + if (outputPos != output.Length) + { + // NOTE: Existing AEAD cipher implementations all give exact output lengths + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return output; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (GetPlaintextLimit(len) < 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] nonce = new byte[decryptImplicitNonce.Length + record_iv_length]; + + switch (nonceMode) + { + case NONCE_RFC5288: + Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length); + Array.Copy(ciphertext, offset, nonce, nonce.Length - record_iv_length, record_iv_length); + break; + case NONCE_DRAFT_CHACHA20_POLY1305: + TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8); + for (int i = 0; i < decryptImplicitNonce.Length; ++i) + { + nonce[i] ^= decryptImplicitNonce[i]; + } + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int ciphertextOffset = offset + record_iv_length; + int ciphertextLength = len - record_iv_length; + int plaintextLength = decryptCipher.GetOutputSize(ciphertextLength); + + byte[] output = new byte[plaintextLength]; + int outputPos = 0; + + byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); + AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData); + + try + { + decryptCipher.Init(false, parameters); + outputPos += decryptCipher.ProcessBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos); + outputPos += decryptCipher.DoFinal(output, outputPos); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.bad_record_mac, e); + } + + if (outputPos != output.Length) + { + // NOTE: Existing AEAD cipher implementations all give exact output lengths + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return output; + } + + /// + protected virtual byte[] GetAdditionalData(long seqNo, byte type, int len) + { + /* + * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + + * TLSCompressed.length + */ + + byte[] additional_data = new byte[13]; + TlsUtilities.WriteUint64(seqNo, additional_data, 0); + TlsUtilities.WriteUint8(type, additional_data, 8); + TlsUtilities.WriteVersion(context.ServerVersion, additional_data, 9); + TlsUtilities.WriteUint16(len, additional_data, 11); + + return additional_data; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs.meta new file mode 100644 index 0000000..c4de2dc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAeadCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cd60419f3a93fb4439f9a62115948e22 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs new file mode 100644 index 0000000..1a0b298 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsAgreementCredentials + : TlsCredentials + { + /// + byte[] GenerateAgreement(AsymmetricKeyParameter peerPublicKey); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs.meta new file mode 100644 index 0000000..62f46cf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAgreementCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5e668ed02ffcd9340b4b08fcc6ef8fc9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs new file mode 100644 index 0000000..7fcd348 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs @@ -0,0 +1,35 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsAuthentication + { + /// + /// Called by the protocol handler to report the server certificate. + /// + /// + /// This method is responsible for certificate verification and validation + /// + /// The server received + /// + void NotifyServerCertificate(Certificate serverCertificate); + + /// + /// Return client credentials in response to server's certificate request + /// + /// + /// A containing server certificate request details + /// + /// + /// A to be used for client authentication + /// (or null for no client authentication) + /// + /// + TlsCredentials GetClientCredentials(TlsContext context, CertificateRequest certificateRequest); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs.meta new file mode 100644 index 0000000..e00a44f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsAuthentication.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c47d5a2f1fcf0924482f99db660945be +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs new file mode 100644 index 0000000..47631e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs @@ -0,0 +1,390 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A generic TLS 1.0-1.2 / SSLv3 block cipher. This can be used for AES or 3DES for example. + /// + public class TlsBlockCipher + : TlsCipher + { + protected readonly TlsContext context; + protected readonly byte[] randomData; + protected readonly bool useExplicitIV; + protected readonly bool encryptThenMac; + + protected readonly IBlockCipher encryptCipher; + protected readonly IBlockCipher decryptCipher; + + protected readonly TlsMac mWriteMac; + protected readonly TlsMac mReadMac; + + public virtual TlsMac WriteMac + { + get { return mWriteMac; } + } + + public virtual TlsMac ReadMac + { + get { return mReadMac; } + } + + /// + public TlsBlockCipher(TlsContext context, IBlockCipher clientWriteCipher, IBlockCipher serverWriteCipher, + IDigest clientWriteDigest, IDigest serverWriteDigest, int cipherKeySize) + { + this.context = context; + + this.randomData = new byte[256]; + context.NonceRandomGenerator.NextBytes(randomData); + + this.useExplicitIV = TlsUtilities.IsTlsV11(context); + this.encryptThenMac = context.SecurityParameters.encryptThenMac; + + int key_block_size = (2 * cipherKeySize) + clientWriteDigest.GetDigestSize() + + serverWriteDigest.GetDigestSize(); + + // From TLS 1.1 onwards, block ciphers don't need client_write_IV + if (!useExplicitIV) + { + key_block_size += clientWriteCipher.GetBlockSize() + serverWriteCipher.GetBlockSize(); + } + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.GetDigestSize()); + offset += clientWriteDigest.GetDigestSize(); + TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.GetDigestSize()); + offset += serverWriteDigest.GetDigestSize(); + + KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + + byte[] client_write_IV, server_write_IV; + if (useExplicitIV) + { + client_write_IV = new byte[clientWriteCipher.GetBlockSize()]; + server_write_IV = new byte[serverWriteCipher.GetBlockSize()]; + } + else + { + client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + clientWriteCipher.GetBlockSize()); + offset += clientWriteCipher.GetBlockSize(); + server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + serverWriteCipher.GetBlockSize()); + offset += serverWriteCipher.GetBlockSize(); + } + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + ICipherParameters encryptParams, decryptParams; + if (context.IsServer) + { + this.mWriteMac = serverWriteMac; + this.mReadMac = clientWriteMac; + this.encryptCipher = serverWriteCipher; + this.decryptCipher = clientWriteCipher; + encryptParams = new ParametersWithIV(server_write_key, server_write_IV); + decryptParams = new ParametersWithIV(client_write_key, client_write_IV); + } + else + { + this.mWriteMac = clientWriteMac; + this.mReadMac = serverWriteMac; + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + encryptParams = new ParametersWithIV(client_write_key, client_write_IV); + decryptParams = new ParametersWithIV(server_write_key, server_write_IV); + } + + this.encryptCipher.Init(true, encryptParams); + this.decryptCipher.Init(false, decryptParams); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + int blockSize = encryptCipher.GetBlockSize(); + int macSize = mWriteMac.Size; + + int plaintextLimit = ciphertextLimit; + + // An explicit IV consumes 1 block + if (useExplicitIV) + { + plaintextLimit -= blockSize; + } + + // Leave room for the MAC, and require block-alignment + if (encryptThenMac) + { + plaintextLimit -= macSize; + plaintextLimit -= plaintextLimit % blockSize; + } + else + { + plaintextLimit -= plaintextLimit % blockSize; + plaintextLimit -= macSize; + } + + // Minimum 1 byte of padding + --plaintextLimit; + + return plaintextLimit; + } + + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + int blockSize = encryptCipher.GetBlockSize(); + int macSize = mWriteMac.Size; + + ProtocolVersion version = context.ServerVersion; + + int enc_input_length = len; + if (!encryptThenMac) + { + enc_input_length += macSize; + } + + int padding_length = blockSize - 1 - (enc_input_length % blockSize); + + // TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though) + if (!version.IsDtls && !version.IsSsl) + { + // Add a random number of extra blocks worth of padding + int maxExtraPadBlocks = (255 - padding_length) / blockSize; + int actualExtraPadBlocks = ChooseExtraPadBlocks(context.SecureRandom, maxExtraPadBlocks); + padding_length += actualExtraPadBlocks * blockSize; + } + + int totalSize = len + macSize + padding_length + 1; + if (useExplicitIV) + { + totalSize += blockSize; + } + + byte[] outBuf = new byte[totalSize]; + int outOff = 0; + + if (useExplicitIV) + { + byte[] explicitIV = new byte[blockSize]; + context.NonceRandomGenerator.NextBytes(explicitIV); + + encryptCipher.Init(true, new ParametersWithIV(null, explicitIV)); + + Array.Copy(explicitIV, 0, outBuf, outOff, blockSize); + outOff += blockSize; + } + + int blocks_start = outOff; + + Array.Copy(plaintext, offset, outBuf, outOff, len); + outOff += len; + + if (!encryptThenMac) + { + byte[] mac = mWriteMac.CalculateMac(seqNo, type, plaintext, offset, len); + Array.Copy(mac, 0, outBuf, outOff, mac.Length); + outOff += mac.Length; + } + + for (int i = 0; i <= padding_length; i++) + { + outBuf[outOff++] = (byte)padding_length; + } + + for (int i = blocks_start; i < outOff; i += blockSize) + { + encryptCipher.ProcessBlock(outBuf, i, outBuf, i); + } + + if (encryptThenMac) + { + byte[] mac = mWriteMac.CalculateMac(seqNo, type, outBuf, 0, outOff); + Array.Copy(mac, 0, outBuf, outOff, mac.Length); + outOff += mac.Length; + } + + // assert outBuf.length == outOff; + + return outBuf; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + int blockSize = decryptCipher.GetBlockSize(); + int macSize = mReadMac.Size; + + int minLen = blockSize; + if (encryptThenMac) + { + minLen += macSize; + } + else + { + minLen = System.Math.Max(minLen, macSize + 1); + } + + if (useExplicitIV) + { + minLen += blockSize; + } + + if (len < minLen) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int blocks_length = len; + if (encryptThenMac) + { + blocks_length -= macSize; + } + + if (blocks_length % blockSize != 0) + throw new TlsFatalAlert(AlertDescription.decryption_failed); + + if (encryptThenMac) + { + int end = offset + len; + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, end - macSize, end); + byte[] calculatedMac = mReadMac.CalculateMac(seqNo, type, ciphertext, offset, len - macSize); + + bool badMacEtm = !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac); + if (badMacEtm) + { + /* + * RFC 7366 3. The MAC SHALL be evaluated before any further processing such as + * decryption is performed, and if the MAC verification fails, then processing SHALL + * terminate immediately. For TLS, a fatal bad_record_mac MUST be generated [2]. For + * DTLS, the record MUST be discarded, and a fatal bad_record_mac MAY be generated + * [4]. This immediate response to a bad MAC eliminates any timing channels that may + * be available through the use of manipulated packet data. + */ + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + } + } + + if (useExplicitIV) + { + decryptCipher.Init(false, new ParametersWithIV(null, ciphertext, offset, blockSize)); + + offset += blockSize; + blocks_length -= blockSize; + } + + for (int i = 0; i < blocks_length; i += blockSize) + { + decryptCipher.ProcessBlock(ciphertext, offset + i, ciphertext, offset + i); + } + + // If there's anything wrong with the padding, this will return zero + int totalPad = CheckPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, encryptThenMac ? 0 : macSize); + bool badMac = (totalPad == 0); + + int dec_output_length = blocks_length - totalPad; + + if (!encryptThenMac) + { + dec_output_length -= macSize; + int macInputLen = dec_output_length; + int macOff = offset + macInputLen; + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, macOff, macOff + macSize); + byte[] calculatedMac = mReadMac.CalculateMacConstantTime(seqNo, type, ciphertext, offset, macInputLen, + blocks_length - macSize, randomData); + + badMac |= !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac); + } + + if (badMac) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + return Arrays.CopyOfRange(ciphertext, offset, offset + dec_output_length); + } + + protected virtual int CheckPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) + { + int end = off + len; + byte lastByte = buf[end - 1]; + int padlen = lastByte & 0xff; + int totalPad = padlen + 1; + + int dummyIndex = 0; + byte padDiff = 0; + + if ((TlsUtilities.IsSsl(context) && totalPad > blockSize) || (macSize + totalPad > len)) + { + totalPad = 0; + } + else + { + int padPos = end - totalPad; + do + { + padDiff |= (byte)(buf[padPos++] ^ lastByte); + } + while (padPos < end); + + dummyIndex = totalPad; + + if (padDiff != 0) + { + totalPad = 0; + } + } + + // Run some extra dummy checks so the number of checks is always constant + { + byte[] dummyPad = randomData; + while (dummyIndex < 256) + { + padDiff |= (byte)(dummyPad[dummyIndex++] ^ lastByte); + } + // Ensure the above loop is not eliminated + dummyPad[0] ^= padDiff; + } + + return totalPad; + } + + protected virtual int ChooseExtraPadBlocks(SecureRandom r, int max) + { + // return r.NextInt(max + 1); + + int x = r.NextInt(); + int n = LowestBitSet(x); + return System.Math.Min(n, max); + } + + protected virtual int LowestBitSet(int x) + { + if (x == 0) + return 32; + + uint ux = (uint)x; + int n = 0; + while ((ux & 1U) == 0) + { + ++n; + ux >>= 1; + } + return n; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs.meta new file mode 100644 index 0000000..2ca2f00 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsBlockCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6ed82dfad77b01e46b2c034e89f070c9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs new file mode 100644 index 0000000..5c6eb8d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs @@ -0,0 +1,20 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCipher + { + int GetPlaintextLimit(int ciphertextLimit); + + /// + byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len); + + /// + byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs.meta new file mode 100644 index 0000000..b09eb4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5595bb6c662c55c4d9b41c10ee8ba729 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs new file mode 100644 index 0000000..5c6fbf3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCipherFactory + { + /// + TlsCipher CreateCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs.meta new file mode 100644 index 0000000..6bc74b9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCipherFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0f7c1d04c20c75c4dbedfaef773eea2b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs new file mode 100644 index 0000000..653ba19 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs @@ -0,0 +1,154 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsClient + : TlsPeer + { + System.Collections.Generic.List HostNames { get; set; } + + /// + /// Called at the start of a new TLS session, before any other methods. + /// + /// + /// A + /// + void Init(TlsClientContext context); + + /// Return the session this client wants to resume, if any. + /// Note that the peer's certificate chain for the session (if any) may need to be periodically revalidated. + /// + /// A representing the resumable session to be used for this connection, + /// or null to use a new session. + /// + TlsSession GetSessionToResume(); + + /// + /// Return the to use for the TLSPlaintext.version field prior to + /// receiving the server version. NOTE: This method is not called for DTLS. + /// + /// + /// See RFC 5246 E.1.: "TLS clients that wish to negotiate with older servers MAY send any value + /// {03,XX} as the record layer version number. Typical values would be {03,00}, the lowest + /// version number supported by the client, and the value of ClientHello.client_version. No + /// single value will guarantee interoperability with all old servers, but this is a complex + /// topic beyond the scope of this document." + /// + /// The to use. + ProtocolVersion ClientHelloRecordLayerVersion { get; } + + ProtocolVersion ClientVersion { get; } + + bool IsFallback { get; } + + /// + /// Get the list of cipher suites that this client supports. + /// + /// + /// An array of values, each specifying a supported cipher suite. + /// + int[] GetCipherSuites(); + + /// + /// Get the list of compression methods that this client supports. + /// + /// + /// An array of values, each specifying a supported compression method. + /// + byte[] GetCompressionMethods(); + + /// + /// Get the (optional) table of client extensions to be included in (extended) client hello. + /// + /// + /// A (Int32 -> byte[]). May be null. + /// + /// + IDictionary GetClientExtensions(); + + /// + void NotifyServerVersion(ProtocolVersion selectedVersion); + + /// + /// Notifies the client of the session_id sent in the ServerHello. + /// + /// An array of + void NotifySessionID(byte[] sessionID); + + /// + /// Report the cipher suite that was selected by the server. + /// + /// + /// The protocol handler validates this value against the offered cipher suites + /// + /// + /// + /// A + /// + void NotifySelectedCipherSuite(int selectedCipherSuite); + + /// + /// Report the compression method that was selected by the server. + /// + /// + /// The protocol handler validates this value against the offered compression methods + /// + /// + /// + /// A + /// + void NotifySelectedCompressionMethod(byte selectedCompressionMethod); + + /// + /// Report the extensions from an extended server hello. + /// + /// + /// Will only be called if we returned a non-null result from . + /// + /// + /// A (Int32 -> byte[]) + /// + void ProcessServerExtensions(IDictionary serverExtensions); + + /// A list of + /// + void ProcessServerSupplementalData(IList serverSupplementalData); + + /// + /// Return an implementation of to negotiate the key exchange + /// part of the protocol. + /// + /// + /// A + /// + /// + TlsKeyExchange GetKeyExchange(); + + /// + /// Return an implementation of to handle authentication + /// part of the protocol. + /// + /// + TlsAuthentication GetAuthentication(); + + /// A list of + /// + IList GetClientSupplementalData(); + + /// RFC 5077 3.3. NewSessionTicket Handshake Message + /// + /// This method will be called (only) when a NewSessionTicket handshake message is received. The + /// ticket is opaque to the client and clients MUST NOT examine the ticket under the assumption + /// that it complies with e.g. RFC 5077 4. Recommended Ticket Construction. + /// + /// The ticket + /// + void NotifyNewSessionTicket(NewSessionTicket newSessionTicket); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs.meta new file mode 100644 index 0000000..44649fc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClient.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 96745de7428eac7458009404ae7f5be8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs new file mode 100644 index 0000000..71b0231 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsClientContext + : TlsContext + { + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs.meta new file mode 100644 index 0000000..f10d8b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContext.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 12f6a51fefbe0364da64091cf6e2313a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs new file mode 100644 index 0000000..8b66c26 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsClientContextImpl + : AbstractTlsContext, TlsClientContext + { + internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) + : base(secureRandom, securityParameters) + { + } + + public override bool IsServer + { + get { return false; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs.meta new file mode 100644 index 0000000..6ed7319 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientContextImpl.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32dbc6eb04c4e42478c01371a1f961c1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs new file mode 100644 index 0000000..aadb1cf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs @@ -0,0 +1,911 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsClientProtocol + : TlsProtocol + { + protected TlsClient mTlsClient = null; + internal TlsClientContextImpl mTlsClientContext = null; + + protected byte[] mSelectedSessionID = null; + + protected TlsKeyExchange mKeyExchange = null; + protected TlsAuthentication mAuthentication = null; + + protected CertificateStatus mCertificateStatus = null; + protected CertificateRequest mCertificateRequest = null; + + /** + * Constructor for blocking mode. + * @param stream The bi-directional stream of data to/from the server + * @param secureRandom Random number generator for various cryptographic functions + */ + public TlsClientProtocol(Stream stream, SecureRandom secureRandom) + : base(stream, secureRandom) + { + } + + /** + * Constructor for blocking mode. + * @param input The stream of data from the server + * @param output The stream of data to the server + * @param secureRandom Random number generator for various cryptographic functions + */ + public TlsClientProtocol(Stream input, Stream output, SecureRandom secureRandom) + : base(input, output, secureRandom) + { + } + + /** + * Constructor for non-blocking mode.
+ *
+ * When data is received, use {@link #offerInput(java.nio.ByteBuffer)} to + * provide the received ciphertext, then use + * {@link #readInput(byte[], int, int)} to read the corresponding cleartext.
+ *
+ * Similarly, when data needs to be sent, use + * {@link #offerOutput(byte[], int, int)} to provide the cleartext, then use + * {@link #readOutput(byte[], int, int)} to get the corresponding + * ciphertext. + * + * @param secureRandom + * Random number generator for various cryptographic functions + */ + public TlsClientProtocol(SecureRandom secureRandom) + : base(secureRandom) + { + } + + /** + * Initiates a TLS handshake in the role of client.
+ *
+ * In blocking mode, this will not return until the handshake is complete. + * In non-blocking mode, use {@link TlsPeer#NotifyHandshakeComplete()} to + * receive a callback when the handshake is complete. + * + * @param tlsClient The {@link TlsClient} to use for the handshake. + * @throws IOException If in blocking mode and handshake was not successful. + */ + public virtual void Connect(TlsClient tlsClient) + { + if (tlsClient == null) + throw new ArgumentNullException("tlsClient"); + if (this.mTlsClient != null) + throw new InvalidOperationException("'Connect' can only be called once"); + + this.mTlsClient = tlsClient; + + this.mSecurityParameters = new SecurityParameters(); + this.mSecurityParameters.entity = ConnectionEnd.client; + + this.mTlsClientContext = new TlsClientContextImpl(mSecureRandom, mSecurityParameters); + + this.mSecurityParameters.clientRandom = CreateRandomBlock(tlsClient.ShouldUseGmtUnixTime(), + mTlsClientContext.NonceRandomGenerator); + + this.mTlsClient.Init(mTlsClientContext); + this.mRecordStream.Init(mTlsClientContext); + + TlsSession sessionToResume = tlsClient.GetSessionToResume(); + if (sessionToResume != null && sessionToResume.IsResumable) + { + SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); + if (sessionParameters != null) + { + this.mTlsSession = sessionToResume; + this.mSessionParameters = sessionParameters; + } + } + + SendClientHelloMessage(); + this.mConnectionState = CS_CLIENT_HELLO; + + BlockForHandshake(); + } + + protected override void CleanupHandshake() + { + base.CleanupHandshake(); + + this.mSelectedSessionID = null; + this.mKeyExchange = null; + this.mAuthentication = null; + this.mCertificateStatus = null; + this.mCertificateRequest = null; + } + + protected override TlsContext Context + { + get { return mTlsClientContext; } + } + + internal override AbstractTlsContext ContextAdmin + { + get { return mTlsClientContext; } + } + + protected override TlsPeer Peer + { + get { return mTlsClient; } + } + + protected override void HandleHandshakeMessage(byte type, byte[] data) + { + MemoryStream buf = new MemoryStream(data, false); + + if (this.mResumedSession) + { + if (type != HandshakeType.finished || this.mConnectionState != CS_SERVER_HELLO) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ProcessFinishedMessage(buf); + this.mConnectionState = CS_SERVER_FINISHED; + + SendFinishedMessage(); + this.mConnectionState = CS_CLIENT_FINISHED; + this.mConnectionState = CS_END; + + CompleteHandshake(); + return; + } + + switch (type) + { + case HandshakeType.certificate: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + { + if (this.mConnectionState == CS_SERVER_HELLO) + { + HandleSupplementalData(null); + } + + // Parse the Certificate message and Send to cipher suite + + this.mPeerCertificate = Certificate.Parse(buf); + + AssertEmpty(buf); + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus + if (this.mPeerCertificate == null || this.mPeerCertificate.IsEmpty) + { + this.mAllowCertificateStatus = false; + } + + this.mKeyExchange.ProcessServerCertificate(this.mPeerCertificate); + + this.mAuthentication = mTlsClient.GetAuthentication(); + this.mAuthentication.NotifyServerCertificate(this.mPeerCertificate); + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_SERVER_CERTIFICATE; + break; + } + case HandshakeType.certificate_status: + { + switch (this.mConnectionState) + { + case CS_SERVER_CERTIFICATE: + { + if (!this.mAllowCertificateStatus) + { + /* + * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the + * server MUST have included an extension of type "status_request" with empty + * "extension_data" in the extended server hello.. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mCertificateStatus = CertificateStatus.Parse(buf); + + AssertEmpty(buf); + + // TODO[RFC 3546] Figure out how to provide this to the client/authentication. + + this.mConnectionState = CS_CERTIFICATE_STATUS; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (this.mConnectionState) + { + case CS_CLIENT_FINISHED: + case CS_SERVER_SESSION_TICKET: + { + if (this.mConnectionState == CS_CLIENT_FINISHED && this.mExpectSessionTicket) + { + /* + * RFC 5077 3.3. This message MUST be sent if the server included a + * SessionTicket extension in the ServerHello. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + ProcessFinishedMessage(buf); + this.mConnectionState = CS_SERVER_FINISHED; + this.mConnectionState = CS_END; + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.server_hello: + { + switch (this.mConnectionState) + { + case CS_CLIENT_HELLO: + { + ReceiveServerHelloMessage(buf); + this.mConnectionState = CS_SERVER_HELLO; + + this.mRecordStream.NotifyHelloComplete(); + + ApplyMaxFragmentLengthExtension(); + + if (this.mResumedSession) + { + this.mSecurityParameters.masterSecret = Arrays.Clone(this.mSessionParameters.MasterSecret); + this.mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); + + SendChangeCipherSpecMessage(); + } + else + { + InvalidateSession(); + + if (this.mSelectedSessionID.Length > 0) + { + this.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null); + } + } + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.supplemental_data: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + { + HandleSupplementalData(ReadSupplementalDataMessage(buf)); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.server_hello_done: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + case CS_CERTIFICATE_REQUEST: + { + if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) + { + HandleSupplementalData(null); + } + + if (mConnectionState < CS_SERVER_CERTIFICATE) + { + // There was no server certificate message; check it's OK + this.mKeyExchange.SkipServerCredentials(); + this.mAuthentication = null; + } + + if (mConnectionState < CS_SERVER_KEY_EXCHANGE) + { + // There was no server key exchange message; check it's OK + this.mKeyExchange.SkipServerKeyExchange(); + } + + AssertEmpty(buf); + + this.mConnectionState = CS_SERVER_HELLO_DONE; + + this.mRecordStream.HandshakeHash.SealHashAlgorithms(); + + IList clientSupplementalData = mTlsClient.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + SendSupplementalDataMessage(clientSupplementalData); + } + this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; + + TlsCredentials clientCreds = null; + if (mCertificateRequest == null) + { + this.mKeyExchange.SkipClientCredentials(); + } + else + { + clientCreds = this.mAuthentication.GetClientCredentials(Context, mCertificateRequest); + + if (clientCreds == null) + { + this.mKeyExchange.SkipClientCredentials(); + + /* + * RFC 5246 If no suitable certificate is available, the client MUST Send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + SendCertificateMessage(Certificate.EmptyChain); + } + else + { + this.mKeyExchange.ProcessClientCredentials(clientCreds); + + SendCertificateMessage(clientCreds.Certificate); + } + } + + this.mConnectionState = CS_CLIENT_CERTIFICATE; + + /* + * Send the client key exchange message, depending on the key exchange we are using + * in our CipherSuite. + */ + SendClientKeyExchangeMessage(); + this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; + + TlsHandshakeHash prepareFinishHash = mRecordStream.PrepareToFinish(); + this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, prepareFinishHash, null); + + EstablishMasterSecret(Context, mKeyExchange); + mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); + + if (clientCreds != null && clientCreds is TlsSignerCredentials) + { + TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCreds; + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + Context, signerCredentials); + + byte[] hash; + if (signatureAndHashAlgorithm == null) + { + hash = mSecurityParameters.SessionHash; + } + else + { + hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); + } + + byte[] signature = signerCredentials.GenerateCertificateSignature(hash); + DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); + SendCertificateVerifyMessage(certificateVerify); + + this.mConnectionState = CS_CERTIFICATE_VERIFY; + } + + SendChangeCipherSpecMessage(); + SendFinishedMessage(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + this.mConnectionState = CS_CLIENT_FINISHED; + break; + } + case HandshakeType.server_key_exchange: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_CERTIFICATE_STATUS: + { + if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) + { + HandleSupplementalData(null); + } + + if (mConnectionState < CS_SERVER_CERTIFICATE) + { + // There was no server certificate message; check it's OK + this.mKeyExchange.SkipServerCredentials(); + this.mAuthentication = null; + } + + this.mKeyExchange.ProcessServerKeyExchange(buf); + + AssertEmpty(buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_SERVER_KEY_EXCHANGE; + break; + } + case HandshakeType.certificate_request: + { + switch (this.mConnectionState) + { + case CS_SERVER_CERTIFICATE: + case CS_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + { + if (this.mConnectionState != CS_SERVER_KEY_EXCHANGE) + { + // There was no server key exchange message; check it's OK + this.mKeyExchange.SkipServerKeyExchange(); + } + + if (this.mAuthentication == null) + { + /* + * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server + * to request client identification. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + this.mCertificateRequest = CertificateRequest.Parse(Context, buf); + + AssertEmpty(buf); + + this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest); + + /* + * TODO Give the client a chance to immediately select the CertificateVerify hash + * algorithm here to avoid tracking the other hash algorithms unnecessarily? + */ + TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, + this.mCertificateRequest.SupportedSignatureAlgorithms); + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_CERTIFICATE_REQUEST; + break; + } + case HandshakeType.session_ticket: + { + switch (this.mConnectionState) + { + case CS_CLIENT_FINISHED: + { + if (!this.mExpectSessionTicket) + { + /* + * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a + * SessionTicket extension in the ServerHello. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + /* + * RFC 5077 3.4. If the client receives a session ticket from the server, then it + * discards any Session ID that was sent in the ServerHello. + */ + InvalidateSession(); + + ReceiveNewSessionTicketMessage(buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_SERVER_SESSION_TICKET; + break; + } + case HandshakeType.hello_request: + { + AssertEmpty(buf); + + /* + * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the + * client is currently negotiating a session. This message may be ignored by the client + * if it does not wish to renegotiate a session, or the client may, if it wishes, + * respond with a no_renegotiation alert. + */ + if (this.mConnectionState == CS_END) + { + RefuseRenegotiation(); + } + break; + } + case HandshakeType.client_hello: + case HandshakeType.client_key_exchange: + case HandshakeType.certificate_verify: + case HandshakeType.hello_verify_request: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + protected virtual void HandleSupplementalData(IList serverSupplementalData) + { + this.mTlsClient.ProcessServerSupplementalData(serverSupplementalData); + this.mConnectionState = CS_SERVER_SUPPLEMENTAL_DATA; + + this.mKeyExchange = mTlsClient.GetKeyExchange(); + this.mKeyExchange.Init(Context); + } + + protected virtual void ReceiveNewSessionTicketMessage(MemoryStream buf) + { + NewSessionTicket newSessionTicket = NewSessionTicket.Parse(buf); + + AssertEmpty(buf); + + mTlsClient.NotifyNewSessionTicket(newSessionTicket); + } + + protected virtual void ReceiveServerHelloMessage(MemoryStream buf) + { + { + ProtocolVersion server_version = TlsUtilities.ReadVersion(buf); + if (server_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + // Check that this matches what the server is Sending in the record layer + if (!server_version.Equals(this.mRecordStream.ReadVersion)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + ProtocolVersion client_version = Context.ClientVersion; + if (!server_version.IsEqualOrEarlierVersionOf(client_version)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mRecordStream.SetWriteVersion(server_version); + ContextAdmin.SetServerVersion(server_version); + this.mTlsClient.NotifyServerVersion(server_version); + } + + /* + * Read the server random + */ + this.mSecurityParameters.serverRandom = TlsUtilities.ReadFully(32, buf); + + this.mSelectedSessionID = TlsUtilities.ReadOpaque8(buf); + if (this.mSelectedSessionID.Length > 32) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + this.mTlsClient.NotifySessionID(this.mSelectedSessionID); + this.mResumedSession = this.mSelectedSessionID.Length > 0 && this.mTlsSession != null + && Arrays.AreEqual(this.mSelectedSessionID, this.mTlsSession.SessionID); + + /* + * Find out which CipherSuite the server has chosen and check that it was one of the offered + * ones, and is a valid selection for the negotiated version. + */ + int selectedCipherSuite = TlsUtilities.ReadUint16(buf); + if (!Arrays.Contains(this.mOfferedCipherSuites, selectedCipherSuite) + || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL + || CipherSuite.IsScsv(selectedCipherSuite) + || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, Context.ServerVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + this.mTlsClient.NotifySelectedCipherSuite(selectedCipherSuite); + + /* + * Find out which CompressionMethod the server has chosen and check that it was one of the + * offered ones. + */ + byte selectedCompressionMethod = TlsUtilities.ReadUint8(buf); + if (!Arrays.Contains(this.mOfferedCompressionMethods, selectedCompressionMethod)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + this.mTlsClient.NotifySelectedCompressionMethod(selectedCompressionMethod); + + /* + * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server + * hello message when the client has requested extended functionality via the extended + * client hello message specified in Section 2.1. ... Note that the extended server hello + * message is only sent in response to an extended client hello message. This prevents the + * possibility that the extended server hello message could "break" existing TLS 1.0 + * clients. + */ + this.mServerExtensions = ReadExtensions(buf); + + /* + * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an + * extended client hello message. + * + * However, see RFC 5746 exception below. We always include the SCSV, so an Extended Server + * Hello is always allowed. + */ + if (this.mServerExtensions != null) + { + foreach (int extType in this.mServerExtensions.Keys) + { + /* + * RFC 5746 3.6. Note that Sending a "renegotiation_info" extension in response to a + * ClientHello containing only the SCSV is an explicit exception to the prohibition + * in RFC 5246, Section 7.4.1.4, on the server Sending unsolicited extensions and is + * only allowed because the client is signaling its willingness to receive the + * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + if (extType == ExtensionType.renegotiation_info) + continue; + + /* + * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the + * same extension type appeared in the corresponding ClientHello. If a client + * receives an extension type in ServerHello that it did not request in the + * associated ClientHello, it MUST abort the handshake with an unsupported_extension + * fatal alert. + */ + if (null == TlsUtilities.GetExtensionData(this.mClientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + + /* + * RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and Send a server hello containing no + * extensions[.] + */ + if (this.mResumedSession) + { + // TODO[compat-gnutls] GnuTLS test server Sends server extensions e.g. ec_point_formats + // TODO[compat-openssl] OpenSSL test server Sends server extensions e.g. ec_point_formats + // TODO[compat-polarssl] PolarSSL test server Sends server extensions e.g. ec_point_formats + // throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake + */ + { + /* + * When a ServerHello is received, the client MUST check if it includes the + * "renegotiation_info" extension: + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(this.mServerExtensions, ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set the secure_renegotiation flag to TRUE. The + * client MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake (by Sending a fatal + * handshake_failure alert). + */ + this.mSecureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + // TODO[compat-gnutls] GnuTLS test server fails to Send renegotiation_info extension when resuming + this.mTlsClient.NotifySecureRenegotiation(this.mSecureRenegotiation); + + IDictionary sessionClientExtensions = mClientExtensions, sessionServerExtensions = mServerExtensions; + if (this.mResumedSession) + { + if (selectedCipherSuite != this.mSessionParameters.CipherSuite + || selectedCompressionMethod != this.mSessionParameters.CompressionAlgorithm) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + sessionClientExtensions = null; + sessionServerExtensions = this.mSessionParameters.ReadServerExtensions(); + } + + this.mSecurityParameters.cipherSuite = selectedCipherSuite; + this.mSecurityParameters.compressionAlgorithm = selectedCompressionMethod; + + if (sessionServerExtensions != null) + { + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + bool serverSentEncryptThenMAC = TlsExtensionsUtilities.HasEncryptThenMacExtension(sessionServerExtensions); + if (serverSentEncryptThenMAC && !TlsUtilities.IsBlockCipherSuite(selectedCipherSuite)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mSecurityParameters.encryptThenMac = serverSentEncryptThenMAC; + } + + this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions); + + this.mSecurityParameters.maxFragmentLength = ProcessMaxFragmentLengthExtension(sessionClientExtensions, + sessionServerExtensions, AlertDescription.illegal_parameter); + + this.mSecurityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(sessionServerExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in + * a session resumption handshake. + */ + this.mAllowCertificateStatus = !this.mResumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.status_request, + AlertDescription.illegal_parameter); + + this.mExpectSessionTicket = !this.mResumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.session_ticket, + AlertDescription.illegal_parameter); + } + + /* + * TODO[session-hash] + * + * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes + * that do not use the extended master secret [..]. (and see 5.2, 5.3) + */ + + if (sessionClientExtensions != null) + { + this.mTlsClient.ProcessServerExtensions(sessionServerExtensions); + } + + this.mSecurityParameters.prfAlgorithm = GetPrfAlgorithm(Context, this.mSecurityParameters.CipherSuite); + + /* + * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify + * verify_data_length has a verify_data_length equal to 12. This includes all + * existing cipher suites. + */ + this.mSecurityParameters.verifyDataLength = 12; + } + + protected virtual void SendCertificateVerifyMessage(DigitallySigned certificateVerify) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_verify); + + certificateVerify.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendClientHelloMessage() + { + this.mRecordStream.SetWriteVersion(this.mTlsClient.ClientHelloRecordLayerVersion); + + ProtocolVersion client_version = this.mTlsClient.ClientVersion; + if (client_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ContextAdmin.SetClientVersion(client_version); + + /* + * TODO RFC 5077 3.4. When presenting a ticket, the client MAY generate and include a + * Session ID in the TLS ClientHello. + */ + byte[] session_id = TlsUtilities.EmptyBytes; + if (this.mTlsSession != null) + { + session_id = this.mTlsSession.SessionID; + if (session_id == null || session_id.Length > 32) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + bool fallback = this.mTlsClient.IsFallback; + + this.mOfferedCipherSuites = this.mTlsClient.GetCipherSuites(); + + this.mOfferedCompressionMethods = this.mTlsClient.GetCompressionMethods(); + + if (session_id.Length > 0 && this.mSessionParameters != null) + { + if (!Arrays.Contains(this.mOfferedCipherSuites, mSessionParameters.CipherSuite) + || !Arrays.Contains(this.mOfferedCompressionMethods, mSessionParameters.CompressionAlgorithm)) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + this.mClientExtensions = this.mTlsClient.GetClientExtensions(); + + HandshakeMessage message = new HandshakeMessage(HandshakeType.client_hello); + + TlsUtilities.WriteVersion(client_version, message); + + message.Write(this.mSecurityParameters.ClientRandom); + + TlsUtilities.WriteOpaque8(session_id, message); + + // Cipher Suites (and SCSV) + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(mClientExtensions, ExtensionType.renegotiation_info); + bool noRenegExt = (null == renegExtData); + + bool noRenegScsv = !Arrays.Contains(mOfferedCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + + if (noRenegExt && noRenegScsv) + { + // TODO Consider whether to default to a client extension instead + // this.mClientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(this.mClientExtensions); + // this.mClientExtensions[ExtensionType.renegotiation_info] = CreateRenegotiationInfo(TlsUtilities.EmptyBytes); + this.mOfferedCipherSuites = Arrays.Append(mOfferedCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + } + + /* + * RFC 7507 4. If a client sends a ClientHello.client_version containing a lower value + * than the latest (highest-valued) version supported by the client, it SHOULD include + * the TLS_FALLBACK_SCSV cipher suite value in ClientHello.cipher_suites [..]. (The + * client SHOULD put TLS_FALLBACK_SCSV after all cipher suites that it actually intends + * to negotiate.) + */ + if (fallback && !Arrays.Contains(mOfferedCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)) + { + this.mOfferedCipherSuites = Arrays.Append(mOfferedCipherSuites, CipherSuite.TLS_FALLBACK_SCSV); + } + + TlsUtilities.WriteUint16ArrayWithUint16Length(mOfferedCipherSuites, message); + } + + TlsUtilities.WriteUint8ArrayWithUint8Length(mOfferedCompressionMethods, message); + + if (mClientExtensions != null) + { + WriteExtensions(message, mClientExtensions); + } + + message.WriteToRecordStream(this); + } + + protected virtual void SendClientKeyExchangeMessage() + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.client_key_exchange); + + this.mKeyExchange.GenerateClientKeyExchange(message); + + message.WriteToRecordStream(this); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs.meta new file mode 100644 index 0000000..fbd6ed8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsClientProtocol.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: efd7608bc44f5434583f0ade20610e6c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs new file mode 100644 index 0000000..0d5bc49 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCompression + { + Stream Compress(Stream output); + + Stream Decompress(Stream output); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs.meta new file mode 100644 index 0000000..0037996 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCompression.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 118ee7f4845b75f4fa6d64e872b4f53e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs new file mode 100644 index 0000000..b921e5e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs @@ -0,0 +1,49 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsContext + { + IRandomGenerator NonceRandomGenerator { get; } + + SecureRandom SecureRandom { get; } + + SecurityParameters SecurityParameters { get; } + + bool IsServer { get; } + + ProtocolVersion ClientVersion { get; } + + ProtocolVersion ServerVersion { get; } + + /** + * Used to get the resumable session, if any, used by this connection. Only available after the + * handshake has successfully completed. + * + * @return A {@link TlsSession} representing the resumable session used by this connection, or + * null if no resumable session available. + * @see TlsPeer#NotifyHandshakeComplete() + */ + TlsSession ResumableSession { get; } + + object UserObject { get; set; } + + /** + * Export keying material according to RFC 5705: "Keying Material Exporters for TLS". + * + * @param asciiLabel indicates which application will use the exported keys. + * @param context_value allows the application using the exporter to mix its own data with the TLS PRF for + * the exporter output. + * @param length the number of bytes to generate + * @return a pseudorandom bit string of 'length' bytes generated from the master_secret. + */ + byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs.meta new file mode 100644 index 0000000..ae13edf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsContext.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 68ec95ad3cb7b5f4495addfe40c83363 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs new file mode 100644 index 0000000..126b0c1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCredentials + { + Certificate Certificate { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs.meta new file mode 100644 index 0000000..8cbfdbf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5bcedf628549c6d428c60b55b1c6286f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs new file mode 100644 index 0000000..3928d71 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs @@ -0,0 +1,228 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS DH key exchange. + public class TlsDHKeyExchange + : AbstractTlsKeyExchange + { + protected TlsSigner mTlsSigner; + protected DHParameters mDHParameters; + + protected AsymmetricKeyParameter mServerPublicKey; + protected TlsAgreementCredentials mAgreementCredentials; + + protected DHPrivateKeyParameters mDHAgreePrivateKey; + protected DHPublicKeyParameters mDHAgreePublicKey; + + public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) + : base(keyExchange, supportedSignatureAlgorithms) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DH_DSS: + this.mTlsSigner = null; + break; + case KeyExchangeAlgorithm.DHE_RSA: + this.mTlsSigner = new TlsRsaSigner(); + break; + case KeyExchangeAlgorithm.DHE_DSS: + this.mTlsSigner = new TlsDssSigner(); + break; + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + + this.mDHParameters = dhParameters; + } + + public override void Init(TlsContext context) + { + base.Init(context); + + if (this.mTlsSigner != null) + { + this.mTlsSigner.Init(context); + } + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.bad_certificate); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + if (mTlsSigner == null) + { + try + { + this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey); + this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement); + } + else + { + if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + } + + base.ProcessServerCertificate(serverCertificate); + } + + public override bool RequiresServerKeyExchange + { + get + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.DH_anon: + return true; + default: + return false; + } + } + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.rsa_fixed_dh: + case ClientCertificateType.dss_fixed_dh: + case ClientCertificateType.ecdsa_sign: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (clientCredentials is TlsAgreementCredentials) + { + // TODO Validate client cert has matching parameters (see 'areCompatibleParameters')? + + this.mAgreementCredentials = (TlsAgreementCredentials)clientCredentials; + } + else if (clientCredentials is TlsSignerCredentials) + { + // OK + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override void GenerateClientKeyExchange(Stream output) + { + /* + * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman + * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key + * Exchange message will be sent, but will be empty. + */ + if (mAgreementCredentials == null) + { + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, + mDHParameters, output); + } + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + // TODO Extract the public key and validate + + /* + * TODO If the certificate is 'fixed', take the public key as dhAgreePublicKey and check + * that the parameters match the server's (see 'areCompatibleParameters'). + */ + } + + public override void ProcessClientKeyExchange(Stream input) + { + if (mDHAgreePublicKey != null) + { + // For dss_fixed_dh and rsa_fixed_dh, the key arrived in the client certificate + return; + } + + BigInteger Yc = TlsDHUtilities.ReadDHParameter(input); + + this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Yc, mDHParameters)); + } + + public override byte[] GeneratePremasterSecret() + { + if (mAgreementCredentials != null) + { + return mAgreementCredentials.GenerateAgreement(mDHAgreePublicKey); + } + + if (mDHAgreePrivateKey != null) + { + return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual int MinimumPrimeBits + { + get { return 1024; } + } + + protected virtual DHParameters ValidateDHParameters(DHParameters parameters) + { + if (parameters.P.BitLength < MinimumPrimeBits) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + return TlsDHUtilities.ValidateDHParameters(parameters); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs.meta new file mode 100644 index 0000000..c4c1e8a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: da85cdeda01348a4b9c96d7be44452ea +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs new file mode 100644 index 0000000..afb383c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs @@ -0,0 +1,482 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsDHUtilities + { + internal static readonly BigInteger Two = BigInteger.Two; + + /* + * TODO[draft-ietf-tls-negotiated-ff-dhe-01] Move these groups to DHStandardGroups once reaches RFC + */ + private static BigInteger FromHex(String hex) + { + return new BigInteger(1, Hex.Decode(hex)); + } + + private static DHParameters FromSafeP(String hexP) + { + BigInteger p = FromHex(hexP), q = p.ShiftRight(1); + return new DHParameters(p, Two, q); + } + + private static readonly string draft_ffdhe2432_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE13098533C8B3FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe2432 = FromSafeP(draft_ffdhe2432_p); + + private static readonly string draft_ffdhe3072_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe3072 = FromSafeP(draft_ffdhe3072_p); + + private static readonly string draft_ffdhe4096_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A" + + "FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe4096 = FromSafeP(draft_ffdhe4096_p); + + private static readonly string draft_ffdhe6144_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe6144 = FromSafeP(draft_ffdhe6144_p); + + private static readonly string draft_ffdhe8192_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838" + + "1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E" + + "0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665" + + "CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282" + + "2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022" + + "BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C" + + "51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9" + + "D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457" + + "1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30" + + "FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D" + + "97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C" + + "D68C8BB7C5C6424CFFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe8192 = FromSafeP(draft_ffdhe8192_p); + + + public static void AddNegotiatedDheGroupsClientExtension(IDictionary extensions, byte[] dheGroups) + { + extensions[ExtensionType.negotiated_ff_dhe_groups] = CreateNegotiatedDheGroupsClientExtension(dheGroups); + } + + public static void AddNegotiatedDheGroupsServerExtension(IDictionary extensions, byte dheGroup) + { + extensions[ExtensionType.negotiated_ff_dhe_groups] = CreateNegotiatedDheGroupsServerExtension(dheGroup); + } + + public static byte[] GetNegotiatedDheGroupsClientExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.negotiated_ff_dhe_groups); + return extensionData == null ? null : ReadNegotiatedDheGroupsClientExtension(extensionData); + } + + public static short GetNegotiatedDheGroupsServerExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.negotiated_ff_dhe_groups); + return extensionData == null ? (short)-1 : (short)ReadNegotiatedDheGroupsServerExtension(extensionData); + } + + public static byte[] CreateNegotiatedDheGroupsClientExtension(byte[] dheGroups) + { + if (dheGroups == null || dheGroups.Length < 1 || dheGroups.Length > 255) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(dheGroups); + } + + public static byte[] CreateNegotiatedDheGroupsServerExtension(byte dheGroup) + { + return new byte[]{ dheGroup }; + } + + public static byte[] ReadNegotiatedDheGroupsClientExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + byte length = TlsUtilities.ReadUint8(buf); + if (length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] dheGroups = TlsUtilities.ReadUint8Array(length, buf); + + TlsProtocol.AssertEmpty(buf); + + return dheGroups; + } + + public static byte ReadNegotiatedDheGroupsServerExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + if (extensionData.Length != 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return extensionData[0]; + } + + public static DHParameters GetParametersForDHEGroup(short dheGroup) + { + switch (dheGroup) + { + case FiniteFieldDheGroup.ffdhe2432: + return draft_ffdhe2432; + case FiniteFieldDheGroup.ffdhe3072: + return draft_ffdhe3072; + case FiniteFieldDheGroup.ffdhe4096: + return draft_ffdhe4096; + case FiniteFieldDheGroup.ffdhe6144: + return draft_ffdhe6144; + case FiniteFieldDheGroup.ffdhe8192: + return draft_ffdhe8192; + default: + return null; + } + } + + public static bool ContainsDheCipherSuites(int[] cipherSuites) + { + for (int i = 0; i < cipherSuites.Length; ++i) + { + if (IsDheCipherSuite(cipherSuites[i])) + return true; + } + return false; + } + + public static bool IsDheCipherSuite(int cipherSuite) + { + switch (cipherSuite) + { + /* + * RFC 2246 + */ + case CipherSuite.TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_DES_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_DES_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + + /* + * RFC 3268 + */ + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + + /* + * RFC 5932 + */ + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + + /* + * RFC 4162 + */ + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + + /* + * RFC 4279 + */ + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + + /* + * RFC 4785 + */ + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + + /* + * RFC 5246 + */ + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + + /* + * RFC 5288 + */ + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + + /* + * RFC 5487 + */ + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + + /* + * RFC 6367 + */ + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + + /* + * RFC 6655 + */ + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + + /* + * draft-zauner-tls-aes-ocb-04 + */ + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB: + + return true; + + default: + return false; + } + } + + public static bool AreCompatibleParameters(DHParameters a, DHParameters b) + { + return a.P.Equals(b.P) && a.G.Equals(b.G) + && (a.Q == null || b.Q == null || a.Q.Equals(b.Q)); + } + + public static byte[] CalculateDHBasicAgreement(DHPublicKeyParameters publicKey, + DHPrivateKeyParameters privateKey) + { + DHBasicAgreement basicAgreement = new DHBasicAgreement(); + basicAgreement.Init(privateKey); + BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); + + /* + * RFC 5246 8.1.2. Leading bytes of Z that contain all zero bits are stripped before it is + * used as the pre_master_secret. + */ + return BigIntegers.AsUnsignedByteArray(agreementValue); + } + + public static AsymmetricCipherKeyPair GenerateDHKeyPair(SecureRandom random, DHParameters dhParams) + { + DHBasicKeyPairGenerator dhGen = new DHBasicKeyPairGenerator(); + dhGen.Init(new DHKeyGenerationParameters(random, dhParams)); + return dhGen.GenerateKeyPair(); + } + + public static DHPrivateKeyParameters GenerateEphemeralClientKeyExchange(SecureRandom random, + DHParameters dhParams, Stream output) + { + AsymmetricCipherKeyPair kp = GenerateDHKeyPair(random, dhParams); + + DHPublicKeyParameters dhPublic = (DHPublicKeyParameters)kp.Public; + WriteDHParameter(dhPublic.Y, output); + + return (DHPrivateKeyParameters)kp.Private; + } + + public static DHPrivateKeyParameters GenerateEphemeralServerKeyExchange(SecureRandom random, + DHParameters dhParams, Stream output) + { + AsymmetricCipherKeyPair kp = GenerateDHKeyPair(random, dhParams); + + DHPublicKeyParameters dhPublic = (DHPublicKeyParameters)kp.Public; + new ServerDHParams(dhPublic).Encode(output); + + return (DHPrivateKeyParameters)kp.Private; + } + + public static DHParameters ValidateDHParameters(DHParameters parameters) + { + BigInteger p = parameters.P; + BigInteger g = parameters.G; + + if (!p.IsProbablePrime(2)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + if (g.CompareTo(Two) < 0 || g.CompareTo(p.Subtract(Two)) > 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + + return parameters; + } + + public static DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key) + { + DHParameters parameters = ValidateDHParameters(key.Parameters); + + BigInteger Y = key.Y; + if (Y.CompareTo(Two) < 0 || Y.CompareTo(parameters.P.Subtract(Two)) > 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + // TODO See RFC 2631 for more discussion of Diffie-Hellman validation + + return key; + } + + public static BigInteger ReadDHParameter(Stream input) + { + return new BigInteger(1, TlsUtilities.ReadOpaque16(input)); + } + + public static void WriteDHParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs.meta new file mode 100644 index 0000000..f7c5efd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDHUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1436a65a79102a14080a0a51db47d919 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs new file mode 100644 index 0000000..69b6c8b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs @@ -0,0 +1,72 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsDeflateCompression : TlsCompression + { + public const int LEVEL_NONE = JZlib.Z_NO_COMPRESSION; + public const int LEVEL_FASTEST = JZlib.Z_BEST_SPEED; + public const int LEVEL_SMALLEST = JZlib.Z_BEST_COMPRESSION; + public const int LEVEL_DEFAULT = JZlib.Z_DEFAULT_COMPRESSION; + + protected readonly ZStream zIn, zOut; + + public TlsDeflateCompression() + : this(LEVEL_DEFAULT) + { + } + + public TlsDeflateCompression(int level) + { + this.zIn = new ZStream(); + this.zIn.inflateInit(); + + this.zOut = new ZStream(); + this.zOut.deflateInit(level); + } + + public virtual Stream Compress(Stream output) + { + return new DeflateOutputStream(output, zOut, true); + } + + public virtual Stream Decompress(Stream output) + { + return new DeflateOutputStream(output, zIn, false); + } + + protected class DeflateOutputStream : ZOutputStream + { + public DeflateOutputStream(Stream output, ZStream z, bool compress) + : base(output, z) + { + this.compress = compress; + + /* + * See discussion at http://www.bolet.org/~pornin/deflate-flush.html . + */ + this.FlushMode = JZlib.Z_SYNC_FLUSH; + } + + public override void Flush() + { + /* + * TODO The inflateSyncPoint doesn't appear to work the way I hoped at the moment. + * In any case, we may like to accept PARTIAL_FLUSH input, not just SYNC_FLUSH. + * It's not clear how to check this in the Inflater. + */ + //if (!this.compress && (z == null || z.istate == null || z.istate.inflateSyncPoint(z) <= 0)) + //{ + // throw new TlsFatalAlert(AlertDescription.decompression_failure); + //} + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs.meta new file mode 100644 index 0000000..09b7636 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDeflateCompression.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4fa4a39186a3e43409048df72c4447a3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs new file mode 100644 index 0000000..5dc93f3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs @@ -0,0 +1,98 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsDheKeyExchange + : TlsDHKeyExchange + { + protected TlsSignerCredentials mServerCredentials = null; + + public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) + : base(keyExchange, supportedSignatureAlgorithms, dhParameters) + { + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsSignerCredentials)serverCredentials; + } + + public override byte[] GenerateServerKeyExchange() + { + if (this.mDHParameters == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + DigestInputBuffer buf = new DigestInputBuffer(); + + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, + this.mDHParameters, buf); + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + mContext, mServerCredentials); + + IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); + + SecurityParameters securityParameters = mContext.SecurityParameters; + d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + buf.UpdateDigest(d); + + byte[] hash = DigestUtilities.DoFinal(d); + + byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); + + DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); + signed_params.Encode(buf); + + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + SecurityParameters securityParameters = mContext.SecurityParameters; + + SignerInputBuffer buf = new SignerInputBuffer(); + Stream teeIn = new TeeInputStream(input, buf); + + ServerDHParams dhParams = ServerDHParams.Parse(teeIn); + + DigitallySigned signed_params = ParseSignature(input); + + ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); + buf.UpdateSigner(signer); + if (!signer.VerifySignature(signed_params.Signature)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + + this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey); + this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); + } + + protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, + SecurityParameters securityParameters) + { + ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey); + signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + return signer; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs.meta new file mode 100644 index 0000000..d953597 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDheKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fdd022dd94e7a09428adb6043fc75a79 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs new file mode 100644 index 0000000..48a08cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs @@ -0,0 +1,86 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsDsaSigner + : AbstractTlsSigner + { + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, true, + new ParametersWithRandom(privateKey, this.mContext.SecureRandom)); + if (algorithm == null) + { + // Note: Only use the SHA1 part of the (MD5/SHA1) hash + signer.BlockUpdate(hash, 16, 20); + } + else + { + signer.BlockUpdate(hash, 0, hash.Length); + } + return signer.GenerateSignature(); + } + + public override bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, false, publicKey); + if (algorithm == null) + { + // Note: Only use the SHA1 part of the (MD5/SHA1) hash + signer.BlockUpdate(hash, 16, 20); + } + else + { + signer.BlockUpdate(hash, 0, hash.Length); + } + return signer.VerifySignature(sigBytes); + } + + public override ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey) + { + return MakeSigner(algorithm, false, true, privateKey); + } + + public override ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey) + { + return MakeSigner(algorithm, false, false, publicKey); + } + + protected virtual ICipherParameters MakeInitParameters(bool forSigning, ICipherParameters cp) + { + return cp; + } + + protected virtual ISigner MakeSigner(SignatureAndHashAlgorithm algorithm, bool raw, bool forSigning, + ICipherParameters cp) + { + if ((algorithm != null) != TlsUtilities.IsTlsV12(mContext)) + throw new InvalidOperationException(); + + if (algorithm != null && algorithm.Signature != SignatureAlgorithm) + throw new InvalidOperationException(); + + byte hashAlgorithm = algorithm == null ? HashAlgorithm.sha1 : algorithm.Hash; + IDigest d = raw ? new NullDigest() : TlsUtilities.CreateHash(hashAlgorithm); + + ISigner s = new DsaDigestSigner(CreateDsaImpl(hashAlgorithm), d); + s.Init(forSigning, MakeInitParameters(forSigning, cp)); + return s; + } + + protected abstract byte SignatureAlgorithm { get; } + + protected abstract IDsa CreateDsaImpl(byte hashAlgorithm); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs.meta new file mode 100644 index 0000000..7eec84d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDsaSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 622a2d819dc4f73468f75ba7ab9ed160 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs new file mode 100644 index 0000000..bd3d726 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs @@ -0,0 +1,30 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsDssSigner + : TlsDsaSigner + { + public override bool IsValidPublicKey(AsymmetricKeyParameter publicKey) + { + return publicKey is DsaPublicKeyParameters; + } + + protected override IDsa CreateDsaImpl(byte hashAlgorithm) + { + return new DsaSigner(new HMacDsaKCalculator(TlsUtilities.CreateHash(hashAlgorithm))); + } + + protected override byte SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.dsa; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs.meta new file mode 100644 index 0000000..fa2f98f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsDssSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c91b91e67a1e0ab44a98aec094cb08ec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs new file mode 100644 index 0000000..cd28099 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs @@ -0,0 +1,253 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS ECDH key exchange (see RFC 4492). + public class TlsECDHKeyExchange + : AbstractTlsKeyExchange + { + protected TlsSigner mTlsSigner; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected AsymmetricKeyParameter mServerPublicKey; + protected TlsAgreementCredentials mAgreementCredentials; + + protected ECPrivateKeyParameters mECAgreePrivateKey; + protected ECPublicKeyParameters mECAgreePublicKey; + + public TlsECDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves, + byte[] clientECPointFormats, byte[] serverECPointFormats) + : base(keyExchange, supportedSignatureAlgorithms) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.ECDHE_RSA: + this.mTlsSigner = new TlsRsaSigner(); + break; + case KeyExchangeAlgorithm.ECDHE_ECDSA: + this.mTlsSigner = new TlsECDsaSigner(); + break; + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDH_ECDSA: + this.mTlsSigner = null; + break; + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + + this.mNamedCurves = namedCurves; + this.mClientECPointFormats = clientECPointFormats; + this.mServerECPointFormats = serverECPointFormats; + } + + public override void Init(TlsContext context) + { + base.Init(context); + + if (this.mTlsSigner != null) + { + this.mTlsSigner.Init(context); + } + } + + public override void SkipServerCredentials() + { + if (mKeyExchange != KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.bad_certificate); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + if (mTlsSigner == null) + { + try + { + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey((ECPublicKeyParameters) this.mServerPublicKey); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement); + } + else + { + if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + } + + base.ProcessServerCertificate(serverCertificate); + } + + public override bool RequiresServerKeyExchange + { + get + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return true; + default: + return false; + } + } + } + + public override byte[] GenerateServerKeyExchange() + { + if (!RequiresServerKeyExchange) + return null; + + // ECDH_anon is handled here, ECDHE_* in a subclass + + MemoryStream buf = new MemoryStream(); + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, + mClientECPointFormats, buf); + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + if (!RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // ECDH_anon is handled here, ECDHE_* in a subclass + + ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input); + + byte[] point = TlsUtilities.ReadOpaque8(input); + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mClientECPointFormats, curve_params, point)); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + /* + * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with + * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because + * the use of a long-term ECDH client key would jeopardize the forward secrecy property of + * these algorithms. + */ + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + case ClientCertificateType.rsa_fixed_ecdh: + case ClientCertificateType.ecdsa_fixed_ecdh: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (clientCredentials is TlsAgreementCredentials) + { + // TODO Validate client cert has matching parameters (see 'TlsEccUtilities.AreOnSameCurve')? + + this.mAgreementCredentials = (TlsAgreementCredentials)clientCredentials; + } + else if (clientCredentials is TlsSignerCredentials) + { + // OK + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override void GenerateClientKeyExchange(Stream output) + { + if (mAgreementCredentials == null) + { + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, + mServerECPointFormats, mECAgreePublicKey.Parameters, output); + } + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // TODO Extract the public key + // TODO If the certificate is 'fixed', take the public key as mECAgreeClientPublicKey + } + + public override void ProcessClientKeyExchange(Stream input) + { + if (mECAgreePublicKey != null) + { + // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate + return; + } + + byte[] point = TlsUtilities.ReadOpaque8(input); + + ECDomainParameters curve_params = this.mECAgreePrivateKey.Parameters; + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mServerECPointFormats, curve_params, point)); + } + + public override byte[] GeneratePremasterSecret() + { + if (mAgreementCredentials != null) + { + return mAgreementCredentials.GenerateAgreement(mECAgreePublicKey); + } + + if (mECAgreePrivateKey != null) + { + return TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs.meta new file mode 100644 index 0000000..3ea6eb0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDHKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d82e1a91d4c267149beadc33b13b1e13 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs new file mode 100644 index 0000000..21b7dd5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs @@ -0,0 +1,135 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS ECDHE key exchange (see RFC 4492). + public class TlsECDheKeyExchange + : TlsECDHKeyExchange + { + protected TlsSignerCredentials mServerCredentials = null; + + public TlsECDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves, + byte[] clientECPointFormats, byte[] serverECPointFormats) + : base(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats) + { + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsSignerCredentials)serverCredentials; + } + + public override byte[] GenerateServerKeyExchange() + { + DigestInputBuffer buf = new DigestInputBuffer(); + + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, + mClientECPointFormats, buf); + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + mContext, mServerCredentials); + + IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); + + SecurityParameters securityParameters = mContext.SecurityParameters; + d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + buf.UpdateDigest(d); + + byte[] hash = DigestUtilities.DoFinal(d); + + byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); + + DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); + signed_params.Encode(buf); + + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + SecurityParameters securityParameters = mContext.SecurityParameters; + + SignerInputBuffer buf = new SignerInputBuffer(); + Stream teeIn = new TeeInputStream(input, buf); + + ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, teeIn); + + byte[] point = TlsUtilities.ReadOpaque8(teeIn); + + DigitallySigned signed_params = ParseSignature(input); + + ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); + buf.UpdateSigner(signer); + if (!signer.VerifySignature(signed_params.Signature)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mClientECPointFormats, curve_params, point)); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + /* + * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with + * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because + * the use of a long-term ECDH client key would jeopardize the forward secrecy property of + * these algorithms. + */ + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (clientCredentials is TlsSignerCredentials) + { + // OK + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, + SecurityParameters securityParameters) + { + ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey); + signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + return signer; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs.meta new file mode 100644 index 0000000..5084c38 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDheKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 45ad60ff6d1404b4aa76988fb43dee8e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs new file mode 100644 index 0000000..e9c5e18 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs @@ -0,0 +1,30 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsECDsaSigner + : TlsDsaSigner + { + public override bool IsValidPublicKey(AsymmetricKeyParameter publicKey) + { + return publicKey is ECPublicKeyParameters; + } + + protected override IDsa CreateDsaImpl(byte hashAlgorithm) + { + return new ECDsaSigner(new HMacDsaKCalculator(TlsUtilities.CreateHash(hashAlgorithm))); + } + + protected override byte SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.ecdsa; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs.meta new file mode 100644 index 0000000..c90c6c7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsECDsaSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32521fa89cfa36546ae5d24cec11efb5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs new file mode 100644 index 0000000..f2baf9f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs @@ -0,0 +1,722 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsEccUtilities + { + private static readonly string[] CurveNames = new string[] { "sect163k1", "sect163r1", "sect163r2", "sect193r1", + "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", + "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1", + "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1", + "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1"}; + + public static void AddSupportedEllipticCurvesExtension(IDictionary extensions, int[] namedCurves) + { + extensions[ExtensionType.elliptic_curves] = CreateSupportedEllipticCurvesExtension(namedCurves); + } + + public static void AddSupportedPointFormatsExtension(IDictionary extensions, byte[] ecPointFormats) + { + extensions[ExtensionType.ec_point_formats] = CreateSupportedPointFormatsExtension(ecPointFormats); + } + + public static int[] GetSupportedEllipticCurvesExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.elliptic_curves); + return extensionData == null ? null : ReadSupportedEllipticCurvesExtension(extensionData); + } + + public static byte[] GetSupportedPointFormatsExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.ec_point_formats); + return extensionData == null ? null : ReadSupportedPointFormatsExtension(extensionData); + } + + public static byte[] CreateSupportedEllipticCurvesExtension(int[] namedCurves) + { + if (namedCurves == null || namedCurves.Length < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint16ArrayWithUint16Length(namedCurves); + } + + public static byte[] CreateSupportedPointFormatsExtension(byte[] ecPointFormats) + { + if (ecPointFormats == null || !Arrays.Contains(ecPointFormats, ECPointFormat.uncompressed)) + { + /* + * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST + * contain the value 0 (uncompressed) as one of the items in the list of point formats. + */ + + // NOTE: We add it at the end (lowest preference) + ecPointFormats = Arrays.Append(ecPointFormats, ECPointFormat.uncompressed); + } + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(ecPointFormats); + } + + public static int[] ReadSupportedEllipticCurvesExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int[] namedCurves = TlsUtilities.ReadUint16Array(length / 2, buf); + + TlsProtocol.AssertEmpty(buf); + + return namedCurves; + } + + public static byte[] ReadSupportedPointFormatsExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + byte length = TlsUtilities.ReadUint8(buf); + if (length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] ecPointFormats = TlsUtilities.ReadUint8Array(length, buf); + + TlsProtocol.AssertEmpty(buf); + + if (!Arrays.Contains(ecPointFormats, ECPointFormat.uncompressed)) + { + /* + * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST + * contain the value 0 (uncompressed) as one of the items in the list of point formats. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + return ecPointFormats; + } + + public static string GetNameOfNamedCurve(int namedCurve) + { + return IsSupportedNamedCurve(namedCurve) ? CurveNames[namedCurve - 1] : null; + } + + public static ECDomainParameters GetParametersForNamedCurve(int namedCurve) + { + string curveName = GetNameOfNamedCurve(namedCurve); + if (curveName == null) + return null; + + // Parameters are lazily created the first time a particular curve is accessed + + X9ECParameters ecP = CustomNamedCurves.GetByName(curveName); + if (ecP == null) + { + ecP = ECNamedCurveTable.GetByName(curveName); + if (ecP == null) + return null; + } + + // It's a bit inefficient to do this conversion every time + return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + } + + public static bool HasAnySupportedNamedCurves() + { + return CurveNames.Length > 0; + } + + public static bool ContainsEccCipherSuites(int[] cipherSuites) + { + for (int i = 0; i < cipherSuites.Length; ++i) + { + if (IsEccCipherSuite(cipherSuites[i])) + return true; + } + return false; + } + + public static bool IsEccCipherSuite(int cipherSuite) + { + switch (cipherSuite) + { + /* + * RFC 4492 + */ + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + + /* + * RFC 5289 + */ + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + + /* + * RFC 5489 + */ + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + + /* + * RFC 6367 + */ + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + + /* + * RFC 7251 + */ + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + + /* + * draft-zauner-tls-aes-ocb-04 + */ + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB: + + return true; + + default: + return false; + } + } + + public static bool AreOnSameCurve(ECDomainParameters a, ECDomainParameters b) + { + return a != null && a.Equals(b); + } + + public static bool IsSupportedNamedCurve(int namedCurve) + { + return (namedCurve > 0 && namedCurve <= CurveNames.Length); + } + + public static bool IsCompressionPreferred(byte[] ecPointFormats, byte compressionFormat) + { + if (ecPointFormats == null) + return false; + + for (int i = 0; i < ecPointFormats.Length; ++i) + { + byte ecPointFormat = ecPointFormats[i]; + if (ecPointFormat == ECPointFormat.uncompressed) + return false; + if (ecPointFormat == compressionFormat) + return true; + } + return false; + } + + public static byte[] SerializeECFieldElement(int fieldSize, BigInteger x) + { + return BigIntegers.AsUnsignedByteArray((fieldSize + 7) / 8, x); + } + + public static byte[] SerializeECPoint(byte[] ecPointFormats, ECPoint point) + { + ECCurve curve = point.Curve; + + /* + * RFC 4492 5.7. ...an elliptic curve point in uncompressed or compressed format. Here, the + * format MUST conform to what the server has requested through a Supported Point Formats + * Extension if this extension was used, and MUST be uncompressed if this extension was not + * used. + */ + bool compressed = false; + if (ECAlgorithms.IsFpCurve(curve)) + { + compressed = IsCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_prime); + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + compressed = IsCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_char2); + } + return point.GetEncoded(compressed); + } + + public static byte[] SerializeECPublicKey(byte[] ecPointFormats, ECPublicKeyParameters keyParameters) + { + return SerializeECPoint(ecPointFormats, keyParameters.Q); + } + + public static BigInteger DeserializeECFieldElement(int fieldSize, byte[] encoding) + { + int requiredLength = (fieldSize + 7) / 8; + if (encoding.Length != requiredLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + return new BigInteger(1, encoding); + } + + public static ECPoint DeserializeECPoint(byte[] ecPointFormats, ECCurve curve, byte[] encoding) + { + if (encoding == null || encoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + byte actualFormat; + switch (encoding[0]) + { + case 0x02: // compressed + case 0x03: // compressed + { + if (ECAlgorithms.IsF2mCurve(curve)) + { + actualFormat = ECPointFormat.ansiX962_compressed_char2; + } + else if (ECAlgorithms.IsFpCurve(curve)) + { + actualFormat = ECPointFormat.ansiX962_compressed_prime; + } + else + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + break; + } + case 0x04: // uncompressed + { + actualFormat = ECPointFormat.uncompressed; + break; + } + case 0x00: // infinity + case 0x06: // hybrid + case 0x07: // hybrid + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + if (actualFormat != ECPointFormat.uncompressed + && (ecPointFormats == null || !Arrays.Contains(ecPointFormats, actualFormat))) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + return curve.DecodePoint(encoding); + } + + public static ECPublicKeyParameters DeserializeECPublicKey(byte[] ecPointFormats, ECDomainParameters curve_params, + byte[] encoding) + { + try + { + ECPoint Y = DeserializeECPoint(ecPointFormats, curve_params.Curve, encoding); + return new ECPublicKeyParameters(Y, curve_params); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + public static byte[] CalculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) + { + ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); + basicAgreement.Init(privateKey); + BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); + + /* + * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by + * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for + * any given field; leading zeros found in this octet string MUST NOT be truncated. + */ + return BigIntegers.AsUnsignedByteArray(basicAgreement.GetFieldSize(), agreementValue); + } + + public static AsymmetricCipherKeyPair GenerateECKeyPair(SecureRandom random, ECDomainParameters ecParams) + { + ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); + keyPairGenerator.Init(new ECKeyGenerationParameters(ecParams, random)); + return keyPairGenerator.GenerateKeyPair(); + } + + public static ECPrivateKeyParameters GenerateEphemeralClientKeyExchange(SecureRandom random, byte[] ecPointFormats, + ECDomainParameters ecParams, Stream output) + { + AsymmetricCipherKeyPair kp = GenerateECKeyPair(random, ecParams); + + ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters)kp.Public; + WriteECPoint(ecPointFormats, ecPublicKey.Q, output); + + return (ECPrivateKeyParameters)kp.Private; + } + + // TODO Refactor around ServerECDHParams before making this public + internal static ECPrivateKeyParameters GenerateEphemeralServerKeyExchange(SecureRandom random, int[] namedCurves, + byte[] ecPointFormats, Stream output) + { + /* First we try to find a supported named curve from the client's list. */ + int namedCurve = -1; + if (namedCurves == null) + { + // TODO Let the peer choose the default named curve + namedCurve = NamedCurve.secp256r1; + } + else + { + for (int i = 0; i < namedCurves.Length; ++i) + { + int entry = namedCurves[i]; + if (NamedCurve.IsValid(entry) && IsSupportedNamedCurve(entry)) + { + namedCurve = entry; + break; + } + } + } + + ECDomainParameters ecParams = null; + if (namedCurve >= 0) + { + ecParams = GetParametersForNamedCurve(namedCurve); + } + else + { + /* If no named curves are suitable, check if the client supports explicit curves. */ + if (Arrays.Contains(namedCurves, NamedCurve.arbitrary_explicit_prime_curves)) + { + ecParams = GetParametersForNamedCurve(NamedCurve.secp256r1); + } + else if (Arrays.Contains(namedCurves, NamedCurve.arbitrary_explicit_char2_curves)) + { + ecParams = GetParametersForNamedCurve(NamedCurve.sect283r1); + } + } + + if (ecParams == null) + { + /* + * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find + * a suitable curve. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + if (namedCurve < 0) + { + WriteExplicitECParameters(ecPointFormats, ecParams, output); + } + else + { + WriteNamedECParameters(namedCurve, output); + } + + return GenerateEphemeralClientKeyExchange(random, ecPointFormats, ecParams, output); + } + + public static ECPublicKeyParameters ValidateECPublicKey(ECPublicKeyParameters key) + { + // TODO Check RFC 4492 for validation + return key; + } + + public static int ReadECExponent(int fieldSize, Stream input) + { + BigInteger K = ReadECParameter(input); + if (K.BitLength < 32) + { + int k = K.IntValue; + if (k > 0 && k < fieldSize) + { + return k; + } + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + public static BigInteger ReadECFieldElement(int fieldSize, Stream input) + { + return DeserializeECFieldElement(fieldSize, TlsUtilities.ReadOpaque8(input)); + } + + public static BigInteger ReadECParameter(Stream input) + { + // TODO Are leading zeroes okay here? + return new BigInteger(1, TlsUtilities.ReadOpaque8(input)); + } + + public static ECDomainParameters ReadECParameters(int[] namedCurves, byte[] ecPointFormats, Stream input) + { + try + { + byte curveType = TlsUtilities.ReadUint8(input); + + switch (curveType) + { + case ECCurveType.explicit_prime: + { + CheckNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_prime_curves); + + BigInteger prime_p = ReadECParameter(input); + BigInteger a = ReadECFieldElement(prime_p.BitLength, input); + BigInteger b = ReadECFieldElement(prime_p.BitLength, input); + byte[] baseEncoding = TlsUtilities.ReadOpaque8(input); + BigInteger order = ReadECParameter(input); + BigInteger cofactor = ReadECParameter(input); + ECCurve curve = new FpCurve(prime_p, a, b, order, cofactor); + ECPoint basePoint = DeserializeECPoint(ecPointFormats, curve, baseEncoding); + return new ECDomainParameters(curve, basePoint, order, cofactor); + } + case ECCurveType.explicit_char2: + { + CheckNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_char2_curves); + + int m = TlsUtilities.ReadUint16(input); + byte basis = TlsUtilities.ReadUint8(input); + if (!ECBasisType.IsValid(basis)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + int k1 = ReadECExponent(m, input), k2 = -1, k3 = -1; + if (basis == ECBasisType.ec_basis_pentanomial) + { + k2 = ReadECExponent(m, input); + k3 = ReadECExponent(m, input); + } + + BigInteger a = ReadECFieldElement(m, input); + BigInteger b = ReadECFieldElement(m, input); + byte[] baseEncoding = TlsUtilities.ReadOpaque8(input); + BigInteger order = ReadECParameter(input); + BigInteger cofactor = ReadECParameter(input); + + ECCurve curve = (basis == ECBasisType.ec_basis_pentanomial) + ? new F2mCurve(m, k1, k2, k3, a, b, order, cofactor) + : new F2mCurve(m, k1, a, b, order, cofactor); + + ECPoint basePoint = DeserializeECPoint(ecPointFormats, curve, baseEncoding); + + return new ECDomainParameters(curve, basePoint, order, cofactor); + } + case ECCurveType.named_curve: + { + int namedCurve = TlsUtilities.ReadUint16(input); + if (!NamedCurve.RefersToASpecificNamedCurve(namedCurve)) + { + /* + * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a + * specific curve. Values of NamedCurve that indicate support for a class of + * explicitly defined curves are not allowed here [...]. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + CheckNamedCurve(namedCurves, namedCurve); + + return GetParametersForNamedCurve(namedCurve); + } + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + private static void CheckNamedCurve(int[] namedCurves, int namedCurve) + { + if (namedCurves != null && !Arrays.Contains(namedCurves, namedCurve)) + { + /* + * RFC 4492 4. [...] servers MUST NOT negotiate the use of an ECC cipher suite + * unless they can complete the handshake while respecting the choice of curves + * and compression techniques specified by the client. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + public static void WriteECExponent(int k, Stream output) + { + BigInteger K = BigInteger.ValueOf(k); + WriteECParameter(K, output); + } + + public static void WriteECFieldElement(ECFieldElement x, Stream output) + { + TlsUtilities.WriteOpaque8(x.GetEncoded(), output); + } + + public static void WriteECFieldElement(int fieldSize, BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque8(SerializeECFieldElement(fieldSize, x), output); + } + + public static void WriteECParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque8(BigIntegers.AsUnsignedByteArray(x), output); + } + + public static void WriteExplicitECParameters(byte[] ecPointFormats, ECDomainParameters ecParameters, + Stream output) + { + ECCurve curve = ecParameters.Curve; + + if (ECAlgorithms.IsFpCurve(curve)) + { + TlsUtilities.WriteUint8(ECCurveType.explicit_prime, output); + + WriteECParameter(curve.Field.Characteristic, output); + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field; + int[] exponents = field.MinimalPolynomial.GetExponentsPresent(); + + TlsUtilities.WriteUint8(ECCurveType.explicit_char2, output); + + int m = exponents[exponents.Length - 1]; + TlsUtilities.CheckUint16(m); + TlsUtilities.WriteUint16(m, output); + + if (exponents.Length == 3) + { + TlsUtilities.WriteUint8(ECBasisType.ec_basis_trinomial, output); + WriteECExponent(exponents[1], output); + } + else if (exponents.Length == 5) + { + TlsUtilities.WriteUint8(ECBasisType.ec_basis_pentanomial, output); + WriteECExponent(exponents[1], output); + WriteECExponent(exponents[2], output); + WriteECExponent(exponents[3], output); + } + else + { + throw new ArgumentException("Only trinomial and pentomial curves are supported"); + } + } + else + { + throw new ArgumentException("'ecParameters' not a known curve type"); + } + + WriteECFieldElement(curve.A, output); + WriteECFieldElement(curve.B, output); + TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, ecParameters.G), output); + WriteECParameter(ecParameters.N, output); + WriteECParameter(ecParameters.H, output); + } + + public static void WriteECPoint(byte[] ecPointFormats, ECPoint point, Stream output) + { + TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, point), output); + } + + public static void WriteNamedECParameters(int namedCurve, Stream output) + { + if (!NamedCurve.RefersToASpecificNamedCurve(namedCurve)) + { + /* + * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a specific + * curve. Values of NamedCurve that indicate support for a class of explicitly defined + * curves are not allowed here [...]. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + TlsUtilities.WriteUint8(ECCurveType.named_curve, output); + TlsUtilities.CheckUint16(namedCurve); + TlsUtilities.WriteUint16(namedCurve, output); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs.meta new file mode 100644 index 0000000..f8e3349 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEccUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 552941c9df6a1f841a85c7ff8312731b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs new file mode 100644 index 0000000..53711e1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsEncryptionCredentials + : TlsCredentials + { + /// + byte[] DecryptPreMasterSecret(byte[] encryptedPreMasterSecret); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs.meta new file mode 100644 index 0000000..1af934d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsEncryptionCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: df922784ce60a3e42b03ed7c6f114886 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs new file mode 100644 index 0000000..409f075 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs @@ -0,0 +1,296 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsExtensionsUtilities + { + public static IDictionary EnsureExtensionsInitialised(IDictionary extensions) + { + return extensions == null ? Org.BouncyCastle.Utilities.Platform.CreateHashtable() : extensions; + } + + public static void AddEncryptThenMacExtension(IDictionary extensions) + { + extensions[ExtensionType.encrypt_then_mac] = CreateEncryptThenMacExtension(); + } + + public static void AddExtendedMasterSecretExtension(IDictionary extensions) + { + extensions[ExtensionType.extended_master_secret] = CreateExtendedMasterSecretExtension(); + } + + /// + public static void AddHeartbeatExtension(IDictionary extensions, HeartbeatExtension heartbeatExtension) + { + extensions[ExtensionType.heartbeat] = CreateHeartbeatExtension(heartbeatExtension); + } + + /// + public static void AddMaxFragmentLengthExtension(IDictionary extensions, byte maxFragmentLength) + { + extensions[ExtensionType.max_fragment_length] = CreateMaxFragmentLengthExtension(maxFragmentLength); + } + + /// + public static void AddPaddingExtension(IDictionary extensions, int dataLength) + { + extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength); + } + + /// + public static void AddServerNameExtension(IDictionary extensions, ServerNameList serverNameList) + { + extensions[ExtensionType.server_name] = CreateServerNameExtension(serverNameList); + } + + /// + public static void AddStatusRequestExtension(IDictionary extensions, CertificateStatusRequest statusRequest) + { + extensions[ExtensionType.status_request] = CreateStatusRequestExtension(statusRequest); + } + + public static void AddTruncatedHMacExtension(IDictionary extensions) + { + extensions[ExtensionType.truncated_hmac] = CreateTruncatedHMacExtension(); + } + + /// + public static HeartbeatExtension GetHeartbeatExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.heartbeat); + return extensionData == null ? null : ReadHeartbeatExtension(extensionData); + } + + /// + public static short GetMaxFragmentLengthExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.max_fragment_length); + return extensionData == null ? (short)-1 : (short)ReadMaxFragmentLengthExtension(extensionData); + } + + /// + public static int GetPaddingExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding); + return extensionData == null ? -1 : ReadPaddingExtension(extensionData); + } + + /// + public static ServerNameList GetServerNameExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name); + return extensionData == null ? null : ReadServerNameExtension(extensionData); + } + + /// + public static CertificateStatusRequest GetStatusRequestExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request); + return extensionData == null ? null : ReadStatusRequestExtension(extensionData); + } + + /// + public static bool HasEncryptThenMacExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.encrypt_then_mac); + return extensionData == null ? false : ReadEncryptThenMacExtension(extensionData); + } + + /// + public static bool HasExtendedMasterSecretExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.extended_master_secret); + return extensionData == null ? false : ReadExtendedMasterSecretExtension(extensionData); + } + + /// + public static bool HasTruncatedHMacExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.truncated_hmac); + return extensionData == null ? false : ReadTruncatedHMacExtension(extensionData); + } + + public static byte[] CreateEmptyExtensionData() + { + return TlsUtilities.EmptyBytes; + } + + public static byte[] CreateEncryptThenMacExtension() + { + return CreateEmptyExtensionData(); + } + + public static byte[] CreateExtendedMasterSecretExtension() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateHeartbeatExtension(HeartbeatExtension heartbeatExtension) + { + if (heartbeatExtension == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + heartbeatExtension.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateMaxFragmentLengthExtension(byte maxFragmentLength) + { + return new byte[]{ maxFragmentLength }; + } + + /// + public static byte[] CreatePaddingExtension(int dataLength) + { + TlsUtilities.CheckUint16(dataLength); + return new byte[dataLength]; + } + + /// + public static byte[] CreateServerNameExtension(ServerNameList serverNameList) + { + if (serverNameList == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + serverNameList.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateStatusRequestExtension(CertificateStatusRequest statusRequest) + { + if (statusRequest == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + MemoryStream buf = new MemoryStream(); + + statusRequest.Encode(buf); + + return buf.ToArray(); + } + + public static byte[] CreateTruncatedHMacExtension() + { + return CreateEmptyExtensionData(); + } + + /// + private static bool ReadEmptyExtensionData(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + if (extensionData.Length != 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return true; + } + + /// + public static bool ReadEncryptThenMacExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static bool ReadExtendedMasterSecretExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static HeartbeatExtension ReadHeartbeatExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + HeartbeatExtension heartbeatExtension = HeartbeatExtension.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return heartbeatExtension; + } + + /// + public static short ReadMaxFragmentLengthExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + if (extensionData.Length != 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return extensionData[0]; + } + + /// + public static int ReadPaddingExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + for (int i = 0; i < extensionData.Length; ++i) + { + if (extensionData[i] != 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + return extensionData.Length; + } + + /// + public static ServerNameList ReadServerNameExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + ServerNameList serverNameList = ServerNameList.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return serverNameList; + } + + /// + public static CertificateStatusRequest ReadStatusRequestExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + CertificateStatusRequest statusRequest = CertificateStatusRequest.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return statusRequest; + } + + /// + public static bool ReadTruncatedHMacExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs.meta new file mode 100644 index 0000000..0e16bab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsExtensionsUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: acef69aa55d244f45ad92252311061c1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs new file mode 100644 index 0000000..4cb6e93 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs @@ -0,0 +1,31 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsFatalAlert + : IOException + { + private readonly byte alertDescription; + + public TlsFatalAlert(byte alertDescription) + : this(alertDescription, null) + { + } + + public TlsFatalAlert(byte alertDescription, Exception alertCause) + : base(Tls.AlertDescription.GetText(alertDescription), alertCause) + { + this.alertDescription = alertDescription; + } + + public virtual byte AlertDescription + { + get { return alertDescription; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs.meta new file mode 100644 index 0000000..82e77c6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsFatalAlert.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ffee8525007c0ac4ab970389710de6ff +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs new file mode 100644 index 0000000..498bb97 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs @@ -0,0 +1,26 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsHandshakeHash + : IDigest + { + void Init(TlsContext context); + + TlsHandshakeHash NotifyPrfDetermined(); + + void TrackHashAlgorithm(byte hashAlgorithm); + + void SealHashAlgorithms(); + + TlsHandshakeHash StopTracking(); + + IDigest ForkPrfHash(); + + byte[] GetFinalHash(byte hashAlgorithm); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs.meta new file mode 100644 index 0000000..dc11189 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsHandshakeHash.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4efa34121572a1d46ac3849616f0d395 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs new file mode 100644 index 0000000..c7a1e02 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs @@ -0,0 +1,58 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A generic interface for key exchange implementations in (D)TLS. + /// + public interface TlsKeyExchange + { + void Init(TlsContext context); + + /// + void SkipServerCredentials(); + + /// + void ProcessServerCredentials(TlsCredentials serverCredentials); + + /// + void ProcessServerCertificate(Certificate serverCertificate); + + bool RequiresServerKeyExchange { get; } + + /// + byte[] GenerateServerKeyExchange(); + + /// + void SkipServerKeyExchange(); + + /// + void ProcessServerKeyExchange(Stream input); + + /// + void ValidateCertificateRequest(CertificateRequest certificateRequest); + + /// + void SkipClientCredentials(); + + /// + void ProcessClientCredentials(TlsCredentials clientCredentials); + + /// + void ProcessClientCertificate(Certificate clientCertificate); + + /// + void GenerateClientKeyExchange(Stream output); + + /// + void ProcessClientKeyExchange(Stream input); + + /// + byte[] GeneratePremasterSecret(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs.meta new file mode 100644 index 0000000..08e7ea3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 03f31ef4465223f439a14aa8fcc60bec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs new file mode 100644 index 0000000..a013cd5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs @@ -0,0 +1,177 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. + /// + public class TlsMac + { + protected readonly TlsContext context; + protected readonly byte[] secret; + protected readonly IMac mac; + protected readonly int digestBlockSize; + protected readonly int digestOverhead; + protected readonly int macLength; + + /** + * Generate a new instance of an TlsMac. + * + * @param context the TLS client context + * @param digest The digest to use. + * @param key A byte-array where the key for this MAC is located. + * @param keyOff The number of bytes to skip, before the key starts in the buffer. + * @param keyLen The length of the key. + */ + public TlsMac(TlsContext context, IDigest digest, byte[] key, int keyOff, int keyLen) + { + this.context = context; + + KeyParameter keyParameter = new KeyParameter(key, keyOff, keyLen); + + this.secret = Arrays.Clone(keyParameter.GetKey()); + + // TODO This should check the actual algorithm, not rely on the engine type + if (digest is LongDigest) + { + this.digestBlockSize = 128; + this.digestOverhead = 16; + } + else + { + this.digestBlockSize = 64; + this.digestOverhead = 8; + } + + if (TlsUtilities.IsSsl(context)) + { + this.mac = new Ssl3Mac(digest); + + // TODO This should check the actual algorithm, not assume based on the digest size + if (digest.GetDigestSize() == 20) + { + /* + * NOTE: When SHA-1 is used with the SSL 3.0 MAC, the secret + input pad is not + * digest block-aligned. + */ + this.digestOverhead = 4; + } + } + else + { + this.mac = new HMac(digest); + + // NOTE: The input pad for HMAC is always a full digest block + } + + this.mac.Init(keyParameter); + + this.macLength = mac.GetMacSize(); + if (context.SecurityParameters.truncatedHMac) + { + this.macLength = System.Math.Min(this.macLength, 10); + } + } + + /** + * @return the MAC write secret + */ + public virtual byte[] MacSecret + { + get { return this.secret; } + } + + /** + * @return The output length of this MAC. + */ + public virtual int Size + { + get { return macLength; } + } + + /** + * Calculate the MAC for some given data. + * + * @param type The message type of the message. + * @param message A byte-buffer containing the message. + * @param offset The number of bytes to skip, before the message starts. + * @param length The length of the message. + * @return A new byte-buffer containing the MAC value. + */ + public virtual byte[] CalculateMac(long seqNo, byte type, byte[] message, int offset, int length) + { + ProtocolVersion serverVersion = context.ServerVersion; + bool isSsl = serverVersion.IsSsl; + + byte[] macHeader = new byte[isSsl ? 11 : 13]; + TlsUtilities.WriteUint64(seqNo, macHeader, 0); + TlsUtilities.WriteUint8(type, macHeader, 8); + if (!isSsl) + { + TlsUtilities.WriteVersion(serverVersion, macHeader, 9); + } + TlsUtilities.WriteUint16(length, macHeader, macHeader.Length - 2); + + mac.BlockUpdate(macHeader, 0, macHeader.Length); + mac.BlockUpdate(message, offset, length); + + return Truncate(MacUtilities.DoFinal(mac)); + } + + public virtual byte[] CalculateMacConstantTime(long seqNo, byte type, byte[] message, int offset, int length, + int fullLength, byte[] dummyData) + { + /* + * Actual MAC only calculated on 'length' bytes... + */ + byte[] result = CalculateMac(seqNo, type, message, offset, length); + + /* + * ...but ensure a constant number of complete digest blocks are processed (as many as would + * be needed for 'fullLength' bytes of input). + */ + int headerLength = TlsUtilities.IsSsl(context) ? 11 : 13; + + // How many extra full blocks do we need to calculate? + int extra = GetDigestBlockCount(headerLength + fullLength) - GetDigestBlockCount(headerLength + length); + + while (--extra >= 0) + { + mac.BlockUpdate(dummyData, 0, digestBlockSize); + } + + // One more byte in case the implementation is "lazy" about processing blocks + mac.Update(dummyData[0]); + mac.Reset(); + + return result; + } + + protected virtual int GetDigestBlockCount(int inputLength) + { + // NOTE: This calculation assumes a minimum of 1 pad byte + return (inputLength + digestOverhead) / digestBlockSize; + } + + protected virtual byte[] Truncate(byte[] bs) + { + if (bs.Length <= macLength) + { + return bs; + } + + return Arrays.CopyOf(bs, macLength); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs.meta new file mode 100644 index 0000000..f59c491 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsMac.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f8292646fa7b0c7439a1c3a0914d6fde +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs new file mode 100644 index 0000000..f22157e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs @@ -0,0 +1,122 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A NULL CipherSuite, with optional MAC. + /// + public class TlsNullCipher + : TlsCipher + { + protected readonly TlsContext context; + + protected readonly TlsMac writeMac; + protected readonly TlsMac readMac; + + public TlsNullCipher(TlsContext context) + { + this.context = context; + this.writeMac = null; + this.readMac = null; + } + + /// + public TlsNullCipher(TlsContext context, IDigest clientWriteDigest, IDigest serverWriteDigest) + { + if ((clientWriteDigest == null) != (serverWriteDigest == null)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.context = context; + + TlsMac clientWriteMac = null, serverWriteMac = null; + + if (clientWriteDigest != null) + { + int key_block_size = clientWriteDigest.GetDigestSize() + + serverWriteDigest.GetDigestSize(); + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.GetDigestSize()); + offset += clientWriteDigest.GetDigestSize(); + + serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.GetDigestSize()); + offset += serverWriteDigest.GetDigestSize(); + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + if (context.IsServer) + { + writeMac = serverWriteMac; + readMac = clientWriteMac; + } + else + { + writeMac = clientWriteMac; + readMac = serverWriteMac; + } + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + int result = ciphertextLimit; + if (writeMac != null) + { + result -= writeMac.Size; + } + return result; + } + + /// + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + if (writeMac == null) + { + return Arrays.CopyOfRange(plaintext, offset, offset + len); + } + + byte[] mac = writeMac.CalculateMac(seqNo, type, plaintext, offset, len); + byte[] ciphertext = new byte[len + mac.Length]; + Array.Copy(plaintext, offset, ciphertext, 0, len); + Array.Copy(mac, 0, ciphertext, len, mac.Length); + return ciphertext; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (readMac == null) + { + return Arrays.CopyOfRange(ciphertext, offset, offset + len); + } + + int macSize = readMac.Size; + if (len < macSize) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int macInputLen = len - macSize; + + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, offset + macInputLen, offset + len); + byte[] computedMac = readMac.CalculateMac(seqNo, type, ciphertext, offset, macInputLen); + + if (!Arrays.ConstantTimeAreEqual(receivedMac, computedMac)) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + return Arrays.CopyOfRange(ciphertext, offset, offset + macInputLen); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs.meta new file mode 100644 index 0000000..977dc21 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 542ace76e14774a4a844b9991b935684 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs new file mode 100644 index 0000000..c2886b3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs @@ -0,0 +1,23 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsNullCompression + : TlsCompression + { + public virtual Stream Compress(Stream output) + { + return output; + } + + public virtual Stream Decompress(Stream output) + { + return output; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs.meta new file mode 100644 index 0000000..e5684be --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsNullCompression.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2dbc8356620c83641823301e670735b3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs new file mode 100644 index 0000000..f261b20 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs @@ -0,0 +1,66 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsPeer + { + /// + /// draft-mathewson-no-gmtunixtime-00 2. "If existing users of a TLS implementation may rely on + /// gmt_unix_time containing the current time, we recommend that implementors MAY provide the + /// ability to set gmt_unix_time as an option only, off by default." + /// + /// + /// true if the current time should be used in the gmt_unix_time field of + /// Random, or false if gmt_unix_time should contain a cryptographically + /// random value. + /// + bool ShouldUseGmtUnixTime(); + + /// + /// Report whether the server supports secure renegotiation + /// + /// + /// The protocol handler automatically processes the relevant extensions + /// + /// + /// A , true if the server supports secure renegotiation + /// + /// + void NotifySecureRenegotiation(bool secureRenegotiation); + + /// + /// Return an implementation of to handle record compression. + /// + /// A + /// + TlsCompression GetCompression(); + + /// + /// Return an implementation of to use for encryption/decryption. + /// + /// A + /// + TlsCipher GetCipher(); + + /// This method will be called when an alert is raised by the protocol. + /// + /// + /// A human-readable message explaining what caused this alert. May be null. + /// The Exception that caused this alert to be raised. May be null. + void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause); + + /// This method will be called when an alert is received from the remote peer. + /// + /// + void NotifyAlertReceived(byte alertLevel, byte alertDescription); + + /// Notifies the peer that the handshake has been successfully completed. + /// + void NotifyHandshakeComplete(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs.meta new file mode 100644 index 0000000..c2c9470 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsPeer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 59b35c099f90afd4bbab07593f6db596 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs new file mode 100644 index 0000000..7ee943c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs @@ -0,0 +1,1388 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsProtocol + { + private static readonly string TLS_ERROR_MESSAGE = "Internal TLS error, this could be an attack"; + + /* + * Our Connection states + */ + protected const short CS_START = 0; + protected const short CS_CLIENT_HELLO = 1; + protected const short CS_SERVER_HELLO = 2; + protected const short CS_SERVER_SUPPLEMENTAL_DATA = 3; + protected const short CS_SERVER_CERTIFICATE = 4; + protected const short CS_CERTIFICATE_STATUS = 5; + protected const short CS_SERVER_KEY_EXCHANGE = 6; + protected const short CS_CERTIFICATE_REQUEST = 7; + protected const short CS_SERVER_HELLO_DONE = 8; + protected const short CS_CLIENT_SUPPLEMENTAL_DATA = 9; + protected const short CS_CLIENT_CERTIFICATE = 10; + protected const short CS_CLIENT_KEY_EXCHANGE = 11; + protected const short CS_CERTIFICATE_VERIFY = 12; + protected const short CS_CLIENT_FINISHED = 13; + protected const short CS_SERVER_SESSION_TICKET = 14; + protected const short CS_SERVER_FINISHED = 15; + protected const short CS_END = 16; + + /* + * Different modes to handle the known IV weakness + */ + protected const short ADS_MODE_1_Nsub1 = 0; // 1/n-1 record splitting + protected const short ADS_MODE_0_N = 1; // 0/n record splitting + protected const short ADS_MODE_0_N_FIRSTONLY = 2; // 0/n record splitting on first data fragment only + + /* + * Queues for data from some protocols. + */ + private ByteQueue mApplicationDataQueue = new ByteQueue(); + private ByteQueue mAlertQueue = new ByteQueue(2); + private ByteQueue mHandshakeQueue = new ByteQueue(); + // private ByteQueue mHeartbeatQueue = new ByteQueue(); + + /* + * The Record Stream we use + */ + internal RecordStream mRecordStream; + protected SecureRandom mSecureRandom; + + private TlsStream mTlsStream = null; + + private volatile bool mClosed = false; + private volatile bool mFailedWithError = false; + private volatile bool mAppDataReady = false; + private volatile bool mAppDataSplitEnabled = true; + private volatile int mAppDataSplitMode = ADS_MODE_1_Nsub1; + private byte[] mExpectedVerifyData = null; + + protected TlsSession mTlsSession = null; + protected SessionParameters mSessionParameters = null; + protected SecurityParameters mSecurityParameters = null; + protected Certificate mPeerCertificate = null; + + protected int[] mOfferedCipherSuites = null; + protected byte[] mOfferedCompressionMethods = null; + protected IDictionary mClientExtensions = null; + protected IDictionary mServerExtensions = null; + + protected short mConnectionState = CS_START; + protected bool mResumedSession = false; + protected bool mReceivedChangeCipherSpec = false; + protected bool mSecureRenegotiation = false; + protected bool mAllowCertificateStatus = false; + protected bool mExpectSessionTicket = false; + + protected bool mBlocking = true; + protected ByteQueueStream mInputBuffers = null; + protected ByteQueueStream mOutputBuffer = null; + + public TlsProtocol(Stream stream, SecureRandom secureRandom) + : this(stream, stream, secureRandom) + { + } + + public TlsProtocol(Stream input, Stream output, SecureRandom secureRandom) + { + this.mRecordStream = new RecordStream(this, input, output); + this.mSecureRandom = secureRandom; + } + + public TlsProtocol(SecureRandom secureRandom) + { + this.mBlocking = false; + this.mInputBuffers = new ByteQueueStream(); + this.mOutputBuffer = new ByteQueueStream(); + this.mRecordStream = new RecordStream(this, mInputBuffers, mOutputBuffer); + this.mSecureRandom = secureRandom; + } + + protected abstract TlsContext Context { get; } + + internal abstract AbstractTlsContext ContextAdmin { get; } + + protected abstract TlsPeer Peer { get; } + + protected virtual void HandleChangeCipherSpecMessage() + { + } + + protected abstract void HandleHandshakeMessage(byte type, byte[] buf); + + protected virtual void HandleWarningMessage(byte description) + { + } + + protected virtual void ApplyMaxFragmentLengthExtension() + { + if (mSecurityParameters.maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid((byte)mSecurityParameters.maxFragmentLength)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int plainTextLimit = 1 << (8 + mSecurityParameters.maxFragmentLength); + mRecordStream.SetPlaintextLimit(plainTextLimit); + } + } + + protected virtual void CheckReceivedChangeCipherSpec(bool expected) + { + if (expected != mReceivedChangeCipherSpec) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + protected virtual void CleanupHandshake() + { + if (this.mExpectedVerifyData != null) + { + Arrays.Fill(this.mExpectedVerifyData, (byte)0); + this.mExpectedVerifyData = null; + } + + this.mSecurityParameters.Clear(); + this.mPeerCertificate = null; + + this.mOfferedCipherSuites = null; + this.mOfferedCompressionMethods = null; + this.mClientExtensions = null; + this.mServerExtensions = null; + + this.mResumedSession = false; + this.mReceivedChangeCipherSpec = false; + this.mSecureRenegotiation = false; + this.mAllowCertificateStatus = false; + this.mExpectSessionTicket = false; + } + + protected virtual void BlockForHandshake() + { + if (mBlocking) + { + while (this.mConnectionState != CS_END) + { + if (this.mClosed) + { + // TODO What kind of exception/alert? + } + + SafeReadRecord(); + } + } + } + + protected virtual void CompleteHandshake() + { + try + { + this.mRecordStream.FinaliseHandshake(); + + this.mAppDataSplitEnabled = !TlsUtilities.IsTlsV11(Context); + + /* + * If this was an initial handshake, we are now ready to send and receive application data. + */ + if (!mAppDataReady) + { + this.mAppDataReady = true; + + if (mBlocking) + { + this.mTlsStream = new TlsStream(this); + } + } + + if (this.mTlsSession != null) + { + if (this.mSessionParameters == null) + { + this.mSessionParameters = new SessionParameters.Builder() + .SetCipherSuite(this.mSecurityParameters.CipherSuite) + .SetCompressionAlgorithm(this.mSecurityParameters.CompressionAlgorithm) + .SetMasterSecret(this.mSecurityParameters.MasterSecret) + .SetPeerCertificate(this.mPeerCertificate) + .SetPskIdentity(this.mSecurityParameters.PskIdentity) + .SetSrpIdentity(this.mSecurityParameters.SrpIdentity) + // TODO Consider filtering extensions that aren't relevant to resumed sessions + .SetServerExtensions(this.mServerExtensions) + .Build(); + + this.mTlsSession = new TlsSessionImpl(this.mTlsSession.SessionID, this.mSessionParameters); + } + + ContextAdmin.SetResumableSession(this.mTlsSession); + } + + Peer.NotifyHandshakeComplete(); + } + finally + { + CleanupHandshake(); + } + } + + protected internal void ProcessRecord(byte protocol, byte[] buf, int offset, int len) + { + /* + * Have a look at the protocol type, and add it to the correct queue. + */ + switch (protocol) + { + case ContentType.alert: + { + mAlertQueue.AddData(buf, offset, len); + ProcessAlert(); + break; + } + case ContentType.application_data: + { + if (!mAppDataReady) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + mApplicationDataQueue.AddData(buf, offset, len); + ProcessApplicationData(); + break; + } + case ContentType.change_cipher_spec: + { + ProcessChangeCipherSpec(buf, offset, len); + break; + } + case ContentType.handshake: + { + mHandshakeQueue.AddData(buf, offset, len); + ProcessHandshake(); + break; + } + case ContentType.heartbeat: + { + if (!mAppDataReady) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // TODO[RFC 6520] + // mHeartbeatQueue.AddData(buf, offset, len); + // ProcessHeartbeat(); + break; + } + default: + /* + * Uh, we don't know this protocol. + * + * RFC2246 defines on page 13, that we should ignore this. + */ + break; + } + } + + private void ProcessHandshake() + { + bool read; + do + { + read = false; + /* + * We need the first 4 bytes, they contain type and length of the message. + */ + if (mHandshakeQueue.Available >= 4) + { + byte[] beginning = new byte[4]; + mHandshakeQueue.Read(beginning, 0, 4, 0); + byte type = TlsUtilities.ReadUint8(beginning, 0); + int len = TlsUtilities.ReadUint24(beginning, 1); + + /* + * Check if we have enough bytes in the buffer to read the full message. + */ + if (mHandshakeQueue.Available >= (len + 4)) + { + /* + * Read the message. + */ + byte[] buf = mHandshakeQueue.RemoveData(len, 4); + + CheckReceivedChangeCipherSpec(mConnectionState == CS_END || type == HandshakeType.finished); + + /* + * RFC 2246 7.4.9. The value handshake_messages includes all handshake messages + * starting at client hello up to, but not including, this finished message. + * [..] Note: [Also,] Hello Request messages are omitted from handshake hashes. + */ + switch (type) + { + case HandshakeType.hello_request: + break; + case HandshakeType.finished: + default: + { + TlsContext ctx = Context; + if (type == HandshakeType.finished + && this.mExpectedVerifyData == null + && ctx.SecurityParameters.MasterSecret != null) + { + this.mExpectedVerifyData = CreateVerifyData(!ctx.IsServer); + } + + mRecordStream.UpdateHandshakeData(beginning, 0, 4); + mRecordStream.UpdateHandshakeData(buf, 0, len); + break; + } + } + + /* + * Now, parse the message. + */ + HandleHandshakeMessage(type, buf); + read = true; + } + } + } + while (read); + } + + private void ProcessApplicationData() + { + /* + * There is nothing we need to do here. + * + * This function could be used for callbacks when application data arrives in the future. + */ + } + + private void ProcessAlert() + { + while (mAlertQueue.Available >= 2) + { + /* + * An alert is always 2 bytes. Read the alert. + */ + byte[] tmp = mAlertQueue.RemoveData(2, 0); + byte level = tmp[0]; + byte description = tmp[1]; + + Peer.NotifyAlertReceived(level, description); + + if (level == AlertLevel.fatal) + { + /* + * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated + * without proper close_notify messages with level equal to warning. + */ + InvalidateSession(); + + this.mFailedWithError = true; + this.mClosed = true; + + mRecordStream.SafeClose(); + + throw new IOException(TLS_ERROR_MESSAGE); + } + else + { + + /* + * RFC 5246 7.2.1. The other party MUST respond with a close_notify alert of its own + * and close down the connection immediately, discarding any pending writes. + */ + // TODO Can close_notify be a fatal alert? + if (description == AlertDescription.close_notify) + { + HandleClose(false); + } + + /* + * If it is just a warning, we continue. + */ + HandleWarningMessage(description); + } + } + } + + /** + * This method is called, when a change cipher spec message is received. + * + * @throws IOException If the message has an invalid content or the handshake is not in the correct + * state. + */ + private void ProcessChangeCipherSpec(byte[] buf, int off, int len) + { + for (int i = 0; i < len; ++i) + { + byte message = TlsUtilities.ReadUint8(buf, off + i); + + if (message != ChangeCipherSpec.change_cipher_spec) + throw new TlsFatalAlert(AlertDescription.decode_error); + + if (this.mReceivedChangeCipherSpec + || mAlertQueue.Available > 0 + || mHandshakeQueue.Available > 0) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + mRecordStream.ReceivedReadCipherSpec(); + + this.mReceivedChangeCipherSpec = true; + + HandleChangeCipherSpecMessage(); + } + } + + protected internal virtual int ApplicationDataAvailable() + { + return mApplicationDataQueue.Available; + } + + /** + * Read data from the network. The method will return immediately, if there is still some data + * left in the buffer, or block until some application data has been read from the network. + * + * @param buf The buffer where the data will be copied to. + * @param offset The position where the data will be placed in the buffer. + * @param len The maximum number of bytes to read. + * @return The number of bytes read. + * @throws IOException If something goes wrong during reading data. + */ + protected internal virtual int ReadApplicationData(byte[] buf, int offset, int len) + { + if (len < 1) + return 0; + + while (mApplicationDataQueue.Available == 0) + { + /* + * We need to read some data. + */ + if (this.mClosed) + { + if (this.mFailedWithError) + { + /* + * Something went terribly wrong, we should throw an IOException + */ + throw new IOException(TLS_ERROR_MESSAGE); + } + + /* + * Connection has been closed, there is no more data to read. + */ + return 0; + } + + SafeReadRecord(); + } + + len = System.Math.Min(len, mApplicationDataQueue.Available); + mApplicationDataQueue.RemoveData(buf, offset, len, 0); + return len; + } + + protected virtual void SafeReadRecord() + { + try + { + if (!mRecordStream.ReadRecord()) + { + // TODO It would be nicer to allow graceful connection close if between records + // this.FailWithError(AlertLevel.warning, AlertDescription.close_notify); + throw new EndOfStreamException(); + } + } + catch (TlsFatalAlert e) + { + if (!mClosed) + { + this.FailWithError(AlertLevel.fatal, e.AlertDescription, "Failed to read record", e); + } + throw e; + } + catch (Exception e) + { + if (!mClosed) + { + this.FailWithError(AlertLevel.fatal, AlertDescription.internal_error, "Failed to read record", e); + } + throw e; + } + } + + protected virtual void SafeWriteRecord(byte type, byte[] buf, int offset, int len) + { + try + { + mRecordStream.WriteRecord(type, buf, offset, len); + } + catch (TlsFatalAlert e) + { + if (!mClosed) + { + this.FailWithError(AlertLevel.fatal, e.AlertDescription, "Failed to write record", e); + } + throw e; + } + catch (Exception e) + { + if (!mClosed) + { + this.FailWithError(AlertLevel.fatal, AlertDescription.internal_error, "Failed to write record", e); + } + throw e; + } + } + + /** + * Send some application data to the remote system. + *

+ * The method will handle fragmentation internally. + * + * @param buf The buffer with the data. + * @param offset The position in the buffer where the data is placed. + * @param len The length of the data. + * @throws IOException If something goes wrong during sending. + */ + protected internal virtual void WriteData(byte[] buf, int offset, int len) + { + if (this.mClosed) + { + if (this.mFailedWithError) + throw new IOException(TLS_ERROR_MESSAGE); + + throw new IOException("Sorry, connection has been closed, you cannot write more data"); + } + + while (len > 0) + { + /* + * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are + * potentially useful as a traffic analysis countermeasure. + * + * NOTE: Actually, implementations appear to have settled on 1/n-1 record splitting. + */ + + if (this.mAppDataSplitEnabled) + { + /* + * Protect against known IV attack! + * + * DO NOT REMOVE THIS CODE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE. + */ + switch (mAppDataSplitMode) + { + case ADS_MODE_0_N: + SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0); + break; + case ADS_MODE_0_N_FIRSTONLY: + this.mAppDataSplitEnabled = false; + SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0); + break; + case ADS_MODE_1_Nsub1: + default: + SafeWriteRecord(ContentType.application_data, buf, offset, 1); + ++offset; + --len; + break; + } + } + + if (len > 0) + { + // Fragment data according to the current fragment limit. + int toWrite = System.Math.Min(len, mRecordStream.GetPlaintextLimit()); + SafeWriteRecord(ContentType.application_data, buf, offset, toWrite); + offset += toWrite; + len -= toWrite; + } + } + } + + protected virtual void SetAppDataSplitMode(int appDataSplitMode) + { + if (appDataSplitMode < ADS_MODE_1_Nsub1 || appDataSplitMode > ADS_MODE_0_N_FIRSTONLY) + throw new ArgumentException("Illegal appDataSplitMode mode: " + appDataSplitMode, "appDataSplitMode"); + + this.mAppDataSplitMode = appDataSplitMode; + } + + protected virtual void WriteHandshakeMessage(byte[] buf, int off, int len) + { + while (len > 0) + { + // Fragment data according to the current fragment limit. + int toWrite = System.Math.Min(len, mRecordStream.GetPlaintextLimit()); + SafeWriteRecord(ContentType.handshake, buf, off, toWrite); + off += toWrite; + len -= toWrite; + } + } + + ///

The secure bidirectional stream for this connection + /// Only allowed in blocking mode. + public virtual Stream Stream + { + get + { + if (!mBlocking) + throw new InvalidOperationException("Cannot use Stream in non-blocking mode! Use OfferInput()/OfferOutput() instead."); + return this.mTlsStream; + } + } + + /** + * Offer input from an arbitrary source. Only allowed in non-blocking mode.
+ *
+ * After this method returns, the input buffer is "owned" by this object. Other code + * must not attempt to do anything with it.
+ *
+ * This method will decrypt and process all records that are fully available. + * If only part of a record is available, the buffer will be retained until the + * remainder of the record is offered.
+ *
+ * If any records containing application data were processed, the decrypted data + * can be obtained using {@link #readInput(byte[], int, int)}. If any records + * containing protocol data were processed, a response may have been generated. + * You should always check to see if there is any available output after calling + * this method by calling {@link #getAvailableOutputBytes()}. + * @param input The input buffer to offer + * @throws IOException If an error occurs while decrypting or processing a record + */ + public virtual void OfferInput(byte[] input) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use OfferInput() in blocking mode! Use Stream instead."); + if (mClosed) + throw new IOException("Connection is closed, cannot accept any more input"); + + mInputBuffers.Write(input); + + // loop while there are enough bytes to read the length of the next record + while (mInputBuffers.Available >= RecordStream.TLS_HEADER_SIZE) + { + byte[] header = new byte[RecordStream.TLS_HEADER_SIZE]; + mInputBuffers.Peek(header); + + int totalLength = TlsUtilities.ReadUint16(header, RecordStream.TLS_HEADER_LENGTH_OFFSET) + RecordStream.TLS_HEADER_SIZE; + if (mInputBuffers.Available < totalLength) + { + // not enough bytes to read a whole record + break; + } + + SafeReadRecord(); + } + } + + /** + * Gets the amount of received application data. A call to {@link #readInput(byte[], int, int)} + * is guaranteed to be able to return at least this much data.
+ *
+ * Only allowed in non-blocking mode. + * @return The number of bytes of available application data + */ + public virtual int GetAvailableInputBytes() + { + if (mBlocking) + throw new InvalidOperationException("Cannot use GetAvailableInputBytes() in blocking mode! Use ApplicationDataAvailable() instead."); + + return ApplicationDataAvailable(); + } + + /** + * Retrieves received application data. Use {@link #getAvailableInputBytes()} to check + * how much application data is currently available. This method functions similarly to + * {@link InputStream#read(byte[], int, int)}, except that it never blocks. If no data + * is available, nothing will be copied and zero will be returned.
+ *
+ * Only allowed in non-blocking mode. + * @param buffer The buffer to hold the application data + * @param offset The start offset in the buffer at which the data is written + * @param length The maximum number of bytes to read + * @return The total number of bytes copied to the buffer. May be less than the + * length specified if the length was greater than the amount of available data. + */ + public virtual int ReadInput(byte[] buffer, int offset, int length) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use ReadInput() in blocking mode! Use Stream instead."); + + return ReadApplicationData(buffer, offset, System.Math.Min(length, ApplicationDataAvailable())); + } + + /** + * Offer output from an arbitrary source. Only allowed in non-blocking mode.
+ *
+ * After this method returns, the specified section of the buffer will have been + * processed. Use {@link #readOutput(byte[], int, int)} to get the bytes to + * transmit to the other peer.
+ *
+ * This method must not be called until after the handshake is complete! Attempting + * to call it before the handshake is complete will result in an exception. + * @param buffer The buffer containing application data to encrypt + * @param offset The offset at which to begin reading data + * @param length The number of bytes of data to read + * @throws IOException If an error occurs encrypting the data, or the handshake is not complete + */ + public virtual void OfferOutput(byte[] buffer, int offset, int length) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use OfferOutput() in blocking mode! Use Stream instead."); + if (!mAppDataReady) + throw new IOException("Application data cannot be sent until the handshake is complete!"); + + WriteData(buffer, offset, length); + } + + /** + * Gets the amount of encrypted data available to be sent. A call to + * {@link #readOutput(byte[], int, int)} is guaranteed to be able to return at + * least this much data.
+ *
+ * Only allowed in non-blocking mode. + * @return The number of bytes of available encrypted data + */ + public virtual int GetAvailableOutputBytes() + { + if (mBlocking) + throw new InvalidOperationException("Cannot use GetAvailableOutputBytes() in blocking mode! Use Stream instead."); + + return mOutputBuffer.Available; + } + + /** + * Retrieves encrypted data to be sent. Use {@link #getAvailableOutputBytes()} to check + * how much encrypted data is currently available. This method functions similarly to + * {@link InputStream#read(byte[], int, int)}, except that it never blocks. If no data + * is available, nothing will be copied and zero will be returned.
+ *
+ * Only allowed in non-blocking mode. + * @param buffer The buffer to hold the encrypted data + * @param offset The start offset in the buffer at which the data is written + * @param length The maximum number of bytes to read + * @return The total number of bytes copied to the buffer. May be less than the + * length specified if the length was greater than the amount of available data. + */ + public virtual int ReadOutput(byte[] buffer, int offset, int length) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use ReadOutput() in blocking mode! Use Stream instead."); + + return mOutputBuffer.Read(buffer, offset, length); + } + + /** + * Terminate this connection with an alert. Can be used for normal closure too. + * + * @param alertLevel + * See {@link AlertLevel} for values. + * @param alertDescription + * See {@link AlertDescription} for values. + * @throws IOException + * If alert was fatal. + */ + protected virtual void FailWithError(byte alertLevel, byte alertDescription, string message, Exception cause) + { + /* + * Check if the connection is still open. + */ + if (!mClosed) + { + /* + * Prepare the message + */ + this.mClosed = true; + + if (alertLevel == AlertLevel.fatal) + { + /* + * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated + * without proper close_notify messages with level equal to warning. + */ + // TODO This isn't quite in the right place. Also, as of TLS 1.1 the above is obsolete. + InvalidateSession(); + + this.mFailedWithError = true; + } + RaiseAlert(alertLevel, alertDescription, message, cause); + mRecordStream.SafeClose(); + if (alertLevel != AlertLevel.fatal) + { + return; + } + } + + throw new IOException(TLS_ERROR_MESSAGE); + } + + protected virtual void InvalidateSession() + { + if (this.mSessionParameters != null) + { + this.mSessionParameters.Clear(); + this.mSessionParameters = null; + } + + if (this.mTlsSession != null) + { + this.mTlsSession.Invalidate(); + this.mTlsSession = null; + } + } + + protected virtual void ProcessFinishedMessage(MemoryStream buf) + { + if (mExpectedVerifyData == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + byte[] verify_data = TlsUtilities.ReadFully(mExpectedVerifyData.Length, buf); + + AssertEmpty(buf); + + /* + * Compare both checksums. + */ + if (!Arrays.ConstantTimeAreEqual(mExpectedVerifyData, verify_data)) + { + /* + * Wrong checksum in the finished message. + */ + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + } + + protected virtual void RaiseAlert(byte alertLevel, byte alertDescription, string message, Exception cause) + { + Peer.NotifyAlertRaised(alertLevel, alertDescription, message, cause); + + byte[] error = new byte[]{ alertLevel, alertDescription }; + + SafeWriteRecord(ContentType.alert, error, 0, 2); + } + + protected virtual void RaiseWarning(byte alertDescription, string message) + { + RaiseAlert(AlertLevel.warning, alertDescription, message, null); + } + + protected virtual void SendCertificateMessage(Certificate certificate) + { + if (certificate == null) + { + certificate = Certificate.EmptyChain; + } + + if (certificate.IsEmpty) + { + TlsContext context = Context; + if (!context.IsServer) + { + ProtocolVersion serverVersion = Context.ServerVersion; + if (serverVersion.IsSsl) + { + string errorMessage = serverVersion.ToString() + " client didn't provide credentials"; + RaiseWarning(AlertDescription.no_certificate, errorMessage); + return; + } + } + } + + HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate); + + certificate.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendChangeCipherSpecMessage() + { + byte[] message = new byte[]{ 1 }; + SafeWriteRecord(ContentType.change_cipher_spec, message, 0, message.Length); + mRecordStream.SentWriteCipherSpec(); + } + + protected virtual void SendFinishedMessage() + { + byte[] verify_data = CreateVerifyData(Context.IsServer); + + HandshakeMessage message = new HandshakeMessage(HandshakeType.finished, verify_data.Length); + + message.Write(verify_data, 0, verify_data.Length); + + message.WriteToRecordStream(this); + } + + protected virtual void SendSupplementalDataMessage(IList supplementalData) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.supplemental_data); + + WriteSupplementalData(message, supplementalData); + + message.WriteToRecordStream(this); + } + + protected virtual byte[] CreateVerifyData(bool isServer) + { + TlsContext context = Context; + string asciiLabel = isServer ? ExporterLabel.server_finished : ExporterLabel.client_finished; + byte[] sslSender = isServer ? TlsUtilities.SSL_SERVER : TlsUtilities.SSL_CLIENT; + byte[] hash = GetCurrentPrfHash(context, mRecordStream.HandshakeHash, sslSender); + return TlsUtilities.CalculateVerifyData(context, asciiLabel, hash); + } + + /** + * Closes this connection. + * + * @throws IOException If something goes wrong during closing. + */ + public virtual void Close() + { + HandleClose(true); + } + + protected virtual void HandleClose(bool user_canceled) + { + if (!mClosed) + { + if (user_canceled && !mAppDataReady) + { + RaiseWarning(AlertDescription.user_canceled, "User canceled handshake"); + } + this.FailWithError(AlertLevel.warning, AlertDescription.close_notify, "Connection closed", null); + } + } + + protected internal virtual void Flush() + { + mRecordStream.Flush(); + } + + public virtual bool IsClosed + { + get { return mClosed; } + } + + protected virtual short ProcessMaxFragmentLengthExtension(IDictionary clientExtensions, IDictionary serverExtensions, + byte alertDescription) + { + short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions); + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid((byte)maxFragmentLength) + || (!this.mResumedSession && maxFragmentLength != TlsExtensionsUtilities + .GetMaxFragmentLengthExtension(clientExtensions))) + { + throw new TlsFatalAlert(alertDescription); + } + } + return maxFragmentLength; + } + + protected virtual void RefuseRenegotiation() + { + /* + * RFC 5746 4.5 SSLv3 clients that refuse renegotiation SHOULD use a fatal + * handshake_failure alert. + */ + if (TlsUtilities.IsSsl(Context)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + RaiseWarning(AlertDescription.no_renegotiation, "Renegotiation not supported"); + } + + /** + * Make sure the InputStream 'buf' now empty. Fail otherwise. + * + * @param buf The InputStream to check. + * @throws IOException If 'buf' is not empty. + */ + protected internal static void AssertEmpty(MemoryStream buf) + { + if (buf.Position < buf.Length) + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + protected internal static byte[] CreateRandomBlock(bool useGmtUnixTime, IRandomGenerator randomGenerator) + { + byte[] result = new byte[32]; + randomGenerator.NextBytes(result); + + if (useGmtUnixTime) + { + TlsUtilities.WriteGmtUnixTime(result, 0); + } + + return result; + } + + protected internal static byte[] CreateRenegotiationInfo(byte[] renegotiated_connection) + { + return TlsUtilities.EncodeOpaque8(renegotiated_connection); + } + + protected internal static void EstablishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) + { + byte[] pre_master_secret = keyExchange.GeneratePremasterSecret(); + + try + { + context.SecurityParameters.masterSecret = TlsUtilities.CalculateMasterSecret(context, pre_master_secret); + } + finally + { + // TODO Is there a way to ensure the data is really overwritten? + /* + * RFC 2246 8.1. The pre_master_secret should be deleted from memory once the + * master_secret has been computed. + */ + if (pre_master_secret != null) + { + Arrays.Fill(pre_master_secret, (byte)0); + } + } + } + + /** + * 'sender' only relevant to SSLv3 + */ + protected internal static byte[] GetCurrentPrfHash(TlsContext context, TlsHandshakeHash handshakeHash, byte[] sslSender) + { + IDigest d = handshakeHash.ForkPrfHash(); + + if (sslSender != null && TlsUtilities.IsSsl(context)) + { + d.BlockUpdate(sslSender, 0, sslSender.Length); + } + + return DigestUtilities.DoFinal(d); + } + + protected internal static IDictionary ReadExtensions(MemoryStream input) + { + if (input.Position >= input.Length) + return null; + + byte[] extBytes = TlsUtilities.ReadOpaque16(input); + + AssertEmpty(input); + + MemoryStream buf = new MemoryStream(extBytes, false); + + // Integer -> byte[] + IDictionary extensions = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + while (buf.Position < buf.Length) + { + int extension_type = TlsUtilities.ReadUint16(buf); + byte[] extension_data = TlsUtilities.ReadOpaque16(buf); + + /* + * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. + */ + if (extensions.Contains(extension_type)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + extensions.Add(extension_type, extension_data); + } + + return extensions; + } + + protected internal static IList ReadSupplementalDataMessage(MemoryStream input) + { + byte[] supp_data = TlsUtilities.ReadOpaque24(input); + + AssertEmpty(input); + + MemoryStream buf = new MemoryStream(supp_data, false); + + IList supplementalData = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + while (buf.Position < buf.Length) + { + int supp_data_type = TlsUtilities.ReadUint16(buf); + byte[] data = TlsUtilities.ReadOpaque16(buf); + + supplementalData.Add(new SupplementalDataEntry(supp_data_type, data)); + } + + return supplementalData; + } + + protected internal static void WriteExtensions(Stream output, IDictionary extensions) + { + MemoryStream buf = new MemoryStream(); + + /* + * NOTE: There are reports of servers that don't accept a zero-length extension as the last + * one, so we write out any zero-length ones first as a best-effort workaround. + */ + WriteSelectedExtensions(buf, extensions, true); + WriteSelectedExtensions(buf, extensions, false); + + byte[] extBytes = buf.ToArray(); + + TlsUtilities.WriteOpaque16(extBytes, output); + } + + protected internal static void WriteSelectedExtensions(Stream output, IDictionary extensions, bool selectEmpty) + { + foreach (int extension_type in extensions.Keys) + { + byte[] extension_data = (byte[])extensions[extension_type]; + if (selectEmpty == (extension_data.Length == 0)) + { + TlsUtilities.CheckUint16(extension_type); + TlsUtilities.WriteUint16(extension_type, output); + TlsUtilities.WriteOpaque16(extension_data, output); + } + } + } + + protected internal static void WriteSupplementalData(Stream output, IList supplementalData) + { + MemoryStream buf = new MemoryStream(); + + foreach (SupplementalDataEntry entry in supplementalData) + { + int supp_data_type = entry.DataType; + TlsUtilities.CheckUint16(supp_data_type); + TlsUtilities.WriteUint16(supp_data_type, buf); + TlsUtilities.WriteOpaque16(entry.Data, buf); + } + + byte[] supp_data = buf.ToArray(); + + TlsUtilities.WriteOpaque24(supp_data, output); + } + + protected internal static int GetPrfAlgorithm(TlsContext context, int ciphersuite) + { + bool isTLSv12 = TlsUtilities.IsTlsV12(context); + + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha256; + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha384; + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha384; + } + return PrfAlgorithm.tls_prf_legacy; + } + + default: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha256; + } + return PrfAlgorithm.tls_prf_legacy; + } + } + } + + internal class HandshakeMessage + : MemoryStream + { + internal HandshakeMessage(byte handshakeType) + : this(handshakeType, 60) + { + } + + internal HandshakeMessage(byte handshakeType, int length) + : base(length + 4) + { + TlsUtilities.WriteUint8(handshakeType, this); + // Reserve space for length + TlsUtilities.WriteUint24(0, this); + } + + internal void Write(byte[] data) + { + Write(data, 0, data.Length); + } + + internal void WriteToRecordStream(TlsProtocol protocol) + { + // Patch actual length back in + long length = Length - 4; + TlsUtilities.CheckUint24(length); + this.Position = 1; + TlsUtilities.WriteUint24((int)length, this); + +#if PORTABLE || NETFX_CORE + byte[] buf = ToArray(); + int bufLen = buf.Length; +#else + byte[] buf = GetBuffer(); + int bufLen = (int)Length; +#endif + + protocol.WriteHandshakeMessage(buf, 0, bufLen); + Org.BouncyCastle.Utilities.Platform.Dispose(this); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs.meta new file mode 100644 index 0000000..cf96b02 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 574c7c786bb3d3646b011a406a951272 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs new file mode 100644 index 0000000..ef7d1f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs @@ -0,0 +1,144 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS and SSLv3 RSA key exchange. + public class TlsRsaKeyExchange + : AbstractTlsKeyExchange + { + protected AsymmetricKeyParameter mServerPublicKey = null; + + protected RsaKeyParameters mRsaServerPublicKey = null; + + protected TlsEncryptionCredentials mServerCredentials = null; + + protected byte[] mPremasterSecret; + + public TlsRsaKeyExchange(IList supportedSignatureAlgorithms) + : base(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms) + { + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsEncryptionCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsEncryptionCredentials)serverCredentials; + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.bad_certificate); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + // Sanity check the PublicKeyFactory + if (this.mServerPublicKey.IsPrivate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey); + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment); + + base.ProcessServerCertificate(serverCertificate); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (!(clientCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext, mRsaServerPublicKey, output); + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] encryptedPreMasterSecret; + if (TlsUtilities.IsSsl(mContext)) + { + // TODO Do any SSLv3 clients actually include the length? + encryptedPreMasterSecret = Streams.ReadAll(input); + } + else + { + encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input); + } + + this.mPremasterSecret = mServerCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret); + } + + public override byte[] GeneratePremasterSecret() + { + if (this.mPremasterSecret == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + byte[] tmp = this.mPremasterSecret; + this.mPremasterSecret = null; + return tmp; + } + + protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key) + { + // TODO What is the minimum bit length required? + // key.Modulus.BitLength; + + if (!key.Exponent.IsProbablePrime(2)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return key; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs.meta new file mode 100644 index 0000000..03adc1d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaKeyExchange.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e10809a192c17c74ca9938acd9b5fd6b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs new file mode 100644 index 0000000..3c72793 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs @@ -0,0 +1,106 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsRsaSigner + : AbstractTlsSigner + { + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, true, + new ParametersWithRandom(privateKey, this.mContext.SecureRandom)); + signer.BlockUpdate(hash, 0, hash.Length); + return signer.GenerateSignature(); + } + + public override bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, false, publicKey); + signer.BlockUpdate(hash, 0, hash.Length); + return signer.VerifySignature(sigBytes); + } + + public override ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey) + { + return MakeSigner(algorithm, false, true, new ParametersWithRandom(privateKey, this.mContext.SecureRandom)); + } + + public override ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey) + { + return MakeSigner(algorithm, false, false, publicKey); + } + + public override bool IsValidPublicKey(AsymmetricKeyParameter publicKey) + { + return publicKey is RsaKeyParameters && !publicKey.IsPrivate; + } + + protected virtual ISigner MakeSigner(SignatureAndHashAlgorithm algorithm, bool raw, bool forSigning, + ICipherParameters cp) + { + if ((algorithm != null) != TlsUtilities.IsTlsV12(mContext)) + throw new InvalidOperationException(); + if (algorithm != null && algorithm.Signature != SignatureAlgorithm.rsa) + throw new InvalidOperationException(); + + IDigest d; + if (raw) + { + d = new NullDigest(); + } + else if (algorithm == null) + { + d = new CombinedHash(); + } + else + { + d = TlsUtilities.CreateHash(algorithm.Hash); + } + + ISigner s; + if (algorithm != null) + { + /* + * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated + * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. + */ + s = new RsaDigestSigner(d, TlsUtilities.GetOidForHashAlgorithm(algorithm.Hash)); + } + else + { + /* + * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme + * that did not include a DigestInfo encoding. + */ + s = new GenericSigner(CreateRsaImpl(), d); + } + s.Init(forSigning, cp); + return s; + } + + protected virtual IAsymmetricBlockCipher CreateRsaImpl() + { + /* + * RFC 5264 7.4.7.1. Implementation note: It is now known that remote timing-based attacks + * on TLS are possible, at least when the client and server are on the same LAN. + * Accordingly, implementations that use static RSA keys MUST use RSA blinding or some other + * anti-timing technique, as described in [TIMING]. + */ + return new Pkcs1Encoding(new RsaBlindedEngine()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs.meta new file mode 100644 index 0000000..0e0d72c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a72e29def0f52934882ba8417e892e72 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs new file mode 100644 index 0000000..6183f7f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs @@ -0,0 +1,136 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsRsaUtilities + { + /// + public static byte[] GenerateEncryptedPreMasterSecret(TlsContext context, RsaKeyParameters rsaServerPublicKey, + Stream output) + { + /* + * Choose a PremasterSecret and send it encrypted to the server + */ + byte[] premasterSecret = new byte[48]; + context.SecureRandom.NextBytes(premasterSecret); + TlsUtilities.WriteVersion(context.ClientVersion, premasterSecret, 0); + + Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine()); + encoding.Init(true, new ParametersWithRandom(rsaServerPublicKey, context.SecureRandom)); + + try + { + byte[] encryptedPreMasterSecret = encoding.ProcessBlock(premasterSecret, 0, premasterSecret.Length); + + if (TlsUtilities.IsSsl(context)) + { + // TODO Do any SSLv3 servers actually expect the length? + output.Write(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length); + } + else + { + TlsUtilities.WriteOpaque16(encryptedPreMasterSecret, output); + } + } + catch (InvalidCipherTextException e) + { + /* + * This should never happen, only during decryption. + */ + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + return premasterSecret; + } + + public static byte[] SafeDecryptPreMasterSecret(TlsContext context, RsaKeyParameters rsaServerPrivateKey, + byte[] encryptedPreMasterSecret) + { + /* + * RFC 5246 7.4.7.1. + */ + ProtocolVersion clientVersion = context.ClientVersion; + + // TODO Provide as configuration option? + bool versionNumberCheckDisabled = false; + + /* + * Generate 48 random bytes we can use as a Pre-Master-Secret, if the + * PKCS1 padding check should fail. + */ + byte[] fallback = new byte[48]; + context.SecureRandom.NextBytes(fallback); + + byte[] M = Arrays.Clone(fallback); + try + { + Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine(), fallback); + encoding.Init(false, + new ParametersWithRandom(rsaServerPrivateKey, context.SecureRandom)); + + M = encoding.ProcessBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length); + } + catch (Exception) + { + /* + * This should never happen since the decryption should never throw an exception + * and return a random value instead. + * + * In any case, a TLS server MUST NOT generate an alert if processing an + * RSA-encrypted premaster secret message fails, or the version number is not as + * expected. Instead, it MUST continue the handshake with a randomly generated + * premaster secret. + */ + } + + /* + * If ClientHello.client_version is TLS 1.1 or higher, server implementations MUST + * check the version number [..]. + */ + if (versionNumberCheckDisabled && clientVersion.IsEqualOrEarlierVersionOf(ProtocolVersion.TLSv10)) + { + /* + * If the version number is TLS 1.0 or earlier, server + * implementations SHOULD check the version number, but MAY have a + * configuration option to disable the check. + * + * So there is nothing to do here. + */ + } + else + { + /* + * OK, we need to compare the version number in the decrypted Pre-Master-Secret with the + * clientVersion received during the handshake. If they don't match, we replace the + * decrypted Pre-Master-Secret with a random one. + */ + int correct = (clientVersion.MajorVersion ^ (M[0] & 0xff)) + | (clientVersion.MinorVersion ^ (M[1] & 0xff)); + correct |= correct >> 1; + correct |= correct >> 2; + correct |= correct >> 4; + int mask = ~((correct & 1) - 1); + + /* + * mask will be all bits set to 0xff if the version number differed. + */ + for (int i = 0; i < 48; i++) + { + M[i] = (byte)((M[i] & (~mask)) | (fallback[i] & mask)); + } + } + return M; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs.meta new file mode 100644 index 0000000..57168ab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsRsaUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3c0c982c94b368040b889309c787f574 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs new file mode 100644 index 0000000..15da59b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs @@ -0,0 +1,97 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsServer + : TlsPeer + { + void Init(TlsServerContext context); + + /// + void NotifyClientVersion(ProtocolVersion clientVersion); + + /// + void NotifyFallback(bool isFallback); + + /// + void NotifyOfferedCipherSuites(int[] offeredCipherSuites); + + /// + void NotifyOfferedCompressionMethods(byte[] offeredCompressionMethods); + + /// A (Int32 -> byte[]). Will never be null. + /// + void ProcessClientExtensions(IDictionary clientExtensions); + + /// + ProtocolVersion GetServerVersion(); + + /// + int GetSelectedCipherSuite(); + + /// + byte GetSelectedCompressionMethod(); + + /// + /// Get the (optional) table of server extensions to be included in (extended) server hello. + /// + /// + /// A (Int32 -> byte[]). May be null. + /// + /// + IDictionary GetServerExtensions(); + + /// + /// A (). May be null. + /// + /// + IList GetServerSupplementalData(); + + /// + TlsCredentials GetCredentials(); + + /// + /// This method will be called (only) if the server included an extension of type + /// "status_request" with empty "extension_data" in the extended server hello. See RFC 3546 + /// 3.6. Certificate Status Request. If a non-null is returned, it + /// is sent to the client as a handshake message of type "certificate_status". + /// + /// A to be sent to the client (or null for none). + /// + CertificateStatus GetCertificateStatus(); + + /// + TlsKeyExchange GetKeyExchange(); + + /// + CertificateRequest GetCertificateRequest(); + + /// () + /// + void ProcessClientSupplementalData(IList clientSupplementalData); + + /// + /// Called by the protocol handler to report the client certificate, only if GetCertificateRequest + /// returned non-null. + /// + /// Note: this method is responsible for certificate verification and validation. + /// the effective client certificate (may be an empty chain). + /// + void NotifyClientCertificate(Certificate clientCertificate); + + /// RFC 5077 3.3. NewSessionTicket Handshake Message. + /// + /// This method will be called (only) if a NewSessionTicket extension was sent by the server. See + /// RFC 5077 4. Recommended Ticket Construction for recommended format and protection. + /// + /// The ticket) + /// + NewSessionTicket GetNewSessionTicket(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs.meta new file mode 100644 index 0000000..71f8165 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7b4331fbbc8986049b27b67a94a7ce65 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs new file mode 100644 index 0000000..2f7efd8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsServerContext + : TlsContext + { + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs.meta new file mode 100644 index 0000000..104af82 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContext.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5cc374d2521dd6147b68f1d913923b00 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs new file mode 100644 index 0000000..df1128d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsServerContextImpl + : AbstractTlsContext, TlsServerContext + { + internal TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) + : base(secureRandom, securityParameters) + { + } + + public override bool IsServer + { + get { return true; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs.meta new file mode 100644 index 0000000..e223c00 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsServerContextImpl.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 701947cdab669614f8cadfbe1fd9ac90 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs new file mode 100644 index 0000000..fc775e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs @@ -0,0 +1,19 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSession + { + SessionParameters ExportSessionParameters(); + + byte[] SessionID { get; } + + void Invalidate(); + + bool IsResumable { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs.meta new file mode 100644 index 0000000..9e1d66a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSession.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3f1d9fbb6b810af4795034160469ac96 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs new file mode 100644 index 0000000..60f3798 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs @@ -0,0 +1,58 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsSessionImpl + : TlsSession + { + internal readonly byte[] mSessionID; + internal SessionParameters mSessionParameters; + + internal TlsSessionImpl(byte[] sessionID, SessionParameters sessionParameters) + { + if (sessionID == null) + throw new ArgumentNullException("sessionID"); + if (sessionID.Length < 1 || sessionID.Length > 32) + throw new ArgumentException("must have length between 1 and 32 bytes, inclusive", "sessionID"); + + this.mSessionID = Arrays.Clone(sessionID); + this.mSessionParameters = sessionParameters; + } + + public virtual SessionParameters ExportSessionParameters() + { + lock (this) + { + return this.mSessionParameters == null ? null : this.mSessionParameters.Copy(); + } + } + + public virtual byte[] SessionID + { + get { lock (this) return mSessionID; } + } + + public virtual void Invalidate() + { + lock (this) + { + if (this.mSessionParameters != null) + { + this.mSessionParameters.Clear(); + this.mSessionParameters = null; + } + } + } + + public virtual bool IsResumable + { + get { lock (this) return this.mSessionParameters != null; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs.meta new file mode 100644 index 0000000..cfddee9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSessionImpl.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5a838e66fd7fe8b4c816147b77fbf9a8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs new file mode 100644 index 0000000..8d0f711 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSigner + { + void Init(TlsContext context); + + byte[] GenerateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1); + + byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash); + + bool VerifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1); + + bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash); + + ISigner CreateSigner(AsymmetricKeyParameter privateKey); + + ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey); + + ISigner CreateVerifyer(AsymmetricKeyParameter publicKey); + + ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey); + + bool IsValidPublicKey(AsymmetricKeyParameter publicKey); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs.meta new file mode 100644 index 0000000..22129e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSigner.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 843bc529cfcb8b042bc162b6439803f5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs new file mode 100644 index 0000000..8c7666e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSignerCredentials + : TlsCredentials + { + /// + byte[] GenerateCertificateSignature(byte[] hash); + + SignatureAndHashAlgorithm SignatureAndHashAlgorithm { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs.meta new file mode 100644 index 0000000..1d9ae39 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsSignerCredentials.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 295e93e4b17fd484caf7f2bca75cdfb3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs new file mode 100644 index 0000000..8070c56 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs @@ -0,0 +1,101 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsStream + : Stream + { + private readonly TlsProtocol handler; + + internal TlsStream(TlsProtocol handler) + { + this.handler = handler; + } + + public override bool CanRead + { + get { return !handler.IsClosed; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return !handler.IsClosed; } + } + +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + handler.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + handler.Close(); + base.Close(); + } +#endif + + public override void Flush() + { + handler.Flush(); + } + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buf, int off, int len) + { + return this.handler.ReadApplicationData(buf, off, len); + } + + public override int ReadByte() + { + byte[] buf = new byte[1]; + if (this.Read(buf, 0, 1) <= 0) + return -1; + return buf[0]; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buf, int off, int len) + { + this.handler.WriteData(buf, off, len); + } + + public override void WriteByte(byte b) + { + this.handler.WriteData(new byte[] { b }, 0, 1); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs.meta new file mode 100644 index 0000000..44c3ae2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8c787d53198668a4d92cdd44e5b92d41 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs new file mode 100644 index 0000000..c911cce --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs @@ -0,0 +1,156 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Tls; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsStreamCipher + : TlsCipher + { + protected readonly TlsContext context; + + protected readonly IStreamCipher encryptCipher; + protected readonly IStreamCipher decryptCipher; + + protected readonly TlsMac writeMac; + protected readonly TlsMac readMac; + + protected readonly bool usesNonce; + + /// + public TlsStreamCipher(TlsContext context, IStreamCipher clientWriteCipher, + IStreamCipher serverWriteCipher, IDigest clientWriteDigest, IDigest serverWriteDigest, + int cipherKeySize, bool usesNonce) + { + bool isServer = context.IsServer; + + this.context = context; + this.usesNonce = usesNonce; + + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + + int key_block_size = (2 * cipherKeySize) + clientWriteDigest.GetDigestSize() + + serverWriteDigest.GetDigestSize(); + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + // Init MACs + TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.GetDigestSize()); + offset += clientWriteDigest.GetDigestSize(); + TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.GetDigestSize()); + offset += serverWriteDigest.GetDigestSize(); + + // Build keys + KeyParameter clientWriteKey = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter serverWriteKey = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + ICipherParameters encryptParams, decryptParams; + if (isServer) + { + this.writeMac = serverWriteMac; + this.readMac = clientWriteMac; + this.encryptCipher = serverWriteCipher; + this.decryptCipher = clientWriteCipher; + encryptParams = serverWriteKey; + decryptParams = clientWriteKey; + } + else + { + this.writeMac = clientWriteMac; + this.readMac = serverWriteMac; + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + encryptParams = clientWriteKey; + decryptParams = serverWriteKey; + } + + if (usesNonce) + { + byte[] dummyNonce = new byte[8]; + encryptParams = new ParametersWithIV(encryptParams, dummyNonce); + decryptParams = new ParametersWithIV(decryptParams, dummyNonce); + } + + this.encryptCipher.Init(true, encryptParams); + this.decryptCipher.Init(false, decryptParams); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit - writeMac.Size; + } + + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + if (usesNonce) + { + UpdateIV(encryptCipher, true, seqNo); + } + + byte[] outBuf = new byte[len + writeMac.Size]; + + encryptCipher.ProcessBytes(plaintext, offset, len, outBuf, 0); + + byte[] mac = writeMac.CalculateMac(seqNo, type, plaintext, offset, len); + encryptCipher.ProcessBytes(mac, 0, mac.Length, outBuf, len); + + return outBuf; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (usesNonce) + { + UpdateIV(decryptCipher, false, seqNo); + } + + int macSize = readMac.Size; + if (len < macSize) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int plaintextLength = len - macSize; + + byte[] deciphered = new byte[len]; + decryptCipher.ProcessBytes(ciphertext, offset, len, deciphered, 0); + CheckMac(seqNo, type, deciphered, plaintextLength, len, deciphered, 0, plaintextLength); + return Arrays.CopyOfRange(deciphered, 0, plaintextLength); + } + + /// + protected virtual void CheckMac(long seqNo, byte type, byte[] recBuf, int recStart, int recEnd, byte[] calcBuf, int calcOff, int calcLen) + { + byte[] receivedMac = Arrays.CopyOfRange(recBuf, recStart, recEnd); + byte[] computedMac = readMac.CalculateMac(seqNo, type, calcBuf, calcOff, calcLen); + + if (!Arrays.ConstantTimeAreEqual(receivedMac, computedMac)) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + } + + protected virtual void UpdateIV(IStreamCipher cipher, bool forEncryption, long seqNo) + { + byte[] nonce = new byte[8]; + TlsUtilities.WriteUint64(seqNo, nonce, 0); + cipher.Init(forEncryption, new ParametersWithIV(null, nonce)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs.meta new file mode 100644 index 0000000..29041cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsStreamCipher.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 695c981a9f3aa3348affbd5877a1aa91 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs new file mode 100644 index 0000000..dc1210c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs @@ -0,0 +1,2253 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// Some helper functions for MicroTLS. + public abstract class TlsUtilities + { + public static readonly byte[] EmptyBytes = new byte[0]; + public static readonly short[] EmptyShorts = new short[0]; + public static readonly int[] EmptyInts = new int[0]; + public static readonly long[] EmptyLongs = new long[0]; + + public static void CheckUint8(int i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint8(long i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint16(int i) + { + if (!IsValidUint16(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint16(long i) + { + if (!IsValidUint16(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint24(int i) + { + if (!IsValidUint24(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint24(long i) + { + if (!IsValidUint24(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint32(long i) + { + if (!IsValidUint32(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint48(long i) + { + if (!IsValidUint48(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint64(long i) + { + if (!IsValidUint64(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static bool IsValidUint8(int i) + { + return (i & 0xFF) == i; + } + + public static bool IsValidUint8(long i) + { + return (i & 0xFFL) == i; + } + + public static bool IsValidUint16(int i) + { + return (i & 0xFFFF) == i; + } + + public static bool IsValidUint16(long i) + { + return (i & 0xFFFFL) == i; + } + + public static bool IsValidUint24(int i) + { + return (i & 0xFFFFFF) == i; + } + + public static bool IsValidUint24(long i) + { + return (i & 0xFFFFFFL) == i; + } + + public static bool IsValidUint32(long i) + { + return (i & 0xFFFFFFFFL) == i; + } + + public static bool IsValidUint48(long i) + { + return (i & 0xFFFFFFFFFFFFL) == i; + } + + public static bool IsValidUint64(long i) + { + return true; + } + + public static bool IsSsl(TlsContext context) + { + return context.ServerVersion.IsSsl; + } + + public static bool IsTlsV11(ProtocolVersion version) + { + return ProtocolVersion.TLSv11.IsEqualOrEarlierVersionOf(version.GetEquivalentTLSVersion()); + } + + public static bool IsTlsV11(TlsContext context) + { + return IsTlsV11(context.ServerVersion); + } + + public static bool IsTlsV12(ProtocolVersion version) + { + return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(version.GetEquivalentTLSVersion()); + } + + public static bool IsTlsV12(TlsContext context) + { + return IsTlsV12(context.ServerVersion); + } + + public static void WriteUint8(byte i, Stream output) + { + output.WriteByte(i); + } + + public static void WriteUint8(byte i, byte[] buf, int offset) + { + buf[offset] = i; + } + + public static void WriteUint16(int i, Stream output) + { + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint16(int i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 8); + buf[offset + 1] = (byte)i; + } + + public static void WriteUint24(int i, Stream output) + { + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint24(int i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 16); + buf[offset + 1] = (byte)(i >> 8); + buf[offset + 2] = (byte)i; + } + + public static void WriteUint32(long i, Stream output) + { + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint32(long i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 24); + buf[offset + 1] = (byte)(i >> 16); + buf[offset + 2] = (byte)(i >> 8); + buf[offset + 3] = (byte)i; + } + + public static void WriteUint48(long i, Stream output) + { + output.WriteByte((byte)(i >> 40)); + output.WriteByte((byte)(i >> 32)); + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint48(long i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 40); + buf[offset + 1] = (byte)(i >> 32); + buf[offset + 2] = (byte)(i >> 24); + buf[offset + 3] = (byte)(i >> 16); + buf[offset + 4] = (byte)(i >> 8); + buf[offset + 5] = (byte)i; + } + + public static void WriteUint64(long i, Stream output) + { + output.WriteByte((byte)(i >> 56)); + output.WriteByte((byte)(i >> 48)); + output.WriteByte((byte)(i >> 40)); + output.WriteByte((byte)(i >> 32)); + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint64(long i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 56); + buf[offset + 1] = (byte)(i >> 48); + buf[offset + 2] = (byte)(i >> 40); + buf[offset + 3] = (byte)(i >> 32); + buf[offset + 4] = (byte)(i >> 24); + buf[offset + 5] = (byte)(i >> 16); + buf[offset + 6] = (byte)(i >> 8); + buf[offset + 7] = (byte)i; + } + + public static void WriteOpaque8(byte[] buf, Stream output) + { + WriteUint8((byte)buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque16(byte[] buf, Stream output) + { + WriteUint16(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque24(byte[] buf, Stream output) + { + WriteUint24(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteUint8Array(byte[] uints, Stream output) + { + output.Write(uints, 0, uints.Length); + } + + public static void WriteUint8Array(byte[] uints, byte[] buf, int offset) + { + for (int i = 0; i < uints.Length; ++i) + { + WriteUint8(uints[i], buf, offset); + ++offset; + } + } + + public static void WriteUint8ArrayWithUint8Length(byte[] uints, Stream output) + { + CheckUint8(uints.Length); + WriteUint8((byte)uints.Length, output); + WriteUint8Array(uints, output); + } + + public static void WriteUint8ArrayWithUint8Length(byte[] uints, byte[] buf, int offset) + { + CheckUint8(uints.Length); + WriteUint8((byte)uints.Length, buf, offset); + WriteUint8Array(uints, buf, offset + 1); + } + + public static void WriteUint16Array(int[] uints, Stream output) + { + for (int i = 0; i < uints.Length; ++i) + { + WriteUint16(uints[i], output); + } + } + + public static void WriteUint16Array(int[] uints, byte[] buf, int offset) + { + for (int i = 0; i < uints.Length; ++i) + { + WriteUint16(uints[i], buf, offset); + offset += 2; + } + } + + public static void WriteUint16ArrayWithUint16Length(int[] uints, Stream output) + { + int length = 2 * uints.Length; + CheckUint16(length); + WriteUint16(length, output); + WriteUint16Array(uints, output); + } + + public static void WriteUint16ArrayWithUint16Length(int[] uints, byte[] buf, int offset) + { + int length = 2 * uints.Length; + CheckUint16(length); + WriteUint16(length, buf, offset); + WriteUint16Array(uints, buf, offset + 2); + } + + public static byte[] EncodeOpaque8(byte[] buf) + { + CheckUint8(buf.Length); + return Arrays.Prepend(buf, (byte)buf.Length); + } + + public static byte[] EncodeUint8ArrayWithUint8Length(byte[] uints) + { + byte[] result = new byte[1 + uints.Length]; + WriteUint8ArrayWithUint8Length(uints, result, 0); + return result; + } + + public static byte[] EncodeUint16ArrayWithUint16Length(int[] uints) + { + int length = 2 * uints.Length; + byte[] result = new byte[2 + length]; + WriteUint16ArrayWithUint16Length(uints, result, 0); + return result; + } + + public static byte ReadUint8(Stream input) + { + int i = input.ReadByte(); + if (i < 0) + throw new EndOfStreamException(); + return (byte)i; + } + + public static byte ReadUint8(byte[] buf, int offset) + { + return buf[offset]; + } + + public static int ReadUint16(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return (i1 << 8) | i2; + } + + public static int ReadUint16(byte[] buf, int offset) + { + uint n = (uint)buf[offset] << 8; + n |= (uint)buf[++offset]; + return (int)n; + } + + public static int ReadUint24(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + int i3 = input.ReadByte(); + if (i3 < 0) + throw new EndOfStreamException(); + return (i1 << 16) | (i2 << 8) | i3; + } + + public static int ReadUint24(byte[] buf, int offset) + { + uint n = (uint)buf[offset] << 16; + n |= (uint)buf[++offset] << 8; + n |= (uint)buf[++offset]; + return (int)n; + } + + public static long ReadUint32(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + int i3 = input.ReadByte(); + int i4 = input.ReadByte(); + if (i4 < 0) + throw new EndOfStreamException(); + return (long)(uint)((i1 << 24) | (i2 << 16) | (i3 << 8) | i4); + } + + public static long ReadUint32(byte[] buf, int offset) + { + uint n = (uint)buf[offset] << 24; + n |= (uint)buf[++offset] << 16; + n |= (uint)buf[++offset] << 8; + n |= (uint)buf[++offset]; + return (long)n; + } + + public static long ReadUint48(Stream input) + { + int hi = ReadUint24(input); + int lo = ReadUint24(input); + return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); + } + + public static long ReadUint48(byte[] buf, int offset) + { + int hi = ReadUint24(buf, offset); + int lo = ReadUint24(buf, offset + 3); + return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); + } + + public static byte[] ReadAllOrNothing(int length, Stream input) + { + if (length < 1) + return EmptyBytes; + byte[] buf = new byte[length]; + int read = Streams.ReadFully(input, buf); + if (read == 0) + return null; + if (read != length) + throw new EndOfStreamException(); + return buf; + } + + public static byte[] ReadFully(int length, Stream input) + { + if (length < 1) + return EmptyBytes; + byte[] buf = new byte[length]; + if (length != Streams.ReadFully(input, buf)) + throw new EndOfStreamException(); + return buf; + } + + public static void ReadFully(byte[] buf, Stream input) + { + if (Streams.ReadFully(input, buf, 0, buf.Length) < buf.Length) + throw new EndOfStreamException(); + } + + public static byte[] ReadOpaque8(Stream input) + { + byte length = ReadUint8(input); + byte[] bytes = new byte[length]; + ReadFully(bytes, input); + return bytes; + } + + public static byte[] ReadOpaque16(Stream input) + { + int length = ReadUint16(input); + byte[] bytes = new byte[length]; + ReadFully(bytes, input); + return bytes; + } + + public static byte[] ReadOpaque24(Stream input) + { + int length = ReadUint24(input); + return ReadFully(length, input); + } + + public static byte[] ReadUint8Array(int count, Stream input) + { + byte[] uints = new byte[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint8(input); + } + return uints; + } + + public static int[] ReadUint16Array(int count, Stream input) + { + int[] uints = new int[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint16(input); + } + return uints; + } + + public static ProtocolVersion ReadVersion(byte[] buf, int offset) + { + return ProtocolVersion.Get(buf[offset], buf[offset + 1]); + } + + public static ProtocolVersion ReadVersion(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return ProtocolVersion.Get(i1, i2); + } + + public static int ReadVersionRaw(byte[] buf, int offset) + { + return (buf[offset] << 8) | buf[offset + 1]; + } + + public static int ReadVersionRaw(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return (i1 << 8) | i2; + } + + public static Asn1Object ReadAsn1Object(byte[] encoding) + { + MemoryStream input = new MemoryStream(encoding, false); + Asn1InputStream asn1 = new Asn1InputStream(input, encoding.Length); + Asn1Object result = asn1.ReadObject(); + if (null == result) + throw new TlsFatalAlert(AlertDescription.decode_error); + if (input.Position != input.Length) + throw new TlsFatalAlert(AlertDescription.decode_error); + return result; + } + + public static Asn1Object ReadDerObject(byte[] encoding) + { + /* + * NOTE: The current ASN.1 parsing code can't enforce DER-only parsing, but since DER is + * canonical, we can check it by re-encoding the result and comparing to the original. + */ + Asn1Object result = ReadAsn1Object(encoding); + byte[] check = result.GetEncoded(Asn1Encodable.Der); + if (!Arrays.AreEqual(check, encoding)) + throw new TlsFatalAlert(AlertDescription.decode_error); + return result; + } + + public static void WriteGmtUnixTime(byte[] buf, int offset) + { + int t = (int)(DateTimeUtilities.CurrentUnixMs() / 1000L); + buf[offset] = (byte)(t >> 24); + buf[offset + 1] = (byte)(t >> 16); + buf[offset + 2] = (byte)(t >> 8); + buf[offset + 3] = (byte)t; + } + + public static void WriteVersion(ProtocolVersion version, Stream output) + { + output.WriteByte((byte)version.MajorVersion); + output.WriteByte((byte)version.MinorVersion); + } + + public static void WriteVersion(ProtocolVersion version, byte[] buf, int offset) + { + buf[offset] = (byte)version.MajorVersion; + buf[offset + 1] = (byte)version.MinorVersion; + } + + public static IList GetDefaultDssSignatureAlgorithms() + { + return VectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); + } + + public static IList GetDefaultECDsaSignatureAlgorithms() + { + return VectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)); + } + + public static IList GetDefaultRsaSignatureAlgorithms() + { + return VectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa)); + } + + public static byte[] GetExtensionData(IDictionary extensions, int extensionType) + { + return extensions == null ? null : (byte[])extensions[extensionType]; + } + + public static IList GetDefaultSupportedSignatureAlgorithms() + { + byte[] hashAlgorithms = new byte[]{ HashAlgorithm.sha1, HashAlgorithm.sha224, HashAlgorithm.sha256, + HashAlgorithm.sha384, HashAlgorithm.sha512 }; + byte[] signatureAlgorithms = new byte[]{ SignatureAlgorithm.rsa, SignatureAlgorithm.dsa, + SignatureAlgorithm.ecdsa }; + + IList result = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + for (int i = 0; i < signatureAlgorithms.Length; ++i) + { + for (int j = 0; j < hashAlgorithms.Length; ++j) + { + result.Add(new SignatureAndHashAlgorithm(hashAlgorithms[j], signatureAlgorithms[i])); + } + } + return result; + } + + public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(TlsContext context, + TlsSignerCredentials signerCredentials) + { + SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; + if (IsTlsV12(context)) + { + signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm; + if (signatureAndHashAlgorithm == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + return signatureAndHashAlgorithm; + } + + public static bool HasExpectedEmptyExtensionData(IDictionary extensions, int extensionType, + byte alertDescription) + { + byte[] extension_data = GetExtensionData(extensions, extensionType); + if (extension_data == null) + return false; + if (extension_data.Length != 0) + throw new TlsFatalAlert(alertDescription); + return true; + } + + public static TlsSession ImportSession(byte[] sessionID, SessionParameters sessionParameters) + { + return new TlsSessionImpl(sessionID, sessionParameters); + } + + public static bool IsSignatureAlgorithmsExtensionAllowed(ProtocolVersion clientVersion) + { + return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(clientVersion.GetEquivalentTLSVersion()); + } + + /** + * Add a 'signature_algorithms' extension to existing extensions. + * + * @param extensions A {@link Hashtable} to add the extension to. + * @param supportedSignatureAlgorithms {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. + * @throws IOException + */ + public static void AddSignatureAlgorithmsExtension(IDictionary extensions, IList supportedSignatureAlgorithms) + { + extensions[ExtensionType.signature_algorithms] = CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms); + } + + /** + * Get a 'signature_algorithms' extension from extensions. + * + * @param extensions A {@link Hashtable} to get the extension from, if it is present. + * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}, or null. + * @throws IOException + */ + public static IList GetSignatureAlgorithmsExtension(IDictionary extensions) + { + byte[] extensionData = GetExtensionData(extensions, ExtensionType.signature_algorithms); + return extensionData == null ? null : ReadSignatureAlgorithmsExtension(extensionData); + } + + /** + * Create a 'signature_algorithms' extension value. + * + * @param supportedSignatureAlgorithms A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. + * @return A byte array suitable for use as an extension value. + * @throws IOException + */ + public static byte[] CreateSignatureAlgorithmsExtension(IList supportedSignatureAlgorithms) + { + MemoryStream buf = new MemoryStream(); + + // supported_signature_algorithms + EncodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, false, buf); + + return buf.ToArray(); + } + + /** + * Read 'signature_algorithms' extension data. + * + * @param extensionData The extension data. + * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. + * @throws IOException + */ + public static IList ReadSignatureAlgorithmsExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + // supported_signature_algorithms + IList supported_signature_algorithms = ParseSupportedSignatureAlgorithms(false, buf); + + TlsProtocol.AssertEmpty(buf); + + return supported_signature_algorithms; + } + + public static void EncodeSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms, bool allowAnonymous, + Stream output) + { + if (supportedSignatureAlgorithms == null) + throw new ArgumentNullException("supportedSignatureAlgorithms"); + if (supportedSignatureAlgorithms.Count < 1 || supportedSignatureAlgorithms.Count >= (1 << 15)) + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms"); + + // supported_signature_algorithms + int length = 2 * supportedSignatureAlgorithms.Count; + CheckUint16(length); + WriteUint16(length, output); + + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (!allowAnonymous && entry.Signature == SignatureAlgorithm.anonymous) + { + /* + * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used + * in Section 7.4.3. It MUST NOT appear in this extension. + */ + throw new ArgumentException( + "SignatureAlgorithm.anonymous MUST NOT appear in the signature_algorithms extension"); + } + entry.Encode(output); + } + } + + public static IList ParseSupportedSignatureAlgorithms(bool allowAnonymous, Stream input) + { + // supported_signature_algorithms + int length = ReadUint16(input); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + int count = length / 2; + IList supportedSignatureAlgorithms = Org.BouncyCastle.Utilities.Platform.CreateArrayList(count); + for (int i = 0; i < count; ++i) + { + SignatureAndHashAlgorithm entry = SignatureAndHashAlgorithm.Parse(input); + if (!allowAnonymous && entry.Signature == SignatureAlgorithm.anonymous) + { + /* + * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used + * in Section 7.4.3. It MUST NOT appear in this extension. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + supportedSignatureAlgorithms.Add(entry); + } + return supportedSignatureAlgorithms; + } + + public static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms, SignatureAndHashAlgorithm signatureAlgorithm) + { + if (supportedSignatureAlgorithms == null) + throw new ArgumentNullException("supportedSignatureAlgorithms"); + if (supportedSignatureAlgorithms.Count < 1 || supportedSignatureAlgorithms.Count >= (1 << 15)) + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms"); + if (signatureAlgorithm == null) + throw new ArgumentNullException("signatureAlgorithm"); + + if (signatureAlgorithm.Signature != SignatureAlgorithm.anonymous) + { + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (entry.Hash == signatureAlgorithm.Hash && entry.Signature == signatureAlgorithm.Signature) + return; + } + } + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + public static byte[] PRF(TlsContext context, byte[] secret, string asciiLabel, byte[] seed, int size) + { + ProtocolVersion version = context.ServerVersion; + + if (version.IsSsl) + throw new InvalidOperationException("No PRF available for SSLv3 session"); + + byte[] label = Strings.ToByteArray(asciiLabel); + byte[] labelSeed = Concat(label, seed); + + int prfAlgorithm = context.SecurityParameters.PrfAlgorithm; + + if (prfAlgorithm == PrfAlgorithm.tls_prf_legacy) + return PRF_legacy(secret, label, labelSeed, size); + + IDigest prfDigest = CreatePrfHash(prfAlgorithm); + byte[] buf = new byte[size]; + HMacHash(prfDigest, secret, labelSeed, buf); + return buf; + } + + public static byte[] PRF_legacy(byte[] secret, string asciiLabel, byte[] seed, int size) + { + byte[] label = Strings.ToByteArray(asciiLabel); + byte[] labelSeed = Concat(label, seed); + + return PRF_legacy(secret, label, labelSeed, size); + } + + internal static byte[] PRF_legacy(byte[] secret, byte[] label, byte[] labelSeed, int size) + { + int s_half = (secret.Length + 1) / 2; + byte[] s1 = new byte[s_half]; + byte[] s2 = new byte[s_half]; + Array.Copy(secret, 0, s1, 0, s_half); + Array.Copy(secret, secret.Length - s_half, s2, 0, s_half); + + byte[] b1 = new byte[size]; + byte[] b2 = new byte[size]; + HMacHash(CreateHash(HashAlgorithm.md5), s1, labelSeed, b1); + HMacHash(CreateHash(HashAlgorithm.sha1), s2, labelSeed, b2); + for (int i = 0; i < size; i++) + { + b1[i] ^= b2[i]; + } + return b1; + } + + internal static byte[] Concat(byte[] a, byte[] b) + { + byte[] c = new byte[a.Length + b.Length]; + Array.Copy(a, 0, c, 0, a.Length); + Array.Copy(b, 0, c, a.Length, b.Length); + return c; + } + + internal static void HMacHash(IDigest digest, byte[] secret, byte[] seed, byte[] output) + { + HMac mac = new HMac(digest); + mac.Init(new KeyParameter(secret)); + byte[] a = seed; + int size = digest.GetDigestSize(); + int iterations = (output.Length + size - 1) / size; + byte[] buf = new byte[mac.GetMacSize()]; + byte[] buf2 = new byte[mac.GetMacSize()]; + for (int i = 0; i < iterations; i++) + { + mac.BlockUpdate(a, 0, a.Length); + mac.DoFinal(buf, 0); + a = buf; + mac.BlockUpdate(a, 0, a.Length); + mac.BlockUpdate(seed, 0, seed.Length); + mac.DoFinal(buf2, 0); + Array.Copy(buf2, 0, output, (size * i), System.Math.Min(size, output.Length - (size * i))); + } + } + + internal static void ValidateKeyUsage(X509CertificateStructure c, int keyUsageBits) + { + X509Extensions exts = c.TbsCertificate.Extensions; + if (exts != null) + { + X509Extension ext = exts.GetExtension(X509Extensions.KeyUsage); + if (ext != null) + { + DerBitString ku = KeyUsage.GetInstance(ext); + int bits = ku.GetBytes()[0]; + if ((bits & keyUsageBits) != keyUsageBits) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + } + } + + internal static byte[] CalculateKeyBlock(TlsContext context, int size) + { + SecurityParameters securityParameters = context.SecurityParameters; + byte[] master_secret = securityParameters.MasterSecret; + byte[] seed = Concat(securityParameters.ServerRandom, securityParameters.ClientRandom); + + if (IsSsl(context)) + return CalculateKeyBlock_Ssl(master_secret, seed, size); + + return PRF(context, master_secret, ExporterLabel.key_expansion, seed, size); + } + + internal static byte[] CalculateKeyBlock_Ssl(byte[] master_secret, byte[] random, int size) + { + IDigest md5 = CreateHash(HashAlgorithm.md5); + IDigest sha1 = CreateHash(HashAlgorithm.sha1); + int md5Size = md5.GetDigestSize(); + byte[] shatmp = new byte[sha1.GetDigestSize()]; + byte[] tmp = new byte[size + md5Size]; + + int i = 0, pos = 0; + while (pos < size) + { + byte[] ssl3Const = SSL3_CONST[i]; + + sha1.BlockUpdate(ssl3Const, 0, ssl3Const.Length); + sha1.BlockUpdate(master_secret, 0, master_secret.Length); + sha1.BlockUpdate(random, 0, random.Length); + sha1.DoFinal(shatmp, 0); + + md5.BlockUpdate(master_secret, 0, master_secret.Length); + md5.BlockUpdate(shatmp, 0, shatmp.Length); + md5.DoFinal(tmp, pos); + + pos += md5Size; + ++i; + } + + return Arrays.CopyOfRange(tmp, 0, size); + } + + internal static byte[] CalculateMasterSecret(TlsContext context, byte[] pre_master_secret) + { + SecurityParameters securityParameters = context.SecurityParameters; + + byte[] seed = securityParameters.extendedMasterSecret + ? securityParameters.SessionHash + : Concat(securityParameters.ClientRandom, securityParameters.ServerRandom); + + if (IsSsl(context)) + return CalculateMasterSecret_Ssl(pre_master_secret, seed); + + string asciiLabel = securityParameters.extendedMasterSecret + ? ExporterLabel.extended_master_secret + : ExporterLabel.master_secret; + + return PRF(context, pre_master_secret, asciiLabel, seed, 48); + } + + internal static byte[] CalculateMasterSecret_Ssl(byte[] pre_master_secret, byte[] random) + { + IDigest md5 = CreateHash(HashAlgorithm.md5); + IDigest sha1 = CreateHash(HashAlgorithm.sha1); + int md5Size = md5.GetDigestSize(); + byte[] shatmp = new byte[sha1.GetDigestSize()]; + + byte[] rval = new byte[md5Size * 3]; + int pos = 0; + + for (int i = 0; i < 3; ++i) + { + byte[] ssl3Const = SSL3_CONST[i]; + + sha1.BlockUpdate(ssl3Const, 0, ssl3Const.Length); + sha1.BlockUpdate(pre_master_secret, 0, pre_master_secret.Length); + sha1.BlockUpdate(random, 0, random.Length); + sha1.DoFinal(shatmp, 0); + + md5.BlockUpdate(pre_master_secret, 0, pre_master_secret.Length); + md5.BlockUpdate(shatmp, 0, shatmp.Length); + md5.DoFinal(rval, pos); + + pos += md5Size; + } + + return rval; + } + + internal static byte[] CalculateVerifyData(TlsContext context, string asciiLabel, byte[] handshakeHash) + { + if (IsSsl(context)) + return handshakeHash; + + SecurityParameters securityParameters = context.SecurityParameters; + byte[] master_secret = securityParameters.MasterSecret; + int verify_data_length = securityParameters.VerifyDataLength; + + return PRF(context, master_secret, asciiLabel, handshakeHash, verify_data_length); + } + + public static IDigest CreateHash(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return new MD5Digest(); + case HashAlgorithm.sha1: + return new Sha1Digest(); + case HashAlgorithm.sha224: + return new Sha224Digest(); + case HashAlgorithm.sha256: + return new Sha256Digest(); + case HashAlgorithm.sha384: + return new Sha384Digest(); + case HashAlgorithm.sha512: + return new Sha512Digest(); + default: + throw new ArgumentException("unknown HashAlgorithm", "hashAlgorithm"); + } + } + + public static IDigest CreateHash(SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + return signatureAndHashAlgorithm == null + ? new CombinedHash() + : CreateHash(signatureAndHashAlgorithm.Hash); + } + + public static IDigest CloneHash(byte hashAlgorithm, IDigest hash) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return new MD5Digest((MD5Digest)hash); + case HashAlgorithm.sha1: + return new Sha1Digest((Sha1Digest)hash); + case HashAlgorithm.sha224: + return new Sha224Digest((Sha224Digest)hash); + case HashAlgorithm.sha256: + return new Sha256Digest((Sha256Digest)hash); + case HashAlgorithm.sha384: + return new Sha384Digest((Sha384Digest)hash); + case HashAlgorithm.sha512: + return new Sha512Digest((Sha512Digest)hash); + default: + throw new ArgumentException("unknown HashAlgorithm", "hashAlgorithm"); + } + } + + public static IDigest CreatePrfHash(int prfAlgorithm) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.tls_prf_legacy: + return new CombinedHash(); + default: + return CreateHash(GetHashAlgorithmForPrfAlgorithm(prfAlgorithm)); + } + } + + public static IDigest ClonePrfHash(int prfAlgorithm, IDigest hash) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.tls_prf_legacy: + return new CombinedHash((CombinedHash)hash); + default: + return CloneHash(GetHashAlgorithmForPrfAlgorithm(prfAlgorithm), hash); + } + } + + public static byte GetHashAlgorithmForPrfAlgorithm(int prfAlgorithm) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.tls_prf_legacy: + throw new ArgumentException("legacy PRF not a valid algorithm", "prfAlgorithm"); + case PrfAlgorithm.tls_prf_sha256: + return HashAlgorithm.sha256; + case PrfAlgorithm.tls_prf_sha384: + return HashAlgorithm.sha384; + default: + throw new ArgumentException("unknown PrfAlgorithm", "prfAlgorithm"); + } + } + + public static DerObjectIdentifier GetOidForHashAlgorithm(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return PkcsObjectIdentifiers.MD5; + case HashAlgorithm.sha1: + return X509ObjectIdentifiers.IdSha1; + case HashAlgorithm.sha224: + return NistObjectIdentifiers.IdSha224; + case HashAlgorithm.sha256: + return NistObjectIdentifiers.IdSha256; + case HashAlgorithm.sha384: + return NistObjectIdentifiers.IdSha384; + case HashAlgorithm.sha512: + return NistObjectIdentifiers.IdSha512; + default: + throw new ArgumentException("unknown HashAlgorithm", "hashAlgorithm"); + } + } + + internal static short GetClientCertificateType(Certificate clientCertificate, Certificate serverCertificate) + { + if (clientCertificate.IsEmpty) + return -1; + + X509CertificateStructure x509Cert = clientCertificate.GetCertificateAt(0); + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); + if (publicKey.IsPrivate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + /* + * TODO RFC 5246 7.4.6. The certificates MUST be signed using an acceptable hash/ + * signature algorithm pair, as described in Section 7.4.4. Note that this relaxes the + * constraints on certificate-signing algorithms found in prior versions of TLS. + */ + + /* + * RFC 5246 7.4.6. Client Certificate + */ + + /* + * RSA public key; the certificate MUST allow the key to be used for signing with the + * signature scheme and hash algorithm that will be employed in the certificate verify + * message. + */ + if (publicKey is RsaKeyParameters) + { + ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + return ClientCertificateType.rsa_sign; + } + + /* + * DSA public key; the certificate MUST allow the key to be used for signing with the + * hash algorithm that will be employed in the certificate verify message. + */ + if (publicKey is DsaPublicKeyParameters) + { + ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + return ClientCertificateType.dss_sign; + } + + /* + * ECDSA-capable public key; the certificate MUST allow the key to be used for signing + * with the hash algorithm that will be employed in the certificate verify message; the + * public key MUST use a curve and point format supported by the server. + */ + if (publicKey is ECPublicKeyParameters) + { + ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + // TODO Check the curve and point format + return ClientCertificateType.ecdsa_sign; + } + + // TODO Add support for ClientCertificateType.*_fixed_* + + throw new TlsFatalAlert(AlertDescription.unsupported_certificate); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + } + + internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms) + { + if (supportedSignatureAlgorithms != null) + { + foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) + { + byte hashAlgorithm = signatureAndHashAlgorithm.Hash; + + // TODO Support values in the "Reserved for Private Use" range + if (!HashAlgorithm.IsPrivate(hashAlgorithm)) + { + handshakeHash.TrackHashAlgorithm(hashAlgorithm); + } + } + } + } + + public static bool HasSigningCapability(byte clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + case ClientCertificateType.rsa_sign: + return true; + default: + return false; + } + } + + public static TlsSigner CreateTlsSigner(byte clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + return new TlsDssSigner(); + case ClientCertificateType.ecdsa_sign: + return new TlsECDsaSigner(); + case ClientCertificateType.rsa_sign: + return new TlsRsaSigner(); + default: + throw new ArgumentException("not a type with signing capability", "clientCertificateType"); + } + } + + internal static readonly byte[] SSL_CLIENT = {0x43, 0x4C, 0x4E, 0x54}; + internal static readonly byte[] SSL_SERVER = {0x53, 0x52, 0x56, 0x52}; + + // SSL3 magic mix constants ("A", "BB", "CCC", ...) + internal static readonly byte[][] SSL3_CONST = GenSsl3Const(); + + private static byte[][] GenSsl3Const() + { + int n = 10; + byte[][] arr = new byte[n][]; + for (int i = 0; i < n; i++) + { + byte[] b = new byte[i + 1]; + Arrays.Fill(b, (byte)('A' + i)); + arr[i] = b; + } + return arr; + } + + private static IList VectorOfOne(object obj) + { + IList v = Org.BouncyCastle.Utilities.Platform.CreateArrayList(1); + v.Add(obj); + return v; + } + + public static int GetCipherType(int ciphersuite) + { + switch (GetEncryptionAlgorithm(ciphersuite)) + { + case EncryptionAlgorithm.AES_128_CCM: + case EncryptionAlgorithm.AES_128_CCM_8: + case EncryptionAlgorithm.AES_128_GCM: + case EncryptionAlgorithm.AES_128_OCB_TAGLEN96: + case EncryptionAlgorithm.AES_256_CCM: + case EncryptionAlgorithm.AES_256_CCM_8: + case EncryptionAlgorithm.AES_256_GCM: + case EncryptionAlgorithm.AES_256_OCB_TAGLEN96: + case EncryptionAlgorithm.CAMELLIA_128_GCM: + case EncryptionAlgorithm.CAMELLIA_256_GCM: + case EncryptionAlgorithm.CHACHA20_POLY1305: + return CipherType.aead; + + case EncryptionAlgorithm.RC2_CBC_40: + case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.DES40_CBC: + case EncryptionAlgorithm.DES_CBC: + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + case EncryptionAlgorithm.AES_128_CBC: + case EncryptionAlgorithm.AES_256_CBC: + case EncryptionAlgorithm.CAMELLIA_128_CBC: + case EncryptionAlgorithm.CAMELLIA_256_CBC: + case EncryptionAlgorithm.SEED_CBC: + return CipherType.block; + + case EncryptionAlgorithm.RC4_40: + case EncryptionAlgorithm.RC4_128: + return CipherType.stream; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static int GetEncryptionAlgorithm(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + return EncryptionAlgorithm.cls_3DES_EDE_CBC; + + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + return EncryptionAlgorithm.AES_128_CBC; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + return EncryptionAlgorithm.AES_128_CCM; + + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + return EncryptionAlgorithm.AES_128_CCM_8; + + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + return EncryptionAlgorithm.AES_128_GCM; + + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_128_OCB: + return EncryptionAlgorithm.AES_128_OCB_TAGLEN96; + + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return EncryptionAlgorithm.AES_256_CBC; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + return EncryptionAlgorithm.AES_256_CCM; + + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + return EncryptionAlgorithm.AES_256_CCM_8; + + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + return EncryptionAlgorithm.AES_256_GCM; + + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_256_OCB: + return EncryptionAlgorithm.AES_256_OCB_TAGLEN96; + + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + return EncryptionAlgorithm.CAMELLIA_128_CBC; + + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + return EncryptionAlgorithm.CAMELLIA_128_CBC; + + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + return EncryptionAlgorithm.CAMELLIA_128_GCM; + + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + return EncryptionAlgorithm.CAMELLIA_256_CBC; + + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + return EncryptionAlgorithm.CAMELLIA_256_CBC; + + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + return EncryptionAlgorithm.CAMELLIA_256_CBC; + + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + return EncryptionAlgorithm.CAMELLIA_256_GCM; + + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + return EncryptionAlgorithm.CHACHA20_POLY1305; + + case CipherSuite.TLS_RSA_WITH_NULL_MD5: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: + case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: + return EncryptionAlgorithm.RC4_128; + + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: + return EncryptionAlgorithm.RC4_128; + + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + return EncryptionAlgorithm.SEED_CBC; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static int GetKeyExchangeAlgorithm(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_DSS; + + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_RSA; + + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DHE_DSS; + + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + return KeyExchangeAlgorithm.DHE_PSK; + + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DHE_RSA; + + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDH_anon; + + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDH_ECDSA; + + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDH_RSA; + + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDHE_ECDSA; + + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDHE_PSK; + + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDHE_RSA; + + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.PSK; + + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_MD5: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: + case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.RSA; + + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.RSA_PSK; + + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP; + + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP_DSS; + + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP_RSA; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static int GetMacAlgorithm(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + return MacAlgorithm.cls_null; + + case CipherSuite.TLS_RSA_WITH_NULL_MD5: + case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: + return MacAlgorithm.hmac_md5; + + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return MacAlgorithm.hmac_sha1; + + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return MacAlgorithm.hmac_sha256; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + return MacAlgorithm.hmac_sha384; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static ProtocolVersion GetMinimumVersion(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_128_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_AES_256_OCB: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_128_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_AES_256_OCB: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_128_OCB: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_AES_256_OCB: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return ProtocolVersion.TLSv12; + + default: + return ProtocolVersion.SSLv3; + } + } + + public static bool IsAeadCipherSuite(int ciphersuite) + { + return CipherType.aead == GetCipherType(ciphersuite); + } + + public static bool IsBlockCipherSuite(int ciphersuite) + { + return CipherType.block == GetCipherType(ciphersuite); + } + + public static bool IsStreamCipherSuite(int ciphersuite) + { + return CipherType.stream == GetCipherType(ciphersuite); + } + + public static bool IsValidCipherSuiteForVersion(int cipherSuite, ProtocolVersion serverVersion) + { + return GetMinimumVersion(cipherSuite).IsEqualOrEarlierVersionOf(serverVersion.GetEquivalentTLSVersion()); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs.meta new file mode 100644 index 0000000..0eeb9bb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e3fd2e5c07ad1dd45931d22a3797521d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util.meta new file mode 100644 index 0000000..a5de757 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e9c7f1f65018a6b489b3d3892004d352 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs new file mode 100644 index 0000000..ab29d5f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs @@ -0,0 +1,366 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Crypto.Utilities +{ + internal sealed class Pack + { + private Pack() + { + } + + internal static void UInt16_To_BE(ushort n, byte[] bs) + { + bs[0] = (byte)(n >> 8); + bs[1] = (byte)(n); + } + + internal static void UInt16_To_BE(ushort n, byte[] bs, int off) + { + bs[off] = (byte)(n >> 8); + bs[off + 1] = (byte)(n); + } + + internal static ushort BE_To_UInt16(byte[] bs) + { + uint n = (uint)bs[0] << 8 + | (uint)bs[1]; + return (ushort)n; + } + + internal static ushort BE_To_UInt16(byte[] bs, int off) + { + uint n = (uint)bs[off] << 8 + | (uint)bs[off + 1]; + return (ushort)n; + } + + internal static byte[] UInt32_To_BE(uint n) + { + byte[] bs = new byte[4]; + UInt32_To_BE(n, bs, 0); + return bs; + } + + internal static void UInt32_To_BE(uint n, byte[] bs) + { + bs[0] = (byte)(n >> 24); + bs[1] = (byte)(n >> 16); + bs[2] = (byte)(n >> 8); + bs[3] = (byte)(n); + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + internal static void UInt32_To_BE(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n >> 24); + bs[off + 1] = (byte)(n >> 16); + bs[off + 2] = (byte)(n >> 8); + bs[off + 3] = (byte)(n); + } +#else + internal static unsafe void UInt32_To_BE(uint n, byte[] bs, int off) + { + fixed (byte* p = bs) + { + p[off + 0] = (byte)(n >> 24); + p[off + 1] = (byte)(n >> 16); + p[off + 2] = (byte)(n >> 8); + p[off + 3] = (byte)(n); + } + //bs[off] = (byte)(n >> 24); + //bs[off + 1] = (byte)(n >> 16); + //bs[off + 2] = (byte)(n >> 8); + //bs[off + 3] = (byte)(n); + } +#endif + + internal static byte[] UInt32_To_BE(uint[] ns) + { + byte[] bs = new byte[4 * ns.Length]; + UInt32_To_BE(ns, bs, 0); + return bs; + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + internal static void UInt32_To_BE(uint[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt32_To_BE(ns[i], bs, off); + off += 4; + } + } +#else + internal static unsafe void UInt32_To_BE(uint[] ns, byte[] bs, int off) + { + //for (int i = 0; i < ns.Length; ++i) + //{ + // UInt32_To_BE(ns[i], bs, off); + // off += 4; + //} + fixed (byte* pbs = bs) + fixed (uint* pns = ns) + { + for (int i = 0; i < ns.Length; ++i) + { + uint n = pns[i]; + + pbs[off + 0] = (byte)(n >> 24); + pbs[off + 1] = (byte)(n >> 16); + pbs[off + 2] = (byte)(n >> 8); + pbs[off + 3] = (byte)(n); + + off += 4; + } + } + } +#endif + + internal static uint BE_To_UInt32(byte[] bs) + { + return (uint)bs[0] << 24 + | (uint)bs[1] << 16 + | (uint)bs[2] << 8 + | (uint)bs[3]; + } + + internal static uint BE_To_UInt32(byte[] bs, int off) + { + return (uint)bs[off] << 24 + | (uint)bs[off + 1] << 16 + | (uint)bs[off + 2] << 8 + | (uint)bs[off + 3]; + } + + internal static void BE_To_UInt32(byte[] bs, int off, uint[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = BE_To_UInt32(bs, off); + off += 4; + } + } + + internal static byte[] UInt64_To_BE(ulong n) + { + byte[] bs = new byte[8]; + UInt64_To_BE(n, bs, 0); + return bs; + } + + internal static void UInt64_To_BE(ulong n, byte[] bs) + { + UInt32_To_BE((uint)(n >> 32), bs); + UInt32_To_BE((uint)(n), bs, 4); + } + + internal static void UInt64_To_BE(ulong n, byte[] bs, int off) + { + UInt32_To_BE((uint)(n >> 32), bs, off); + UInt32_To_BE((uint)(n), bs, off + 4); + } + + internal static byte[] UInt64_To_BE(ulong[] ns) + { + byte[] bs = new byte[8 * ns.Length]; + UInt64_To_BE(ns, bs, 0); + return bs; + } + + internal static void UInt64_To_BE(ulong[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt64_To_BE(ns[i], bs, off); + off += 8; + } + } + + internal static ulong BE_To_UInt64(byte[] bs) + { + uint hi = BE_To_UInt32(bs); + uint lo = BE_To_UInt32(bs, 4); + return ((ulong)hi << 32) | (ulong)lo; + } + + internal static ulong BE_To_UInt64(byte[] bs, int off) + { + uint hi = BE_To_UInt32(bs, off); + uint lo = BE_To_UInt32(bs, off + 4); + return ((ulong)hi << 32) | (ulong)lo; + } + + internal static void BE_To_UInt64(byte[] bs, int off, ulong[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = BE_To_UInt64(bs, off); + off += 8; + } + } + + internal static void UInt16_To_LE(ushort n, byte[] bs) + { + bs[0] = (byte)(n); + bs[1] = (byte)(n >> 8); + } + + internal static void UInt16_To_LE(ushort n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[off + 1] = (byte)(n >> 8); + } + + internal static ushort LE_To_UInt16(byte[] bs) + { + uint n = (uint)bs[0] + | (uint)bs[1] << 8; + return (ushort)n; + } + + internal static ushort LE_To_UInt16(byte[] bs, int off) + { + uint n = (uint)bs[off] + | (uint)bs[off + 1] << 8; + return (ushort)n; + } + + internal static byte[] UInt32_To_LE(uint n) + { + byte[] bs = new byte[4]; + UInt32_To_LE(n, bs, 0); + return bs; + } + + internal static void UInt32_To_LE(uint n, byte[] bs) + { + bs[0] = (byte)(n); + bs[1] = (byte)(n >> 8); + bs[2] = (byte)(n >> 16); + bs[3] = (byte)(n >> 24); + } + +#if true //!ENABLE_IL2CPP || UNITY_WEBGL + internal static void UInt32_To_LE(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[off + 1] = (byte)(n >> 8); + bs[off + 2] = (byte)(n >> 16); + bs[off + 3] = (byte)(n >> 24); + } +#else + internal static unsafe void UInt32_To_LE(uint n, byte[] bs, int off) + { + fixed (byte* p = bs) + { + p[off + 0] = (byte)(n); + p[off + 1] = (byte)(n >> 8); + p[off + 2] = (byte)(n >> 16); + p[off + 3] = (byte)(n >> 24); + } + //bs[off] = (byte)(n); + //bs[off + 1] = (byte)(n >> 8); + //bs[off + 2] = (byte)(n >> 16); + //bs[off + 3] = (byte)(n >> 24); + } +#endif + + internal static byte[] UInt32_To_LE(uint[] ns) + { + byte[] bs = new byte[4 * ns.Length]; + UInt32_To_LE(ns, bs, 0); + return bs; + } + + internal static void UInt32_To_LE(uint[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt32_To_LE(ns[i], bs, off); + off += 4; + } + } + + internal static uint LE_To_UInt32(byte[] bs) + { + return (uint)bs[0] + | (uint)bs[1] << 8 + | (uint)bs[2] << 16 + | (uint)bs[3] << 24; + } + + internal static uint LE_To_UInt32(byte[] bs, int off) + { + return (uint)bs[off] + | (uint)bs[off + 1] << 8 + | (uint)bs[off + 2] << 16 + | (uint)bs[off + 3] << 24; + } + + internal static void LE_To_UInt32(byte[] bs, int off, uint[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = LE_To_UInt32(bs, off); + off += 4; + } + } + + internal static void LE_To_UInt32(byte[] bs, int bOff, uint[] ns, int nOff, int count) + { + for (int i = 0; i < count; ++i) + { + ns[nOff + i] = LE_To_UInt32(bs, bOff); + bOff += 4; + } + } + + internal static uint[] LE_To_UInt32(byte[] bs, int off, int count) + { + uint[] ns = new uint[count]; + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = LE_To_UInt32(bs, off); + off += 4; + } + return ns; + } + + internal static byte[] UInt64_To_LE(ulong n) + { + byte[] bs = new byte[8]; + UInt64_To_LE(n, bs, 0); + return bs; + } + + internal static void UInt64_To_LE(ulong n, byte[] bs) + { + UInt32_To_LE((uint)(n), bs); + UInt32_To_LE((uint)(n >> 32), bs, 4); + } + + internal static void UInt64_To_LE(ulong n, byte[] bs, int off) + { + UInt32_To_LE((uint)(n), bs, off); + UInt32_To_LE((uint)(n >> 32), bs, off + 4); + } + + internal static ulong LE_To_UInt64(byte[] bs) + { + uint lo = LE_To_UInt32(bs); + uint hi = LE_To_UInt32(bs, 4); + return ((ulong)hi << 32) | (ulong)lo; + } + + internal static ulong LE_To_UInt64(byte[] bs, int off) + { + uint lo = LE_To_UInt32(bs, off); + uint hi = LE_To_UInt32(bs, off + 4); + return ((ulong)hi << 32) | (ulong)lo; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs.meta new file mode 100644 index 0000000..fcbd18a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/util/Pack.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1d5c1783497718141a4efcd23f5d22a5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math.meta new file mode 100644 index 0000000..1571104 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5701df17f62065143b8cf179ae96e414 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs new file mode 100644 index 0000000..d8bdf8d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs @@ -0,0 +1,3596 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.Diagnostics; +using System.Globalization; +using System.Text; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class BigInteger + { + // The first few odd primes + /* + 3 5 7 11 13 17 19 23 29 + 31 37 41 43 47 53 59 61 67 71 + 73 79 83 89 97 101 103 107 109 113 + 127 131 137 139 149 151 157 163 167 173 + 179 181 191 193 197 199 211 223 227 229 + 233 239 241 251 257 263 269 271 277 281 + 283 293 307 311 313 317 331 337 347 349 + 353 359 367 373 379 383 389 397 401 409 + 419 421 431 433 439 443 449 457 461 463 + 467 479 487 491 499 503 509 521 523 541 + 547 557 563 569 571 577 587 593 599 601 + 607 613 617 619 631 641 643 647 653 659 + 661 673 677 683 691 701 709 719 727 733 + 739 743 751 757 761 769 773 787 797 809 + 811 821 823 827 829 839 853 857 859 863 + 877 881 883 887 907 911 919 929 937 941 + 947 953 967 971 977 983 991 997 1009 + 1013 1019 1021 1031 1033 1039 1049 1051 + 1061 1063 1069 1087 1091 1093 1097 1103 + 1109 1117 1123 1129 1151 1153 1163 1171 + 1181 1187 1193 1201 1213 1217 1223 1229 + 1231 1237 1249 1259 1277 1279 1283 1289 + */ + + // Each list has a product < 2^31 + internal static readonly int[][] primeLists = new int[][] + { + new int[]{ 3, 5, 7, 11, 13, 17, 19, 23 }, + new int[]{ 29, 31, 37, 41, 43 }, + new int[]{ 47, 53, 59, 61, 67 }, + new int[]{ 71, 73, 79, 83 }, + new int[]{ 89, 97, 101, 103 }, + + new int[]{ 107, 109, 113, 127 }, + new int[]{ 131, 137, 139, 149 }, + new int[]{ 151, 157, 163, 167 }, + new int[]{ 173, 179, 181, 191 }, + new int[]{ 193, 197, 199, 211 }, + + new int[]{ 223, 227, 229 }, + new int[]{ 233, 239, 241 }, + new int[]{ 251, 257, 263 }, + new int[]{ 269, 271, 277 }, + new int[]{ 281, 283, 293 }, + + new int[]{ 307, 311, 313 }, + new int[]{ 317, 331, 337 }, + new int[]{ 347, 349, 353 }, + new int[]{ 359, 367, 373 }, + new int[]{ 379, 383, 389 }, + + new int[]{ 397, 401, 409 }, + new int[]{ 419, 421, 431 }, + new int[]{ 433, 439, 443 }, + new int[]{ 449, 457, 461 }, + new int[]{ 463, 467, 479 }, + + new int[]{ 487, 491, 499 }, + new int[]{ 503, 509, 521 }, + new int[]{ 523, 541, 547 }, + new int[]{ 557, 563, 569 }, + new int[]{ 571, 577, 587 }, + + new int[]{ 593, 599, 601 }, + new int[]{ 607, 613, 617 }, + new int[]{ 619, 631, 641 }, + new int[]{ 643, 647, 653 }, + new int[]{ 659, 661, 673 }, + + new int[]{ 677, 683, 691 }, + new int[]{ 701, 709, 719 }, + new int[]{ 727, 733, 739 }, + new int[]{ 743, 751, 757 }, + new int[]{ 761, 769, 773 }, + + new int[]{ 787, 797, 809 }, + new int[]{ 811, 821, 823 }, + new int[]{ 827, 829, 839 }, + new int[]{ 853, 857, 859 }, + new int[]{ 863, 877, 881 }, + + new int[]{ 883, 887, 907 }, + new int[]{ 911, 919, 929 }, + new int[]{ 937, 941, 947 }, + new int[]{ 953, 967, 971 }, + new int[]{ 977, 983, 991 }, + + new int[]{ 997, 1009, 1013 }, + new int[]{ 1019, 1021, 1031 }, + new int[]{ 1033, 1039, 1049 }, + new int[]{ 1051, 1061, 1063 }, + new int[]{ 1069, 1087, 1091 }, + + new int[]{ 1093, 1097, 1103 }, + new int[]{ 1109, 1117, 1123 }, + new int[]{ 1129, 1151, 1153 }, + new int[]{ 1163, 1171, 1181 }, + new int[]{ 1187, 1193, 1201 }, + + new int[]{ 1213, 1217, 1223 }, + new int[]{ 1229, 1231, 1237 }, + new int[]{ 1249, 1259, 1277 }, + new int[]{ 1279, 1283, 1289 }, + }; + + internal static readonly int[] primeProducts; + + private const long IMASK = 0xFFFFFFFFL; + private const ulong UIMASK = 0xFFFFFFFFUL; + + private static readonly int[] ZeroMagnitude = new int[0]; + private static readonly byte[] ZeroEncoding = new byte[0]; + + private static readonly BigInteger[] SMALL_CONSTANTS = new BigInteger[17]; + public static readonly BigInteger Zero; + public static readonly BigInteger One; + public static readonly BigInteger Two; + public static readonly BigInteger Three; + public static readonly BigInteger Ten; + + //private readonly static byte[] BitCountTable = + //{ + // 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + //}; + + private readonly static byte[] BitLengthTable = + { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // TODO Parse radix-2 64 bits at a time and radix-8 63 bits at a time + private const int chunk2 = 1, chunk8 = 1, chunk10 = 19, chunk16 = 16; + private static readonly BigInteger radix2, radix2E, radix8, radix8E, radix10, radix10E, radix16, radix16E; + + private static readonly SecureRandom RandomSource = new SecureRandom(); + + /* + * These are the threshold bit-lengths (of an exponent) where we increase the window size. + * They are calculated according to the expected savings in multiplications. + * Some squares will also be saved on average, but we offset these against the extra storage costs. + */ + private static readonly int[] ExpWindowThresholds = { 7, 25, 81, 241, 673, 1793, 4609, Int32.MaxValue }; + + private const int BitsPerByte = 8; + private const int BitsPerInt = 32; + private const int BytesPerInt = 4; + + static BigInteger() + { + Zero = new BigInteger(0, ZeroMagnitude, false); + Zero.nBits = 0; Zero.nBitLength = 0; + + SMALL_CONSTANTS[0] = Zero; + for (uint i = 1; i < SMALL_CONSTANTS.Length; ++i) + { + SMALL_CONSTANTS[i] = CreateUValueOf(i); + } + + One = SMALL_CONSTANTS[1]; + Two = SMALL_CONSTANTS[2]; + Three = SMALL_CONSTANTS[3]; + Ten = SMALL_CONSTANTS[10]; + + radix2 = ValueOf(2); + radix2E = radix2.Pow(chunk2); + + radix8 = ValueOf(8); + radix8E = radix8.Pow(chunk8); + + radix10 = ValueOf(10); + radix10E = radix10.Pow(chunk10); + + radix16 = ValueOf(16); + radix16E = radix16.Pow(chunk16); + + primeProducts = new int[primeLists.Length]; + + for (int i = 0; i < primeLists.Length; ++i) + { + int[] primeList = primeLists[i]; + int product = primeList[0]; + for (int j = 1; j < primeList.Length; ++j) + { + product *= primeList[j]; + } + primeProducts[i] = product; + } + } + + private int[] magnitude; // array of ints with [0] being the most significant + private int sign; // -1 means -ve; +1 means +ve; 0 means 0; + private int nBits = -1; // cache BitCount() value + private int nBitLength = -1; // cache BitLength() value + private int mQuote = 0; // -m^(-1) mod b, b = 2^32 (see Montgomery mult.), 0 when uninitialised + + private static int GetByteLength( + int nBits) + { + return (nBits + BitsPerByte - 1) / BitsPerByte; + } + + internal static BigInteger Arbitrary(int sizeInBits) + { + return new BigInteger(sizeInBits, RandomSource); + } + + private BigInteger( + int signum, + int[] mag, + bool checkMag) + { + if (checkMag) + { + int i = 0; + while (i < mag.Length && mag[i] == 0) + { + ++i; + } + + if (i == mag.Length) + { + this.sign = 0; + this.magnitude = ZeroMagnitude; + } + else + { + this.sign = signum; + + if (i == 0) + { + this.magnitude = mag; + } + else + { + // strip leading 0 words + this.magnitude = new int[mag.Length - i]; + Array.Copy(mag, i, this.magnitude, 0, this.magnitude.Length); + } + } + } + else + { + this.sign = signum; + this.magnitude = mag; + } + } + + public BigInteger( + string value) + : this(value, 10) + { + } + + public BigInteger( + string str, + int radix) + { + if (str.Length == 0) + throw new FormatException("Zero length BigInteger"); + + NumberStyles style; + int chunk; + BigInteger r; + BigInteger rE; + + switch (radix) + { + case 2: + // Is there anyway to restrict to binary digits? + style = NumberStyles.Integer; + chunk = chunk2; + r = radix2; + rE = radix2E; + break; + case 8: + // Is there anyway to restrict to octal digits? + style = NumberStyles.Integer; + chunk = chunk8; + r = radix8; + rE = radix8E; + break; + case 10: + // This style seems to handle spaces and minus sign already (our processing redundant?) + style = NumberStyles.Integer; + chunk = chunk10; + r = radix10; + rE = radix10E; + break; + case 16: + // TODO Should this be HexNumber? + style = NumberStyles.AllowHexSpecifier; + chunk = chunk16; + r = radix16; + rE = radix16E; + break; + default: + throw new FormatException("Only bases 2, 8, 10, or 16 allowed"); + } + + + int index = 0; + sign = 1; + + if (str[0] == '-') + { + if (str.Length == 1) + throw new FormatException("Zero length BigInteger"); + + sign = -1; + index = 1; + } + + // strip leading zeros from the string str + while (index < str.Length && Int32.Parse(str[index].ToString(), style) == 0) + { + index++; + } + + if (index >= str.Length) + { + // zero value - we're done + sign = 0; + magnitude = ZeroMagnitude; + return; + } + + ////// + // could we work out the max number of ints required to store + // str.Length digits in the given base, then allocate that + // storage in one hit?, then Generate the magnitude in one hit too? + ////// + + BigInteger b = Zero; + + + int next = index + chunk; + + if (next <= str.Length) + { + do + { + string s = str.Substring(index, chunk); + ulong i = ulong.Parse(s, style); + BigInteger bi = CreateUValueOf(i); + + switch (radix) + { + case 2: + // TODO Need this because we are parsing in radix 10 above + if (i >= 2) + throw new FormatException("Bad character in radix 2 string: " + s); + + // TODO Parse 64 bits at a time + b = b.ShiftLeft(1); + break; + case 8: + // TODO Need this because we are parsing in radix 10 above + if (i >= 8) + throw new FormatException("Bad character in radix 8 string: " + s); + + // TODO Parse 63 bits at a time + b = b.ShiftLeft(3); + break; + case 16: + b = b.ShiftLeft(64); + break; + default: + b = b.Multiply(rE); + break; + } + + b = b.Add(bi); + + index = next; + next += chunk; + } + while (next <= str.Length); + } + + if (index < str.Length) + { + string s = str.Substring(index); + ulong i = ulong.Parse(s, style); + BigInteger bi = CreateUValueOf(i); + + if (b.sign > 0) + { + if (radix == 2) + { + // NB: Can't reach here since we are parsing one char at a time + Debug.Assert(false); + + // TODO Parse all bits at once +// b = b.ShiftLeft(s.Length); + } + else if (radix == 8) + { + // NB: Can't reach here since we are parsing one char at a time + Debug.Assert(false); + + // TODO Parse all bits at once +// b = b.ShiftLeft(s.Length * 3); + } + else if (radix == 16) + { + b = b.ShiftLeft(s.Length << 2); + } + else + { + b = b.Multiply(r.Pow(s.Length)); + } + + b = b.Add(bi); + } + else + { + b = bi; + } + } + + // Note: This is the previous (slower) algorithm +// while (index < value.Length) +// { +// char c = value[index]; +// string s = c.ToString(); +// int i = Int32.Parse(s, style); +// +// b = b.Multiply(r).Add(ValueOf(i)); +// index++; +// } + + magnitude = b.magnitude; + } + + public BigInteger( + byte[] bytes) + : this(bytes, 0, bytes.Length) + { + } + + public BigInteger( + byte[] bytes, + int offset, + int length) + { + if (length == 0) + throw new FormatException("Zero length BigInteger"); + + // TODO Move this processing into MakeMagnitude (provide sign argument) + if ((sbyte)bytes[offset] < 0) + { + this.sign = -1; + + int end = offset + length; + + int iBval; + // strip leading sign bytes + for (iBval = offset; iBval < end && ((sbyte)bytes[iBval] == -1); iBval++) + { + } + + if (iBval >= end) + { + this.magnitude = One.magnitude; + } + else + { + int numBytes = end - iBval; + byte[] inverse = new byte[numBytes]; + + int index = 0; + while (index < numBytes) + { + inverse[index++] = (byte)~bytes[iBval++]; + } + + Debug.Assert(iBval == end); + + while (inverse[--index] == byte.MaxValue) + { + inverse[index] = byte.MinValue; + } + + inverse[index]++; + + this.magnitude = MakeMagnitude(inverse, 0, inverse.Length); + } + } + else + { + // strip leading zero bytes and return magnitude bytes + this.magnitude = MakeMagnitude(bytes, offset, length); + this.sign = this.magnitude.Length > 0 ? 1 : 0; + } + } + + private static int[] MakeMagnitude( + byte[] bytes, + int offset, + int length) + { + int end = offset + length; + + // strip leading zeros + int firstSignificant; + for (firstSignificant = offset; firstSignificant < end + && bytes[firstSignificant] == 0; firstSignificant++) + { + } + + if (firstSignificant >= end) + { + return ZeroMagnitude; + } + + int nInts = (end - firstSignificant + 3) / BytesPerInt; + int bCount = (end - firstSignificant) % BytesPerInt; + if (bCount == 0) + { + bCount = BytesPerInt; + } + + if (nInts < 1) + { + return ZeroMagnitude; + } + + int[] mag = new int[nInts]; + + int v = 0; + int magnitudeIndex = 0; + for (int i = firstSignificant; i < end; ++i) + { + v <<= 8; + v |= bytes[i] & 0xff; + bCount--; + if (bCount <= 0) + { + mag[magnitudeIndex] = v; + magnitudeIndex++; + bCount = BytesPerInt; + v = 0; + } + } + + if (magnitudeIndex < mag.Length) + { + mag[magnitudeIndex] = v; + } + + return mag; + } + + public BigInteger( + int sign, + byte[] bytes) + : this(sign, bytes, 0, bytes.Length) + { + } + + public BigInteger( + int sign, + byte[] bytes, + int offset, + int length) + { + if (sign < -1 || sign > 1) + throw new FormatException("Invalid sign value"); + + if (sign == 0) + { + this.sign = 0; + this.magnitude = ZeroMagnitude; + } + else + { + // copy bytes + this.magnitude = MakeMagnitude(bytes, offset, length); + this.sign = this.magnitude.Length < 1 ? 0 : sign; + } + } + + public BigInteger( + int sizeInBits, + Random random) + { + if (sizeInBits < 0) + throw new ArgumentException("sizeInBits must be non-negative"); + + this.nBits = -1; + this.nBitLength = -1; + + if (sizeInBits == 0) + { + this.sign = 0; + this.magnitude = ZeroMagnitude; + return; + } + + int nBytes = GetByteLength(sizeInBits); + byte[] b = new byte[nBytes]; + random.NextBytes(b); + + // strip off any excess bits in the MSB + int xBits = BitsPerByte * nBytes - sizeInBits; + b[0] &= (byte)(255U >> xBits); + + this.magnitude = MakeMagnitude(b, 0, b.Length); + this.sign = this.magnitude.Length < 1 ? 0 : 1; + } + + public BigInteger( + int bitLength, + int certainty, + Random random) + { + if (bitLength < 2) + throw new ArithmeticException("bitLength < 2"); + + this.sign = 1; + this.nBitLength = bitLength; + + if (bitLength == 2) + { + this.magnitude = random.Next(2) == 0 + ? Two.magnitude + : Three.magnitude; + return; + } + + int nBytes = GetByteLength(bitLength); + byte[] b = new byte[nBytes]; + + int xBits = BitsPerByte * nBytes - bitLength; + byte mask = (byte)(255U >> xBits); + byte lead = (byte)(1 << (7 - xBits)); + + for (;;) + { + random.NextBytes(b); + + // strip off any excess bits in the MSB + b[0] &= mask; + + // ensure the leading bit is 1 (to meet the strength requirement) + b[0] |= lead; + + // ensure the trailing bit is 1 (i.e. must be odd) + b[nBytes - 1] |= 1; + + this.magnitude = MakeMagnitude(b, 0, b.Length); + this.nBits = -1; + this.mQuote = 0; + + if (certainty < 1) + break; + + if (CheckProbablePrime(certainty, random, true)) + break; + + for (int j = 1; j < (magnitude.Length - 1); ++j) + { + this.magnitude[j] ^= random.Next(); + + if (CheckProbablePrime(certainty, random, true)) + return; + } + } + } + + public BigInteger Abs() + { + return sign >= 0 ? this : Negate(); + } + + /** + * return a = a + b - b preserved. + */ + private static int[] AddMagnitudes( + int[] a, + int[] b) + { + int tI = a.Length - 1; + int vI = b.Length - 1; + long m = 0; + + while (vI >= 0) + { + m += ((long)(uint)a[tI] + (long)(uint)b[vI--]); + a[tI--] = (int)m; + m = (long)((ulong)m >> 32); + } + + if (m != 0) + { + while (tI >= 0 && ++a[tI--] == 0) + { + } + } + + return a; + } + + public BigInteger Add( + BigInteger value) + { + if (this.sign == 0) + return value; + + if (this.sign != value.sign) + { + if (value.sign == 0) + return this; + + if (value.sign < 0) + return Subtract(value.Negate()); + + return value.Subtract(Negate()); + } + + return AddToMagnitude(value.magnitude); + } + + private BigInteger AddToMagnitude( + int[] magToAdd) + { + int[] big, small; + if (this.magnitude.Length < magToAdd.Length) + { + big = magToAdd; + small = this.magnitude; + } + else + { + big = this.magnitude; + small = magToAdd; + } + + // Conservatively avoid over-allocation when no overflow possible + uint limit = uint.MaxValue; + if (big.Length == small.Length) + limit -= (uint) small[0]; + + bool possibleOverflow = (uint) big[0] >= limit; + + int[] bigCopy; + if (possibleOverflow) + { + bigCopy = new int[big.Length + 1]; + big.CopyTo(bigCopy, 1); + } + else + { + bigCopy = (int[]) big.Clone(); + } + + bigCopy = AddMagnitudes(bigCopy, small); + + return new BigInteger(this.sign, bigCopy, possibleOverflow); + } + + public BigInteger And( + BigInteger value) + { + if (this.sign == 0 || value.sign == 0) + { + return Zero; + } + + int[] aMag = this.sign > 0 + ? this.magnitude + : Add(One).magnitude; + + int[] bMag = value.sign > 0 + ? value.magnitude + : value.Add(One).magnitude; + + bool resultNeg = sign < 0 && value.sign < 0; + int resultLength = System.Math.Max(aMag.Length, bMag.Length); + int[] resultMag = new int[resultLength]; + + int aStart = resultMag.Length - aMag.Length; + int bStart = resultMag.Length - bMag.Length; + + for (int i = 0; i < resultMag.Length; ++i) + { + int aWord = i >= aStart ? aMag[i - aStart] : 0; + int bWord = i >= bStart ? bMag[i - bStart] : 0; + + if (this.sign < 0) + { + aWord = ~aWord; + } + + if (value.sign < 0) + { + bWord = ~bWord; + } + + resultMag[i] = aWord & bWord; + + if (resultNeg) + { + resultMag[i] = ~resultMag[i]; + } + } + + BigInteger result = new BigInteger(1, resultMag, true); + + // TODO Optimise this case + if (resultNeg) + { + result = result.Not(); + } + + return result; + } + + public BigInteger AndNot( + BigInteger val) + { + return And(val.Not()); + } + + public int BitCount + { + get + { + if (nBits == -1) + { + if (sign < 0) + { + // TODO Optimise this case + nBits = Not().BitCount; + } + else + { + int sum = 0; + for (int i = 0; i < magnitude.Length; ++i) + { + sum += BitCnt(magnitude[i]); + } + nBits = sum; + } + } + + return nBits; + } + } + + public static int BitCnt(int i) + { + uint u = (uint)i; + u = u - ((u >> 1) & 0x55555555); + u = (u & 0x33333333) + ((u >> 2) & 0x33333333); + u = (u + (u >> 4)) & 0x0f0f0f0f; + u += (u >> 8); + u += (u >> 16); + u &= 0x3f; + return (int)u; + } + + private static int CalcBitLength(int sign, int indx, int[] mag) + { + for (;;) + { + if (indx >= mag.Length) + return 0; + + if (mag[indx] != 0) + break; + + ++indx; + } + + // bit length for everything after the first int + int bitLength = 32 * ((mag.Length - indx) - 1); + + // and determine bitlength of first int + int firstMag = mag[indx]; + bitLength += BitLen(firstMag); + + // Check for negative powers of two + if (sign < 0 && ((firstMag & -firstMag) == firstMag)) + { + do + { + if (++indx >= mag.Length) + { + --bitLength; + break; + } + } + while (mag[indx] == 0); + } + + return bitLength; + } + + public int BitLength + { + get + { + if (nBitLength == -1) + { + nBitLength = sign == 0 + ? 0 + : CalcBitLength(sign, 0, magnitude); + } + + return nBitLength; + } + } + + // + // BitLen(value) is the number of bits in value. + // + internal static int BitLen(int w) + { + uint v = (uint)w; + uint t = v >> 24; + if (t != 0) + return 24 + BitLengthTable[t]; + t = v >> 16; + if (t != 0) + return 16 + BitLengthTable[t]; + t = v >> 8; + if (t != 0) + return 8 + BitLengthTable[t]; + return BitLengthTable[v]; + } + + private bool QuickPow2Check() + { + return sign > 0 && nBits == 1; + } + + public int CompareTo( + object obj) + { + return CompareTo((BigInteger)obj); + } + + /** + * unsigned comparison on two arrays - note the arrays may + * start with leading zeros. + */ + private static int CompareTo( + int xIndx, + int[] x, + int yIndx, + int[] y) + { + while (xIndx != x.Length && x[xIndx] == 0) + { + xIndx++; + } + + while (yIndx != y.Length && y[yIndx] == 0) + { + yIndx++; + } + + return CompareNoLeadingZeroes(xIndx, x, yIndx, y); + } + + private static int CompareNoLeadingZeroes( + int xIndx, + int[] x, + int yIndx, + int[] y) + { + int diff = (x.Length - y.Length) - (xIndx - yIndx); + + if (diff != 0) + { + return diff < 0 ? -1 : 1; + } + + // lengths of magnitudes the same, test the magnitude values + + while (xIndx < x.Length) + { + uint v1 = (uint)x[xIndx++]; + uint v2 = (uint)y[yIndx++]; + + if (v1 != v2) + return v1 < v2 ? -1 : 1; + } + + return 0; + } + + public int CompareTo( + BigInteger value) + { + return sign < value.sign ? -1 + : sign > value.sign ? 1 + : sign == 0 ? 0 + : sign * CompareNoLeadingZeroes(0, magnitude, 0, value.magnitude); + } + + /** + * return z = x / y - done in place (z value preserved, x contains the + * remainder) + */ + private int[] Divide( + int[] x, + int[] y) + { + int xStart = 0; + while (xStart < x.Length && x[xStart] == 0) + { + ++xStart; + } + + int yStart = 0; + while (yStart < y.Length && y[yStart] == 0) + { + ++yStart; + } + + Debug.Assert(yStart < y.Length); + + int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + int[] count; + + if (xyCmp > 0) + { + int yBitLength = CalcBitLength(1, yStart, y); + int xBitLength = CalcBitLength(1, xStart, x); + int shift = xBitLength - yBitLength; + + int[] iCount; + int iCountStart = 0; + + int[] c; + int cStart = 0; + int cBitLength = yBitLength; + if (shift > 0) + { +// iCount = ShiftLeft(One.magnitude, shift); + iCount = new int[(shift >> 5) + 1]; + iCount[0] = 1 << (shift % 32); + + c = ShiftLeft(y, shift); + cBitLength += shift; + } + else + { + iCount = new int[] { 1 }; + + int len = y.Length - yStart; + c = new int[len]; + Array.Copy(y, yStart, c, 0, len); + } + + count = new int[iCount.Length]; + + for (;;) + { + if (cBitLength < xBitLength + || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0) + { + Subtract(xStart, x, cStart, c); + AddMagnitudes(count, iCount); + + while (x[xStart] == 0) + { + if (++xStart == x.Length) + return count; + } + + //xBitLength = CalcBitLength(xStart, x); + xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]); + + if (xBitLength <= yBitLength) + { + if (xBitLength < yBitLength) + return count; + + xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + + if (xyCmp <= 0) + break; + } + } + + shift = cBitLength - xBitLength; + + // NB: The case where c[cStart] is 1-bit is harmless + if (shift == 1) + { + uint firstC = (uint) c[cStart] >> 1; + uint firstX = (uint) x[xStart]; + if (firstC > firstX) + ++shift; + } + + if (shift < 2) + { + ShiftRightOneInPlace(cStart, c); + --cBitLength; + ShiftRightOneInPlace(iCountStart, iCount); + } + else + { + ShiftRightInPlace(cStart, c, shift); + cBitLength -= shift; + ShiftRightInPlace(iCountStart, iCount, shift); + } + + //cStart = c.Length - ((cBitLength + 31) / 32); + while (c[cStart] == 0) + { + ++cStart; + } + + while (iCount[iCountStart] == 0) + { + ++iCountStart; + } + } + } + else + { + count = new int[1]; + } + + if (xyCmp == 0) + { + AddMagnitudes(count, One.magnitude); + Array.Clear(x, xStart, x.Length - xStart); + } + + return count; + } + + public BigInteger Divide( + BigInteger val) + { + if (val.sign == 0) + throw new ArithmeticException("Division by zero error"); + + if (sign == 0) + return Zero; + + if (val.QuickPow2Check()) // val is power of two + { + BigInteger result = this.Abs().ShiftRight(val.Abs().BitLength - 1); + return val.sign == this.sign ? result : result.Negate(); + } + + int[] mag = (int[]) this.magnitude.Clone(); + + return new BigInteger(this.sign * val.sign, Divide(mag, val.magnitude), true); + } + + public BigInteger[] DivideAndRemainder( + BigInteger val) + { + if (val.sign == 0) + throw new ArithmeticException("Division by zero error"); + + BigInteger[] biggies = new BigInteger[2]; + + if (sign == 0) + { + biggies[0] = Zero; + biggies[1] = Zero; + } + else if (val.QuickPow2Check()) // val is power of two + { + int e = val.Abs().BitLength - 1; + BigInteger quotient = this.Abs().ShiftRight(e); + int[] remainder = this.LastNBits(e); + + biggies[0] = val.sign == this.sign ? quotient : quotient.Negate(); + biggies[1] = new BigInteger(this.sign, remainder, true); + } + else + { + int[] remainder = (int[]) this.magnitude.Clone(); + int[] quotient = Divide(remainder, val.magnitude); + + biggies[0] = new BigInteger(this.sign * val.sign, quotient, true); + biggies[1] = new BigInteger(this.sign, remainder, true); + } + + return biggies; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + BigInteger biggie = obj as BigInteger; + if (biggie == null) + return false; + + return sign == biggie.sign && IsEqualMagnitude(biggie); + } + + private bool IsEqualMagnitude(BigInteger x) + { + //int[] xMag = x.magnitude; + if (magnitude.Length != x.magnitude.Length) + return false; + for (int i = 0; i < magnitude.Length; i++) + { + if (magnitude[i] != x.magnitude[i]) + return false; + } + return true; + } + + public BigInteger Gcd( + BigInteger value) + { + if (value.sign == 0) + return Abs(); + + if (sign == 0) + return value.Abs(); + + BigInteger r; + BigInteger u = this; + BigInteger v = value; + + while (v.sign != 0) + { + r = u.Mod(v); + u = v; + v = r; + } + + return u; + } + + public override int GetHashCode() + { + int hc = magnitude.Length; + if (magnitude.Length > 0) + { + hc ^= magnitude[0]; + + if (magnitude.Length > 1) + { + hc ^= magnitude[magnitude.Length - 1]; + } + } + + return sign < 0 ? ~hc : hc; + } + + // TODO Make public? + private BigInteger Inc() + { + if (this.sign == 0) + return One; + + if (this.sign < 0) + return new BigInteger(-1, doSubBigLil(this.magnitude, One.magnitude), true); + + return AddToMagnitude(One.magnitude); + } + + public int IntValue + { + get + { + if (sign == 0) + return 0; + + int n = magnitude.Length; + + int v = magnitude[n - 1]; + + return sign < 0 ? -v : v; + } + } + + /** + * return whether or not a BigInteger is probably prime with a + * probability of 1 - (1/2)**certainty. + *

From Knuth Vol 2, pg 395.

+ */ + public bool IsProbablePrime(int certainty) + { + return IsProbablePrime(certainty, false); + } + + internal bool IsProbablePrime(int certainty, bool randomlySelected) + { + if (certainty <= 0) + return true; + + BigInteger n = Abs(); + + if (!n.TestBit(0)) + return n.Equals(Two); + + if (n.Equals(One)) + return false; + + return n.CheckProbablePrime(certainty, RandomSource, randomlySelected); + } + + private bool CheckProbablePrime(int certainty, Random random, bool randomlySelected) + { + Debug.Assert(certainty > 0); + Debug.Assert(CompareTo(Two) > 0); + Debug.Assert(TestBit(0)); + + + // Try to reduce the penalty for really small numbers + int numLists = System.Math.Min(BitLength - 1, primeLists.Length); + + for (int i = 0; i < numLists; ++i) + { + int test = Remainder(primeProducts[i]); + + int[] primeList = primeLists[i]; + for (int j = 0; j < primeList.Length; ++j) + { + int prime = primeList[j]; + int qRem = test % prime; + if (qRem == 0) + { + // We may find small numbers in the list + return BitLength < 16 && IntValue == prime; + } + } + } + + + // TODO Special case for < 10^16 (RabinMiller fixed list) +// if (BitLength < 30) +// { +// RabinMiller against 2, 3, 5, 7, 11, 13, 23 is sufficient +// } + + + // TODO Is it worth trying to create a hybrid of these two? + return RabinMillerTest(certainty, random, randomlySelected); +// return SolovayStrassenTest(certainty, random); + +// bool rbTest = RabinMillerTest(certainty, random); +// bool ssTest = SolovayStrassenTest(certainty, random); +// +// Debug.Assert(rbTest == ssTest); +// +// return rbTest; + } + + public bool RabinMillerTest(int certainty, Random random) + { + return RabinMillerTest(certainty, random, false); + } + + internal bool RabinMillerTest(int certainty, Random random, bool randomlySelected) + { + int bits = BitLength; + + Debug.Assert(certainty > 0); + Debug.Assert(bits > 2); + Debug.Assert(TestBit(0)); + + int iterations = ((certainty - 1) / 2) + 1; + if (randomlySelected) + { + int itersFor100Cert = bits >= 1024 ? 4 + : bits >= 512 ? 8 + : bits >= 256 ? 16 + : 50; + + if (certainty < 100) + { + iterations = System.Math.Min(itersFor100Cert, iterations); + } + else + { + iterations -= 50; + iterations += itersFor100Cert; + } + } + + // let n = 1 + d . 2^s + BigInteger n = this; + int s = n.GetLowestSetBitMaskFirst(-1 << 1); + Debug.Assert(s >= 1); + BigInteger r = n.ShiftRight(s); + + // NOTE: Avoid conversion to/from Montgomery form and check for R/-R as result instead + + BigInteger montRadix = One.ShiftLeft(32 * n.magnitude.Length).Remainder(n); + BigInteger minusMontRadix = n.Subtract(montRadix); + + do + { + BigInteger a; + do + { + a = new BigInteger(n.BitLength, random); + } + while (a.sign == 0 || a.CompareTo(n) >= 0 + || a.IsEqualMagnitude(montRadix) || a.IsEqualMagnitude(minusMontRadix)); + + BigInteger y = ModPowMonty(a, r, n, false); + + if (!y.Equals(montRadix)) + { + int j = 0; + while (!y.Equals(minusMontRadix)) + { + if (++j == s) + return false; + + y = ModPowMonty(y, Two, n, false); + + if (y.Equals(montRadix)) + return false; + } + } + } + while (--iterations > 0); + + return true; + } + +// private bool SolovayStrassenTest( +// int certainty, +// Random random) +// { +// Debug.Assert(certainty > 0); +// Debug.Assert(CompareTo(Two) > 0); +// Debug.Assert(TestBit(0)); +// +// BigInteger n = this; +// BigInteger nMinusOne = n.Subtract(One); +// BigInteger e = nMinusOne.ShiftRight(1); +// +// do +// { +// BigInteger a; +// do +// { +// a = new BigInteger(nBitLength, random); +// } +// // NB: Spec says 0 < x < n, but 1 is trivial +// while (a.CompareTo(One) <= 0 || a.CompareTo(n) >= 0); +// +// +// // TODO Check this is redundant given the way Jacobi() works? +//// if (!a.Gcd(n).Equals(One)) +//// return false; +// +// int x = Jacobi(a, n); +// +// if (x == 0) +// return false; +// +// BigInteger check = a.ModPow(e, n); +// +// if (x == 1 && !check.Equals(One)) +// return false; +// +// if (x == -1 && !check.Equals(nMinusOne)) +// return false; +// +// --certainty; +// } +// while (certainty > 0); +// +// return true; +// } +// +// private static int Jacobi( +// BigInteger a, +// BigInteger b) +// { +// Debug.Assert(a.sign >= 0); +// Debug.Assert(b.sign > 0); +// Debug.Assert(b.TestBit(0)); +// Debug.Assert(a.CompareTo(b) < 0); +// +// int totalS = 1; +// for (;;) +// { +// if (a.sign == 0) +// return 0; +// +// if (a.Equals(One)) +// break; +// +// int e = a.GetLowestSetBit(); +// +// int bLsw = b.magnitude[b.magnitude.Length - 1]; +// if ((e & 1) != 0 && ((bLsw & 7) == 3 || (bLsw & 7) == 5)) +// totalS = -totalS; +// +// // TODO Confirm this is faster than later a1.Equals(One) test +// if (a.BitLength == e + 1) +// break; +// BigInteger a1 = a.ShiftRight(e); +//// if (a1.Equals(One)) +//// break; +// +// int a1Lsw = a1.magnitude[a1.magnitude.Length - 1]; +// if ((bLsw & 3) == 3 && (a1Lsw & 3) == 3) +// totalS = -totalS; +// +//// a = b.Mod(a1); +// a = b.Remainder(a1); +// b = a1; +// } +// return totalS; +// } + + public long LongValue + { + get + { + if (sign == 0) + return 0; + + int n = magnitude.Length; + + long v = magnitude[n - 1] & IMASK; + if (n > 1) + { + v |= (magnitude[n - 2] & IMASK) << 32; + } + + return sign < 0 ? -v : v; + } + } + + public BigInteger Max( + BigInteger value) + { + return CompareTo(value) > 0 ? this : value; + } + + public BigInteger Min( + BigInteger value) + { + return CompareTo(value) < 0 ? this : value; + } + + public BigInteger Mod( + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + BigInteger biggie = Remainder(m); + + return (biggie.sign >= 0 ? biggie : biggie.Add(m)); + } + + public BigInteger ModInverse( + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + // TODO Too slow at the moment +// // "Fast Key Exchange with Elliptic Curve Systems" R.Schoeppel +// if (m.TestBit(0)) +// { +// //The Almost Inverse Algorithm +// int k = 0; +// BigInteger B = One, C = Zero, F = this, G = m, tmp; +// +// for (;;) +// { +// // While F is even, do F=F/u, C=C*u, k=k+1. +// int zeroes = F.GetLowestSetBit(); +// if (zeroes > 0) +// { +// F = F.ShiftRight(zeroes); +// C = C.ShiftLeft(zeroes); +// k += zeroes; +// } +// +// // If F = 1, then return B,k. +// if (F.Equals(One)) +// { +// BigInteger half = m.Add(One).ShiftRight(1); +// BigInteger halfK = half.ModPow(BigInteger.ValueOf(k), m); +// return B.Multiply(halfK).Mod(m); +// } +// +// if (F.CompareTo(G) < 0) +// { +// tmp = G; G = F; F = tmp; +// tmp = B; B = C; C = tmp; +// } +// +// F = F.Add(G); +// B = B.Add(C); +// } +// } + + if (m.QuickPow2Check()) + { + return ModInversePow2(m); + } + + BigInteger d = this.Remainder(m); + BigInteger x; + BigInteger gcd = ExtEuclid(d, m, out x); + + if (!gcd.Equals(One)) + throw new ArithmeticException("Numbers not relatively prime."); + + if (x.sign < 0) + { + x = x.Add(m); + } + + return x; + } + + private BigInteger ModInversePow2(BigInteger m) + { + Debug.Assert(m.SignValue > 0); + Debug.Assert(m.BitCount == 1); + + if (!TestBit(0)) + { + throw new ArithmeticException("Numbers not relatively prime."); + } + + int pow = m.BitLength - 1; + + long inv64 = ModInverse64(LongValue); + if (pow < 64) + { + inv64 &= ((1L << pow) - 1); + } + + BigInteger x = BigInteger.ValueOf(inv64); + + if (pow > 64) + { + BigInteger d = this.Remainder(m); + int bitsCorrect = 64; + + do + { + BigInteger t = x.Multiply(d).Remainder(m); + x = x.Multiply(Two.Subtract(t)).Remainder(m); + bitsCorrect <<= 1; + } + while (bitsCorrect < pow); + } + + if (x.sign < 0) + { + x = x.Add(m); + } + + return x; + } + + private static int ModInverse32(int d) + { + // Newton's method with initial estimate "correct to 4 bits" + Debug.Assert((d & 1) != 0); + int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4 + Debug.Assert(((d * x) & 15) == 1); + x *= 2 - d * x; // d.x == 1 mod 2**8 + x *= 2 - d * x; // d.x == 1 mod 2**16 + x *= 2 - d * x; // d.x == 1 mod 2**32 + Debug.Assert(d * x == 1); + return x; + } + + private static long ModInverse64(long d) + { + // Newton's method with initial estimate "correct to 4 bits" + Debug.Assert((d & 1L) != 0); + long x = d + (((d + 1L) & 4L) << 1); // d.x == 1 mod 2**4 + Debug.Assert(((d * x) & 15L) == 1L); + x *= 2 - d * x; // d.x == 1 mod 2**8 + x *= 2 - d * x; // d.x == 1 mod 2**16 + x *= 2 - d * x; // d.x == 1 mod 2**32 + x *= 2 - d * x; // d.x == 1 mod 2**64 + Debug.Assert(d * x == 1L); + return x; + } + + /** + * Calculate the numbers u1, u2, and u3 such that: + * + * u1 * a + u2 * b = u3 + * + * where u3 is the greatest common divider of a and b. + * a and b using the extended Euclid algorithm (refer p. 323 + * of The Art of Computer Programming vol 2, 2nd ed). + * This also seems to have the side effect of calculating + * some form of multiplicative inverse. + * + * @param a First number to calculate gcd for + * @param b Second number to calculate gcd for + * @param u1Out the return object for the u1 value + * @return The greatest common divisor of a and b + */ + private static BigInteger ExtEuclid(BigInteger a, BigInteger b, out BigInteger u1Out) + { + BigInteger u1 = One, v1 = Zero; + BigInteger u3 = a, v3 = b; + + if (v3.sign > 0) + { + for (;;) + { + BigInteger[] q = u3.DivideAndRemainder(v3); + u3 = v3; + v3 = q[1]; + + BigInteger oldU1 = u1; + u1 = v1; + + if (v3.sign <= 0) + break; + + v1 = oldU1.Subtract(v1.Multiply(q[0])); + } + } + + u1Out = u1; + + return u3; + } + + private static void ZeroOut( + int[] x) + { + Array.Clear(x, 0, x.Length); + } + + public BigInteger ModPow(BigInteger e, BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + if (m.Equals(One)) + return Zero; + + if (e.sign == 0) + return One; + + if (sign == 0) + return Zero; + + bool negExp = e.sign < 0; + if (negExp) + e = e.Negate(); + + BigInteger result = this.Mod(m); + if (!e.Equals(One)) + { + if ((m.magnitude[m.magnitude.Length - 1] & 1) == 0) + { + result = ModPowBarrett(result, e, m); + } + else + { + result = ModPowMonty(result, e, m, true); + } + } + + if (negExp) + result = result.ModInverse(m); + + return result; + } + + private static BigInteger ModPowBarrett(BigInteger b, BigInteger e, BigInteger m) + { + int k = m.magnitude.Length; + BigInteger mr = One.ShiftLeft((k + 1) << 5); + BigInteger yu = One.ShiftLeft(k << 6).Divide(m); + + // Sliding window from MSW to LSW + int extraBits = 0, expLength = e.BitLength; + while (expLength > ExpWindowThresholds[extraBits]) + { + ++extraBits; + } + + int numPowers = 1 << extraBits; + BigInteger[] oddPowers = new BigInteger[numPowers]; + oddPowers[0] = b; + + BigInteger b2 = ReduceBarrett(b.Square(), m, mr, yu); + + for (int i = 1; i < numPowers; ++i) + { + oddPowers[i] = ReduceBarrett(oddPowers[i - 1].Multiply(b2), m, mr, yu); + } + + int[] windowList = GetWindowList(e.magnitude, extraBits); + Debug.Assert(windowList.Length > 0); + + int window = windowList[0]; + int mult = window & 0xFF, lastZeroes = window >> 8; + + BigInteger y; + if (mult == 1) + { + y = b2; + --lastZeroes; + } + else + { + y = oddPowers[mult >> 1]; + } + + int windowPos = 1; + while ((window = windowList[windowPos++]) != -1) + { + mult = window & 0xFF; + + int bits = lastZeroes + BitLengthTable[mult]; + for (int j = 0; j < bits; ++j) + { + y = ReduceBarrett(y.Square(), m, mr, yu); + } + + y = ReduceBarrett(y.Multiply(oddPowers[mult >> 1]), m, mr, yu); + + lastZeroes = window >> 8; + } + + for (int i = 0; i < lastZeroes; ++i) + { + y = ReduceBarrett(y.Square(), m, mr, yu); + } + + return y; + } + + private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu) + { + int xLen = x.BitLength, mLen = m.BitLength; + if (xLen < mLen) + return x; + + if (xLen - mLen > 1) + { + int k = m.magnitude.Length; + + BigInteger q1 = x.DivideWords(k - 1); + BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here + BigInteger q3 = q2.DivideWords(k + 1); + + BigInteger r1 = x.RemainderWords(k + 1); + BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here + BigInteger r3 = r2.RemainderWords(k + 1); + + x = r1.Subtract(r3); + if (x.sign < 0) + { + x = x.Add(mr); + } + } + + while (x.CompareTo(m) >= 0) + { + x = x.Subtract(m); + } + + return x; + } + + private static BigInteger ModPowMonty(BigInteger b, BigInteger e, BigInteger m, bool convert) + { + int n = m.magnitude.Length; + int powR = 32 * n; + bool smallMontyModulus = m.BitLength + 2 <= powR; + uint mDash = (uint)m.GetMQuote(); + + // tmp = this * R mod m + if (convert) + { + b = b.ShiftLeft(powR).Remainder(m); + } + + int[] yAccum = new int[n + 1]; + + int[] zVal = b.magnitude; + Debug.Assert(zVal.Length <= n); + if (zVal.Length < n) + { + int[] tmp = new int[n]; + zVal.CopyTo(tmp, n - zVal.Length); + zVal = tmp; + } + + // Sliding window from MSW to LSW + + int extraBits = 0; + + // Filter the common case of small RSA exponents with few bits set + if (e.magnitude.Length > 1 || e.BitCount > 2) + { + int expLength = e.BitLength; + while (expLength > ExpWindowThresholds[extraBits]) + { + ++extraBits; + } + } + + int numPowers = 1 << extraBits; + int[][] oddPowers = new int[numPowers][]; + oddPowers[0] = zVal; + + int[] zSquared = Arrays.Clone(zVal); + SquareMonty(yAccum, zSquared, m.magnitude, mDash, smallMontyModulus); + + for (int i = 1; i < numPowers; ++i) + { + oddPowers[i] = Arrays.Clone(oddPowers[i - 1]); + MultiplyMonty(yAccum, oddPowers[i], zSquared, m.magnitude, mDash, smallMontyModulus); + } + + int[] windowList = GetWindowList(e.magnitude, extraBits); + Debug.Assert(windowList.Length > 1); + + int window = windowList[0]; + int mult = window & 0xFF, lastZeroes = window >> 8; + + int[] yVal; + if (mult == 1) + { + yVal = zSquared; + --lastZeroes; + } + else + { + yVal = Arrays.Clone(oddPowers[mult >> 1]); + } + + int windowPos = 1; + while ((window = windowList[windowPos++]) != -1) + { + mult = window & 0xFF; + + int bits = lastZeroes + BitLengthTable[mult]; + for (int j = 0; j < bits; ++j) + { + SquareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); + } + + MultiplyMonty(yAccum, yVal, oddPowers[mult >> 1], m.magnitude, mDash, smallMontyModulus); + + lastZeroes = window >> 8; + } + + for (int i = 0; i < lastZeroes; ++i) + { + SquareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); + } + + if (convert) + { + // Return y * R^(-1) mod m + MontgomeryReduce(yVal, m.magnitude, mDash); + } + else if (smallMontyModulus && CompareTo(0, yVal, 0, m.magnitude) >= 0) + { + Subtract(0, yVal, 0, m.magnitude); + } + + return new BigInteger(1, yVal, true); + } + + private static int[] GetWindowList(int[] mag, int extraBits) + { + int v = mag[0]; + Debug.Assert(v != 0); + + int leadingBits = BitLen(v); + + int resultSize = (((mag.Length - 1) << 5) + leadingBits) / (1 + extraBits) + 2; + int[] result = new int[resultSize]; + int resultPos = 0; + + int bitPos = 33 - leadingBits; + v <<= bitPos; + + int mult = 1, multLimit = 1 << extraBits; + int zeroes = 0; + + int i = 0; + for (; ; ) + { + for (; bitPos < 32; ++bitPos) + { + if (mult < multLimit) + { + mult = (mult << 1) | (int)((uint)v >> 31); + } + else if (v < 0) + { + result[resultPos++] = CreateWindowEntry(mult, zeroes); + mult = 1; + zeroes = 0; + } + else + { + ++zeroes; + } + + v <<= 1; + } + + if (++i == mag.Length) + { + result[resultPos++] = CreateWindowEntry(mult, zeroes); + break; + } + + v = mag[i]; + bitPos = 0; + } + + result[resultPos] = -1; + return result; + } + + private static int CreateWindowEntry(int mult, int zeroes) + { + while ((mult & 1) == 0) + { + mult >>= 1; + ++zeroes; + } + + return mult | (zeroes << 8); + } + + /** + * return w with w = x * x - w is assumed to have enough space. + */ + private static int[] Square( + int[] w, + int[] x) + { + // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit +// if (w.Length != 2 * x.Length) +// throw new ArgumentException("no I don't think so..."); + + ulong c; + + int wBase = w.Length - 1; + + for (int i = x.Length - 1; i > 0; --i) + { + ulong v = (uint)x[i]; + + c = v * v + (uint)w[wBase]; + w[wBase] = (int)c; + c >>= 32; + + for (int j = i - 1; j >= 0; --j) + { + ulong prod = v * (uint)x[j]; + + c += ((uint)w[--wBase] & UIMASK) + ((uint)prod << 1); + w[wBase] = (int)c; + c = (c >> 32) + (prod >> 31); + } + + c += (uint)w[--wBase]; + w[wBase] = (int)c; + + if (--wBase >= 0) + { + w[wBase] = (int)(c >> 32); + } + else + { + Debug.Assert((c >> 32) == 0); + } + + wBase += i; + } + + c = (uint)x[0]; + + c = c * c + (uint)w[wBase]; + w[wBase] = (int)c; + + if (--wBase >= 0) + { + w[wBase] += (int)(c >> 32); + } + else + { + Debug.Assert((c >> 32) == 0); + } + + return w; + } + + /** + * return x with x = y * z - x is assumed to have enough space. + */ + private static int[] Multiply(int[] x, int[] y, int[] z) + { + int i = z.Length; + + if (i < 1) + return x; + + int xBase = x.Length - y.Length; + + do + { + long a = z[--i] & IMASK; + long val = 0; + + if (a != 0) + { + for (int j = y.Length - 1; j >= 0; j--) + { + val += a * (y[j] & IMASK) + (x[xBase + j] & IMASK); + + x[xBase + j] = (int)val; + + val = (long)((ulong)val >> 32); + } + } + + --xBase; + + if (xBase >= 0) + { + x[xBase] = (int)val; + } + else + { + Debug.Assert(val == 0); + } + } + while (i > 0); + + return x; + } + + /** + * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size) + */ + private int GetMQuote() + { + if (mQuote != 0) + { + return mQuote; // already calculated + } + + Debug.Assert(this.sign > 0); + + int d = -magnitude[magnitude.Length - 1]; + + Debug.Assert((d & 1) != 0); + + return mQuote = ModInverse32(d); + } + + private static void MontgomeryReduce(int[] x, int[] m, uint mDash) // mDash = -m^(-1) mod b + { + // NOTE: Not a general purpose reduction (which would allow x up to twice the bitlength of m) + Debug.Assert(x.Length == m.Length); + + int n = m.Length; + + for (int i = n - 1; i >= 0; --i) + { + uint x0 = (uint)x[n - 1]; + ulong t = x0 * mDash; + + ulong carry = t * (uint)m[n - 1] + x0; + Debug.Assert((uint)carry == 0); + carry >>= 32; + + for (int j = n - 2; j >= 0; --j) + { + carry += t * (uint)m[j] + (uint)x[j]; + x[j + 1] = (int)carry; + carry >>= 32; + } + + x[0] = (int)carry; + Debug.Assert(carry >> 32 == 0); + } + + if (CompareTo(0, x, 0, m) >= 0) + { + Subtract(0, x, 0, m); + } + } + + /** + * Montgomery multiplication: a = x * y * R^(-1) mod m + *
+ * Based algorithm 14.36 of Handbook of Applied Cryptography. + *
+ *
  • m, x, y should have length n
  • + *
  • a should have length (n + 1)
  • + *
  • b = 2^32, R = b^n
  • + *
    + * The result is put in x + *
    + * NOTE: the indices of x, y, m, a different in HAC and in Java + */ + private static void MultiplyMonty(int[] a, int[] x, int[] y, int[] m, uint mDash, bool smallMontyModulus) + // mDash = -m^(-1) mod b + { + int n = m.Length; + + if (n == 1) + { + x[0] = (int)MultiplyMontyNIsOne((uint)x[0], (uint)y[0], (uint)m[0], mDash); + return; + } + + uint y0 = (uint)y[n - 1]; + int aMax; + + { + ulong xi = (uint)x[n - 1]; + + ulong carry = xi * y0; + ulong t = (uint)carry * mDash; + + ulong prod2 = t * (uint)m[n - 1]; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod2 >> 32); + + for (int j = n - 2; j >= 0; --j) + { + ulong prod1 = xi * (uint)y[j]; + prod2 = t * (uint)m[j]; + + carry += (prod1 & UIMASK) + (uint)prod2; + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + } + + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + for (int i = n - 2; i >= 0; --i) + { + uint a0 = (uint)a[n]; + ulong xi = (uint)x[i]; + + ulong prod1 = xi * y0; + ulong carry = (prod1 & UIMASK) + a0; + ulong t = (uint)carry * mDash; + + ulong prod2 = t * (uint)m[n - 1]; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + + for (int j = n - 2; j >= 0; --j) + { + prod1 = xi * (uint)y[j]; + prod2 = t * (uint)m[j]; + + carry += (prod1 & UIMASK) + (uint)prod2 + (uint)a[j + 1]; + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + } + + carry += (uint)aMax; + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + a[0] = aMax; + + if (!smallMontyModulus && CompareTo(0, a, 0, m) >= 0) + { + Subtract(0, a, 0, m); + } + + Array.Copy(a, 1, x, 0, n); + } + + private static void SquareMonty(int[] a, int[] x, int[] m, uint mDash, bool smallMontyModulus) + // mDash = -m^(-1) mod b + { + int n = m.Length; + + if (n == 1) + { + uint xVal = (uint)x[0]; + x[0] = (int)MultiplyMontyNIsOne(xVal, xVal, (uint)m[0], mDash); + return; + } + + ulong x0 = (uint)x[n - 1]; + int aMax; + + { + ulong carry = x0 * x0; + ulong t = (uint)carry * mDash; + + ulong prod2 = t * (uint)m[n - 1]; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod2 >> 32); + + for (int j = n - 2; j >= 0; --j) + { + ulong prod1 = x0 * (uint)x[j]; + prod2 = t * (uint)m[j]; + + carry += (prod2 & UIMASK) + ((uint)prod1 << 1); + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 31) + (prod2 >> 32); + } + + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + for (int i = n - 2; i >= 0; --i) + { + uint a0 = (uint)a[n]; + ulong t = a0 * mDash; + + ulong carry = t * (uint)m[n - 1] + a0; + Debug.Assert((uint)carry == 0); + carry >>= 32; + + for (int j = n - 2; j > i; --j) + { + carry += t * (uint)m[j] + (uint)a[j + 1]; + a[j + 2] = (int)carry; + carry >>= 32; + } + + ulong xi = (uint)x[i]; + + { + ulong prod1 = xi * xi; + ulong prod2 = t * (uint)m[i]; + + carry += (prod1 & UIMASK) + (uint)prod2 + (uint)a[i + 1]; + a[i + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + } + + for (int j = i - 1; j >= 0; --j) + { + ulong prod1 = xi * (uint)x[j]; + ulong prod2 = t * (uint)m[j]; + + carry += (prod2 & UIMASK) + ((uint)prod1 << 1) + (uint)a[j + 1]; + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 31) + (prod2 >> 32); + } + + carry += (uint)aMax; + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + a[0] = aMax; + + if (!smallMontyModulus && CompareTo(0, a, 0, m) >= 0) + { + Subtract(0, a, 0, m); + } + + Array.Copy(a, 1, x, 0, n); + } + + private static uint MultiplyMontyNIsOne(uint x, uint y, uint m, uint mDash) + { + ulong carry = (ulong)x * y; + uint t = (uint)carry * mDash; + ulong um = m; + ulong prod2 = um * t; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod2 >> 32); + if (carry > um) + { + carry -= um; + } + Debug.Assert(carry < um); + return (uint)carry; + } + + public BigInteger Multiply( + BigInteger val) + { + if (val == this) + return Square(); + + if ((sign & val.sign) == 0) + return Zero; + + if (val.QuickPow2Check()) // val is power of two + { + BigInteger result = this.ShiftLeft(val.Abs().BitLength - 1); + return val.sign > 0 ? result : result.Negate(); + } + + if (this.QuickPow2Check()) // this is power of two + { + BigInteger result = val.ShiftLeft(this.Abs().BitLength - 1); + return this.sign > 0 ? result : result.Negate(); + } + + int resLength = magnitude.Length + val.magnitude.Length; + int[] res = new int[resLength]; + + Multiply(res, this.magnitude, val.magnitude); + + int resSign = sign ^ val.sign ^ 1; + return new BigInteger(resSign, res, true); + } + + public BigInteger Square() + { + if (sign == 0) + return Zero; + if (this.QuickPow2Check()) + return ShiftLeft(Abs().BitLength - 1); + int resLength = magnitude.Length << 1; + if ((uint)magnitude[0] >> 16 == 0) + --resLength; + int[] res = new int[resLength]; + Square(res, magnitude); + return new BigInteger(1, res, false); + } + + public BigInteger Negate() + { + if (sign == 0) + return this; + + return new BigInteger(-sign, magnitude, false); + } + + public BigInteger NextProbablePrime() + { + if (sign < 0) + throw new ArithmeticException("Cannot be called on value < 0"); + + if (CompareTo(Two) < 0) + return Two; + + BigInteger n = Inc().SetBit(0); + + while (!n.CheckProbablePrime(100, RandomSource, false)) + { + n = n.Add(Two); + } + + return n; + } + + public BigInteger Not() + { + return Inc().Negate(); + } + + public BigInteger Pow(int exp) + { + if (exp <= 0) + { + if (exp < 0) + throw new ArithmeticException("Negative exponent"); + + return One; + } + + if (sign == 0) + { + return this; + } + + if (QuickPow2Check()) + { + long powOf2 = (long)exp * (BitLength - 1); + if (powOf2 > Int32.MaxValue) + { + throw new ArithmeticException("Result too large"); + } + return One.ShiftLeft((int)powOf2); + } + + BigInteger y = One; + BigInteger z = this; + + for (;;) + { + if ((exp & 0x1) == 1) + { + y = y.Multiply(z); + } + exp >>= 1; + if (exp == 0) break; + z = z.Multiply(z); + } + + return y; + } + + public static BigInteger ProbablePrime( + int bitLength, + Random random) + { + return new BigInteger(bitLength, 100, random); + } + + private int Remainder( + int m) + { + Debug.Assert(m > 0); + + long acc = 0; + for (int pos = 0; pos < magnitude.Length; ++pos) + { + long posVal = (uint) magnitude[pos]; + acc = (acc << 32 | posVal) % m; + } + + return (int) acc; + } + + /** + * return x = x % y - done in place (y value preserved) + */ + private static int[] Remainder( + int[] x, + int[] y) + { + int xStart = 0; + while (xStart < x.Length && x[xStart] == 0) + { + ++xStart; + } + + int yStart = 0; + while (yStart < y.Length && y[yStart] == 0) + { + ++yStart; + } + + Debug.Assert(yStart < y.Length); + + int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + + if (xyCmp > 0) + { + int yBitLength = CalcBitLength(1, yStart, y); + int xBitLength = CalcBitLength(1, xStart, x); + int shift = xBitLength - yBitLength; + + int[] c; + int cStart = 0; + int cBitLength = yBitLength; + if (shift > 0) + { + c = ShiftLeft(y, shift); + cBitLength += shift; + Debug.Assert(c[0] != 0); + } + else + { + int len = y.Length - yStart; + c = new int[len]; + Array.Copy(y, yStart, c, 0, len); + } + + for (;;) + { + if (cBitLength < xBitLength + || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0) + { + Subtract(xStart, x, cStart, c); + + while (x[xStart] == 0) + { + if (++xStart == x.Length) + return x; + } + + //xBitLength = CalcBitLength(xStart, x); + xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]); + + if (xBitLength <= yBitLength) + { + if (xBitLength < yBitLength) + return x; + + xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + + if (xyCmp <= 0) + break; + } + } + + shift = cBitLength - xBitLength; + + // NB: The case where c[cStart] is 1-bit is harmless + if (shift == 1) + { + uint firstC = (uint) c[cStart] >> 1; + uint firstX = (uint) x[xStart]; + if (firstC > firstX) + ++shift; + } + + if (shift < 2) + { + ShiftRightOneInPlace(cStart, c); + --cBitLength; + } + else + { + ShiftRightInPlace(cStart, c, shift); + cBitLength -= shift; + } + + //cStart = c.Length - ((cBitLength + 31) / 32); + while (c[cStart] == 0) + { + ++cStart; + } + } + } + + if (xyCmp == 0) + { + Array.Clear(x, xStart, x.Length - xStart); + } + + return x; + } + + public BigInteger Remainder( + BigInteger n) + { + if (n.sign == 0) + throw new ArithmeticException("Division by zero error"); + + if (this.sign == 0) + return Zero; + + // For small values, use fast remainder method + if (n.magnitude.Length == 1) + { + int val = n.magnitude[0]; + + if (val > 0) + { + if (val == 1) + return Zero; + + // TODO Make this func work on uint, and handle val == 1? + int rem = Remainder(val); + + return rem == 0 + ? Zero + : new BigInteger(sign, new int[]{ rem }, false); + } + } + + if (CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude) < 0) + return this; + + int[] result; + if (n.QuickPow2Check()) // n is power of two + { + // TODO Move before small values branch above? + result = LastNBits(n.Abs().BitLength - 1); + } + else + { + result = (int[]) this.magnitude.Clone(); + result = Remainder(result, n.magnitude); + } + + return new BigInteger(sign, result, true); + } + + private int[] LastNBits( + int n) + { + if (n < 1) + return ZeroMagnitude; + + int numWords = (n + BitsPerInt - 1) / BitsPerInt; + numWords = System.Math.Min(numWords, this.magnitude.Length); + int[] result = new int[numWords]; + + Array.Copy(this.magnitude, this.magnitude.Length - numWords, result, 0, numWords); + + int excessBits = (numWords << 5) - n; + if (excessBits > 0) + { + result[0] &= (int)(UInt32.MaxValue >> excessBits); + } + + return result; + } + + private BigInteger DivideWords(int w) + { + Debug.Assert(w >= 0); + int n = magnitude.Length; + if (w >= n) + return Zero; + int[] mag = new int[n - w]; + Array.Copy(magnitude, 0, mag, 0, n - w); + return new BigInteger(sign, mag, false); + } + + private BigInteger RemainderWords(int w) + { + Debug.Assert(w >= 0); + int n = magnitude.Length; + if (w >= n) + return this; + int[] mag = new int[w]; + Array.Copy(magnitude, n - w, mag, 0, w); + return new BigInteger(sign, mag, false); + } + + /** + * do a left shift - this returns a new array. + */ + private static int[] ShiftLeft( + int[] mag, + int n) + { + int nInts = (int)((uint)n >> 5); + int nBits = n & 0x1f; + int magLen = mag.Length; + int[] newMag; + + if (nBits == 0) + { + newMag = new int[magLen + nInts]; + mag.CopyTo(newMag, 0); + } + else + { + int i = 0; + int nBits2 = 32 - nBits; + int highBits = (int)((uint)mag[0] >> nBits2); + + if (highBits != 0) + { + newMag = new int[magLen + nInts + 1]; + newMag[i++] = highBits; + } + else + { + newMag = new int[magLen + nInts]; + } + + int m = mag[0]; + for (int j = 0; j < magLen - 1; j++) + { + int next = mag[j + 1]; + + newMag[i++] = (m << nBits) | (int)((uint)next >> nBits2); + m = next; + } + + newMag[i] = mag[magLen - 1] << nBits; + } + + return newMag; + } + + private static int ShiftLeftOneInPlace(int[] x, int carry) + { + Debug.Assert(carry == 0 || carry == 1); + int pos = x.Length; + while (--pos >= 0) + { + uint val = (uint)x[pos]; + x[pos] = (int)(val << 1) | carry; + carry = (int)(val >> 31); + } + return carry; + } + + public BigInteger ShiftLeft( + int n) + { + if (sign == 0 || magnitude.Length == 0) + return Zero; + + if (n == 0) + return this; + + if (n < 0) + return ShiftRight(-n); + + BigInteger result = new BigInteger(sign, ShiftLeft(magnitude, n), true); + + if (this.nBits != -1) + { + result.nBits = sign > 0 + ? this.nBits + : this.nBits + n; + } + + if (this.nBitLength != -1) + { + result.nBitLength = this.nBitLength + n; + } + + return result; + } + + /** + * do a right shift - this does it in place. + */ + private static void ShiftRightInPlace( + int start, + int[] mag, + int n) + { + int nInts = (int)((uint)n >> 5) + start; + int nBits = n & 0x1f; + int magEnd = mag.Length - 1; + + if (nInts != start) + { + int delta = (nInts - start); + + for (int i = magEnd; i >= nInts; i--) + { + mag[i] = mag[i - delta]; + } + for (int i = nInts - 1; i >= start; i--) + { + mag[i] = 0; + } + } + + if (nBits != 0) + { + int nBits2 = 32 - nBits; + int m = mag[magEnd]; + + for (int i = magEnd; i > nInts; --i) + { + int next = mag[i - 1]; + + mag[i] = (int)((uint)m >> nBits) | (next << nBits2); + m = next; + } + + mag[nInts] = (int)((uint)mag[nInts] >> nBits); + } + } + + /** + * do a right shift by one - this does it in place. + */ + private static void ShiftRightOneInPlace( + int start, + int[] mag) + { + int i = mag.Length; + int m = mag[i - 1]; + + while (--i > start) + { + int next = mag[i - 1]; + mag[i] = ((int)((uint)m >> 1)) | (next << 31); + m = next; + } + + mag[start] = (int)((uint)mag[start] >> 1); + } + + public BigInteger ShiftRight( + int n) + { + if (n == 0) + return this; + + if (n < 0) + return ShiftLeft(-n); + + if (n >= BitLength) + return (this.sign < 0 ? One.Negate() : Zero); + +// int[] res = (int[]) this.magnitude.Clone(); +// +// ShiftRightInPlace(0, res, n); +// +// return new BigInteger(this.sign, res, true); + + int resultLength = (BitLength - n + 31) >> 5; + int[] res = new int[resultLength]; + + int numInts = n >> 5; + int numBits = n & 31; + + if (numBits == 0) + { + Array.Copy(this.magnitude, 0, res, 0, res.Length); + } + else + { + int numBits2 = 32 - numBits; + + int magPos = this.magnitude.Length - 1 - numInts; + for (int i = resultLength - 1; i >= 0; --i) + { + res[i] = (int)((uint) this.magnitude[magPos--] >> numBits); + + if (magPos >= 0) + { + res[i] |= this.magnitude[magPos] << numBits2; + } + } + } + + Debug.Assert(res[0] != 0); + + return new BigInteger(this.sign, res, false); + } + + public int SignValue + { + get { return sign; } + } + + /** + * returns x = x - y - we assume x is >= y + */ + private static int[] Subtract( + int xStart, + int[] x, + int yStart, + int[] y) + { + Debug.Assert(yStart < y.Length); + Debug.Assert(x.Length - xStart >= y.Length - yStart); + + int iT = x.Length; + int iV = y.Length; + long m; + int borrow = 0; + + do + { + m = (x[--iT] & IMASK) - (y[--iV] & IMASK) + borrow; + x[iT] = (int) m; + +// borrow = (m < 0) ? -1 : 0; + borrow = (int)(m >> 63); + } + while (iV > yStart); + + if (borrow != 0) + { + while (--x[--iT] == -1) + { + } + } + + return x; + } + + public BigInteger Subtract( + BigInteger n) + { + if (n.sign == 0) + return this; + + if (this.sign == 0) + return n.Negate(); + + if (this.sign != n.sign) + return Add(n.Negate()); + + int compare = CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude); + if (compare == 0) + return Zero; + + BigInteger bigun, lilun; + if (compare < 0) + { + bigun = n; + lilun = this; + } + else + { + bigun = this; + lilun = n; + } + + return new BigInteger(this.sign * compare, doSubBigLil(bigun.magnitude, lilun.magnitude), true); + } + + private static int[] doSubBigLil( + int[] bigMag, + int[] lilMag) + { + int[] res = (int[]) bigMag.Clone(); + + return Subtract(0, res, 0, lilMag); + } + + public byte[] ToByteArray() + { + return ToByteArray(false); + } + + public byte[] ToByteArrayUnsigned() + { + return ToByteArray(true); + } + + private byte[] ToByteArray( + bool unsigned) + { + if (sign == 0) + return unsigned ? ZeroEncoding : new byte[1]; + + int nBits = (unsigned && sign > 0) + ? BitLength + : BitLength + 1; + + int nBytes = GetByteLength(nBits); + byte[] bytes = new byte[nBytes]; + + int magIndex = magnitude.Length; + int bytesIndex = bytes.Length; + + if (sign > 0) + { + while (magIndex > 1) + { + uint mag = (uint) magnitude[--magIndex]; + bytes[--bytesIndex] = (byte) mag; + bytes[--bytesIndex] = (byte)(mag >> 8); + bytes[--bytesIndex] = (byte)(mag >> 16); + bytes[--bytesIndex] = (byte)(mag >> 24); + } + + uint lastMag = (uint) magnitude[0]; + while (lastMag > byte.MaxValue) + { + bytes[--bytesIndex] = (byte) lastMag; + lastMag >>= 8; + } + + bytes[--bytesIndex] = (byte) lastMag; + } + else // sign < 0 + { + bool carry = true; + + while (magIndex > 1) + { + uint mag = ~((uint) magnitude[--magIndex]); + + if (carry) + { + carry = (++mag == uint.MinValue); + } + + bytes[--bytesIndex] = (byte) mag; + bytes[--bytesIndex] = (byte)(mag >> 8); + bytes[--bytesIndex] = (byte)(mag >> 16); + bytes[--bytesIndex] = (byte)(mag >> 24); + } + + uint lastMag = (uint) magnitude[0]; + + if (carry) + { + // Never wraps because magnitude[0] != 0 + --lastMag; + } + + while (lastMag > byte.MaxValue) + { + bytes[--bytesIndex] = (byte) ~lastMag; + lastMag >>= 8; + } + + bytes[--bytesIndex] = (byte) ~lastMag; + + if (bytesIndex > 0) + { + bytes[--bytesIndex] = byte.MaxValue; + } + } + + return bytes; + } + + public override string ToString() + { + return ToString(10); + } + + public string ToString(int radix) + { + // TODO Make this method work for other radices (ideally 2 <= radix <= 36 as in Java) + + switch (radix) + { + case 2: + case 8: + case 10: + case 16: + break; + default: + throw new FormatException("Only bases 2, 8, 10, 16 are allowed"); + } + + // NB: Can only happen to internally managed instances + if (magnitude == null) + return "null"; + + if (sign == 0) + return "0"; + + + // NOTE: This *should* be unnecessary, since the magnitude *should* never have leading zero digits + int firstNonZero = 0; + while (firstNonZero < magnitude.Length) + { + if (magnitude[firstNonZero] != 0) + { + break; + } + ++firstNonZero; + } + + if (firstNonZero == magnitude.Length) + { + return "0"; + } + + + StringBuilder sb = new StringBuilder(); + if (sign == -1) + { + sb.Append('-'); + } + + switch (radix) + { + case 2: + { + int pos = firstNonZero; + sb.Append(Convert.ToString(magnitude[pos], 2)); + while (++pos < magnitude.Length) + { + AppendZeroExtendedString(sb, Convert.ToString(magnitude[pos], 2), 32); + } + break; + } + case 8: + { + int mask = (1 << 30) - 1; + BigInteger u = this.Abs(); + int bits = u.BitLength; + IList S = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + while (bits > 30) + { + S.Add(Convert.ToString(u.IntValue & mask, 8)); + u = u.ShiftRight(30); + bits -= 30; + } + sb.Append(Convert.ToString(u.IntValue, 8)); + for (int i = S.Count - 1; i >= 0; --i) + { + AppendZeroExtendedString(sb, (string)S[i], 10); + } + break; + } + case 16: + { + int pos = firstNonZero; + sb.Append(Convert.ToString(magnitude[pos], 16)); + while (++pos < magnitude.Length) + { + AppendZeroExtendedString(sb, Convert.ToString(magnitude[pos], 16), 8); + } + break; + } + // TODO This could work for other radices if there is an alternative to Convert.ToString method + //default: + case 10: + { + BigInteger q = this.Abs(); + if (q.BitLength < 64) + { + sb.Append(Convert.ToString(q.LongValue, radix)); + break; + } + + // Based on algorithm 1a from chapter 4.4 in Seminumerical Algorithms (Knuth) + + // Work out the largest power of 'rdx' that is a positive 64-bit integer + // TODO possibly cache power/exponent against radix? + long limit = Int64.MaxValue / radix; + long power = radix; + int exponent = 1; + while (power <= limit) + { + power *= radix; + ++exponent; + } + + BigInteger bigPower = BigInteger.ValueOf(power); + + IList S = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + while (q.CompareTo(bigPower) >= 0) + { + BigInteger[] qr = q.DivideAndRemainder(bigPower); + S.Add(Convert.ToString(qr[1].LongValue, radix)); + q = qr[0]; + } + + sb.Append(Convert.ToString(q.LongValue, radix)); + for (int i = S.Count - 1; i >= 0; --i) + { + AppendZeroExtendedString(sb, (string)S[i], exponent); + } + break; + } + } + + return sb.ToString(); + } + + private static void AppendZeroExtendedString(StringBuilder sb, string s, int minLength) + { + for (int len = s.Length; len < minLength; ++len) + { + sb.Append('0'); + } + sb.Append(s); + } + + private static BigInteger CreateUValueOf( + ulong value) + { + int msw = (int)(value >> 32); + int lsw = (int)value; + + if (msw != 0) + return new BigInteger(1, new int[] { msw, lsw }, false); + + if (lsw != 0) + { + BigInteger n = new BigInteger(1, new int[] { lsw }, false); + // Check for a power of two + if ((lsw & -lsw) == lsw) + { + n.nBits = 1; + } + return n; + } + + return Zero; + } + + private static BigInteger CreateValueOf( + long value) + { + if (value < 0) + { + if (value == long.MinValue) + return CreateValueOf(~value).Not(); + + return CreateValueOf(-value).Negate(); + } + + return CreateUValueOf((ulong)value); + } + + public static BigInteger ValueOf( + long value) + { + if (value >= 0 && value < SMALL_CONSTANTS.Length) + { + return SMALL_CONSTANTS[value]; + } + + return CreateValueOf(value); + } + + public int GetLowestSetBit() + { + if (this.sign == 0) + return -1; + + return GetLowestSetBitMaskFirst(-1); + } + + private int GetLowestSetBitMaskFirst(int firstWordMask) + { + int w = magnitude.Length, offset = 0; + + uint word = (uint)(magnitude[--w] & firstWordMask); + Debug.Assert(magnitude[0] != 0); + + while (word == 0) + { + word = (uint)magnitude[--w]; + offset += 32; + } + + while ((word & 0xFF) == 0) + { + word >>= 8; + offset += 8; + } + + while ((word & 1) == 0) + { + word >>= 1; + ++offset; + } + + return offset; + } + + public bool TestBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit position must not be negative"); + + if (sign < 0) + return !Not().TestBit(n); + + int wordNum = n / 32; + if (wordNum >= magnitude.Length) + return false; + + int word = magnitude[magnitude.Length - 1 - wordNum]; + return ((word >> (n % 32)) & 1) > 0; + } + + public BigInteger Or( + BigInteger value) + { + if (this.sign == 0) + return value; + + if (value.sign == 0) + return this; + + int[] aMag = this.sign > 0 + ? this.magnitude + : Add(One).magnitude; + + int[] bMag = value.sign > 0 + ? value.magnitude + : value.Add(One).magnitude; + + bool resultNeg = sign < 0 || value.sign < 0; + int resultLength = System.Math.Max(aMag.Length, bMag.Length); + int[] resultMag = new int[resultLength]; + + int aStart = resultMag.Length - aMag.Length; + int bStart = resultMag.Length - bMag.Length; + + for (int i = 0; i < resultMag.Length; ++i) + { + int aWord = i >= aStart ? aMag[i - aStart] : 0; + int bWord = i >= bStart ? bMag[i - bStart] : 0; + + if (this.sign < 0) + { + aWord = ~aWord; + } + + if (value.sign < 0) + { + bWord = ~bWord; + } + + resultMag[i] = aWord | bWord; + + if (resultNeg) + { + resultMag[i] = ~resultMag[i]; + } + } + + BigInteger result = new BigInteger(1, resultMag, true); + + // TODO Optimise this case + if (resultNeg) + { + result = result.Not(); + } + + return result; + } + + public BigInteger Xor( + BigInteger value) + { + if (this.sign == 0) + return value; + + if (value.sign == 0) + return this; + + int[] aMag = this.sign > 0 + ? this.magnitude + : Add(One).magnitude; + + int[] bMag = value.sign > 0 + ? value.magnitude + : value.Add(One).magnitude; + + // TODO Can just replace with sign != value.sign? + bool resultNeg = (sign < 0 && value.sign >= 0) || (sign >= 0 && value.sign < 0); + int resultLength = System.Math.Max(aMag.Length, bMag.Length); + int[] resultMag = new int[resultLength]; + + int aStart = resultMag.Length - aMag.Length; + int bStart = resultMag.Length - bMag.Length; + + for (int i = 0; i < resultMag.Length; ++i) + { + int aWord = i >= aStart ? aMag[i - aStart] : 0; + int bWord = i >= bStart ? bMag[i - bStart] : 0; + + if (this.sign < 0) + { + aWord = ~aWord; + } + + if (value.sign < 0) + { + bWord = ~bWord; + } + + resultMag[i] = aWord ^ bWord; + + if (resultNeg) + { + resultMag[i] = ~resultMag[i]; + } + } + + BigInteger result = new BigInteger(1, resultMag, true); + + // TODO Optimise this case + if (resultNeg) + { + result = result.Not(); + } + + return result; + } + + public BigInteger SetBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit address less than zero"); + + if (TestBit(n)) + return this; + + // TODO Handle negative values and zero + if (sign > 0 && n < (BitLength - 1)) + return FlipExistingBit(n); + + return Or(One.ShiftLeft(n)); + } + + public BigInteger ClearBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit address less than zero"); + + if (!TestBit(n)) + return this; + + // TODO Handle negative values + if (sign > 0 && n < (BitLength - 1)) + return FlipExistingBit(n); + + return AndNot(One.ShiftLeft(n)); + } + + public BigInteger FlipBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit address less than zero"); + + // TODO Handle negative values and zero + if (sign > 0 && n < (BitLength - 1)) + return FlipExistingBit(n); + + return Xor(One.ShiftLeft(n)); + } + + private BigInteger FlipExistingBit( + int n) + { + Debug.Assert(sign > 0); + Debug.Assert(n >= 0); + Debug.Assert(n < BitLength - 1); + + int[] mag = (int[]) this.magnitude.Clone(); + mag[mag.Length - 1 - (n >> 5)] ^= (1 << (n & 31)); // Flip bit + //mag[mag.Length - 1 - (n / 32)] ^= (1 << (n % 32)); + return new BigInteger(this.sign, mag, false); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs.meta new file mode 100644 index 0000000..8df1b1b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/BigInteger.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 192ce040c8f883047926a9f104e89219 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec.meta new file mode 100644 index 0000000..b4cf81e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1d60220356cda474badfff94d625ad9d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs new file mode 100644 index 0000000..0cd9763 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs @@ -0,0 +1,483 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Field; + +namespace Org.BouncyCastle.Math.EC +{ + public class ECAlgorithms + { + public static bool IsF2mCurve(ECCurve c) + { + return IsF2mField(c.Field); + } + + public static bool IsF2mField(IFiniteField field) + { + return field.Dimension > 1 && field.Characteristic.Equals(BigInteger.Two) + && field is IPolynomialExtensionField; + } + + public static bool IsFpCurve(ECCurve c) + { + return IsFpField(c.Field); + } + + public static bool IsFpField(IFiniteField field) + { + return field.Dimension == 1; + } + + public static ECPoint SumOfMultiplies(ECPoint[] ps, BigInteger[] ks) + { + if (ps == null || ks == null || ps.Length != ks.Length || ps.Length < 1) + throw new ArgumentException("point and scalar arrays should be non-null, and of equal, non-zero, length"); + + int count = ps.Length; + switch (count) + { + case 1: + return ps[0].Multiply(ks[0]); + case 2: + return SumOfTwoMultiplies(ps[0], ks[0], ps[1], ks[1]); + default: + break; + } + + ECPoint p = ps[0]; + ECCurve c = p.Curve; + + ECPoint[] imported = new ECPoint[count]; + imported[0] = p; + for (int i = 1; i < count; ++i) + { + imported[i] = ImportPoint(c, ps[i]); + } + + GlvEndomorphism glvEndomorphism = c.GetEndomorphism() as GlvEndomorphism; + if (glvEndomorphism != null) + { + return ValidatePoint(ImplSumOfMultipliesGlv(imported, ks, glvEndomorphism)); + } + + return ValidatePoint(ImplSumOfMultiplies(imported, ks)); + } + + public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) + { + ECCurve cp = P.Curve; + Q = ImportPoint(cp, Q); + + // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick + { + AbstractF2mCurve f2mCurve = cp as AbstractF2mCurve; + if (f2mCurve != null && f2mCurve.IsKoblitz) + { + return ValidatePoint(P.Multiply(a).Add(Q.Multiply(b))); + } + } + + GlvEndomorphism glvEndomorphism = cp.GetEndomorphism() as GlvEndomorphism; + if (glvEndomorphism != null) + { + return ValidatePoint( + ImplSumOfMultipliesGlv(new ECPoint[] { P, Q }, new BigInteger[] { a, b }, glvEndomorphism)); + } + + return ValidatePoint(ImplShamirsTrickWNaf(P, a, Q, b)); + } + + /* + * "Shamir's Trick", originally due to E. G. Straus + * (Addition chains of vectors. American Mathematical Monthly, + * 71(7):806-808, Aug./Sept. 1964) + * + * Input: The points P, Q, scalar k = (km?, ... , k1, k0) + * and scalar l = (lm?, ... , l1, l0). + * Output: R = k * P + l * Q. + * 1: Z <- P + Q + * 2: R <- O + * 3: for i from m-1 down to 0 do + * 4: R <- R + R {point doubling} + * 5: if (ki = 1) and (li = 0) then R <- R + P end if + * 6: if (ki = 0) and (li = 1) then R <- R + Q end if + * 7: if (ki = 1) and (li = 1) then R <- R + Z end if + * 8: end for + * 9: return R + */ + public static ECPoint ShamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) + { + ECCurve cp = P.Curve; + Q = ImportPoint(cp, Q); + + return ValidatePoint(ImplShamirsTrickJsf(P, k, Q, l)); + } + + public static ECPoint ImportPoint(ECCurve c, ECPoint p) + { + ECCurve cp = p.Curve; + if (!c.Equals(cp)) + throw new ArgumentException("Point must be on the same curve"); + + return c.ImportPoint(p); + } + + public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len) + { + MontgomeryTrick(zs, off, len, null); + } + + public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len, ECFieldElement scale) + { + /* + * Uses the "Montgomery Trick" to invert many field elements, with only a single actual + * field inversion. See e.g. the paper: + * "Fast Multi-scalar Multiplication Methods on Elliptic Curves with Precomputation Strategy Using Montgomery Trick" + * by Katsuyuki Okeya, Kouichi Sakurai. + */ + + ECFieldElement[] c = new ECFieldElement[len]; + c[0] = zs[off]; + + int i = 0; + while (++i < len) + { + c[i] = c[i - 1].Multiply(zs[off + i]); + } + + --i; + + if (scale != null) + { + c[i] = c[i].Multiply(scale); + } + + ECFieldElement u = c[i].Invert(); + + while (i > 0) + { + int j = off + i--; + ECFieldElement tmp = zs[j]; + zs[j] = c[i].Multiply(u); + u = u.Multiply(tmp); + } + + zs[off] = u; + } + + /** + * Simple shift-and-add multiplication. Serves as reference implementation + * to verify (possibly faster) implementations, and for very small scalars. + * + * @param p + * The point to multiply. + * @param k + * The multiplier. + * @return The result of the point multiplication kP. + */ + public static ECPoint ReferenceMultiply(ECPoint p, BigInteger k) + { + BigInteger x = k.Abs(); + ECPoint q = p.Curve.Infinity; + int t = x.BitLength; + if (t > 0) + { + if (x.TestBit(0)) + { + q = p; + } + for (int i = 1; i < t; i++) + { + p = p.Twice(); + if (x.TestBit(i)) + { + q = q.Add(p); + } + } + } + return k.SignValue < 0 ? q.Negate() : q; + } + + public static ECPoint ValidatePoint(ECPoint p) + { + if (!p.IsValid()) + throw new ArgumentException("Invalid point", "p"); + + return p; + } + + internal static ECPoint ImplShamirsTrickJsf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) + { + ECCurve curve = P.Curve; + ECPoint infinity = curve.Infinity; + + // TODO conjugate co-Z addition (ZADDC) can return both of these + ECPoint PaddQ = P.Add(Q); + ECPoint PsubQ = P.Subtract(Q); + + ECPoint[] points = new ECPoint[] { Q, PsubQ, P, PaddQ }; + curve.NormalizeAll(points); + + ECPoint[] table = new ECPoint[] { + points[3].Negate(), points[2].Negate(), points[1].Negate(), + points[0].Negate(), infinity, points[0], + points[1], points[2], points[3] }; + + byte[] jsf = WNafUtilities.GenerateJsf(k, l); + + ECPoint R = infinity; + + int i = jsf.Length; + while (--i >= 0) + { + int jsfi = jsf[i]; + + // NOTE: The shifting ensures the sign is extended correctly + int kDigit = ((jsfi << 24) >> 28), lDigit = ((jsfi << 28) >> 28); + + int index = 4 + (kDigit * 3) + lDigit; + R = R.TwicePlus(table[index]); + } + + return R; + } + + internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, + ECPoint Q, BigInteger l) + { + bool negK = k.SignValue < 0, negL = l.SignValue < 0; + + k = k.Abs(); + l = l.Abs(); + + int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength))); + int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength))); + + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true); + WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true); + + ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp; + ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp; + ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg; + ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg; + + byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k); + byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l); + + return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); + } + + internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPointMap pointMapQ, BigInteger l) + { + bool negK = k.SignValue < 0, negL = l.SignValue < 0; + + k = k.Abs(); + l = l.Abs(); + + int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength)))); + + ECPoint Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMapQ); + WNafPreCompInfo infoP = WNafUtilities.GetWNafPreCompInfo(P); + WNafPreCompInfo infoQ = WNafUtilities.GetWNafPreCompInfo(Q); + + ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp; + ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp; + ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg; + ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg; + + byte[] wnafP = WNafUtilities.GenerateWindowNaf(width, k); + byte[] wnafQ = WNafUtilities.GenerateWindowNaf(width, l); + + return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); + } + + private static ECPoint ImplShamirsTrickWNaf(ECPoint[] preCompP, ECPoint[] preCompNegP, byte[] wnafP, + ECPoint[] preCompQ, ECPoint[] preCompNegQ, byte[] wnafQ) + { + int len = System.Math.Max(wnafP.Length, wnafQ.Length); + + ECCurve curve = preCompP[0].Curve; + ECPoint infinity = curve.Infinity; + + ECPoint R = infinity; + int zeroes = 0; + + for (int i = len - 1; i >= 0; --i) + { + int wiP = i < wnafP.Length ? (int)(sbyte)wnafP[i] : 0; + int wiQ = i < wnafQ.Length ? (int)(sbyte)wnafQ[i] : 0; + + if ((wiP | wiQ) == 0) + { + ++zeroes; + continue; + } + + ECPoint r = infinity; + if (wiP != 0) + { + int nP = System.Math.Abs(wiP); + ECPoint[] tableP = wiP < 0 ? preCompNegP : preCompP; + r = r.Add(tableP[nP >> 1]); + } + if (wiQ != 0) + { + int nQ = System.Math.Abs(wiQ); + ECPoint[] tableQ = wiQ < 0 ? preCompNegQ : preCompQ; + r = r.Add(tableQ[nQ >> 1]); + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + zeroes = 0; + } + + R = R.TwicePlus(r); + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + } + + return R; + } + + internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks) + { + int count = ps.Length; + bool[] negs = new bool[count]; + WNafPreCompInfo[] infos = new WNafPreCompInfo[count]; + byte[][] wnafs = new byte[count][]; + + for (int i = 0; i < count; ++i) + { + BigInteger ki = ks[i]; negs[i] = ki.SignValue < 0; ki = ki.Abs(); + + int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(ki.BitLength))); + infos[i] = WNafUtilities.Precompute(ps[i], width, true); + wnafs[i] = WNafUtilities.GenerateWindowNaf(width, ki); + } + + return ImplSumOfMultiplies(negs, infos, wnafs); + } + + internal static ECPoint ImplSumOfMultipliesGlv(ECPoint[] ps, BigInteger[] ks, GlvEndomorphism glvEndomorphism) + { + BigInteger n = ps[0].Curve.Order; + + int len = ps.Length; + + BigInteger[] abs = new BigInteger[len << 1]; + for (int i = 0, j = 0; i < len; ++i) + { + BigInteger[] ab = glvEndomorphism.DecomposeScalar(ks[i].Mod(n)); + abs[j++] = ab[0]; + abs[j++] = ab[1]; + } + + ECPointMap pointMap = glvEndomorphism.PointMap; + if (glvEndomorphism.HasEfficientPointMap) + { + return ECAlgorithms.ImplSumOfMultiplies(ps, pointMap, abs); + } + + ECPoint[] pqs = new ECPoint[len << 1]; + for (int i = 0, j = 0; i < len; ++i) + { + ECPoint p = ps[i], q = pointMap.Map(p); + pqs[j++] = p; + pqs[j++] = q; + } + + return ECAlgorithms.ImplSumOfMultiplies(pqs, abs); + } + + internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, ECPointMap pointMap, BigInteger[] ks) + { + int halfCount = ps.Length, fullCount = halfCount << 1; + + bool[] negs = new bool[fullCount]; + WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount]; + byte[][] wnafs = new byte[fullCount][]; + + for (int i = 0; i < halfCount; ++i) + { + int j0 = i << 1, j1 = j0 + 1; + + BigInteger kj0 = ks[j0]; negs[j0] = kj0.SignValue < 0; kj0 = kj0.Abs(); + BigInteger kj1 = ks[j1]; negs[j1] = kj1.SignValue < 0; kj1 = kj1.Abs(); + + int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength)))); + + ECPoint P = ps[i], Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMap); + infos[j0] = WNafUtilities.GetWNafPreCompInfo(P); + infos[j1] = WNafUtilities.GetWNafPreCompInfo(Q); + wnafs[j0] = WNafUtilities.GenerateWindowNaf(width, kj0); + wnafs[j1] = WNafUtilities.GenerateWindowNaf(width, kj1); + } + + return ImplSumOfMultiplies(negs, infos, wnafs); + } + + private static ECPoint ImplSumOfMultiplies(bool[] negs, WNafPreCompInfo[] infos, byte[][] wnafs) + { + int len = 0, count = wnafs.Length; + for (int i = 0; i < count; ++i) + { + len = System.Math.Max(len, wnafs[i].Length); + } + + ECCurve curve = infos[0].PreComp[0].Curve; + ECPoint infinity = curve.Infinity; + + ECPoint R = infinity; + int zeroes = 0; + + for (int i = len - 1; i >= 0; --i) + { + ECPoint r = infinity; + + for (int j = 0; j < count; ++j) + { + byte[] wnaf = wnafs[j]; + int wi = i < wnaf.Length ? (int)(sbyte)wnaf[i] : 0; + if (wi != 0) + { + int n = System.Math.Abs(wi); + WNafPreCompInfo info = infos[j]; + ECPoint[] table = (wi < 0 == negs[j]) ? info.PreComp : info.PreCompNeg; + r = r.Add(table[n >> 1]); + } + } + + if (r == infinity) + { + ++zeroes; + continue; + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + zeroes = 0; + } + + R = R.TwicePlus(r); + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + } + + return R; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs.meta new file mode 100644 index 0000000..9e2c804 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECAlgorithms.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d5f3620d97ee7c342a95b5b57c924d90 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs new file mode 100644 index 0000000..06a00dd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs @@ -0,0 +1,1132 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Math.EC.Abc; +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC +{ + /// Base class for an elliptic curve. + public abstract class ECCurve + { + public const int COORD_AFFINE = 0; + public const int COORD_HOMOGENEOUS = 1; + public const int COORD_JACOBIAN = 2; + public const int COORD_JACOBIAN_CHUDNOVSKY = 3; + public const int COORD_JACOBIAN_MODIFIED = 4; + public const int COORD_LAMBDA_AFFINE = 5; + public const int COORD_LAMBDA_PROJECTIVE = 6; + public const int COORD_SKEWED = 7; + + public static int[] GetAllCoordinateSystems() + { + return new int[]{ COORD_AFFINE, COORD_HOMOGENEOUS, COORD_JACOBIAN, COORD_JACOBIAN_CHUDNOVSKY, + COORD_JACOBIAN_MODIFIED, COORD_LAMBDA_AFFINE, COORD_LAMBDA_PROJECTIVE, COORD_SKEWED }; + } + + public class Config + { + protected ECCurve outer; + protected int coord; + protected ECEndomorphism endomorphism; + protected ECMultiplier multiplier; + + internal Config(ECCurve outer, int coord, ECEndomorphism endomorphism, ECMultiplier multiplier) + { + this.outer = outer; + this.coord = coord; + this.endomorphism = endomorphism; + this.multiplier = multiplier; + } + + public Config SetCoordinateSystem(int coord) + { + this.coord = coord; + return this; + } + + public Config SetEndomorphism(ECEndomorphism endomorphism) + { + this.endomorphism = endomorphism; + return this; + } + + public Config SetMultiplier(ECMultiplier multiplier) + { + this.multiplier = multiplier; + return this; + } + + public ECCurve Create() + { + if (!outer.SupportsCoordinateSystem(coord)) + { + throw new InvalidOperationException("unsupported coordinate system"); + } + + ECCurve c = outer.CloneCurve(); + if (c == outer) + { + throw new InvalidOperationException("implementation returned current curve"); + } + + c.m_coord = coord; + c.m_endomorphism = endomorphism; + c.m_multiplier = multiplier; + + return c; + } + } + + protected readonly IFiniteField m_field; + protected ECFieldElement m_a, m_b; + protected BigInteger m_order, m_cofactor; + + protected int m_coord = COORD_AFFINE; + protected ECEndomorphism m_endomorphism = null; + protected ECMultiplier m_multiplier = null; + + protected ECCurve(IFiniteField field) + { + this.m_field = field; + } + + public abstract int FieldSize { get; } + public abstract ECFieldElement FromBigInteger(BigInteger x); + public abstract bool IsValidFieldElement(BigInteger x); + + public virtual Config Configure() + { + return new Config(this, this.m_coord, this.m_endomorphism, this.m_multiplier); + } + + public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y) + { + ECPoint p = CreatePoint(x, y); + if (!p.IsValid()) + { + throw new ArgumentException("Invalid point coordinates"); + } + return p; + } + + public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y, bool withCompression) + { + ECPoint p = CreatePoint(x, y, withCompression); + if (!p.IsValid()) + { + throw new ArgumentException("Invalid point coordinates"); + } + return p; + } + + public virtual ECPoint CreatePoint(BigInteger x, BigInteger y) + { + return CreatePoint(x, y, false); + } + + public virtual ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression) + { + return CreateRawPoint(FromBigInteger(x), FromBigInteger(y), withCompression); + } + + protected abstract ECCurve CloneCurve(); + + protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression); + + protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression); + + protected virtual ECMultiplier CreateDefaultMultiplier() + { + GlvEndomorphism glvEndomorphism = m_endomorphism as GlvEndomorphism; + if (glvEndomorphism != null) + { + return new GlvMultiplier(this, glvEndomorphism); + } + + return new WNafL2RMultiplier(); + } + + public virtual bool SupportsCoordinateSystem(int coord) + { + return coord == COORD_AFFINE; + } + + public virtual PreCompInfo GetPreCompInfo(ECPoint point, string name) + { + CheckPoint(point); + lock (point) + { + IDictionary table = point.m_preCompTable; + return table == null ? null : (PreCompInfo)table[name]; + } + } + + /** + * Adds PreCompInfo for a point on this curve, under a given name. Used by + * ECMultipliers to save the precomputation for this ECPoint for use + * by subsequent multiplication. + * + * @param point + * The ECPoint to store precomputations for. + * @param name + * A String used to index precomputations of different types. + * @param preCompInfo + * The values precomputed by the ECMultiplier. + */ + public virtual void SetPreCompInfo(ECPoint point, string name, PreCompInfo preCompInfo) + { + CheckPoint(point); + lock (point) + { + IDictionary table = point.m_preCompTable; + if (null == table) + { + point.m_preCompTable = table = Org.BouncyCastle.Utilities.Platform.CreateHashtable(4); + } + table[name] = preCompInfo; + } + } + + public virtual ECPoint ImportPoint(ECPoint p) + { + if (this == p.Curve) + { + return p; + } + if (p.IsInfinity) + { + return Infinity; + } + + // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates. + p = p.Normalize(); + + return ValidatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed); + } + + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. Where more + * than one point is to be normalized, this method will generally be more efficient than + * normalizing each point separately. + * + * @param points + * An array of points that will be updated in place with their normalized versions, + * where necessary + */ + public virtual void NormalizeAll(ECPoint[] points) + { + NormalizeAll(points, 0, points.Length, null); + } + + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. Where more + * than one point is to be normalized, this method will generally be more efficient than + * normalizing each point separately. An (optional) z-scaling factor can be applied; effectively + * each z coordinate is scaled by this value prior to normalization (but only one + * actual multiplication is needed). + * + * @param points + * An array of points that will be updated in place with their normalized versions, + * where necessary + * @param off + * The start of the range of points to normalize + * @param len + * The length of the range of points to normalize + * @param iso + * The (optional) z-scaling factor - can be null + */ + public virtual void NormalizeAll(ECPoint[] points, int off, int len, ECFieldElement iso) + { + CheckPoints(points, off, len); + + switch (this.CoordinateSystem) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + if (iso != null) + throw new ArgumentException("not valid for affine coordinates", "iso"); + + return; + } + } + + /* + * Figure out which of the points actually need to be normalized + */ + ECFieldElement[] zs = new ECFieldElement[len]; + int[] indices = new int[len]; + int count = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + if (null != p && (iso != null || !p.IsNormalized())) + { + zs[count] = p.GetZCoord(0); + indices[count++] = off + i; + } + } + + if (count == 0) + { + return; + } + + ECAlgorithms.MontgomeryTrick(zs, 0, count, iso); + + for (int j = 0; j < count; ++j) + { + int index = indices[j]; + points[index] = points[index].Normalize(zs[j]); + } + } + + public abstract ECPoint Infinity { get; } + + public virtual IFiniteField Field + { + get { return m_field; } + } + + public virtual ECFieldElement A + { + get { return m_a; } + } + + public virtual ECFieldElement B + { + get { return m_b; } + } + + public virtual BigInteger Order + { + get { return m_order; } + } + + public virtual BigInteger Cofactor + { + get { return m_cofactor; } + } + + public virtual int CoordinateSystem + { + get { return m_coord; } + } + + protected virtual void CheckPoint(ECPoint point) + { + if (null == point || (this != point.Curve)) + throw new ArgumentException("must be non-null and on this curve", "point"); + } + + protected virtual void CheckPoints(ECPoint[] points) + { + CheckPoints(points, 0, points.Length); + } + + protected virtual void CheckPoints(ECPoint[] points, int off, int len) + { + if (points == null) + throw new ArgumentNullException("points"); + if (off < 0 || len < 0 || (off > (points.Length - len))) + throw new ArgumentException("invalid range specified", "points"); + + for (int i = 0; i < len; ++i) + { + ECPoint point = points[off + i]; + if (null != point && this != point.Curve) + throw new ArgumentException("entries must be null or on this curve", "points"); + } + } + + public virtual bool Equals(ECCurve other) + { + if (this == other) + return true; + if (null == other) + return false; + return Field.Equals(other.Field) + && A.ToBigInteger().Equals(other.A.ToBigInteger()) + && B.ToBigInteger().Equals(other.B.ToBigInteger()); + } + + public override bool Equals(object obj) + { + return Equals(obj as ECCurve); + } + + public override int GetHashCode() + { + return Field.GetHashCode() + ^ Integers.RotateLeft(A.ToBigInteger().GetHashCode(), 8) + ^ Integers.RotateLeft(B.ToBigInteger().GetHashCode(), 16); + } + + protected abstract ECPoint DecompressPoint(int yTilde, BigInteger X1); + + public virtual ECEndomorphism GetEndomorphism() + { + return m_endomorphism; + } + + /** + * Sets the default ECMultiplier, unless already set. + */ + public virtual ECMultiplier GetMultiplier() + { + lock (this) + { + if (this.m_multiplier == null) + { + this.m_multiplier = CreateDefaultMultiplier(); + } + return this.m_multiplier; + } + } + + /** + * Decode a point on this curve from its ASN.1 encoding. The different + * encodings are taken account of, including point compression for + * Fp (X9.62 s 4.2.1 pg 17). + * @return The decoded point. + */ + public virtual ECPoint DecodePoint(byte[] encoded) + { + ECPoint p = null; + int expectedLength = (FieldSize + 7) / 8; + + byte type = encoded[0]; + switch (type) + { + case 0x00: // infinity + { + if (encoded.Length != 1) + throw new ArgumentException("Incorrect length for infinity encoding", "encoded"); + + p = Infinity; + break; + } + + case 0x02: // compressed + case 0x03: // compressed + { + if (encoded.Length != (expectedLength + 1)) + throw new ArgumentException("Incorrect length for compressed encoding", "encoded"); + + int yTilde = type & 1; + BigInteger X = new BigInteger(1, encoded, 1, expectedLength); + + p = DecompressPoint(yTilde, X); + if (!p.SatisfiesCofactor()) + throw new ArgumentException("Invalid point"); + + break; + } + + case 0x04: // uncompressed + { + if (encoded.Length != (2 * expectedLength + 1)) + throw new ArgumentException("Incorrect length for uncompressed encoding", "encoded"); + + BigInteger X = new BigInteger(1, encoded, 1, expectedLength); + BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); + + p = ValidatePoint(X, Y); + break; + } + + case 0x06: // hybrid + case 0x07: // hybrid + { + if (encoded.Length != (2 * expectedLength + 1)) + throw new ArgumentException("Incorrect length for hybrid encoding", "encoded"); + + BigInteger X = new BigInteger(1, encoded, 1, expectedLength); + BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); + + if (Y.TestBit(0) != (type == 0x07)) + throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded"); + + p = ValidatePoint(X, Y); + break; + } + + default: + throw new FormatException("Invalid point encoding " + type); + } + + if (type != 0x00 && p.IsInfinity) + throw new ArgumentException("Invalid infinity encoding", "encoded"); + + return p; + } + } + + public abstract class AbstractFpCurve + : ECCurve + { + protected AbstractFpCurve(BigInteger q) + : base(FiniteFields.GetPrimeField(q)) + { + } + + public override bool IsValidFieldElement(BigInteger x) + { + return x != null && x.SignValue >= 0 && x.CompareTo(Field.Characteristic) < 0; + } + + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement x = FromBigInteger(X1); + ECFieldElement rhs = x.Square().Add(A).Multiply(x).Add(B); + ECFieldElement y = rhs.Sqrt(); + + /* + * If y is not a square, then we haven't got a point on the curve + */ + if (y == null) + throw new ArgumentException("Invalid point compression"); + + if (y.TestBitZero() != (yTilde == 1)) + { + // Use the other root + y = y.Negate(); + } + + return CreateRawPoint(x, y, true); + } + } + + /** + * Elliptic curve over Fp + */ + public class FpCurve + : AbstractFpCurve + { + private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + + protected readonly BigInteger m_q, m_r; + protected readonly FpPoint m_infinity; + + public FpCurve(BigInteger q, BigInteger a, BigInteger b) + : this(q, a, b, null, null) + { + } + + public FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor) + : base(q) + { + this.m_q = q; + this.m_r = FpFieldElement.CalculateResidue(q); + this.m_infinity = new FpPoint(this, null, null); + + this.m_a = FromBigInteger(a); + this.m_b = FromBigInteger(b); + this.m_order = order; + this.m_cofactor = cofactor; + this.m_coord = FP_DEFAULT_COORDS; + } + + protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b) + : this(q, r, a, b, null, null) + { + } + + protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) + : base(q) + { + this.m_q = q; + this.m_r = r; + this.m_infinity = new FpPoint(this, null, null); + + this.m_a = a; + this.m_b = b; + this.m_order = order; + this.m_cofactor = cofactor; + this.m_coord = FP_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new FpCurve(m_q, m_r, m_a, m_b, m_order, m_cofactor); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_AFFINE: + case COORD_HOMOGENEOUS: + case COORD_JACOBIAN: + case COORD_JACOBIAN_MODIFIED: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return m_q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return m_q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new FpFieldElement(this.m_q, this.m_r, x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new FpPoint(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new FpPoint(this, x, y, zs, withCompression); + } + + public override ECPoint ImportPoint(ECPoint p) + { + if (this != p.Curve && this.CoordinateSystem == COORD_JACOBIAN && !p.IsInfinity) + { + switch (p.Curve.CoordinateSystem) + { + case COORD_JACOBIAN: + case COORD_JACOBIAN_CHUDNOVSKY: + case COORD_JACOBIAN_MODIFIED: + return new FpPoint(this, + FromBigInteger(p.RawXCoord.ToBigInteger()), + FromBigInteger(p.RawYCoord.ToBigInteger()), + new ECFieldElement[] { FromBigInteger(p.GetZCoord(0).ToBigInteger()) }, + p.IsCompressed); + default: + break; + } + } + + return base.ImportPoint(p); + } + } + + public abstract class AbstractF2mCurve + : ECCurve + { + public static BigInteger Inverse(int m, int[] ks, BigInteger x) + { + return new LongArray(x).ModInverse(m, ks).ToBigInteger(); + } + + /** + * The auxiliary values s0 and + * s1 used for partial modular reduction for + * Koblitz curves. + */ + private BigInteger[] si = null; + + private static IFiniteField BuildField(int m, int k1, int k2, int k3) + { + if (k1 == 0) + { + throw new ArgumentException("k1 must be > 0"); + } + + if (k2 == 0) + { + if (k3 != 0) + { + throw new ArgumentException("k3 must be 0 if k2 == 0"); + } + + return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, m }); + } + + if (k2 <= k1) + { + throw new ArgumentException("k2 must be > k1"); + } + + if (k3 <= k2) + { + throw new ArgumentException("k3 must be > k2"); + } + + return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, k2, k3, m }); + } + + protected AbstractF2mCurve(int m, int k1, int k2, int k3) + : base(BuildField(m, k1, k2, k3)) + { + } + + public override bool IsValidFieldElement(BigInteger x) + { + return x != null && x.SignValue >= 0 && x.BitLength <= FieldSize; + } + + public override ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression) + { + ECFieldElement X = FromBigInteger(x), Y = FromBigInteger(y); + + switch (this.CoordinateSystem) + { + case COORD_LAMBDA_AFFINE: + case COORD_LAMBDA_PROJECTIVE: + { + if (X.IsZero) + { + if (!Y.Square().Equals(B)) + throw new ArgumentException(); + } + else + { + // Y becomes Lambda (X + Y/X) here + Y = Y.Divide(X).Add(X); + } + break; + } + default: + { + break; + } + } + + return CreateRawPoint(X, Y, withCompression); + } + + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement xp = FromBigInteger(X1), yp = null; + if (xp.IsZero) + { + yp = B.Sqrt(); + } + else + { + ECFieldElement beta = xp.Square().Invert().Multiply(B).Add(A).Add(xp); + ECFieldElement z = SolveQuadradicEquation(beta); + + if (z != null) + { + if (z.TestBitZero() != (yTilde == 1)) + { + z = z.AddOne(); + } + + switch (this.CoordinateSystem) + { + case COORD_LAMBDA_AFFINE: + case COORD_LAMBDA_PROJECTIVE: + { + yp = z.Add(xp); + break; + } + default: + { + yp = z.Multiply(xp); + break; + } + } + } + } + + if (yp == null) + throw new ArgumentException("Invalid point compression"); + + return CreateRawPoint(xp, yp, true); + } + + /** + * Solves a quadratic equation z2 + z = beta(X9.62 + * D.1.6) The other solution is z + 1. + * + * @param beta + * The value to solve the qradratic equation for. + * @return the solution for z2 + z = beta or + * null if no solution exists. + */ + private ECFieldElement SolveQuadradicEquation(ECFieldElement beta) + { + if (beta.IsZero) + return beta; + + ECFieldElement gamma, z, zeroElement = FromBigInteger(BigInteger.Zero); + + int m = FieldSize; + do + { + ECFieldElement t = FromBigInteger(BigInteger.Arbitrary(m)); + z = zeroElement; + ECFieldElement w = beta; + for (int i = 1; i < m; i++) + { + ECFieldElement w2 = w.Square(); + z = z.Square().Add(w2.Multiply(t)); + w = w2.Add(beta); + } + if (!w.IsZero) + { + return null; + } + gamma = z.Square().Add(z); + } + while (gamma.IsZero); + + return z; + } + + /** + * @return the auxiliary values s0 and + * s1 used for partial modular reduction for + * Koblitz curves. + */ + internal virtual BigInteger[] GetSi() + { + if (si == null) + { + lock (this) + { + if (si == null) + { + si = Tnaf.GetSi(this); + } + } + } + return si; + } + + /** + * Returns true if this is a Koblitz curve (ABC curve). + * @return true if this is a Koblitz curve (ABC curve), false otherwise + */ + public virtual bool IsKoblitz + { + get + { + return m_order != null && m_cofactor != null && m_b.IsOne && (m_a.IsZero || m_a.IsOne); + } + } + } + + /** + * Elliptic curves over F2m. The Weierstrass equation is given by + * y2 + xy = x3 + ax2 + b. + */ + public class F2mCurve + : AbstractF2mCurve + { + private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + /** + * The exponent m of F2m. + */ + private readonly int m; + + /** + * TPB: The integer k where xm + + * xk + 1 represents the reduction polynomial + * f(z).
    + * PPB: The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + private readonly int k1; + + /** + * TPB: Always set to 0
    + * PPB: The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + private readonly int k2; + + /** + * TPB: Always set to 0
    + * PPB: The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + private readonly int k3; + + /** + * The point at infinity on this curve. + */ + protected readonly F2mPoint m_infinity; + + /** + * Constructor for Trinomial Polynomial Basis (TPB). + * @param m The exponent m of + * F2m. + * @param k The integer k where xm + + * xk + 1 represents the reduction + * polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + */ + public F2mCurve( + int m, + int k, + BigInteger a, + BigInteger b) + : this(m, k, 0, 0, a, b, null, null) + { + } + + /** + * Constructor for Trinomial Polynomial Basis (TPB). + * @param m The exponent m of + * F2m. + * @param k The integer k where xm + + * xk + 1 represents the reduction + * polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param order The order of the main subgroup of the elliptic curve. + * @param cofactor The cofactor of the elliptic curve, i.e. + * #Ea(F2m) = h * n. + */ + public F2mCurve( + int m, + int k, + BigInteger a, + BigInteger b, + BigInteger order, + BigInteger cofactor) + : this(m, k, 0, 0, a, b, order, cofactor) + { + } + + /** + * Constructor for Pentanomial Polynomial Basis (PPB). + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + */ + public F2mCurve( + int m, + int k1, + int k2, + int k3, + BigInteger a, + BigInteger b) + : this(m, k1, k2, k3, a, b, null, null) + { + } + + /** + * Constructor for Pentanomial Polynomial Basis (PPB). + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param order The order of the main subgroup of the elliptic curve. + * @param cofactor The cofactor of the elliptic curve, i.e. + * #Ea(F2m) = h * n. + */ + public F2mCurve( + int m, + int k1, + int k2, + int k3, + BigInteger a, + BigInteger b, + BigInteger order, + BigInteger cofactor) + : base(m, k1, k2, k3) + { + this.m = m; + this.k1 = k1; + this.k2 = k2; + this.k3 = k3; + this.m_order = order; + this.m_cofactor = cofactor; + this.m_infinity = new F2mPoint(this, null, null); + + if (k1 == 0) + throw new ArgumentException("k1 must be > 0"); + + if (k2 == 0) + { + if (k3 != 0) + throw new ArgumentException("k3 must be 0 if k2 == 0"); + } + else + { + if (k2 <= k1) + throw new ArgumentException("k2 must be > k1"); + + if (k3 <= k2) + throw new ArgumentException("k3 must be > k2"); + } + + this.m_a = FromBigInteger(a); + this.m_b = FromBigInteger(b); + this.m_coord = F2M_DEFAULT_COORDS; + } + + protected F2mCurve(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) + : base(m, k1, k2, k3) + { + this.m = m; + this.k1 = k1; + this.k2 = k2; + this.k3 = k3; + this.m_order = order; + this.m_cofactor = cofactor; + + this.m_infinity = new F2mPoint(this, null, null); + this.m_a = a; + this.m_b = b; + this.m_coord = F2M_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new F2mCurve(m, k1, k2, k3, m_a, m_b, m_order, m_cofactor); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_AFFINE: + case COORD_HOMOGENEOUS: + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + if (IsKoblitz) + { + return new WTauNafMultiplier(); + } + + return base.CreateDefaultMultiplier(); + } + + public override int FieldSize + { + get { return m; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new F2mPoint(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new F2mPoint(this, x, y, zs, withCompression); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public int M + { + get { return m; } + } + + /** + * Return true if curve uses a Trinomial basis. + * + * @return true if curve Trinomial, false otherwise. + */ + public bool IsTrinomial() + { + return k2 == 0 && k3 == 0; + } + + public int K1 + { + get { return k1; } + } + + public int K2 + { + get { return k2; } + } + + public int K3 + { + get { return k3; } + } + + [Obsolete("Use 'Order' property instead")] + public BigInteger N + { + get { return m_order; } + } + + [Obsolete("Use 'Cofactor' property instead")] + public BigInteger H + { + get { return m_cofactor; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs.meta new file mode 100644 index 0000000..ceb2c08 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECCurve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2ba3b2a3c2430914fbced44c7df90596 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs new file mode 100644 index 0000000..6b30f84 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs @@ -0,0 +1,931 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC +{ + public abstract class ECFieldElement + { + public abstract BigInteger ToBigInteger(); + public abstract string FieldName { get; } + public abstract int FieldSize { get; } + public abstract ECFieldElement Add(ECFieldElement b); + public abstract ECFieldElement AddOne(); + public abstract ECFieldElement Subtract(ECFieldElement b); + public abstract ECFieldElement Multiply(ECFieldElement b); + public abstract ECFieldElement Divide(ECFieldElement b); + public abstract ECFieldElement Negate(); + public abstract ECFieldElement Square(); + public abstract ECFieldElement Invert(); + public abstract ECFieldElement Sqrt(); + + public virtual int BitLength + { + get { return ToBigInteger().BitLength; } + } + + public virtual bool IsOne + { + get { return BitLength == 1; } + } + + public virtual bool IsZero + { + get { return 0 == ToBigInteger().SignValue; } + } + + public virtual ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return Multiply(b).Subtract(x.Multiply(y)); + } + + public virtual ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return Multiply(b).Add(x.Multiply(y)); + } + + public virtual ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return Square().Subtract(x.Multiply(y)); + } + + public virtual ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + return Square().Add(x.Multiply(y)); + } + + public virtual ECFieldElement SquarePow(int pow) + { + ECFieldElement r = this; + for (int i = 0; i < pow; ++i) + { + r = r.Square(); + } + return r; + } + + public virtual bool TestBitZero() + { + return ToBigInteger().TestBit(0); + } + + public override bool Equals(object obj) + { + return Equals(obj as ECFieldElement); + } + + public virtual bool Equals(ECFieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return ToBigInteger().Equals(other.ToBigInteger()); + } + + public override int GetHashCode() + { + return ToBigInteger().GetHashCode(); + } + + public override string ToString() + { + return this.ToBigInteger().ToString(16); + } + + public virtual byte[] GetEncoded() + { + return BigIntegers.AsUnsignedByteArray((FieldSize + 7) / 8, ToBigInteger()); + } + } + + public class FpFieldElement + : ECFieldElement + { + private readonly BigInteger q, r, x; + + internal static BigInteger CalculateResidue(BigInteger p) + { + int bitLength = p.BitLength; + if (bitLength >= 96) + { + BigInteger firstWord = p.ShiftRight(bitLength - 64); + if (firstWord.LongValue == -1L) + { + return BigInteger.One.ShiftLeft(bitLength).Subtract(p); + } + if ((bitLength & 7) == 0) + { + return BigInteger.One.ShiftLeft(bitLength << 1).Divide(p).Negate(); + } + } + return null; + } + + public FpFieldElement(BigInteger q, BigInteger x) + : this(q, CalculateResidue(q), x) + { + } + + internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0) + throw new ArgumentException("value invalid in Fp field element", "x"); + + this.q = q; + this.r = r; + this.x = x; + } + + public override BigInteger ToBigInteger() + { + return x; + } + + /** + * return the field name for this field. + * + * @return the string "Fp". + */ + public override string FieldName + { + get { return "Fp"; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public BigInteger Q + { + get { return q; } + } + + public override ECFieldElement Add( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger())); + } + + public override ECFieldElement AddOne() + { + BigInteger x2 = x.Add(BigInteger.One); + if (x2.CompareTo(q) == 0) + { + x2 = BigInteger.Zero; + } + return new FpFieldElement(q, r, x2); + } + + public override ECFieldElement Subtract( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModSubtract(x, b.ToBigInteger())); + } + + public override ECFieldElement Multiply( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger())); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger ab = ax.Multiply(bx); + BigInteger xy = xx.Multiply(yx); + return new FpFieldElement(q, r, ModReduce(ab.Subtract(xy))); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger ab = ax.Multiply(bx); + BigInteger xy = xx.Multiply(yx); + BigInteger sum = ab.Add(xy); + if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1)) + { + sum = sum.Subtract(q.ShiftLeft(q.BitLength)); + } + return new FpFieldElement(q, r, ModReduce(sum)); + } + + public override ECFieldElement Divide( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModMult(x, ModInverse(b.ToBigInteger()))); + } + + public override ECFieldElement Negate() + { + return x.SignValue == 0 ? this : new FpFieldElement(q, r, q.Subtract(x)); + } + + public override ECFieldElement Square() + { + return new FpFieldElement(q, r, ModMult(x, x)); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger aa = ax.Multiply(ax); + BigInteger xy = xx.Multiply(yx); + return new FpFieldElement(q, r, ModReduce(aa.Subtract(xy))); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger aa = ax.Multiply(ax); + BigInteger xy = xx.Multiply(yx); + BigInteger sum = aa.Add(xy); + if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1)) + { + sum = sum.Subtract(q.ShiftLeft(q.BitLength)); + } + return new FpFieldElement(q, r, ModReduce(sum)); + } + + public override ECFieldElement Invert() + { + // TODO Modular inversion can be faster for a (Generalized) Mersenne Prime. + return new FpFieldElement(q, r, ModInverse(x)); + } + + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + if (IsZero || IsOne) + return this; + + if (!q.TestBit(0)) + throw Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("even value of q"); + + if (q.TestBit(1)) // q == 4m + 3 + { + BigInteger e = q.ShiftRight(2).Add(BigInteger.One); + return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q))); + } + + if (q.TestBit(2)) // q == 8m + 5 + { + BigInteger t1 = x.ModPow(q.ShiftRight(3), q); + BigInteger t2 = ModMult(t1, x); + BigInteger t3 = ModMult(t2, t1); + + if (t3.Equals(BigInteger.One)) + { + return CheckSqrt(new FpFieldElement(q, r, t2)); + } + + // TODO This is constant and could be precomputed + BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q); + + BigInteger y = ModMult(t2, t4); + + return CheckSqrt(new FpFieldElement(q, r, y)); + } + + // q == 8m + 1 + + BigInteger legendreExponent = q.ShiftRight(1); + if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) + return null; + + BigInteger X = this.x; + BigInteger fourX = ModDouble(ModDouble(X)); ; + + BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One); + + BigInteger U, V; + do + { + BigInteger P; + do + { + P = BigInteger.Arbitrary(q.BitLength); + } + while (P.CompareTo(q) >= 0 + || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne)); + + BigInteger[] result = LucasSequence(P, X, k); + U = result[0]; + V = result[1]; + + if (ModMult(V, V).Equals(fourX)) + { + return new FpFieldElement(q, r, ModHalfAbs(V)); + } + } + while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); + + return null; + } + + private ECFieldElement CheckSqrt(ECFieldElement z) + { + return z.Square().Equals(this) ? z : null; + } + + private BigInteger[] LucasSequence( + BigInteger P, + BigInteger Q, + BigInteger k) + { + // TODO Research and apply "common-multiplicand multiplication here" + + int n = k.BitLength; + int s = k.GetLowestSetBit(); + + Debug.Assert(k.TestBit(s)); + + BigInteger Uh = BigInteger.One; + BigInteger Vl = BigInteger.Two; + BigInteger Vh = P; + BigInteger Ql = BigInteger.One; + BigInteger Qh = BigInteger.One; + + for (int j = n - 1; j >= s + 1; --j) + { + Ql = ModMult(Ql, Qh); + + if (k.TestBit(j)) + { + Qh = ModMult(Ql, Q); + Uh = ModMult(Uh, Vh); + Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql))); + Vh = ModReduce(Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1))); + } + else + { + Qh = Ql; + Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql)); + Vh = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql))); + Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1))); + } + } + + Ql = ModMult(Ql, Qh); + Qh = ModMult(Ql, Q); + Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql)); + Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql))); + Ql = ModMult(Ql, Qh); + + for (int j = 1; j <= s; ++j) + { + Uh = ModMult(Uh, Vl); + Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1))); + Ql = ModMult(Ql, Ql); + } + + return new BigInteger[] { Uh, Vl }; + } + + protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2) + { + BigInteger x3 = x1.Add(x2); + if (x3.CompareTo(q) >= 0) + { + x3 = x3.Subtract(q); + } + return x3; + } + + protected virtual BigInteger ModDouble(BigInteger x) + { + BigInteger _2x = x.ShiftLeft(1); + if (_2x.CompareTo(q) >= 0) + { + _2x = _2x.Subtract(q); + } + return _2x; + } + + protected virtual BigInteger ModHalf(BigInteger x) + { + if (x.TestBit(0)) + { + x = q.Add(x); + } + return x.ShiftRight(1); + } + + protected virtual BigInteger ModHalfAbs(BigInteger x) + { + if (x.TestBit(0)) + { + x = q.Subtract(x); + } + return x.ShiftRight(1); + } + + protected virtual BigInteger ModInverse(BigInteger x) + { + int bits = FieldSize; + int len = (bits + 31) >> 5; + uint[] p = Nat.FromBigInteger(bits, q); + uint[] n = Nat.FromBigInteger(bits, x); + uint[] z = Nat.Create(len); + Mod.Invert(p, n, z); + return Nat.ToBigInteger(len, z); + } + + protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2) + { + return ModReduce(x1.Multiply(x2)); + } + + protected virtual BigInteger ModReduce(BigInteger x) + { + if (r == null) + { + x = x.Mod(q); + } + else + { + bool negative = x.SignValue < 0; + if (negative) + { + x = x.Abs(); + } + int qLen = q.BitLength; + if (r.SignValue > 0) + { + BigInteger qMod = BigInteger.One.ShiftLeft(qLen); + bool rIsOne = r.Equals(BigInteger.One); + while (x.BitLength > (qLen + 1)) + { + BigInteger u = x.ShiftRight(qLen); + BigInteger v = x.Remainder(qMod); + if (!rIsOne) + { + u = u.Multiply(r); + } + x = u.Add(v); + } + } + else + { + int d = ((qLen - 1) & 31) + 1; + BigInteger mu = r.Negate(); + BigInteger u = mu.Multiply(x.ShiftRight(qLen - d)); + BigInteger quot = u.ShiftRight(qLen + d); + BigInteger v = quot.Multiply(q); + BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d); + v = v.Remainder(bk1); + x = x.Remainder(bk1); + x = x.Subtract(v); + if (x.SignValue < 0) + { + x = x.Add(bk1); + } + } + while (x.CompareTo(q) >= 0) + { + x = x.Subtract(q); + } + if (negative && x.SignValue != 0) + { + x = q.Subtract(x); + } + } + return x; + } + + protected virtual BigInteger ModSubtract(BigInteger x1, BigInteger x2) + { + BigInteger x3 = x1.Subtract(x2); + if (x3.SignValue < 0) + { + x3 = x3.Add(q); + } + return x3; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + FpFieldElement other = obj as FpFieldElement; + + if (other == null) + return false; + + return Equals(other); + } + + public virtual bool Equals( + FpFieldElement other) + { + return q.Equals(other.q) && base.Equals(other); + } + + public override int GetHashCode() + { + return q.GetHashCode() ^ base.GetHashCode(); + } + } + + /** + * Class representing the Elements of the finite field + * F2m in polynomial basis (PB) + * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial + * basis representations are supported. Gaussian normal basis (GNB) + * representation is not supported. + */ + public class F2mFieldElement + : ECFieldElement + { + /** + * Indicates gaussian normal basis representation (GNB). Number chosen + * according to X9.62. GNB is not implemented at present. + */ + public const int Gnb = 1; + + /** + * Indicates trinomial basis representation (Tpb). Number chosen + * according to X9.62. + */ + public const int Tpb = 2; + + /** + * Indicates pentanomial basis representation (Ppb). Number chosen + * according to X9.62. + */ + public const int Ppb = 3; + + /** + * Tpb or Ppb. + */ + private int representation; + + /** + * The exponent m of F2m. + */ + private int m; + + private int[] ks; + + /** + * The LongArray holding the bits. + */ + private LongArray x; + + /** + * Constructor for Ppb. + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param x The BigInteger representing the value of the field element. + */ + public F2mFieldElement( + int m, + int k1, + int k2, + int k3, + BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > m) + throw new ArgumentException("value invalid in F2m field element", "x"); + + if ((k2 == 0) && (k3 == 0)) + { + this.representation = Tpb; + this.ks = new int[] { k1 }; + } + else + { + if (k2 >= k3) + throw new ArgumentException("k2 must be smaller than k3"); + if (k2 <= 0) + throw new ArgumentException("k2 must be larger than 0"); + + this.representation = Ppb; + this.ks = new int[] { k1, k2, k3 }; + } + + this.m = m; + this.x = new LongArray(x); + } + + /** + * Constructor for Tpb. + * @param m The exponent m of + * F2m. + * @param k The integer k where xm + + * xk + 1 represents the reduction + * polynomial f(z). + * @param x The BigInteger representing the value of the field element. + */ + public F2mFieldElement( + int m, + int k, + BigInteger x) + : this(m, k, 0, 0, x) + { + // Set k1 to k, and set k2 and k3 to 0 + } + + private F2mFieldElement(int m, int[] ks, LongArray x) + { + this.m = m; + this.representation = (ks.Length == 1) ? Tpb : Ppb; + this.ks = ks; + this.x = x; + } + + public override int BitLength + { + get { return x.Degree(); } + } + + public override bool IsOne + { + get { return x.IsOne(); } + } + + public override bool IsZero + { + get { return x.IsZero(); } + } + + public override bool TestBitZero() + { + return x.TestBitZero(); + } + + public override BigInteger ToBigInteger() + { + return x.ToBigInteger(); + } + + public override string FieldName + { + get { return "F2m"; } + } + + public override int FieldSize + { + get { return m; } + } + + /** + * Checks, if the ECFieldElements a and b + * are elements of the same field F2m + * (having the same representation). + * @param a field element. + * @param b field element to be compared. + * @throws ArgumentException if a and b + * are not elements of the same field + * F2m (having the same + * representation). + */ + public static void CheckFieldElements( + ECFieldElement a, + ECFieldElement b) + { + if (!(a is F2mFieldElement) || !(b is F2mFieldElement)) + { + throw new ArgumentException("Field elements are not " + + "both instances of F2mFieldElement"); + } + + F2mFieldElement aF2m = (F2mFieldElement)a; + F2mFieldElement bF2m = (F2mFieldElement)b; + + if (aF2m.representation != bF2m.representation) + { + // Should never occur + throw new ArgumentException("One of the F2m field elements has incorrect representation"); + } + + if ((aF2m.m != bF2m.m) || !Arrays.AreEqual(aF2m.ks, bF2m.ks)) + { + throw new ArgumentException("Field elements are not elements of the same field F2m"); + } + } + + public override ECFieldElement Add( + ECFieldElement b) + { + // No check performed here for performance reasons. Instead the + // elements involved are checked in ECPoint.F2m + // checkFieldElements(this, b); + LongArray iarrClone = this.x.Copy(); + F2mFieldElement bF2m = (F2mFieldElement)b; + iarrClone.AddShiftedByWords(bF2m.x, 0); + return new F2mFieldElement(m, ks, iarrClone); + } + + public override ECFieldElement AddOne() + { + return new F2mFieldElement(m, ks, x.AddOne()); + } + + public override ECFieldElement Subtract( + ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply( + ECFieldElement b) + { + // Right-to-left comb multiplication in the LongArray + // Input: Binary polynomials a(z) and b(z) of degree at most m-1 + // Output: c(z) = a(z) * b(z) mod f(z) + + // No check performed here for performance reasons. Instead the + // elements involved are checked in ECPoint.F2m + // checkFieldElements(this, b); + return new F2mFieldElement(m, ks, x.ModMultiply(((F2mFieldElement)b).x, m, ks)); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x; + + LongArray ab = ax.Multiply(bx, m, ks); + LongArray xy = xx.Multiply(yx, m, ks); + + if (ab == ax || ab == bx) + { + ab = (LongArray)ab.Copy(); + } + + ab.AddShiftedByWords(xy, 0); + ab.Reduce(m, ks); + + return new F2mFieldElement(m, ks, ab); + } + + public override ECFieldElement Divide( + ECFieldElement b) + { + // There may be more efficient implementations + ECFieldElement bInv = b.Invert(); + return Multiply(bInv); + } + + public override ECFieldElement Negate() + { + // -x == x holds for all x in F2m + return this; + } + + public override ECFieldElement Square() + { + return new F2mFieldElement(m, ks, x.ModSquare(m, ks)); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x; + + LongArray aa = ax.Square(m, ks); + LongArray xy = xx.Multiply(yx, m, ks); + + if (aa == ax) + { + aa = (LongArray)aa.Copy(); + } + + aa.AddShiftedByWords(xy, 0); + aa.Reduce(m, ks); + + return new F2mFieldElement(m, ks, aa); + } + + public override ECFieldElement SquarePow(int pow) + { + return pow < 1 ? this : new F2mFieldElement(m, ks, x.ModSquareN(pow, m, ks)); + } + + public override ECFieldElement Invert() + { + return new F2mFieldElement(this.m, this.ks, this.x.ModInverse(m, ks)); + } + + public override ECFieldElement Sqrt() + { + return (x.IsZero() || x.IsOne()) ? this : SquarePow(m - 1); + } + + /** + * @return the representation of the field + * F2m, either of + * {@link F2mFieldElement.Tpb} (trinomial + * basis representation) or + * {@link F2mFieldElement.Ppb} (pentanomial + * basis representation). + */ + public int Representation + { + get { return this.representation; } + } + + /** + * @return the degree m of the reduction polynomial + * f(z). + */ + public int M + { + get { return this.m; } + } + + /** + * @return Tpb: The integer k where xm + + * xk + 1 represents the reduction polynomial + * f(z).
    + * Ppb: The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + public int K1 + { + get { return this.ks[0]; } + } + + /** + * @return Tpb: Always returns 0
    + * Ppb: The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + public int K2 + { + get { return this.ks.Length >= 2 ? this.ks[1] : 0; } + } + + /** + * @return Tpb: Always set to 0
    + * Ppb: The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + public int K3 + { + get { return this.ks.Length >= 3 ? this.ks[2] : 0; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + F2mFieldElement other = obj as F2mFieldElement; + + if (other == null) + return false; + + return Equals(other); + } + + public virtual bool Equals( + F2mFieldElement other) + { + return ((this.m == other.m) + && (this.representation == other.representation) + && Arrays.AreEqual(this.ks, other.ks) + && (this.x.Equals(other.x))); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ m ^ Arrays.GetHashCode(ks); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs.meta new file mode 100644 index 0000000..ed0977b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECFieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c83e7d57be27b5d428630a56b05d18a1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs new file mode 100644 index 0000000..5d0f89f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs @@ -0,0 +1,2068 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.Diagnostics; +using System.Text; + +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Math.EC +{ + /** + * base class for points on elliptic curves. + */ + public abstract class ECPoint + { + protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; + + protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) + { + // Cope with null curve, most commonly used by implicitlyCa + int coord = null == curve ? ECCurve.COORD_AFFINE : curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + return EMPTY_ZS; + default: + break; + } + + ECFieldElement one = curve.FromBigInteger(BigInteger.One); + + switch (coord) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + return new ECFieldElement[] { one }; + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + return new ECFieldElement[] { one, one, one }; + case ECCurve.COORD_JACOBIAN_MODIFIED: + return new ECFieldElement[] { one, curve.A }; + default: + throw new ArgumentException("unknown coordinate system"); + } + } + + protected internal readonly ECCurve m_curve; + protected internal readonly ECFieldElement m_x, m_y; + protected internal readonly ECFieldElement[] m_zs; + protected internal readonly bool m_withCompression; + + // Dictionary is (string -> PreCompInfo) + protected internal IDictionary m_preCompTable = null; + + protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : this(curve, x, y, GetInitialZCoords(curve), withCompression) + { + } + + internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + this.m_curve = curve; + this.m_x = x; + this.m_y = y; + this.m_zs = zs; + this.m_withCompression = withCompression; + } + + protected internal bool SatisfiesCofactor() + { + BigInteger h = Curve.Cofactor; + return h == null || h.Equals(BigInteger.One) || !ECAlgorithms.ReferenceMultiply(this, h).IsInfinity; + } + + protected abstract bool SatisfiesCurveEquation(); + + public ECPoint GetDetachedPoint() + { + return Normalize().Detach(); + } + + public virtual ECCurve Curve + { + get { return m_curve; } + } + + protected abstract ECPoint Detach(); + + protected virtual int CurveCoordinateSystem + { + get + { + // Cope with null curve, most commonly used by implicitlyCa + return null == m_curve ? ECCurve.COORD_AFFINE : m_curve.CoordinateSystem; + } + } + + /** + * Normalizes this point, and then returns the affine x-coordinate. + * + * Note: normalization can be expensive, this method is deprecated in favour + * of caller-controlled normalization. + */ + [Obsolete("Use AffineXCoord, or Normalize() and XCoord, instead")] + public virtual ECFieldElement X + { + get { return Normalize().XCoord; } + } + + /** + * Normalizes this point, and then returns the affine y-coordinate. + * + * Note: normalization can be expensive, this method is deprecated in favour + * of caller-controlled normalization. + */ + [Obsolete("Use AffineYCoord, or Normalize() and YCoord, instead")] + public virtual ECFieldElement Y + { + get { return Normalize().YCoord; } + } + + /** + * Returns the affine x-coordinate after checking that this point is normalized. + * + * @return The affine x-coordinate of this point + * @throws IllegalStateException if the point is not normalized + */ + public virtual ECFieldElement AffineXCoord + { + get + { + CheckNormalized(); + return XCoord; + } + } + + /** + * Returns the affine y-coordinate after checking that this point is normalized + * + * @return The affine y-coordinate of this point + * @throws IllegalStateException if the point is not normalized + */ + public virtual ECFieldElement AffineYCoord + { + get + { + CheckNormalized(); + return YCoord; + } + } + + /** + * Returns the x-coordinate. + * + * Caution: depending on the curve's coordinate system, this may not be the same value as in an + * affine coordinate system; use Normalize() to get a point where the coordinates have their + * affine values, or use AffineXCoord if you expect the point to already have been normalized. + * + * @return the x-coordinate of this point + */ + public virtual ECFieldElement XCoord + { + get { return m_x; } + } + + /** + * Returns the y-coordinate. + * + * Caution: depending on the curve's coordinate system, this may not be the same value as in an + * affine coordinate system; use Normalize() to get a point where the coordinates have their + * affine values, or use AffineYCoord if you expect the point to already have been normalized. + * + * @return the y-coordinate of this point + */ + public virtual ECFieldElement YCoord + { + get { return m_y; } + } + + public virtual ECFieldElement GetZCoord(int index) + { + return (index < 0 || index >= m_zs.Length) ? null : m_zs[index]; + } + + public virtual ECFieldElement[] GetZCoords() + { + int zsLen = m_zs.Length; + if (zsLen == 0) + { + return m_zs; + } + ECFieldElement[] copy = new ECFieldElement[zsLen]; + Array.Copy(m_zs, 0, copy, 0, zsLen); + return copy; + } + + protected internal ECFieldElement RawXCoord + { + get { return m_x; } + } + + protected internal ECFieldElement RawYCoord + { + get { return m_y; } + } + + protected internal ECFieldElement[] RawZCoords + { + get { return m_zs; } + } + + protected virtual void CheckNormalized() + { + if (!IsNormalized()) + throw new InvalidOperationException("point not in normal form"); + } + + public virtual bool IsNormalized() + { + int coord = this.CurveCoordinateSystem; + + return coord == ECCurve.COORD_AFFINE + || coord == ECCurve.COORD_LAMBDA_AFFINE + || IsInfinity + || RawZCoords[0].IsOne; + } + + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. + * + * @return a new ECPoint instance representing the same point, but with normalized coordinates + */ + public virtual ECPoint Normalize() + { + if (this.IsInfinity) + { + return this; + } + + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + return this; + } + default: + { + ECFieldElement Z1 = RawZCoords[0]; + if (Z1.IsOne) + { + return this; + } + + return Normalize(Z1.Invert()); + } + } + } + + internal virtual ECPoint Normalize(ECFieldElement zInv) + { + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + return CreateScaledPoint(zInv, zInv); + } + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv); + return CreateScaledPoint(zInv2, zInv3); + } + default: + { + throw new InvalidOperationException("not a projective coordinate system"); + } + } + } + + protected virtual ECPoint CreateScaledPoint(ECFieldElement sx, ECFieldElement sy) + { + return Curve.CreateRawPoint(RawXCoord.Multiply(sx), RawYCoord.Multiply(sy), IsCompressed); + } + + public bool IsInfinity + { + get { return m_x == null && m_y == null; } + } + + public bool IsCompressed + { + get { return m_withCompression; } + } + + public bool IsValid() + { + if (IsInfinity) + return true; + + // TODO Sanity-check the field elements + + ECCurve curve = Curve; + if (curve != null) + { + if (!SatisfiesCurveEquation()) + return false; + + if (!SatisfiesCofactor()) + return false; + } + + return true; + } + + public virtual ECPoint ScaleX(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord, RawZCoords, IsCompressed); + } + + public virtual ECPoint ScaleY(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed); + } + + public override bool Equals(object obj) + { + return Equals(obj as ECPoint); + } + + public virtual bool Equals(ECPoint other) + { + if (this == other) + return true; + if (null == other) + return false; + + ECCurve c1 = this.Curve, c2 = other.Curve; + bool n1 = (null == c1), n2 = (null == c2); + bool i1 = IsInfinity, i2 = other.IsInfinity; + + if (i1 || i2) + { + return (i1 && i2) && (n1 || n2 || c1.Equals(c2)); + } + + ECPoint p1 = this, p2 = other; + if (n1 && n2) + { + // Points with null curve are in affine form, so already normalized + } + else if (n1) + { + p2 = p2.Normalize(); + } + else if (n2) + { + p1 = p1.Normalize(); + } + else if (!c1.Equals(c2)) + { + return false; + } + else + { + // TODO Consider just requiring already normalized, to avoid silent performance degradation + + ECPoint[] points = new ECPoint[] { this, c1.ImportPoint(p2) }; + + // TODO This is a little strong, really only requires coZNormalizeAll to get Zs equal + c1.NormalizeAll(points); + + p1 = points[0]; + p2 = points[1]; + } + + return p1.XCoord.Equals(p2.XCoord) && p1.YCoord.Equals(p2.YCoord); + } + + public override int GetHashCode() + { + ECCurve c = this.Curve; + int hc = (null == c) ? 0 : ~c.GetHashCode(); + + if (!this.IsInfinity) + { + // TODO Consider just requiring already normalized, to avoid silent performance degradation + + ECPoint p = Normalize(); + + hc ^= p.XCoord.GetHashCode() * 17; + hc ^= p.YCoord.GetHashCode() * 257; + } + + return hc; + } + + public override string ToString() + { + if (this.IsInfinity) + { + return "INF"; + } + + StringBuilder sb = new StringBuilder(); + sb.Append('('); + sb.Append(RawXCoord); + sb.Append(','); + sb.Append(RawYCoord); + for (int i = 0; i < m_zs.Length; ++i) + { + sb.Append(','); + sb.Append(m_zs[i]); + } + sb.Append(')'); + return sb.ToString(); + } + + public virtual byte[] GetEncoded() + { + return GetEncoded(m_withCompression); + } + + public abstract byte[] GetEncoded(bool compressed); + + protected internal abstract bool CompressionYTilde { get; } + + public abstract ECPoint Add(ECPoint b); + public abstract ECPoint Subtract(ECPoint b); + public abstract ECPoint Negate(); + + public virtual ECPoint TimesPow2(int e) + { + if (e < 0) + throw new ArgumentException("cannot be negative", "e"); + + ECPoint p = this; + while (--e >= 0) + { + p = p.Twice(); + } + return p; + } + + public abstract ECPoint Twice(); + public abstract ECPoint Multiply(BigInteger b); + + public virtual ECPoint TwicePlus(ECPoint b) + { + return Twice().Add(b); + } + + public virtual ECPoint ThreeTimes() + { + return TwicePlus(this); + } + } + + public abstract class ECPointBase + : ECPoint + { + protected internal ECPointBase( + ECCurve curve, + ECFieldElement x, + ECFieldElement y, + bool withCompression) + : base(curve, x, y, withCompression) + { + } + + protected internal ECPointBase(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + /** + * return the field element encoded with point compression. (S 4.3.6) + */ + public override byte[] GetEncoded(bool compressed) + { + if (this.IsInfinity) + { + return new byte[1]; + } + + ECPoint normed = Normalize(); + + byte[] X = normed.XCoord.GetEncoded(); + + if (compressed) + { + byte[] PO = new byte[X.Length + 1]; + PO[0] = (byte)(normed.CompressionYTilde ? 0x03 : 0x02); + Array.Copy(X, 0, PO, 1, X.Length); + return PO; + } + + byte[] Y = normed.YCoord.GetEncoded(); + + { + byte[] PO = new byte[X.Length + Y.Length + 1]; + PO[0] = 0x04; + Array.Copy(X, 0, PO, 1, X.Length); + Array.Copy(Y, 0, PO, X.Length + 1, Y.Length); + return PO; + } + } + + /** + * Multiplies this ECPoint by the given number. + * @param k The multiplicator. + * @return k * this. + */ + public override ECPoint Multiply(BigInteger k) + { + return this.Curve.GetMultiplier().Multiply(this, k); + } + } + + public abstract class AbstractFpPoint + : ECPointBase + { + protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + } + + protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected internal override bool CompressionYTilde + { + get { return this.AffineYCoord.TestBitZero(); } + } + + protected override bool SatisfiesCurveEquation() + { + ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = Curve.A, B = Curve.B; + ECFieldElement lhs = Y.Square(); + + switch (CurveCoordinateSystem) + { + case ECCurve.COORD_AFFINE: + break; + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z = this.RawZCoords[0]; + if (!Z.IsOne) + { + ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2); + lhs = lhs.Multiply(Z); + A = A.Multiply(Z2); + B = B.Multiply(Z3); + } + break; + } + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement Z = this.RawZCoords[0]; + if (!Z.IsOne) + { + ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square(), Z6 = Z2.Multiply(Z4); + A = A.Multiply(Z4); + B = B.Multiply(Z6); + } + break; + } + default: + throw new InvalidOperationException("unsupported coordinate system"); + } + + ECFieldElement rhs = X.Square().Add(A).Multiply(X).Add(B); + return lhs.Equals(rhs); + } + + public override ECPoint Subtract(ECPoint b) + { + if (b.IsInfinity) + return this; + + // Add -b + return Add(b.Negate()); + } + } + + /** + * Elliptic curve points over Fp + */ + public class FpPoint + : AbstractFpPoint + { + /** + * Create a point which encodes without point compression. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + */ + public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compression. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + * @param withCompression if true encode with point compression + */ + public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new FpPoint(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement GetZCoord(int index) + { + if (index == 1 && ECCurve.COORD_JACOBIAN_MODIFIED == this.CurveCoordinateSystem) + { + return GetJacobianModifiedW(); + } + + return base.GetZCoord(index); + } + + // B.3 pg 62 + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord; + ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + + if (dx.IsZero) + { + if (dy.IsZero) + { + // this == b, i.e. this must be doubled + return Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return Curve.Infinity; + } + + ECFieldElement gamma = dy.Divide(dx); + ECFieldElement X3 = gamma.Square().Subtract(X1).Subtract(X2); + ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + + return new FpPoint(Curve, X3, Y3, IsCompressed); + } + + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z1 = this.RawZCoords[0]; + ECFieldElement Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + bool Z2IsOne = Z2.IsOne; + + ECFieldElement u1 = Z1IsOne ? Y2 : Y2.Multiply(Z1); + ECFieldElement u2 = Z2IsOne ? Y1 : Y1.Multiply(Z2); + ECFieldElement u = u1.Subtract(u2); + ECFieldElement v1 = Z1IsOne ? X2 : X2.Multiply(Z1); + ECFieldElement v2 = Z2IsOne ? X1 : X1.Multiply(Z2); + ECFieldElement v = v1.Subtract(v2); + + // Check if b == this or b == -this + if (v.IsZero) + { + if (u.IsZero) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + // TODO Optimize for when w == 1 + ECFieldElement w = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2); + ECFieldElement vSquared = v.Square(); + ECFieldElement vCubed = vSquared.Multiply(v); + ECFieldElement vSquaredV2 = vSquared.Multiply(v2); + ECFieldElement A = u.Square().Multiply(w).Subtract(vCubed).Subtract(Two(vSquaredV2)); + + ECFieldElement X3 = v.Multiply(A); + ECFieldElement Y3 = vSquaredV2.Subtract(A).MultiplyMinusProduct(u, u2, vCubed); + ECFieldElement Z3 = vCubed.Multiply(w); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement Z1 = this.RawZCoords[0]; + ECFieldElement Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + + ECFieldElement X3, Y3, Z3, Z3Squared = null; + + if (!Z1IsOne && Z1.Equals(Z2)) + { + // TODO Make this available as public method coZAdd? + + ECFieldElement dx = X1.Subtract(X2), dy = Y1.Subtract(Y2); + if (dx.IsZero) + { + if (dy.IsZero) + { + return Twice(); + } + return curve.Infinity; + } + + ECFieldElement C = dx.Square(); + ECFieldElement W1 = X1.Multiply(C), W2 = X2.Multiply(C); + ECFieldElement A1 = W1.Subtract(W2).Multiply(Y1); + + X3 = dy.Square().Subtract(W1).Subtract(W2); + Y3 = W1.Subtract(X3).Multiply(dy).Subtract(A1); + Z3 = dx; + + if (Z1IsOne) + { + Z3Squared = C; + } + else + { + Z3 = Z3.Multiply(Z1); + } + } + else + { + ECFieldElement Z1Squared, U2, S2; + if (Z1IsOne) + { + Z1Squared = Z1; U2 = X2; S2 = Y2; + } + else + { + Z1Squared = Z1.Square(); + U2 = Z1Squared.Multiply(X2); + ECFieldElement Z1Cubed = Z1Squared.Multiply(Z1); + S2 = Z1Cubed.Multiply(Y2); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement Z2Squared, U1, S1; + if (Z2IsOne) + { + Z2Squared = Z2; U1 = X1; S1 = Y1; + } + else + { + Z2Squared = Z2.Square(); + U1 = Z2Squared.Multiply(X1); + ECFieldElement Z2Cubed = Z2Squared.Multiply(Z2); + S1 = Z2Cubed.Multiply(Y1); + } + + ECFieldElement H = U1.Subtract(U2); + ECFieldElement R = S1.Subtract(S2); + + // Check if b == this or b == -this + if (H.IsZero) + { + if (R.IsZero) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + ECFieldElement HSquared = H.Square(); + ECFieldElement G = HSquared.Multiply(H); + ECFieldElement V = HSquared.Multiply(U1); + + X3 = R.Square().Add(G).Subtract(Two(V)); + Y3 = V.Subtract(X3).MultiplyMinusProduct(R, G, S1); + + Z3 = H; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + if (!Z2IsOne) + { + Z3 = Z3.Multiply(Z2); + } + + // Alternative calculation of Z3 using fast square + //X3 = four(X3); + //Y3 = eight(Y3); + //Z3 = doubleProductFromSquares(Z1, Z2, Z1Squared, Z2Squared).Multiply(H); + + if (Z3 == H) + { + Z3Squared = HSquared; + } + } + + ECFieldElement[] zs; + if (coord == ECCurve.COORD_JACOBIAN_MODIFIED) + { + // TODO If the result will only be used in a subsequent addition, we don't need W3 + ECFieldElement W3 = CalculateJacobianModifiedW(Z3, Z3Squared); + + zs = new ECFieldElement[] { Z3, W3 }; + } + else + { + zs = new ECFieldElement[] { Z3 }; + } + + return new FpPoint(curve, X3, Y3, zs, IsCompressed); + } + + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + // B.3 pg 62 + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1Squared = X1.Square(); + ECFieldElement gamma = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1)); + ECFieldElement X3 = gamma.Square().Subtract(Two(X1)); + ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + + return new FpPoint(Curve, X3, Y3, IsCompressed); + } + + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + + // TODO Optimize for small negative a4 and -3 + ECFieldElement w = curve.A; + if (!w.IsZero && !Z1IsOne) + { + w = w.Multiply(Z1.Square()); + } + w = w.Add(Three(X1.Square())); + + ECFieldElement s = Z1IsOne ? Y1 : Y1.Multiply(Z1); + ECFieldElement t = Z1IsOne ? Y1.Square() : s.Multiply(Y1); + ECFieldElement B = X1.Multiply(t); + ECFieldElement _4B = Four(B); + ECFieldElement h = w.Square().Subtract(Two(_4B)); + + ECFieldElement _2s = Two(s); + ECFieldElement X3 = h.Multiply(_2s); + ECFieldElement _2t = Two(t); + ECFieldElement Y3 = _4B.Subtract(h).Multiply(w).Subtract(Two(_2t.Square())); + ECFieldElement _4sSquared = Z1IsOne ? Two(_2t) : _2s.Square(); + ECFieldElement Z3 = Two(_4sSquared).Multiply(s); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + case ECCurve.COORD_JACOBIAN: + { + ECFieldElement Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + + ECFieldElement Y1Squared = Y1.Square(); + ECFieldElement T = Y1Squared.Square(); + + ECFieldElement a4 = curve.A; + ECFieldElement a4Neg = a4.Negate(); + + ECFieldElement M, S; + if (a4Neg.ToBigInteger().Equals(BigInteger.ValueOf(3))) + { + ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square(); + M = Three(X1.Add(Z1Squared).Multiply(X1.Subtract(Z1Squared))); + S = Four(Y1Squared.Multiply(X1)); + } + else + { + ECFieldElement X1Squared = X1.Square(); + M = Three(X1Squared); + if (Z1IsOne) + { + M = M.Add(a4); + } + else if (!a4.IsZero) + { + ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement Z1Pow4 = Z1Squared.Square(); + if (a4Neg.BitLength < a4.BitLength) + { + M = M.Subtract(Z1Pow4.Multiply(a4Neg)); + } + else + { + M = M.Add(Z1Pow4.Multiply(a4)); + } + } + //S = two(doubleProductFromSquares(X1, Y1Squared, X1Squared, T)); + S = Four(X1.Multiply(Y1Squared)); + } + + ECFieldElement X3 = M.Square().Subtract(Two(S)); + ECFieldElement Y3 = S.Subtract(X3).Multiply(M).Subtract(Eight(T)); + + ECFieldElement Z3 = Two(Y1); + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + + // Alternative calculation of Z3 using fast square + //ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + return TwiceJacobianModified(true); + } + + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord; + + ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + + if (dx.IsZero) + { + if (dy.IsZero) + { + // this == b i.e. the result is 3P + return ThreeTimes(); + } + + // this == -b, i.e. the result is P + return this; + } + + /* + * Optimized calculation of 2P + Q, as described in "Trading Inversions for + * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery. + */ + + ECFieldElement X = dx.Square(), Y = dy.Square(); + ECFieldElement d = X.Multiply(Two(X1).Add(X2)).Subtract(Y); + if (d.IsZero) + { + return Curve.Infinity; + } + + ECFieldElement D = d.Multiply(dx); + ECFieldElement I = D.Invert(); + ECFieldElement L1 = d.Multiply(I).Multiply(dy); + ECFieldElement L2 = Two(Y1).Multiply(X).Multiply(dx).Multiply(I).Subtract(L1); + ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X2); + ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + + return new FpPoint(Curve, X4, Y4, IsCompressed); + } + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + return TwiceJacobianModified(false).Add(b); + } + default: + { + return Twice().Add(b); + } + } + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity) + return this; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1 = this.RawXCoord; + + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement X = _2Y1.Square(); + ECFieldElement Z = Three(X1.Square()).Add(Curve.A); + ECFieldElement Y = Z.Square(); + + ECFieldElement d = Three(X1).Multiply(X).Subtract(Y); + if (d.IsZero) + { + return Curve.Infinity; + } + + ECFieldElement D = d.Multiply(_2Y1); + ECFieldElement I = D.Invert(); + ECFieldElement L1 = d.Multiply(I).Multiply(Z); + ECFieldElement L2 = X.Square().Multiply(I).Subtract(L1); + + ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X1); + ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + return new FpPoint(Curve, X4, Y4, IsCompressed); + } + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + return TwiceJacobianModified(false).Add(this); + } + default: + { + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + } + } + + public override ECPoint TimesPow2(int e) + { + if (e < 0) + throw new ArgumentException("cannot be negative", "e"); + if (e == 0 || this.IsInfinity) + return this; + if (e == 1) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + int coord = curve.CoordinateSystem; + + ECFieldElement W1 = curve.A; + ECFieldElement X1 = this.RawXCoord; + ECFieldElement Z1 = this.RawZCoords.Length < 1 ? curve.FromBigInteger(BigInteger.One) : this.RawZCoords[0]; + + if (!Z1.IsOne) + { + switch (coord) + { + case ECCurve.COORD_HOMOGENEOUS: + ECFieldElement Z1Sq = Z1.Square(); + X1 = X1.Multiply(Z1); + Y1 = Y1.Multiply(Z1Sq); + W1 = CalculateJacobianModifiedW(Z1, Z1Sq); + break; + case ECCurve.COORD_JACOBIAN: + W1 = CalculateJacobianModifiedW(Z1, null); + break; + case ECCurve.COORD_JACOBIAN_MODIFIED: + W1 = GetJacobianModifiedW(); + break; + } + } + + for (int i = 0; i < e; ++i) + { + if (Y1.IsZero) + return curve.Infinity; + + ECFieldElement X1Squared = X1.Square(); + ECFieldElement M = Three(X1Squared); + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement _2Y1Squared = _2Y1.Multiply(Y1); + ECFieldElement S = Two(X1.Multiply(_2Y1Squared)); + ECFieldElement _4T = _2Y1Squared.Square(); + ECFieldElement _8T = Two(_4T); + + if (!W1.IsZero) + { + M = M.Add(W1); + W1 = Two(_8T.Multiply(W1)); + } + + X1 = M.Square().Subtract(Two(S)); + Y1 = M.Multiply(S.Subtract(X1)).Subtract(_8T); + Z1 = Z1.IsOne ? _2Y1 : _2Y1.Multiply(Z1); + } + + switch (coord) + { + case ECCurve.COORD_AFFINE: + ECFieldElement zInv = Z1.Invert(), zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv); + return new FpPoint(curve, X1.Multiply(zInv2), Y1.Multiply(zInv3), IsCompressed); + case ECCurve.COORD_HOMOGENEOUS: + X1 = X1.Multiply(Z1); + Z1 = Z1.Multiply(Z1.Square()); + return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1 }, IsCompressed); + case ECCurve.COORD_JACOBIAN: + return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1 }, IsCompressed); + case ECCurve.COORD_JACOBIAN_MODIFIED: + return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1, W1 }, IsCompressed); + default: + throw new InvalidOperationException("unsupported coordinate system"); + } + } + + protected virtual ECFieldElement Two(ECFieldElement x) + { + return x.Add(x); + } + + protected virtual ECFieldElement Three(ECFieldElement x) + { + return Two(x).Add(x); + } + + protected virtual ECFieldElement Four(ECFieldElement x) + { + return Two(Two(x)); + } + + protected virtual ECFieldElement Eight(ECFieldElement x) + { + return Four(Two(x)); + } + + protected virtual ECFieldElement DoubleProductFromSquares(ECFieldElement a, ECFieldElement b, + ECFieldElement aSquared, ECFieldElement bSquared) + { + /* + * NOTE: If squaring in the field is faster than multiplication, then this is a quicker + * way to calculate 2.A.B, if A^2 and B^2 are already known. + */ + return a.Add(b).Square().Subtract(aSquared).Subtract(bSquared); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECCurve curve = Curve; + int coord = curve.CoordinateSystem; + + if (ECCurve.COORD_AFFINE != coord) + { + return new FpPoint(curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + + return new FpPoint(curve, RawXCoord, RawYCoord.Negate(), IsCompressed); + } + + protected virtual ECFieldElement CalculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared) + { + ECFieldElement a4 = this.Curve.A; + if (a4.IsZero || Z.IsOne) + return a4; + + if (ZSquared == null) + { + ZSquared = Z.Square(); + } + + ECFieldElement W = ZSquared.Square(); + ECFieldElement a4Neg = a4.Negate(); + if (a4Neg.BitLength < a4.BitLength) + { + W = W.Multiply(a4Neg).Negate(); + } + else + { + W = W.Multiply(a4); + } + return W; + } + + protected virtual ECFieldElement GetJacobianModifiedW() + { + ECFieldElement[] ZZ = this.RawZCoords; + ECFieldElement W = ZZ[1]; + if (W == null) + { + // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here + ZZ[1] = W = CalculateJacobianModifiedW(ZZ[0], null); + } + return W; + } + + protected virtual FpPoint TwiceJacobianModified(bool calculateW) + { + ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord, Z1 = this.RawZCoords[0], W1 = GetJacobianModifiedW(); + + ECFieldElement X1Squared = X1.Square(); + ECFieldElement M = Three(X1Squared).Add(W1); + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement _2Y1Squared = _2Y1.Multiply(Y1); + ECFieldElement S = Two(X1.Multiply(_2Y1Squared)); + ECFieldElement X3 = M.Square().Subtract(Two(S)); + ECFieldElement _4T = _2Y1Squared.Square(); + ECFieldElement _8T = Two(_4T); + ECFieldElement Y3 = M.Multiply(S.Subtract(X3)).Subtract(_8T); + ECFieldElement W3 = calculateW ? Two(_8T.Multiply(W1)) : null; + ECFieldElement Z3 = Z1.IsOne ? _2Y1 : _2Y1.Multiply(Z1); + + return new FpPoint(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 }, IsCompressed); + } + } + + public abstract class AbstractF2mPoint + : ECPointBase + { + protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + } + + protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override bool SatisfiesCurveEquation() + { + ECCurve curve = Curve; + ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = curve.A, B = curve.B; + ECFieldElement lhs, rhs; + + int coord = curve.CoordinateSystem; + if (coord == ECCurve.COORD_LAMBDA_PROJECTIVE) + { + ECFieldElement Z = this.RawZCoords[0]; + bool ZIsOne = Z.IsOne; + + if (X.IsZero) + { + // NOTE: For x == 0, we expect the affine-y instead of the lambda-y + lhs = Y.Square(); + rhs = B; + if (!ZIsOne) + { + ECFieldElement Z2 = Z.Square(); + rhs = rhs.Multiply(Z2); + } + } + else + { + ECFieldElement L = Y, X2 = X.Square(); + if (ZIsOne) + { + lhs = L.Square().Add(L).Add(A); + rhs = X2.Square().Add(B); + } + else + { + ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square(); + lhs = L.Add(Z).MultiplyPlusProduct(L, A, Z2); + // TODO If sqrt(b) is precomputed this can be simplified to a single square + rhs = X2.SquarePlusProduct(B, Z4); + } + lhs = lhs.Multiply(X2); + } + } + else + { + lhs = Y.Add(X).Multiply(Y); + + switch (coord) + { + case ECCurve.COORD_AFFINE: + break; + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z = this.RawZCoords[0]; + if (!Z.IsOne) + { + ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2); + lhs = lhs.Multiply(Z); + A = A.Multiply(Z); + B = B.Multiply(Z3); + } + break; + } + default: + throw new InvalidOperationException("unsupported coordinate system"); + } + + rhs = X.Add(A).Multiply(X.Square()).Add(B); + } + + return lhs.Equals(rhs); + } + + public override ECPoint ScaleX(ECFieldElement scale) + { + if (this.IsInfinity) + return this; + + switch (CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + { + // Y is actually Lambda (X + Y/X) here + ECFieldElement X = RawXCoord, L = RawYCoord; + + ECFieldElement X2 = X.Multiply(scale); + ECFieldElement L2 = L.Add(X).Divide(scale).Add(X2); + + return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // Y is actually Lambda (X + Y/X) here + ECFieldElement X = RawXCoord, L = RawYCoord, Z = RawZCoords[0]; + + // We scale the Z coordinate also, to avoid an inversion + ECFieldElement X2 = X.Multiply(scale.Square()); + ECFieldElement L2 = L.Add(X).Add(X2); + ECFieldElement Z2 = Z.Multiply(scale); + + return Curve.CreateRawPoint(X, L2, new ECFieldElement[] { Z2 }, IsCompressed); + } + default: + { + return base.ScaleX(scale); + } + } + } + + public override ECPoint ScaleY(ECFieldElement scale) + { + if (this.IsInfinity) + return this; + + switch (CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + // Y is actually Lambda (X + Y/X) here + ECFieldElement L2 = L.Add(X).Multiply(scale).Add(X); + + return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed); + } + default: + { + return base.ScaleY(scale); + } + } + } + + public override ECPoint Subtract(ECPoint b) + { + if (b.IsInfinity) + return this; + + // Add -b + return Add(b.Negate()); + } + + public virtual AbstractF2mPoint Tau() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.Square(), Y1.Square(), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.Square(), Y1.Square(), + new ECFieldElement[] { Z1.Square() }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + public virtual AbstractF2mPoint TauPow(int pow) + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.SquarePow(pow), Y1.SquarePow(pow), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.SquarePow(pow), Y1.SquarePow(pow), + new ECFieldElement[] { Z1.SquarePow(pow) }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + } + + /** + * Elliptic curve points over F2m + */ + public class F2mPoint + : AbstractF2mPoint + { + /** + * @param curve base curve + * @param x x point + * @param y y point + */ + public F2mPoint( + ECCurve curve, + ECFieldElement x, + ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @param curve base curve + * @param x x point + * @param y y point + * @param withCompression true if encode with point compression. + */ + public F2mPoint( + ECCurve curve, + ECFieldElement x, + ECFieldElement y, + bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + { + throw new ArgumentException("Exactly one of the field elements is null"); + } + + if (x != null) + { + // Check if x and y are elements of the same field + F2mFieldElement.CheckFieldElements(x, y); + + // Check if x and a are elements of the same field + if (curve != null) + { + F2mFieldElement.CheckFieldElements(x, curve.A); + } + } + } + + internal F2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + /** + * Constructor for point at infinity + */ + [Obsolete("Use ECCurve.Infinity property")] + public F2mPoint( + ECCurve curve) + : this(curve, null, null) + { + } + + protected override ECPoint Detach() + { + return new F2mPoint(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + int coord = this.CurveCoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + if (ECCurve.COORD_LAMBDA_PROJECTIVE == coord) + { + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + } + return Y; + } + default: + { + return RawYCoord; + } + } + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + { + return false; + } + + ECFieldElement Y = this.RawYCoord; + + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + default: + { + return Y.Divide(X).TestBitZero(); + } + } + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + ECFieldElement Y2 = b.RawYCoord; + + ECFieldElement dx = X1.Add(X2), dy = Y1.Add(Y2); + if (dx.IsZero) + { + if (dy.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement L = dy.Divide(dx); + + ECFieldElement X3 = L.Square().Add(L).Add(dx).Add(curve.A); + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + + return new F2mPoint(curve, X3, Y3, IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement Y2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U1 = Y2, V1 = X2; + if (!Z1IsOne) + { + U1 = U1.Multiply(Z1); + V1 = V1.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U2 = Y1, V2 = X1; + if (!Z2IsOne) + { + U2 = U2.Multiply(Z2); + V2 = V2.Multiply(Z2); + } + + ECFieldElement U = U1.Add(U2); + ECFieldElement V = V1.Add(V2); + + if (V.IsZero) + { + if (U.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement VSq = V.Square(); + ECFieldElement VCu = VSq.Multiply(V); + ECFieldElement W = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2); + ECFieldElement uv = U.Add(V); + ECFieldElement A = uv.MultiplyPlusProduct(U, VSq, curve.A).Multiply(W).Add(VCu); + + ECFieldElement X3 = V.Multiply(A); + ECFieldElement VSqZ2 = Z2IsOne ? VSq : VSq.Multiply(Z2); + ECFieldElement Y3 = U.MultiplyPlusProduct(X1, V, Y1).MultiplyPlusProduct(VSqZ2, uv, A); + ECFieldElement Z3 = VCu.Multiply(W); + + return new F2mPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.RawXCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + /* (non-Javadoc) + * @see Org.BouncyCastle.Math.EC.ECPoint#twice() + */ + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own additive inverse + return curve.Infinity; + } + + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + + ECFieldElement L1 = Y1.Divide(X1).Add(X1); + + ECFieldElement X3 = L1.Square().Add(L1).Add(curve.A); + ECFieldElement Y3 = X1.SquarePlusProduct(X3, L1.AddOne()); + + return new F2mPoint(curve, X3, Y3, IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement Y1Z1 = Z1IsOne ? Y1 : Y1.Multiply(Z1); + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement S = X1Sq.Add(Y1Z1); + ECFieldElement V = X1Z1; + ECFieldElement vSquared = V.Square(); + ECFieldElement sv = S.Add(V); + ECFieldElement h = sv.MultiplyPlusProduct(S, vSquared, curve.A); + + ECFieldElement X3 = V.Multiply(h); + ECFieldElement Y3 = X1Sq.Square().MultiplyPlusProduct(V, h, sv); + ECFieldElement Z3 = V.Multiply(vSquared); + + return new F2mPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new F2mPoint(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement b = curve.B; + ECFieldElement L3; + if (b.BitLength < (curve.FieldSize >> 1)) + { + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2; + if (b.IsOne) + { + t2 = aZ1Sq.Add(Z1Sq).Square(); + } + else + { + // TODO Can be calculated with one square if we pre-compute sqrt(b) + t2 = aZ1Sq.SquarePlusProduct(b, Z1Sq.Square()); + } + L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3); + if (a.IsZero) + { + L3 = L3.Add(Z3); + } + else if (!a.IsOne) + { + L3 = L3.Add(a.AddOne().Multiply(Z3)); + } + } + else + { + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + } + + return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own additive inverse + return b; + } + + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // NOTE: twicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + { + return b.Twice(); + } + + return curve.Infinity; + } + + if (A.IsZero) + { + return new F2mPoint(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + default: + { + return Twice().Add(b); + } + } + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement Y = this.RawYCoord; + return new F2mPoint(curve, X, Y.Add(X), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Y = this.RawYCoord, Z = this.RawZCoords[0]; + return new F2mPoint(curve, X, Y.Add(X), new ECFieldElement[] { Z }, IsCompressed); + } + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement L = this.RawYCoord; + return new F2mPoint(curve, X, L.AddOne(), IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new F2mPoint(curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs.meta new file mode 100644 index 0000000..07c52c5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPoint.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0708bb98a46600e47b0eee7ea6b0d44d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs new file mode 100644 index 0000000..8ee47af --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs @@ -0,0 +1,13 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public interface ECPointMap + { + ECPoint Map(ECPoint p); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs.meta new file mode 100644 index 0000000..7aaea14 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ECPointMap.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b16b78238477b4749b0ad4ff2a2bcf28 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs new file mode 100644 index 0000000..ba527b5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs @@ -0,0 +1,2205 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC +{ + internal class LongArray + { + //private static long DEInterleave_MASK = 0x5555555555555555L; + + /* + * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits. + * In a binary field, this operation is the same as squaring an 8 bit number. + */ + private static readonly ushort[] INTERLEAVE2_TABLE = new ushort[] + { + 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, + 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, + 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, + 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, + 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, + 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, + 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, + 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, + 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, + 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, + 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, + 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, + 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, + 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, + 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, + 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, + 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, + 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, + 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, + 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, + 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, + 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, + 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, + 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, + 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, + 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, + 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, + 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, + 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, + 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, + 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, + 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 + }; + + /* + * This expands 7 bit indices into 21 bit contents (high bit 18), by inserting 0s between bits. + */ + private static readonly int[] INTERLEAVE3_TABLE = new int[] + { + 0x00000, 0x00001, 0x00008, 0x00009, 0x00040, 0x00041, 0x00048, 0x00049, + 0x00200, 0x00201, 0x00208, 0x00209, 0x00240, 0x00241, 0x00248, 0x00249, + 0x01000, 0x01001, 0x01008, 0x01009, 0x01040, 0x01041, 0x01048, 0x01049, + 0x01200, 0x01201, 0x01208, 0x01209, 0x01240, 0x01241, 0x01248, 0x01249, + 0x08000, 0x08001, 0x08008, 0x08009, 0x08040, 0x08041, 0x08048, 0x08049, + 0x08200, 0x08201, 0x08208, 0x08209, 0x08240, 0x08241, 0x08248, 0x08249, + 0x09000, 0x09001, 0x09008, 0x09009, 0x09040, 0x09041, 0x09048, 0x09049, + 0x09200, 0x09201, 0x09208, 0x09209, 0x09240, 0x09241, 0x09248, 0x09249, + 0x40000, 0x40001, 0x40008, 0x40009, 0x40040, 0x40041, 0x40048, 0x40049, + 0x40200, 0x40201, 0x40208, 0x40209, 0x40240, 0x40241, 0x40248, 0x40249, + 0x41000, 0x41001, 0x41008, 0x41009, 0x41040, 0x41041, 0x41048, 0x41049, + 0x41200, 0x41201, 0x41208, 0x41209, 0x41240, 0x41241, 0x41248, 0x41249, + 0x48000, 0x48001, 0x48008, 0x48009, 0x48040, 0x48041, 0x48048, 0x48049, + 0x48200, 0x48201, 0x48208, 0x48209, 0x48240, 0x48241, 0x48248, 0x48249, + 0x49000, 0x49001, 0x49008, 0x49009, 0x49040, 0x49041, 0x49048, 0x49049, + 0x49200, 0x49201, 0x49208, 0x49209, 0x49240, 0x49241, 0x49248, 0x49249 + }; + + /* + * This expands 8 bit indices into 32 bit contents (high bit 28), by inserting 0s between bits. + */ + private static readonly int[] INTERLEAVE4_TABLE = new int[] + { + 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, 0x00000101, 0x00000110, 0x00000111, + 0x00001000, 0x00001001, 0x00001010, 0x00001011, 0x00001100, 0x00001101, 0x00001110, 0x00001111, + 0x00010000, 0x00010001, 0x00010010, 0x00010011, 0x00010100, 0x00010101, 0x00010110, 0x00010111, + 0x00011000, 0x00011001, 0x00011010, 0x00011011, 0x00011100, 0x00011101, 0x00011110, 0x00011111, + 0x00100000, 0x00100001, 0x00100010, 0x00100011, 0x00100100, 0x00100101, 0x00100110, 0x00100111, + 0x00101000, 0x00101001, 0x00101010, 0x00101011, 0x00101100, 0x00101101, 0x00101110, 0x00101111, + 0x00110000, 0x00110001, 0x00110010, 0x00110011, 0x00110100, 0x00110101, 0x00110110, 0x00110111, + 0x00111000, 0x00111001, 0x00111010, 0x00111011, 0x00111100, 0x00111101, 0x00111110, 0x00111111, + 0x01000000, 0x01000001, 0x01000010, 0x01000011, 0x01000100, 0x01000101, 0x01000110, 0x01000111, + 0x01001000, 0x01001001, 0x01001010, 0x01001011, 0x01001100, 0x01001101, 0x01001110, 0x01001111, + 0x01010000, 0x01010001, 0x01010010, 0x01010011, 0x01010100, 0x01010101, 0x01010110, 0x01010111, + 0x01011000, 0x01011001, 0x01011010, 0x01011011, 0x01011100, 0x01011101, 0x01011110, 0x01011111, + 0x01100000, 0x01100001, 0x01100010, 0x01100011, 0x01100100, 0x01100101, 0x01100110, 0x01100111, + 0x01101000, 0x01101001, 0x01101010, 0x01101011, 0x01101100, 0x01101101, 0x01101110, 0x01101111, + 0x01110000, 0x01110001, 0x01110010, 0x01110011, 0x01110100, 0x01110101, 0x01110110, 0x01110111, + 0x01111000, 0x01111001, 0x01111010, 0x01111011, 0x01111100, 0x01111101, 0x01111110, 0x01111111, + 0x10000000, 0x10000001, 0x10000010, 0x10000011, 0x10000100, 0x10000101, 0x10000110, 0x10000111, + 0x10001000, 0x10001001, 0x10001010, 0x10001011, 0x10001100, 0x10001101, 0x10001110, 0x10001111, + 0x10010000, 0x10010001, 0x10010010, 0x10010011, 0x10010100, 0x10010101, 0x10010110, 0x10010111, + 0x10011000, 0x10011001, 0x10011010, 0x10011011, 0x10011100, 0x10011101, 0x10011110, 0x10011111, + 0x10100000, 0x10100001, 0x10100010, 0x10100011, 0x10100100, 0x10100101, 0x10100110, 0x10100111, + 0x10101000, 0x10101001, 0x10101010, 0x10101011, 0x10101100, 0x10101101, 0x10101110, 0x10101111, + 0x10110000, 0x10110001, 0x10110010, 0x10110011, 0x10110100, 0x10110101, 0x10110110, 0x10110111, + 0x10111000, 0x10111001, 0x10111010, 0x10111011, 0x10111100, 0x10111101, 0x10111110, 0x10111111, + 0x11000000, 0x11000001, 0x11000010, 0x11000011, 0x11000100, 0x11000101, 0x11000110, 0x11000111, + 0x11001000, 0x11001001, 0x11001010, 0x11001011, 0x11001100, 0x11001101, 0x11001110, 0x11001111, + 0x11010000, 0x11010001, 0x11010010, 0x11010011, 0x11010100, 0x11010101, 0x11010110, 0x11010111, + 0x11011000, 0x11011001, 0x11011010, 0x11011011, 0x11011100, 0x11011101, 0x11011110, 0x11011111, + 0x11100000, 0x11100001, 0x11100010, 0x11100011, 0x11100100, 0x11100101, 0x11100110, 0x11100111, + 0x11101000, 0x11101001, 0x11101010, 0x11101011, 0x11101100, 0x11101101, 0x11101110, 0x11101111, + 0x11110000, 0x11110001, 0x11110010, 0x11110011, 0x11110100, 0x11110101, 0x11110110, 0x11110111, + 0x11111000, 0x11111001, 0x11111010, 0x11111011, 0x11111100, 0x11111101, 0x11111110, 0x11111111 + }; + + /* + * This expands 7 bit indices into 35 bit contents (high bit 30), by inserting 0s between bits. + */ + private static readonly int[] INTERLEAVE5_TABLE = new int[] { + 0x00000000, 0x00000001, 0x00000020, 0x00000021, 0x00000400, 0x00000401, 0x00000420, 0x00000421, + 0x00008000, 0x00008001, 0x00008020, 0x00008021, 0x00008400, 0x00008401, 0x00008420, 0x00008421, + 0x00100000, 0x00100001, 0x00100020, 0x00100021, 0x00100400, 0x00100401, 0x00100420, 0x00100421, + 0x00108000, 0x00108001, 0x00108020, 0x00108021, 0x00108400, 0x00108401, 0x00108420, 0x00108421, + 0x02000000, 0x02000001, 0x02000020, 0x02000021, 0x02000400, 0x02000401, 0x02000420, 0x02000421, + 0x02008000, 0x02008001, 0x02008020, 0x02008021, 0x02008400, 0x02008401, 0x02008420, 0x02008421, + 0x02100000, 0x02100001, 0x02100020, 0x02100021, 0x02100400, 0x02100401, 0x02100420, 0x02100421, + 0x02108000, 0x02108001, 0x02108020, 0x02108021, 0x02108400, 0x02108401, 0x02108420, 0x02108421, + 0x40000000, 0x40000001, 0x40000020, 0x40000021, 0x40000400, 0x40000401, 0x40000420, 0x40000421, + 0x40008000, 0x40008001, 0x40008020, 0x40008021, 0x40008400, 0x40008401, 0x40008420, 0x40008421, + 0x40100000, 0x40100001, 0x40100020, 0x40100021, 0x40100400, 0x40100401, 0x40100420, 0x40100421, + 0x40108000, 0x40108001, 0x40108020, 0x40108021, 0x40108400, 0x40108401, 0x40108420, 0x40108421, + 0x42000000, 0x42000001, 0x42000020, 0x42000021, 0x42000400, 0x42000401, 0x42000420, 0x42000421, + 0x42008000, 0x42008001, 0x42008020, 0x42008021, 0x42008400, 0x42008401, 0x42008420, 0x42008421, + 0x42100000, 0x42100001, 0x42100020, 0x42100021, 0x42100400, 0x42100401, 0x42100420, 0x42100421, + 0x42108000, 0x42108001, 0x42108020, 0x42108021, 0x42108400, 0x42108401, 0x42108420, 0x42108421 + }; + + /* + * This expands 9 bit indices into 63 bit (long) contents (high bit 56), by inserting 0s between bits. + */ + private static readonly long[] INTERLEAVE7_TABLE = new long[] + { + 0x0000000000000000L, 0x0000000000000001L, 0x0000000000000080L, 0x0000000000000081L, + 0x0000000000004000L, 0x0000000000004001L, 0x0000000000004080L, 0x0000000000004081L, + 0x0000000000200000L, 0x0000000000200001L, 0x0000000000200080L, 0x0000000000200081L, + 0x0000000000204000L, 0x0000000000204001L, 0x0000000000204080L, 0x0000000000204081L, + 0x0000000010000000L, 0x0000000010000001L, 0x0000000010000080L, 0x0000000010000081L, + 0x0000000010004000L, 0x0000000010004001L, 0x0000000010004080L, 0x0000000010004081L, + 0x0000000010200000L, 0x0000000010200001L, 0x0000000010200080L, 0x0000000010200081L, + 0x0000000010204000L, 0x0000000010204001L, 0x0000000010204080L, 0x0000000010204081L, + 0x0000000800000000L, 0x0000000800000001L, 0x0000000800000080L, 0x0000000800000081L, + 0x0000000800004000L, 0x0000000800004001L, 0x0000000800004080L, 0x0000000800004081L, + 0x0000000800200000L, 0x0000000800200001L, 0x0000000800200080L, 0x0000000800200081L, + 0x0000000800204000L, 0x0000000800204001L, 0x0000000800204080L, 0x0000000800204081L, + 0x0000000810000000L, 0x0000000810000001L, 0x0000000810000080L, 0x0000000810000081L, + 0x0000000810004000L, 0x0000000810004001L, 0x0000000810004080L, 0x0000000810004081L, + 0x0000000810200000L, 0x0000000810200001L, 0x0000000810200080L, 0x0000000810200081L, + 0x0000000810204000L, 0x0000000810204001L, 0x0000000810204080L, 0x0000000810204081L, + 0x0000040000000000L, 0x0000040000000001L, 0x0000040000000080L, 0x0000040000000081L, + 0x0000040000004000L, 0x0000040000004001L, 0x0000040000004080L, 0x0000040000004081L, + 0x0000040000200000L, 0x0000040000200001L, 0x0000040000200080L, 0x0000040000200081L, + 0x0000040000204000L, 0x0000040000204001L, 0x0000040000204080L, 0x0000040000204081L, + 0x0000040010000000L, 0x0000040010000001L, 0x0000040010000080L, 0x0000040010000081L, + 0x0000040010004000L, 0x0000040010004001L, 0x0000040010004080L, 0x0000040010004081L, + 0x0000040010200000L, 0x0000040010200001L, 0x0000040010200080L, 0x0000040010200081L, + 0x0000040010204000L, 0x0000040010204001L, 0x0000040010204080L, 0x0000040010204081L, + 0x0000040800000000L, 0x0000040800000001L, 0x0000040800000080L, 0x0000040800000081L, + 0x0000040800004000L, 0x0000040800004001L, 0x0000040800004080L, 0x0000040800004081L, + 0x0000040800200000L, 0x0000040800200001L, 0x0000040800200080L, 0x0000040800200081L, + 0x0000040800204000L, 0x0000040800204001L, 0x0000040800204080L, 0x0000040800204081L, + 0x0000040810000000L, 0x0000040810000001L, 0x0000040810000080L, 0x0000040810000081L, + 0x0000040810004000L, 0x0000040810004001L, 0x0000040810004080L, 0x0000040810004081L, + 0x0000040810200000L, 0x0000040810200001L, 0x0000040810200080L, 0x0000040810200081L, + 0x0000040810204000L, 0x0000040810204001L, 0x0000040810204080L, 0x0000040810204081L, + 0x0002000000000000L, 0x0002000000000001L, 0x0002000000000080L, 0x0002000000000081L, + 0x0002000000004000L, 0x0002000000004001L, 0x0002000000004080L, 0x0002000000004081L, + 0x0002000000200000L, 0x0002000000200001L, 0x0002000000200080L, 0x0002000000200081L, + 0x0002000000204000L, 0x0002000000204001L, 0x0002000000204080L, 0x0002000000204081L, + 0x0002000010000000L, 0x0002000010000001L, 0x0002000010000080L, 0x0002000010000081L, + 0x0002000010004000L, 0x0002000010004001L, 0x0002000010004080L, 0x0002000010004081L, + 0x0002000010200000L, 0x0002000010200001L, 0x0002000010200080L, 0x0002000010200081L, + 0x0002000010204000L, 0x0002000010204001L, 0x0002000010204080L, 0x0002000010204081L, + 0x0002000800000000L, 0x0002000800000001L, 0x0002000800000080L, 0x0002000800000081L, + 0x0002000800004000L, 0x0002000800004001L, 0x0002000800004080L, 0x0002000800004081L, + 0x0002000800200000L, 0x0002000800200001L, 0x0002000800200080L, 0x0002000800200081L, + 0x0002000800204000L, 0x0002000800204001L, 0x0002000800204080L, 0x0002000800204081L, + 0x0002000810000000L, 0x0002000810000001L, 0x0002000810000080L, 0x0002000810000081L, + 0x0002000810004000L, 0x0002000810004001L, 0x0002000810004080L, 0x0002000810004081L, + 0x0002000810200000L, 0x0002000810200001L, 0x0002000810200080L, 0x0002000810200081L, + 0x0002000810204000L, 0x0002000810204001L, 0x0002000810204080L, 0x0002000810204081L, + 0x0002040000000000L, 0x0002040000000001L, 0x0002040000000080L, 0x0002040000000081L, + 0x0002040000004000L, 0x0002040000004001L, 0x0002040000004080L, 0x0002040000004081L, + 0x0002040000200000L, 0x0002040000200001L, 0x0002040000200080L, 0x0002040000200081L, + 0x0002040000204000L, 0x0002040000204001L, 0x0002040000204080L, 0x0002040000204081L, + 0x0002040010000000L, 0x0002040010000001L, 0x0002040010000080L, 0x0002040010000081L, + 0x0002040010004000L, 0x0002040010004001L, 0x0002040010004080L, 0x0002040010004081L, + 0x0002040010200000L, 0x0002040010200001L, 0x0002040010200080L, 0x0002040010200081L, + 0x0002040010204000L, 0x0002040010204001L, 0x0002040010204080L, 0x0002040010204081L, + 0x0002040800000000L, 0x0002040800000001L, 0x0002040800000080L, 0x0002040800000081L, + 0x0002040800004000L, 0x0002040800004001L, 0x0002040800004080L, 0x0002040800004081L, + 0x0002040800200000L, 0x0002040800200001L, 0x0002040800200080L, 0x0002040800200081L, + 0x0002040800204000L, 0x0002040800204001L, 0x0002040800204080L, 0x0002040800204081L, + 0x0002040810000000L, 0x0002040810000001L, 0x0002040810000080L, 0x0002040810000081L, + 0x0002040810004000L, 0x0002040810004001L, 0x0002040810004080L, 0x0002040810004081L, + 0x0002040810200000L, 0x0002040810200001L, 0x0002040810200080L, 0x0002040810200081L, + 0x0002040810204000L, 0x0002040810204001L, 0x0002040810204080L, 0x0002040810204081L, + 0x0100000000000000L, 0x0100000000000001L, 0x0100000000000080L, 0x0100000000000081L, + 0x0100000000004000L, 0x0100000000004001L, 0x0100000000004080L, 0x0100000000004081L, + 0x0100000000200000L, 0x0100000000200001L, 0x0100000000200080L, 0x0100000000200081L, + 0x0100000000204000L, 0x0100000000204001L, 0x0100000000204080L, 0x0100000000204081L, + 0x0100000010000000L, 0x0100000010000001L, 0x0100000010000080L, 0x0100000010000081L, + 0x0100000010004000L, 0x0100000010004001L, 0x0100000010004080L, 0x0100000010004081L, + 0x0100000010200000L, 0x0100000010200001L, 0x0100000010200080L, 0x0100000010200081L, + 0x0100000010204000L, 0x0100000010204001L, 0x0100000010204080L, 0x0100000010204081L, + 0x0100000800000000L, 0x0100000800000001L, 0x0100000800000080L, 0x0100000800000081L, + 0x0100000800004000L, 0x0100000800004001L, 0x0100000800004080L, 0x0100000800004081L, + 0x0100000800200000L, 0x0100000800200001L, 0x0100000800200080L, 0x0100000800200081L, + 0x0100000800204000L, 0x0100000800204001L, 0x0100000800204080L, 0x0100000800204081L, + 0x0100000810000000L, 0x0100000810000001L, 0x0100000810000080L, 0x0100000810000081L, + 0x0100000810004000L, 0x0100000810004001L, 0x0100000810004080L, 0x0100000810004081L, + 0x0100000810200000L, 0x0100000810200001L, 0x0100000810200080L, 0x0100000810200081L, + 0x0100000810204000L, 0x0100000810204001L, 0x0100000810204080L, 0x0100000810204081L, + 0x0100040000000000L, 0x0100040000000001L, 0x0100040000000080L, 0x0100040000000081L, + 0x0100040000004000L, 0x0100040000004001L, 0x0100040000004080L, 0x0100040000004081L, + 0x0100040000200000L, 0x0100040000200001L, 0x0100040000200080L, 0x0100040000200081L, + 0x0100040000204000L, 0x0100040000204001L, 0x0100040000204080L, 0x0100040000204081L, + 0x0100040010000000L, 0x0100040010000001L, 0x0100040010000080L, 0x0100040010000081L, + 0x0100040010004000L, 0x0100040010004001L, 0x0100040010004080L, 0x0100040010004081L, + 0x0100040010200000L, 0x0100040010200001L, 0x0100040010200080L, 0x0100040010200081L, + 0x0100040010204000L, 0x0100040010204001L, 0x0100040010204080L, 0x0100040010204081L, + 0x0100040800000000L, 0x0100040800000001L, 0x0100040800000080L, 0x0100040800000081L, + 0x0100040800004000L, 0x0100040800004001L, 0x0100040800004080L, 0x0100040800004081L, + 0x0100040800200000L, 0x0100040800200001L, 0x0100040800200080L, 0x0100040800200081L, + 0x0100040800204000L, 0x0100040800204001L, 0x0100040800204080L, 0x0100040800204081L, + 0x0100040810000000L, 0x0100040810000001L, 0x0100040810000080L, 0x0100040810000081L, + 0x0100040810004000L, 0x0100040810004001L, 0x0100040810004080L, 0x0100040810004081L, + 0x0100040810200000L, 0x0100040810200001L, 0x0100040810200080L, 0x0100040810200081L, + 0x0100040810204000L, 0x0100040810204001L, 0x0100040810204080L, 0x0100040810204081L, + 0x0102000000000000L, 0x0102000000000001L, 0x0102000000000080L, 0x0102000000000081L, + 0x0102000000004000L, 0x0102000000004001L, 0x0102000000004080L, 0x0102000000004081L, + 0x0102000000200000L, 0x0102000000200001L, 0x0102000000200080L, 0x0102000000200081L, + 0x0102000000204000L, 0x0102000000204001L, 0x0102000000204080L, 0x0102000000204081L, + 0x0102000010000000L, 0x0102000010000001L, 0x0102000010000080L, 0x0102000010000081L, + 0x0102000010004000L, 0x0102000010004001L, 0x0102000010004080L, 0x0102000010004081L, + 0x0102000010200000L, 0x0102000010200001L, 0x0102000010200080L, 0x0102000010200081L, + 0x0102000010204000L, 0x0102000010204001L, 0x0102000010204080L, 0x0102000010204081L, + 0x0102000800000000L, 0x0102000800000001L, 0x0102000800000080L, 0x0102000800000081L, + 0x0102000800004000L, 0x0102000800004001L, 0x0102000800004080L, 0x0102000800004081L, + 0x0102000800200000L, 0x0102000800200001L, 0x0102000800200080L, 0x0102000800200081L, + 0x0102000800204000L, 0x0102000800204001L, 0x0102000800204080L, 0x0102000800204081L, + 0x0102000810000000L, 0x0102000810000001L, 0x0102000810000080L, 0x0102000810000081L, + 0x0102000810004000L, 0x0102000810004001L, 0x0102000810004080L, 0x0102000810004081L, + 0x0102000810200000L, 0x0102000810200001L, 0x0102000810200080L, 0x0102000810200081L, + 0x0102000810204000L, 0x0102000810204001L, 0x0102000810204080L, 0x0102000810204081L, + 0x0102040000000000L, 0x0102040000000001L, 0x0102040000000080L, 0x0102040000000081L, + 0x0102040000004000L, 0x0102040000004001L, 0x0102040000004080L, 0x0102040000004081L, + 0x0102040000200000L, 0x0102040000200001L, 0x0102040000200080L, 0x0102040000200081L, + 0x0102040000204000L, 0x0102040000204001L, 0x0102040000204080L, 0x0102040000204081L, + 0x0102040010000000L, 0x0102040010000001L, 0x0102040010000080L, 0x0102040010000081L, + 0x0102040010004000L, 0x0102040010004001L, 0x0102040010004080L, 0x0102040010004081L, + 0x0102040010200000L, 0x0102040010200001L, 0x0102040010200080L, 0x0102040010200081L, + 0x0102040010204000L, 0x0102040010204001L, 0x0102040010204080L, 0x0102040010204081L, + 0x0102040800000000L, 0x0102040800000001L, 0x0102040800000080L, 0x0102040800000081L, + 0x0102040800004000L, 0x0102040800004001L, 0x0102040800004080L, 0x0102040800004081L, + 0x0102040800200000L, 0x0102040800200001L, 0x0102040800200080L, 0x0102040800200081L, + 0x0102040800204000L, 0x0102040800204001L, 0x0102040800204080L, 0x0102040800204081L, + 0x0102040810000000L, 0x0102040810000001L, 0x0102040810000080L, 0x0102040810000081L, + 0x0102040810004000L, 0x0102040810004001L, 0x0102040810004080L, 0x0102040810004081L, + 0x0102040810200000L, 0x0102040810200001L, 0x0102040810200080L, 0x0102040810200081L, + 0x0102040810204000L, 0x0102040810204001L, 0x0102040810204080L, 0x0102040810204081L + }; + + // For toString(); must have length 64 + private const string ZEROES = "0000000000000000000000000000000000000000000000000000000000000000"; + + internal static readonly byte[] BitLengths = + { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // TODO make m fixed for the LongArray, and hence compute T once and for all + + private long[] m_ints; + + public LongArray(int intLen) + { + m_ints = new long[intLen]; + } + + public LongArray(long[] ints) + { + m_ints = ints; + } + + public LongArray(long[] ints, int off, int len) + { + if (off == 0 && len == ints.Length) + { + m_ints = ints; + } + else + { + m_ints = new long[len]; + Array.Copy(ints, off, m_ints, 0, len); + } + } + + public LongArray(BigInteger bigInt) + { + if (bigInt == null || bigInt.SignValue < 0) + { + throw new ArgumentException("invalid F2m field value", "bigInt"); + } + + if (bigInt.SignValue == 0) + { + m_ints = new long[] { 0L }; + return; + } + + byte[] barr = bigInt.ToByteArray(); + int barrLen = barr.Length; + int barrStart = 0; + if (barr[0] == 0) + { + // First byte is 0 to enforce highest (=sign) bit is zero. + // In this case ignore barr[0]. + barrLen--; + barrStart = 1; + } + int intLen = (barrLen + 7) / 8; + m_ints = new long[intLen]; + + int iarrJ = intLen - 1; + int rem = barrLen % 8 + barrStart; + long temp = 0; + int barrI = barrStart; + if (barrStart < rem) + { + for (; barrI < rem; barrI++) + { + temp <<= 8; + uint barrBarrI = barr[barrI]; + temp |= barrBarrI; + } + m_ints[iarrJ--] = temp; + } + + for (; iarrJ >= 0; iarrJ--) + { + temp = 0; + for (int i = 0; i < 8; i++) + { + temp <<= 8; + uint barrBarrI = barr[barrI++]; + temp |= barrBarrI; + } + m_ints[iarrJ] = temp; + } + } + + public bool IsOne() + { + long[] a = m_ints; + if (a[0] != 1L) + { + return false; + } + for (int i = 1; i < a.Length; ++i) + { + if (a[i] != 0L) + { + return false; + } + } + return true; + } + + public bool IsZero() + { + long[] a = m_ints; + for (int i = 0; i < a.Length; ++i) + { + if (a[i] != 0L) + { + return false; + } + } + return true; + } + + public int GetUsedLength() + { + return GetUsedLengthFrom(m_ints.Length); + } + + public int GetUsedLengthFrom(int from) + { + long[] a = m_ints; + from = System.Math.Min(from, a.Length); + + if (from < 1) + { + return 0; + } + + // Check if first element will act as sentinel + if (a[0] != 0) + { + while (a[--from] == 0) + { + } + return from + 1; + } + + do + { + if (a[--from] != 0) + { + return from + 1; + } + } + while (from > 0); + + return 0; + } + + public int Degree() + { + int i = m_ints.Length; + long w; + do + { + if (i == 0) + { + return 0; + } + w = m_ints[--i]; + } + while (w == 0); + + return (i << 6) + BitLength(w); + } + + private int DegreeFrom(int limit) + { + int i = (int)(((uint)limit + 62) >> 6); + long w; + do + { + if (i == 0) + { + return 0; + } + w = m_ints[--i]; + } + while (w == 0); + + return (i << 6) + BitLength(w); + } + + // private int lowestCoefficient() + // { + // for (int i = 0; i < m_ints.Length; ++i) + // { + // long mi = m_ints[i]; + // if (mi != 0) + // { + // int j = 0; + // while ((mi & 0xFFL) == 0) + // { + // j += 8; + // mi >>>= 8; + // } + // while ((mi & 1L) == 0) + // { + // ++j; + // mi >>>= 1; + // } + // return (i << 6) + j; + // } + // } + // return -1; + // } + + private static int BitLength(long w) + { + int u = (int)((ulong)w >> 32), b; + if (u == 0) + { + u = (int)w; + b = 0; + } + else + { + b = 32; + } + + int t = (int)((uint)u >> 16), k; + if (t == 0) + { + t = (int)((uint)u >> 8); + k = (t == 0) ? BitLengths[u] : 8 + BitLengths[t]; + } + else + { + int v = (int)((uint)t >> 8); + k = (v == 0) ? 16 + BitLengths[t] : 24 + BitLengths[v]; + } + + return b + k; + } + + private long[] ResizedInts(int newLen) + { + long[] newInts = new long[newLen]; + Array.Copy(m_ints, 0, newInts, 0, System.Math.Min(m_ints.Length, newLen)); + return newInts; + } + + public BigInteger ToBigInteger() + { + int usedLen = GetUsedLength(); + if (usedLen == 0) + { + return BigInteger.Zero; + } + + long highestInt = m_ints[usedLen - 1]; + byte[] temp = new byte[8]; + int barrI = 0; + bool trailingZeroBytesDone = false; + for (int j = 7; j >= 0; j--) + { + byte thisByte = (byte)((ulong)highestInt >> (8 * j)); + if (trailingZeroBytesDone || (thisByte != 0)) + { + trailingZeroBytesDone = true; + temp[barrI++] = thisByte; + } + } + + int barrLen = 8 * (usedLen - 1) + barrI; + byte[] barr = new byte[barrLen]; + for (int j = 0; j < barrI; j++) + { + barr[j] = temp[j]; + } + // Highest value int is done now + + for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--) + { + long mi = m_ints[iarrJ]; + for (int j = 7; j >= 0; j--) + { + barr[barrI++] = (byte)((ulong)mi >> (8 * j)); + } + } + return new BigInteger(1, barr); + } + + // private static long shiftUp(long[] x, int xOff, int count) + // { + // long prev = 0; + // for (int i = 0; i < count; ++i) + // { + // long next = x[xOff + i]; + // x[xOff + i] = (next << 1) | prev; + // prev = next >>> 63; + // } + // return prev; + // } + + private static long ShiftUp(long[] x, int xOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + for (int i = 0; i < count; ++i) + { + long next = x[xOff + i]; + x[xOff + i] = (next << shift) | prev; + prev = (long)((ulong)next >> shiftInv); + } + return prev; + } + + private static long ShiftUp(long[] x, int xOff, long[] z, int zOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + for (int i = 0; i < count; ++i) + { + long next = x[xOff + i]; + z[zOff + i] = (next << shift) | prev; + prev = (long)((ulong)next >> shiftInv); + } + return prev; + } + + public LongArray AddOne() + { + if (m_ints.Length == 0) + { + return new LongArray(new long[]{ 1L }); + } + + int resultLen = System.Math.Max(1, GetUsedLength()); + long[] ints = ResizedInts(resultLen); + ints[0] ^= 1L; + return new LongArray(ints); + } + + // private void addShiftedByBits(LongArray other, int bits) + // { + // int words = bits >>> 6; + // int shift = bits & 0x3F; + // + // if (shift == 0) + // { + // addShiftedByWords(other, words); + // return; + // } + // + // int otherUsedLen = other.GetUsedLength(); + // if (otherUsedLen == 0) + // { + // return; + // } + // + // int minLen = otherUsedLen + words + 1; + // if (minLen > m_ints.Length) + // { + // m_ints = resizedInts(minLen); + // } + // + // long carry = addShiftedByBits(m_ints, words, other.m_ints, 0, otherUsedLen, shift); + // m_ints[otherUsedLen + words] ^= carry; + // } + + private void AddShiftedByBitsSafe(LongArray other, int otherDegree, int bits) + { + int otherLen = (int)((uint)(otherDegree + 63) >> 6); + + int words = (int)((uint)bits >> 6); + int shift = bits & 0x3F; + + if (shift == 0) + { + Add(m_ints, words, other.m_ints, 0, otherLen); + return; + } + + long carry = AddShiftedUp(m_ints, words, other.m_ints, 0, otherLen, shift); + if (carry != 0L) + { + m_ints[otherLen + words] ^= carry; + } + } + + private static long AddShiftedUp(long[] x, int xOff, long[] y, int yOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + for (int i = 0; i < count; ++i) + { + long next = y[yOff + i]; + x[xOff + i] ^= (next << shift) | prev; + prev = (long)((ulong)next >> shiftInv); + } + return prev; + } + + private static long AddShiftedDown(long[] x, int xOff, long[] y, int yOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + int i = count; + while (--i >= 0) + { + long next = y[yOff + i]; + x[xOff + i] ^= (long)((ulong)next >> shift) | prev; + prev = next << shiftInv; + } + return prev; + } + + public void AddShiftedByWords(LongArray other, int words) + { + int otherUsedLen = other.GetUsedLength(); + if (otherUsedLen == 0) + { + return; + } + + int minLen = otherUsedLen + words; + if (minLen > m_ints.Length) + { + m_ints = ResizedInts(minLen); + } + + Add(m_ints, words, other.m_ints, 0, otherUsedLen); + } + + private static void Add(long[] x, int xOff, long[] y, int yOff, int count) + { + for (int i = 0; i < count; ++i) + { + x[xOff + i] ^= y[yOff + i]; + } + } + + private static void Add(long[] x, int xOff, long[] y, int yOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = x[xOff + i] ^ y[yOff + i]; + } + } + + private static void AddBoth(long[] x, int xOff, long[] y1, int y1Off, long[] y2, int y2Off, int count) + { + for (int i = 0; i < count; ++i) + { + x[xOff + i] ^= y1[y1Off + i] ^ y2[y2Off + i]; + } + } + + private static void Distribute(long[] x, int src, int dst1, int dst2, int count) + { + for (int i = 0; i < count; ++i) + { + long v = x[src + i]; + x[dst1 + i] ^= v; + x[dst2 + i] ^= v; + } + } + + public int Length + { + get { return m_ints.Length; } + } + + private static void FlipWord(long[] buf, int off, int bit, long word) + { + int n = off + (int)((uint)bit >> 6); + int shift = bit & 0x3F; + if (shift == 0) + { + buf[n] ^= word; + } + else + { + buf[n] ^= word << shift; + word = (long)((ulong)word >> (64 - shift)); + if (word != 0) + { + buf[++n] ^= word; + } + } + } + + // private static long getWord(long[] buf, int off, int len, int bit) + // { + // int n = off + (bit >>> 6); + // int shift = bit & 0x3F; + // if (shift == 0) + // { + // return buf[n]; + // } + // long result = buf[n] >>> shift; + // if (++n < len) + // { + // result |= buf[n] << (64 - shift); + // } + // return result; + // } + + public bool TestBitZero() + { + return m_ints.Length > 0 && (m_ints[0] & 1L) != 0; + } + + private static bool TestBit(long[] buf, int off, int n) + { + // theInt = n / 64 + int theInt = (int)((uint)n >> 6); + // theBit = n % 64 + int theBit = n & 0x3F; + long tester = 1L << theBit; + return (buf[off + theInt] & tester) != 0; + } + + private static void FlipBit(long[] buf, int off, int n) + { + // theInt = n / 64 + int theInt = (int)((uint)n >> 6); + // theBit = n % 64 + int theBit = n & 0x3F; + long flipper = 1L << theBit; + buf[off + theInt] ^= flipper; + } + + // private static void SetBit(long[] buf, int off, int n) + // { + // // theInt = n / 64 + // int theInt = n >>> 6; + // // theBit = n % 64 + // int theBit = n & 0x3F; + // long setter = 1L << theBit; + // buf[off + theInt] |= setter; + // } + // + // private static void ClearBit(long[] buf, int off, int n) + // { + // // theInt = n / 64 + // int theInt = n >>> 6; + // // theBit = n % 64 + // int theBit = n & 0x3F; + // long setter = 1L << theBit; + // buf[off + theInt] &= ~setter; + // } + + private static void MultiplyWord(long a, long[] b, int bLen, long[] c, int cOff) + { + if ((a & 1L) != 0L) + { + Add(c, cOff, b, 0, bLen); + } + int k = 1; + while ((a = (long)((ulong)a >> 1)) != 0L) + { + if ((a & 1L) != 0L) + { + long carry = AddShiftedUp(c, cOff, b, 0, bLen, k); + if (carry != 0L) + { + c[cOff + bLen] ^= carry; + } + } + ++k; + } + } + + public LongArray ModMultiplyLD(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + return ReduceResult(c0, 0, cLen, m, ks); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + Array.Copy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); + } + else + { + Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.Length]; + ShiftUp(T0, 0, T1, 0, T0.Length, 4); + // shiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen]; + + int MASK = 0xF; + + /* + * Lopez-Dahab algorithm + */ + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 1; j < aLen; j += 2) + { + int aVal = (int)((ulong)a[j] >> k); + int u = aVal & MASK; + int v = (int)((uint)aVal >> 4) & MASK; + AddBoth(c, j - 1, T0, ti[u], T1, ti[v], bMax); + } + ShiftUp(c, 0, cLen, 8); + } + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 0; j < aLen; j += 2) + { + int aVal = (int)((ulong)a[j] >> k); + int u = aVal & MASK; + int v = (int)((uint)aVal >> 4) & MASK; + AddBoth(c, j, T0, ti[u], T1, ti[v], bMax); + } + if (k > 0) + { + ShiftUp(c, 0, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + return ReduceResult(c, 0, cLen, m, ks); + } + + public LongArray ModMultiply(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + return ReduceResult(c0, 0, cLen, m, ks); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + Array.Copy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); + } + else + { + Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.Length]; + ShiftUp(T0, 0, T1, 0, T0.Length, 4); + // ShiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen << 3]; + + int MASK = 0xF; + + /* + * Lopez-Dahab (Modified) algorithm + */ + + for (int aPos = 0; aPos < aLen; ++aPos) + { + long aVal = a[aPos]; + int cOff = aPos; + for (;;) + { + int u = (int)aVal & MASK; + aVal = (long)((ulong)aVal >> 4); + int v = (int)aVal & MASK; + AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); + aVal = (long)((ulong)aVal >> 4); + if (aVal == 0L) + { + break; + } + cOff += cLen; + } + } + + { + int cOff = c.Length; + while ((cOff -= cLen) != 0) + { + AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + return ReduceResult(c, 0, cLen, m, ks); + } + + public LongArray ModMultiplyAlt(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + return ReduceResult(c0, 0, cLen, m, ks); + } + + // NOTE: This works, but is slower than width 4 processing + // if (aLen == 2) + // { + // /* + // * Use common-multiplicand optimization to save ~1/4 of the adds + // */ + // long a1 = A.m_ints[0], a2 = A.m_ints[1]; + // long aa = a1 & a2; a1 ^= aa; a2 ^= aa; + // + // long[] b = B.m_ints; + // long[] c = new long[cLen]; + // multiplyWord(aa, b, bLen, c, 1); + // add(c, 0, c, 1, cLen - 1); + // multiplyWord(a1, b, bLen, c, 0); + // multiplyWord(a2, b, bLen, c, 1); + // + // /* + // * Reduce the raw answer against the reduction coefficients + // */ + // return ReduceResult(c, 0, cLen, m, ks); + // } + + /* + * Determine the parameters of the Interleaved window algorithm: the 'width' in bits to + * process together, the number of evaluation 'positions' implied by that width, and the + * 'top' position at which the regular window algorithm stops. + */ + int width, positions, top, banks; + + // NOTE: width 4 is the fastest over the entire range of sizes used in current crypto + // width = 1; positions = 64; top = 64; banks = 4; + // width = 2; positions = 32; top = 64; banks = 4; + // width = 3; positions = 21; top = 63; banks = 3; + width = 4; positions = 16; top = 64; banks = 8; + // width = 5; positions = 13; top = 65; banks = 7; + // width = 7; positions = 9; top = 63; banks = 9; + // width = 8; positions = 8; top = 64; banks = 8; + + /* + * Determine if B will get bigger during shifting + */ + int shifts = top < 64 ? positions : positions - 1; + int bMax = (int)((uint)(bDeg + shifts + 63) >> 6); + + int bTotal = bMax * banks, stride = width * banks; + + /* + * Create a single temporary buffer, with an offset table to find the positions of things in it + */ + int[] ci = new int[1 << width]; + int cTotal = aLen; + { + ci[0] = cTotal; + cTotal += bTotal; + ci[1] = cTotal; + for (int i = 2; i < ci.Length; ++i) + { + cTotal += cLen; + ci[i] = cTotal; + } + cTotal += cLen; + } + // NOTE: Provide a safe dump for "high zeroes" since we are adding 'bMax' and not 'bLen' + ++cTotal; + + long[] c = new long[cTotal]; + + // Prepare A in Interleaved form, according to the chosen width + Interleave(A.m_ints, 0, c, 0, aLen, width); + + // Make a working copy of B, since we will be shifting it + { + int bOff = aLen; + Array.Copy(B.m_ints, 0, c, bOff, bLen); + for (int bank = 1; bank < banks; ++bank) + { + ShiftUp(c, aLen, c, bOff += bMax, bMax, bank); + } + } + + /* + * The main loop analyzes the Interleaved windows in A, and for each non-zero window + * a single word-array XOR is performed to a carefully selected slice of 'c'. The loop is + * breadth-first, checking the lowest window in each word, then looping again for the + * next higher window position. + */ + int MASK = (1 << width) - 1; + + int k = 0; + for (;;) + { + int aPos = 0; + do + { + long aVal = (long)((ulong)c[aPos] >> k); + int bank = 0, bOff = aLen; + for (;;) + { + int index = (int)(aVal) & MASK; + if (index != 0) + { + /* + * Add to a 'c' buffer based on the bit-pattern of 'index'. Since A is in + * Interleaved form, the bits represent the current B shifted by 0, 'positions', + * 'positions' * 2, ..., 'positions' * ('width' - 1) + */ + Add(c, aPos + ci[index], c, bOff, bMax); + } + if (++bank == banks) + { + break; + } + bOff += bMax; + aVal = (long)((ulong)aVal >> width); + } + } + while (++aPos < aLen); + + if ((k += stride) >= top) + { + if (k >= 64) + { + break; + } + + /* + * Adjustment for window setups with top == 63, the final bit (if any) is processed + * as the top-bit of a window + */ + k = 64 - width; + MASK &= MASK << (top - k); + } + + /* + * After each position has been checked for all words of A, B is shifted up 1 place + */ + ShiftUp(c, aLen, bTotal, banks); + } + + int ciPos = ci.Length; + while (--ciPos > 1) + { + if ((ciPos & 1L) == 0L) + { + /* + * For even numbers, shift contents and add to the half-position + */ + AddShiftedUp(c, ci[(uint)ciPos >> 1], c, ci[ciPos], cLen, positions); + } + else + { + /* + * For odd numbers, 'distribute' contents to the result and the next-lowest position + */ + Distribute(c, ci[ciPos], ci[ciPos - 1], ci[1], cLen); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + return ReduceResult(c, ci[1], cLen, m, ks); + } + + public LongArray ModReduce(int m, int[] ks) + { + long[] buf = Arrays.Clone(m_ints); + int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks); + return new LongArray(buf, 0, rLen); + } + + public LongArray Multiply(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + //return ReduceResult(c0, 0, cLen, m, ks); + return new LongArray(c0, 0, cLen); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + Array.Copy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); + } + else + { + Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.Length]; + ShiftUp(T0, 0, T1, 0, T0.Length, 4); + // ShiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen << 3]; + + int MASK = 0xF; + + /* + * Lopez-Dahab (Modified) algorithm + */ + + for (int aPos = 0; aPos < aLen; ++aPos) + { + long aVal = a[aPos]; + int cOff = aPos; + for (; ; ) + { + int u = (int)aVal & MASK; + aVal = (long)((ulong)aVal >> 4); + int v = (int)aVal & MASK; + AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); + aVal = (long)((ulong)aVal >> 4); + if (aVal == 0L) + { + break; + } + cOff += cLen; + } + } + + { + int cOff = c.Length; + while ((cOff -= cLen) != 0) + { + AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + //return ReduceResult(c, 0, cLen, m, ks); + return new LongArray(c, 0, cLen); + } + + public void Reduce(int m, int[] ks) + { + long[] buf = m_ints; + int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks); + if (rLen < buf.Length) + { + m_ints = new long[rLen]; + Array.Copy(buf, 0, m_ints, 0, rLen); + } + } + + private static LongArray ReduceResult(long[] buf, int off, int len, int m, int[] ks) + { + int rLen = ReduceInPlace(buf, off, len, m, ks); + return new LongArray(buf, off, rLen); + } + + // private static void deInterleave(long[] x, int xOff, long[] z, int zOff, int count, int rounds) + // { + // for (int i = 0; i < count; ++i) + // { + // z[zOff + i] = deInterleave(x[zOff + i], rounds); + // } + // } + // + // private static long deInterleave(long x, int rounds) + // { + // while (--rounds >= 0) + // { + // x = deInterleave32(x & DEInterleave_MASK) | (deInterleave32((x >>> 1) & DEInterleave_MASK) << 32); + // } + // return x; + // } + // + // private static long deInterleave32(long x) + // { + // x = (x | (x >>> 1)) & 0x3333333333333333L; + // x = (x | (x >>> 2)) & 0x0F0F0F0F0F0F0F0FL; + // x = (x | (x >>> 4)) & 0x00FF00FF00FF00FFL; + // x = (x | (x >>> 8)) & 0x0000FFFF0000FFFFL; + // x = (x | (x >>> 16)) & 0x00000000FFFFFFFFL; + // return x; + // } + + private static int ReduceInPlace(long[] buf, int off, int len, int m, int[] ks) + { + int mLen = (m + 63) >> 6; + if (len < mLen) + { + return len; + } + + int numBits = System.Math.Min(len << 6, (m << 1) - 1); // TODO use actual degree? + int excessBits = (len << 6) - numBits; + while (excessBits >= 64) + { + --len; + excessBits -= 64; + } + + int kLen = ks.Length, kMax = ks[kLen - 1], kNext = kLen > 1 ? ks[kLen - 2] : 0; + int wordWiseLimit = System.Math.Max(m, kMax + 64); + int vectorableWords = (excessBits + System.Math.Min(numBits - wordWiseLimit, m - kNext)) >> 6; + if (vectorableWords > 1) + { + int vectorWiseWords = len - vectorableWords; + ReduceVectorWise(buf, off, len, vectorWiseWords, m, ks); + while (len > vectorWiseWords) + { + buf[off + --len] = 0L; + } + numBits = vectorWiseWords << 6; + } + + if (numBits > wordWiseLimit) + { + ReduceWordWise(buf, off, len, wordWiseLimit, m, ks); + numBits = wordWiseLimit; + } + + if (numBits > m) + { + ReduceBitWise(buf, off, numBits, m, ks); + } + + return mLen; + } + + private static void ReduceBitWise(long[] buf, int off, int BitLength, int m, int[] ks) + { + while (--BitLength >= m) + { + if (TestBit(buf, off, BitLength)) + { + ReduceBit(buf, off, BitLength, m, ks); + } + } + } + + private static void ReduceBit(long[] buf, int off, int bit, int m, int[] ks) + { + FlipBit(buf, off, bit); + int n = bit - m; + int j = ks.Length; + while (--j >= 0) + { + FlipBit(buf, off, ks[j] + n); + } + FlipBit(buf, off, n); + } + + private static void ReduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks) + { + int toPos = (int)((uint)toBit >> 6); + + while (--len > toPos) + { + long word = buf[off + len]; + if (word != 0) + { + buf[off + len] = 0; + ReduceWord(buf, off, (len << 6), word, m, ks); + } + } + + { + int partial = toBit & 0x3F; + long word = (long)((ulong)buf[off + toPos] >> partial); + if (word != 0) + { + buf[off + toPos] ^= word << partial; + ReduceWord(buf, off, toBit, word, m, ks); + } + } + } + + private static void ReduceWord(long[] buf, int off, int bit, long word, int m, int[] ks) + { + int offset = bit - m; + int j = ks.Length; + while (--j >= 0) + { + FlipWord(buf, off, offset + ks[j], word); + } + FlipWord(buf, off, offset, word); + } + + private static void ReduceVectorWise(long[] buf, int off, int len, int words, int m, int[] ks) + { + /* + * NOTE: It's important we go from highest coefficient to lowest, because for the highest + * one (only) we allow the ranges to partially overlap, and therefore any changes must take + * effect for the subsequent lower coefficients. + */ + int baseBit = (words << 6) - m; + int j = ks.Length; + while (--j >= 0) + { + FlipVector(buf, off, buf, off + words, len - words, baseBit + ks[j]); + } + FlipVector(buf, off, buf, off + words, len - words, baseBit); + } + + private static void FlipVector(long[] x, int xOff, long[] y, int yOff, int yLen, int bits) + { + xOff += (int)((uint)bits >> 6); + bits &= 0x3F; + + if (bits == 0) + { + Add(x, xOff, y, yOff, yLen); + } + else + { + long carry = AddShiftedDown(x, xOff + 1, y, yOff, yLen, 64 - bits); + x[xOff] ^= carry; + } + } + + public LongArray ModSquare(int m, int[] ks) + { + int len = GetUsedLength(); + if (len == 0) + { + return this; + } + + int _2len = len << 1; + long[] r = new long[_2len]; + + int pos = 0; + while (pos < _2len) + { + long mi = m_ints[(uint)pos >> 1]; + r[pos++] = Interleave2_32to64((int)mi); + r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32)); + } + + return new LongArray(r, 0, ReduceInPlace(r, 0, r.Length, m, ks)); + } + + public LongArray ModSquareN(int n, int m, int[] ks) + { + int len = GetUsedLength(); + if (len == 0) + { + return this; + } + + int mLen = (m + 63) >> 6; + long[] r = new long[mLen << 1]; + Array.Copy(m_ints, 0, r, 0, len); + + while (--n >= 0) + { + SquareInPlace(r, len, m, ks); + len = ReduceInPlace(r, 0, r.Length, m, ks); + } + + return new LongArray(r, 0, len); + } + + public LongArray Square(int m, int[] ks) + { + int len = GetUsedLength(); + if (len == 0) + { + return this; + } + + int _2len = len << 1; + long[] r = new long[_2len]; + + int pos = 0; + while (pos < _2len) + { + long mi = m_ints[(uint)pos >> 1]; + r[pos++] = Interleave2_32to64((int)mi); + r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32)); + } + + return new LongArray(r, 0, r.Length); + } + + private static void SquareInPlace(long[] x, int xLen, int m, int[] ks) + { + int pos = xLen << 1; + while (--xLen >= 0) + { + long xVal = x[xLen]; + x[--pos] = Interleave2_32to64((int)((ulong)xVal >> 32)); + x[--pos] = Interleave2_32to64((int)xVal); + } + } + + private static void Interleave(long[] x, int xOff, long[] z, int zOff, int count, int width) + { + switch (width) + { + case 3: + Interleave3(x, xOff, z, zOff, count); + break; + case 5: + Interleave5(x, xOff, z, zOff, count); + break; + case 7: + Interleave7(x, xOff, z, zOff, count); + break; + default: + Interleave2_n(x, xOff, z, zOff, count, BitLengths[width] - 1); + break; + } + } + + private static void Interleave3(long[] x, int xOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave3(x[xOff + i]); + } + } + + private static long Interleave3(long x) + { + long z = x & (1L << 63); + return z + | Interleave3_21to63((int)x & 0x1FFFFF) + | Interleave3_21to63((int)((ulong)x >> 21) & 0x1FFFFF) << 1 + | Interleave3_21to63((int)((ulong)x >> 42) & 0x1FFFFF) << 2; + + // int zPos = 0, wPos = 0, xPos = 0; + // for (;;) + // { + // z |= ((x >>> xPos) & 1L) << zPos; + // if (++zPos == 63) + // { + // String sz2 = Long.toBinaryString(z); + // return z; + // } + // if ((xPos += 21) >= 63) + // { + // xPos = ++wPos; + // } + // } + } + + private static long Interleave3_21to63(int x) + { + int r00 = INTERLEAVE3_TABLE[x & 0x7F]; + int r21 = INTERLEAVE3_TABLE[((uint)x >> 7) & 0x7F]; + int r42 = INTERLEAVE3_TABLE[(uint)x >> 14]; + return (r42 & 0xFFFFFFFFL) << 42 | (r21 & 0xFFFFFFFFL) << 21 | (r00 & 0xFFFFFFFFL); + } + + private static void Interleave5(long[] x, int xOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave5(x[xOff + i]); + } + } + + private static long Interleave5(long x) + { + return Interleave3_13to65((int)x & 0x1FFF) + | Interleave3_13to65((int)((ulong)x >> 13) & 0x1FFF) << 1 + | Interleave3_13to65((int)((ulong)x >> 26) & 0x1FFF) << 2 + | Interleave3_13to65((int)((ulong)x >> 39) & 0x1FFF) << 3 + | Interleave3_13to65((int)((ulong)x >> 52) & 0x1FFF) << 4; + + // long z = 0; + // int zPos = 0, wPos = 0, xPos = 0; + // for (;;) + // { + // z |= ((x >>> xPos) & 1L) << zPos; + // if (++zPos == 64) + // { + // return z; + // } + // if ((xPos += 13) >= 64) + // { + // xPos = ++wPos; + // } + // } + } + + private static long Interleave3_13to65(int x) + { + int r00 = INTERLEAVE5_TABLE[x & 0x7F]; + int r35 = INTERLEAVE5_TABLE[(uint)x >> 7]; + return (r35 & 0xFFFFFFFFL) << 35 | (r00 & 0xFFFFFFFFL); + } + + private static void Interleave7(long[] x, int xOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave7(x[xOff + i]); + } + } + + private static long Interleave7(long x) + { + long z = x & (1L << 63); + return z + | INTERLEAVE7_TABLE[(int)x & 0x1FF] + | INTERLEAVE7_TABLE[(int)((ulong)x >> 9) & 0x1FF] << 1 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 18) & 0x1FF] << 2 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 27) & 0x1FF] << 3 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 36) & 0x1FF] << 4 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 45) & 0x1FF] << 5 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 54) & 0x1FF] << 6; + + // int zPos = 0, wPos = 0, xPos = 0; + // for (;;) + // { + // z |= ((x >>> xPos) & 1L) << zPos; + // if (++zPos == 63) + // { + // return z; + // } + // if ((xPos += 9) >= 63) + // { + // xPos = ++wPos; + // } + // } + } + + private static void Interleave2_n(long[] x, int xOff, long[] z, int zOff, int count, int rounds) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave2_n(x[xOff + i], rounds); + } + } + + private static long Interleave2_n(long x, int rounds) + { + while (rounds > 1) + { + rounds -= 2; + x = Interleave4_16to64((int)x & 0xFFFF) + | Interleave4_16to64((int)((ulong)x >> 16) & 0xFFFF) << 1 + | Interleave4_16to64((int)((ulong)x >> 32) & 0xFFFF) << 2 + | Interleave4_16to64((int)((ulong)x >> 48) & 0xFFFF) << 3; + } + if (rounds > 0) + { + x = Interleave2_32to64((int)x) | Interleave2_32to64((int)((ulong)x >> 32)) << 1; + } + return x; + } + + private static long Interleave4_16to64(int x) + { + int r00 = INTERLEAVE4_TABLE[x & 0xFF]; + int r32 = INTERLEAVE4_TABLE[(uint)x >> 8]; + return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL); + } + + private static long Interleave2_32to64(int x) + { + int r00 = INTERLEAVE2_TABLE[x & 0xFF] | INTERLEAVE2_TABLE[((uint)x >> 8) & 0xFF] << 16; + int r32 = INTERLEAVE2_TABLE[((uint)x >> 16) & 0xFF] | INTERLEAVE2_TABLE[(uint)x >> 24] << 16; + return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL); + } + + // private static LongArray ExpItohTsujii2(LongArray B, int n, int m, int[] ks) + // { + // LongArray t1 = B, t3 = new LongArray(new long[]{ 1L }); + // int scale = 1; + // + // int numTerms = n; + // while (numTerms > 1) + // { + // if ((numTerms & 1) != 0) + // { + // t3 = t3.ModMultiply(t1, m, ks); + // t1 = t1.modSquareN(scale, m, ks); + // } + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // numTerms >>>= 1; scale <<= 1; + // } + // + // return t3.ModMultiply(t1, m, ks); + // } + // + // private static LongArray ExpItohTsujii23(LongArray B, int n, int m, int[] ks) + // { + // LongArray t1 = B, t3 = new LongArray(new long[]{ 1L }); + // int scale = 1; + // + // int numTerms = n; + // while (numTerms > 1) + // { + // bool m03 = numTerms % 3 == 0; + // bool m14 = !m03 && (numTerms & 1) != 0; + // + // if (m14) + // { + // t3 = t3.ModMultiply(t1, m, ks); + // t1 = t1.modSquareN(scale, m, ks); + // } + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // + // if (m03) + // { + // t2 = t2.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // numTerms /= 3; scale *= 3; + // } + // else + // { + // numTerms >>>= 1; scale <<= 1; + // } + // } + // + // return t3.ModMultiply(t1, m, ks); + // } + // + // private static LongArray ExpItohTsujii235(LongArray B, int n, int m, int[] ks) + // { + // LongArray t1 = B, t4 = new LongArray(new long[]{ 1L }); + // int scale = 1; + // + // int numTerms = n; + // while (numTerms > 1) + // { + // if (numTerms % 5 == 0) + // { + //// t1 = ExpItohTsujii23(t1, 5, m, ks); + // + // LongArray t3 = t1; + // t1 = t1.modSquareN(scale, m, ks); + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // t2 = t1.modSquareN(scale << 1, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // + // t1 = t1.ModMultiply(t3, m, ks); + // + // numTerms /= 5; scale *= 5; + // continue; + // } + // + // bool m03 = numTerms % 3 == 0; + // bool m14 = !m03 && (numTerms & 1) != 0; + // + // if (m14) + // { + // t4 = t4.ModMultiply(t1, m, ks); + // t1 = t1.modSquareN(scale, m, ks); + // } + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // + // if (m03) + // { + // t2 = t2.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // numTerms /= 3; scale *= 3; + // } + // else + // { + // numTerms >>>= 1; scale <<= 1; + // } + // } + // + // return t4.ModMultiply(t1, m, ks); + // } + + public LongArray ModInverse(int m, int[] ks) + { + /* + * Fermat's Little Theorem + */ + // LongArray A = this; + // LongArray B = A.modSquare(m, ks); + // LongArray R0 = B, R1 = B; + // for (int i = 2; i < m; ++i) + // { + // R1 = R1.modSquare(m, ks); + // R0 = R0.ModMultiply(R1, m, ks); + // } + // + // return R0; + + /* + * Itoh-Tsujii + */ + // LongArray B = modSquare(m, ks); + // switch (m) + // { + // case 409: + // return ExpItohTsujii23(B, m - 1, m, ks); + // case 571: + // return ExpItohTsujii235(B, m - 1, m, ks); + // case 163: + // case 233: + // case 283: + // default: + // return ExpItohTsujii2(B, m - 1, m, ks); + // } + + /* + * Inversion in F2m using the extended Euclidean algorithm + * + * Input: A nonzero polynomial a(z) of degree at most m-1 + * Output: a(z)^(-1) mod f(z) + */ + int uzDegree = Degree(); + if (uzDegree == 0) + { + throw new InvalidOperationException(); + } + if (uzDegree == 1) + { + return this; + } + + // u(z) := a(z) + LongArray uz = (LongArray)Copy(); + + int t = (m + 63) >> 6; + + // v(z) := f(z) + LongArray vz = new LongArray(t); + ReduceBit(vz.m_ints, 0, m, m, ks); + + // g1(z) := 1, g2(z) := 0 + LongArray g1z = new LongArray(t); + g1z.m_ints[0] = 1L; + LongArray g2z = new LongArray(t); + + int[] uvDeg = new int[]{ uzDegree, m + 1 }; + LongArray[] uv = new LongArray[]{ uz, vz }; + + int[] ggDeg = new int[]{ 1, 0 }; + LongArray[] gg = new LongArray[]{ g1z, g2z }; + + int b = 1; + int duv1 = uvDeg[b]; + int dgg1 = ggDeg[b]; + int j = duv1 - uvDeg[1 - b]; + + for (;;) + { + if (j < 0) + { + j = -j; + uvDeg[b] = duv1; + ggDeg[b] = dgg1; + b = 1 - b; + duv1 = uvDeg[b]; + dgg1 = ggDeg[b]; + } + + uv[b].AddShiftedByBitsSafe(uv[1 - b], uvDeg[1 - b], j); + + int duv2 = uv[b].DegreeFrom(duv1); + if (duv2 == 0) + { + return gg[1 - b]; + } + + { + int dgg2 = ggDeg[1 - b]; + gg[b].AddShiftedByBitsSafe(gg[1 - b], dgg2, j); + dgg2 += j; + + if (dgg2 > dgg1) + { + dgg1 = dgg2; + } + else if (dgg2 == dgg1) + { + dgg1 = gg[b].DegreeFrom(dgg1); + } + } + + j += (duv2 - duv1); + duv1 = duv2; + } + } + + public override bool Equals(object obj) + { + return Equals(obj as LongArray); + } + + public virtual bool Equals(LongArray other) + { + if (this == other) + return true; + if (null == other) + return false; + int usedLen = GetUsedLength(); + if (other.GetUsedLength() != usedLen) + { + return false; + } + for (int i = 0; i < usedLen; i++) + { + if (m_ints[i] != other.m_ints[i]) + { + return false; + } + } + return true; + } + + public override int GetHashCode() + { + int usedLen = GetUsedLength(); + int hash = 1; + for (int i = 0; i < usedLen; i++) + { + long mi = m_ints[i]; + hash *= 31; + hash ^= (int)mi; + hash *= 31; + hash ^= (int)((ulong)mi >> 32); + } + return hash; + } + + public LongArray Copy() + { + return new LongArray(Arrays.Clone(m_ints)); + } + + public override string ToString() + { + int i = GetUsedLength(); + if (i == 0) + { + return "0"; + } + + StringBuilder sb = new StringBuilder(Convert.ToString(m_ints[--i], 2)); + while (--i >= 0) + { + string s = Convert.ToString(m_ints[i], 2); + + // Add leading zeroes, except for highest significant word + int len = s.Length; + if (len < 64) + { + sb.Append(ZEROES.Substring(len)); + } + + sb.Append(s); + } + return sb.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs.meta new file mode 100644 index 0000000..6dd0fac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/LongArray.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c64005ee201237e4fb747b16625d3307 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs new file mode 100644 index 0000000..628d8d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleXPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleXPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleX(scale); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs.meta new file mode 100644 index 0000000..908f1e0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/ScaleXPointMap.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9dfd9f72fc2d48e42b878a2169f7e4d4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc.meta new file mode 100644 index 0000000..03e1890 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 40e69c1e558a62e4cb5a52d30eb8fdfd +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs new file mode 100644 index 0000000..444f719 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs @@ -0,0 +1,245 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +namespace Org.BouncyCastle.Math.EC.Abc +{ + /** + * Class representing a simple version of a big decimal. A + * SimpleBigDecimal is basically a + * {@link java.math.BigInteger BigInteger} with a few digits on the right of + * the decimal point. The number of (binary) digits on the right of the decimal + * point is called the scale of the SimpleBigDecimal. + * Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted + * automatically, but must be set manually. All SimpleBigDecimals + * taking part in the same arithmetic operation must have equal scale. The + * result of a multiplication of two SimpleBigDecimals returns a + * SimpleBigDecimal with double scale. + */ + internal class SimpleBigDecimal + // : Number + { + // private static final long serialVersionUID = 1L; + + private readonly BigInteger bigInt; + private readonly int scale; + + /** + * Returns a SimpleBigDecimal representing the same numerical + * value as value. + * @param value The value of the SimpleBigDecimal to be + * created. + * @param scale The scale of the SimpleBigDecimal to be + * created. + * @return The such created SimpleBigDecimal. + */ + public static SimpleBigDecimal GetInstance(BigInteger val, int scale) + { + return new SimpleBigDecimal(val.ShiftLeft(scale), scale); + } + + /** + * Constructor for SimpleBigDecimal. The value of the + * constructed SimpleBigDecimal Equals bigInt / + * 2scale. + * @param bigInt The bigInt value parameter. + * @param scale The scale of the constructed SimpleBigDecimal. + */ + public SimpleBigDecimal(BigInteger bigInt, int scale) + { + if (scale < 0) + throw new ArgumentException("scale may not be negative"); + + this.bigInt = bigInt; + this.scale = scale; + } + + private SimpleBigDecimal(SimpleBigDecimal limBigDec) + { + bigInt = limBigDec.bigInt; + scale = limBigDec.scale; + } + + private void CheckScale(SimpleBigDecimal b) + { + if (scale != b.scale) + throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations"); + } + + public SimpleBigDecimal AdjustScale(int newScale) + { + if (newScale < 0) + throw new ArgumentException("scale may not be negative"); + + if (newScale == scale) + return this; + + return new SimpleBigDecimal(bigInt.ShiftLeft(newScale - scale), newScale); + } + + public SimpleBigDecimal Add(SimpleBigDecimal b) + { + CheckScale(b); + return new SimpleBigDecimal(bigInt.Add(b.bigInt), scale); + } + + public SimpleBigDecimal Add(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale); + } + + public SimpleBigDecimal Negate() + { + return new SimpleBigDecimal(bigInt.Negate(), scale); + } + + public SimpleBigDecimal Subtract(SimpleBigDecimal b) + { + return Add(b.Negate()); + } + + public SimpleBigDecimal Subtract(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale); + } + + public SimpleBigDecimal Multiply(SimpleBigDecimal b) + { + CheckScale(b); + return new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale); + } + + public SimpleBigDecimal Multiply(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Multiply(b), scale); + } + + public SimpleBigDecimal Divide(SimpleBigDecimal b) + { + CheckScale(b); + BigInteger dividend = bigInt.ShiftLeft(scale); + return new SimpleBigDecimal(dividend.Divide(b.bigInt), scale); + } + + public SimpleBigDecimal Divide(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Divide(b), scale); + } + + public SimpleBigDecimal ShiftLeft(int n) + { + return new SimpleBigDecimal(bigInt.ShiftLeft(n), scale); + } + + public int CompareTo(SimpleBigDecimal val) + { + CheckScale(val); + return bigInt.CompareTo(val.bigInt); + } + + public int CompareTo(BigInteger val) + { + return bigInt.CompareTo(val.ShiftLeft(scale)); + } + + public BigInteger Floor() + { + return bigInt.ShiftRight(scale); + } + + public BigInteger Round() + { + SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1); + return Add(oneHalf.AdjustScale(scale)).Floor(); + } + + public int IntValue + { + get { return Floor().IntValue; } + } + + public long LongValue + { + get { return Floor().LongValue; } + } + +// public double doubleValue() +// { +// return new Double(ToString()).doubleValue(); +// } +// +// public float floatValue() +// { +// return new Float(ToString()).floatValue(); +// } + + public int Scale + { + get { return scale; } + } + + public override string ToString() + { + if (scale == 0) + return bigInt.ToString(); + + BigInteger floorBigInt = Floor(); + + BigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale)); + if (bigInt.SignValue < 0) + { + fract = BigInteger.One.ShiftLeft(scale).Subtract(fract); + } + + if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero)))) + { + floorBigInt = floorBigInt.Add(BigInteger.One); + } + string leftOfPoint = floorBigInt.ToString(); + + char[] fractCharArr = new char[scale]; + string fractStr = fract.ToString(2); + int fractLen = fractStr.Length; + int zeroes = scale - fractLen; + for (int i = 0; i < zeroes; i++) + { + fractCharArr[i] = '0'; + } + for (int j = 0; j < fractLen; j++) + { + fractCharArr[zeroes + j] = fractStr[j]; + } + string rightOfPoint = new string(fractCharArr); + + StringBuilder sb = new StringBuilder(leftOfPoint); + sb.Append("."); + sb.Append(rightOfPoint); + + return sb.ToString(); + } + + public override bool Equals( + object obj) + { + if (this == obj) + return true; + + SimpleBigDecimal other = obj as SimpleBigDecimal; + + if (other == null) + return false; + + return bigInt.Equals(other.bigInt) + && scale == other.scale; + } + + public override int GetHashCode() + { + return bigInt.GetHashCode() ^ scale; + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs.meta new file mode 100644 index 0000000..260fc0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/SimpleBigDecimal.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 90b2a6bdef50756439d9f47423252e4b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs new file mode 100644 index 0000000..26fea2b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs @@ -0,0 +1,849 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Abc +{ + /** + * Class holding methods for point multiplication based on the window + * τ-adic nonadjacent form (WTNAF). The algorithms are based on the + * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves" + * by Jerome A. Solinas. The paper first appeared in the Proceedings of + * Crypto 1997. + */ + internal class Tnaf + { + private static readonly BigInteger MinusOne = BigInteger.One.Negate(); + private static readonly BigInteger MinusTwo = BigInteger.Two.Negate(); + private static readonly BigInteger MinusThree = BigInteger.Three.Negate(); + private static readonly BigInteger Four = BigInteger.ValueOf(4); + + /** + * The window width of WTNAF. The standard value of 4 is slightly less + * than optimal for running time, but keeps space requirements for + * precomputation low. For typical curves, a value of 5 or 6 results in + * a better running time. When changing this value, the + * αu's must be computed differently, see + * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson, + * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004, + * p. 121-122 + */ + public const sbyte Width = 4; + + /** + * 24 + */ + public const sbyte Pow2Width = 16; + + /** + * The αu's for a=0 as an array + * of ZTauElements. + */ + public static readonly ZTauElement[] Alpha0 = + { + null, + new ZTauElement(BigInteger.One, BigInteger.Zero), null, + new ZTauElement(MinusThree, MinusOne), null, + new ZTauElement(MinusOne, MinusOne), null, + new ZTauElement(BigInteger.One, MinusOne), null + }; + + /** + * The αu's for a=0 as an array + * of TNAFs. + */ + public static readonly sbyte[][] Alpha0Tnaf = + { + null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1} + }; + + /** + * The αu's for a=1 as an array + * of ZTauElements. + */ + public static readonly ZTauElement[] Alpha1 = + { + null, + new ZTauElement(BigInteger.One, BigInteger.Zero), null, + new ZTauElement(MinusThree, BigInteger.One), null, + new ZTauElement(MinusOne, BigInteger.One), null, + new ZTauElement(BigInteger.One, BigInteger.One), null + }; + + /** + * The αu's for a=1 as an array + * of TNAFs. + */ + public static readonly sbyte[][] Alpha1Tnaf = + { + null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1} + }; + + /** + * Computes the norm of an element λ of + * Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ]. + * @return The norm of λ. + */ + public static BigInteger Norm(sbyte mu, ZTauElement lambda) + { + BigInteger norm; + + // s1 = u^2 + BigInteger s1 = lambda.u.Multiply(lambda.u); + + // s2 = u * v + BigInteger s2 = lambda.u.Multiply(lambda.v); + + // s3 = 2 * v^2 + BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1); + + if (mu == 1) + { + norm = s1.Add(s2).Add(s3); + } + else if (mu == -1) + { + norm = s1.Subtract(s2).Add(s3); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + return norm; + } + + /** + * Computes the norm of an element λ of + * R[τ], where λ = u + vτ + * and u and u are real numbers (elements of + * R). + * @param mu The parameter μ of the elliptic curve. + * @param u The real part of the element λ of + * R[τ]. + * @param v The τ-adic part of the element + * λ of R[τ]. + * @return The norm of λ. + */ + public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v) + { + SimpleBigDecimal norm; + + // s1 = u^2 + SimpleBigDecimal s1 = u.Multiply(u); + + // s2 = u * v + SimpleBigDecimal s2 = u.Multiply(v); + + // s3 = 2 * v^2 + SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1); + + if (mu == 1) + { + norm = s1.Add(s2).Add(s3); + } + else if (mu == -1) + { + norm = s1.Subtract(s2).Add(s3); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + return norm; + } + + /** + * Rounds an element λ of R[τ] + * to an element of Z[τ], such that their difference + * has minimal norm. λ is given as + * λ = λ0 + λ1τ. + * @param lambda0 The component λ0. + * @param lambda1 The component λ1. + * @param mu The parameter μ of the elliptic curve. Must + * equal 1 or -1. + * @return The rounded element of Z[τ]. + * @throws ArgumentException if lambda0 and + * lambda1 do not have same scale. + */ + public static ZTauElement Round(SimpleBigDecimal lambda0, + SimpleBigDecimal lambda1, sbyte mu) + { + int scale = lambda0.Scale; + if (lambda1.Scale != scale) + throw new ArgumentException("lambda0 and lambda1 do not have same scale"); + + if (!((mu == 1) || (mu == -1))) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger f0 = lambda0.Round(); + BigInteger f1 = lambda1.Round(); + + SimpleBigDecimal eta0 = lambda0.Subtract(f0); + SimpleBigDecimal eta1 = lambda1.Subtract(f1); + + // eta = 2*eta0 + mu*eta1 + SimpleBigDecimal eta = eta0.Add(eta0); + if (mu == 1) + { + eta = eta.Add(eta1); + } + else + { + // mu == -1 + eta = eta.Subtract(eta1); + } + + // check1 = eta0 - 3*mu*eta1 + // check2 = eta0 + 4*mu*eta1 + SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1); + SimpleBigDecimal fourEta1 = threeEta1.Add(eta1); + SimpleBigDecimal check1; + SimpleBigDecimal check2; + if (mu == 1) + { + check1 = eta0.Subtract(threeEta1); + check2 = eta0.Add(fourEta1); + } + else + { + // mu == -1 + check1 = eta0.Add(threeEta1); + check2 = eta0.Subtract(fourEta1); + } + + sbyte h0 = 0; + sbyte h1 = 0; + + // if eta >= 1 + if (eta.CompareTo(BigInteger.One) >= 0) + { + if (check1.CompareTo(MinusOne) < 0) + { + h1 = mu; + } + else + { + h0 = 1; + } + } + else + { + // eta < 1 + if (check2.CompareTo(BigInteger.Two) >= 0) + { + h1 = mu; + } + } + + // if eta < -1 + if (eta.CompareTo(MinusOne) < 0) + { + if (check1.CompareTo(BigInteger.One) >= 0) + { + h1 = (sbyte)-mu; + } + else + { + h0 = -1; + } + } + else + { + // eta >= -1 + if (check2.CompareTo(MinusTwo) < 0) + { + h1 = (sbyte)-mu; + } + } + + BigInteger q0 = f0.Add(BigInteger.ValueOf(h0)); + BigInteger q1 = f1.Add(BigInteger.ValueOf(h1)); + return new ZTauElement(q0, q1); + } + + /** + * Approximate division by n. For an integer + * k, the value λ = s k / n is + * computed to c bits of accuracy. + * @param k The parameter k. + * @param s The curve parameter s0 or + * s1. + * @param vm The Lucas Sequence element Vm. + * @param a The parameter a of the elliptic curve. + * @param m The bit length of the finite field + * Fm. + * @param c The number of bits of accuracy, i.e. the scale of the returned + * SimpleBigDecimal. + * @return The value λ = s k / n computed to + * c bits of accuracy. + */ + public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k, + BigInteger s, BigInteger vm, sbyte a, int m, int c) + { + int _k = (m + 5)/2 + c; + BigInteger ns = k.ShiftRight(m - _k - 2 + a); + + BigInteger gs = s.Multiply(ns); + + BigInteger hs = gs.ShiftRight(m); + + BigInteger js = vm.Multiply(hs); + + BigInteger gsPlusJs = gs.Add(js); + BigInteger ls = gsPlusJs.ShiftRight(_k-c); + if (gsPlusJs.TestBit(_k-c-1)) + { + // round up + ls = ls.Add(BigInteger.One); + } + + return new SimpleBigDecimal(ls, c); + } + + /** + * Computes the τ-adic NAF (non-adjacent form) of an + * element λ of Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ]. + * @return The τ-adic NAF of λ. + */ + public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda) + { + if (!((mu == 1) || (mu == -1))) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger norm = Norm(mu, lambda); + + // Ceiling of log2 of the norm + int log2Norm = norm.BitLength; + + // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 + int maxLength = log2Norm > 30 ? log2Norm + 4 : 34; + + // The array holding the TNAF + sbyte[] u = new sbyte[maxLength]; + int i = 0; + + // The actual length of the TNAF + int length = 0; + + BigInteger r0 = lambda.u; + BigInteger r1 = lambda.v; + + while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) + { + // If r0 is odd + if (r0.TestBit(0)) + { + u[i] = (sbyte) BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue; + + // r0 = r0 - u[i] + if (u[i] == 1) + { + r0 = r0.ClearBit(0); + } + else + { + // u[i] == -1 + r0 = r0.Add(BigInteger.One); + } + length = i; + } + else + { + u[i] = 0; + } + + BigInteger t = r0; + BigInteger s = r0.ShiftRight(1); + if (mu == 1) + { + r0 = r1.Add(s); + } + else + { + // mu == -1 + r0 = r1.Subtract(s); + } + + r1 = t.ShiftRight(1).Negate(); + i++; + } + + length++; + + // Reduce the TNAF array to its actual length + sbyte[] tnaf = new sbyte[length]; + Array.Copy(u, 0, tnaf, 0, length); + return tnaf; + } + + /** + * Applies the operation τ() to an + * AbstractF2mPoint. + * @param p The AbstractF2mPoint to which τ() is applied. + * @return τ(p) + */ + public static AbstractF2mPoint Tau(AbstractF2mPoint p) + { + return p.Tau(); + } + + /** + * Returns the parameter μ of the elliptic curve. + * @param curve The elliptic curve from which to obtain μ. + * The curve must be a Koblitz curve, i.e. a Equals + * 0 or 1 and b Equals + * 1. + * @return μ of the elliptic curve. + * @throws ArgumentException if the given ECCurve is not a Koblitz + * curve. + */ + public static sbyte GetMu(AbstractF2mCurve curve) + { + BigInteger a = curve.A.ToBigInteger(); + + sbyte mu; + if (a.SignValue == 0) + { + mu = -1; + } + else if (a.Equals(BigInteger.One)) + { + mu = 1; + } + else + { + throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible"); + } + return mu; + } + + public static sbyte GetMu(ECFieldElement curveA) + { + return (sbyte)(curveA.IsZero ? -1 : 1); + } + + public static sbyte GetMu(int curveA) + { + return (sbyte)(curveA == 0 ? -1 : 1); + } + + /** + * Calculates the Lucas Sequence elements Uk-1 and + * Uk or Vk-1 and + * Vk. + * @param mu The parameter μ of the elliptic curve. + * @param k The index of the second element of the Lucas Sequence to be + * returned. + * @param doV If set to true, computes Vk-1 and + * Vk, otherwise Uk-1 and + * Uk. + * @return An array with 2 elements, containing Uk-1 + * and Uk or Vk-1 + * and Vk. + */ + public static BigInteger[] GetLucas(sbyte mu, int k, bool doV) + { + if (!(mu == 1 || mu == -1)) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger u0; + BigInteger u1; + BigInteger u2; + + if (doV) + { + u0 = BigInteger.Two; + u1 = BigInteger.ValueOf(mu); + } + else + { + u0 = BigInteger.Zero; + u1 = BigInteger.One; + } + + for (int i = 1; i < k; i++) + { + // u2 = mu*u1 - 2*u0; + BigInteger s = null; + if (mu == 1) + { + s = u1; + } + else + { + // mu == -1 + s = u1.Negate(); + } + + u2 = s.Subtract(u0.ShiftLeft(1)); + u0 = u1; + u1 = u2; + // System.out.println(i + ": " + u2); + // System.out.println(); + } + + BigInteger[] retVal = {u0, u1}; + return retVal; + } + + /** + * Computes the auxiliary value tw. If the width is + * 4, then for mu = 1, tw = 6 and for + * mu = -1, tw = 10 + * @param mu The parameter μ of the elliptic curve. + * @param w The window width of the WTNAF. + * @return the auxiliary value tw + */ + public static BigInteger GetTw(sbyte mu, int w) + { + if (w == 4) + { + if (mu == 1) + { + return BigInteger.ValueOf(6); + } + else + { + // mu == -1 + return BigInteger.ValueOf(10); + } + } + else + { + // For w <> 4, the values must be computed + BigInteger[] us = GetLucas(mu, w, false); + BigInteger twoToW = BigInteger.Zero.SetBit(w); + BigInteger u1invert = us[1].ModInverse(twoToW); + BigInteger tw; + tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW); + //System.out.println("mu = " + mu); + //System.out.println("tw = " + tw); + return tw; + } + } + + /** + * Computes the auxiliary values s0 and + * s1 used for partial modular reduction. + * @param curve The elliptic curve for which to compute + * s0 and s1. + * @throws ArgumentException if curve is not a + * Koblitz curve (Anomalous Binary Curve, ABC). + */ + public static BigInteger[] GetSi(AbstractF2mCurve curve) + { + if (!curve.IsKoblitz) + throw new ArgumentException("si is defined for Koblitz curves only"); + + int m = curve.FieldSize; + int a = curve.A.ToBigInteger().IntValue; + sbyte mu = GetMu(a); + int shifts = GetShiftsForCofactor(curve.Cofactor); + int index = m + 3 - a; + BigInteger[] ui = GetLucas(mu, index, false); + + if (mu == 1) + { + ui[0] = ui[0].Negate(); + ui[1] = ui[1].Negate(); + } + + BigInteger dividend0 = BigInteger.One.Add(ui[1]).ShiftRight(shifts); + BigInteger dividend1 = BigInteger.One.Add(ui[0]).ShiftRight(shifts).Negate(); + + return new BigInteger[] { dividend0, dividend1 }; + } + + public static BigInteger[] GetSi(int fieldSize, int curveA, BigInteger cofactor) + { + sbyte mu = GetMu(curveA); + int shifts = GetShiftsForCofactor(cofactor); + int index = fieldSize + 3 - curveA; + BigInteger[] ui = GetLucas(mu, index, false); + if (mu == 1) + { + ui[0] = ui[0].Negate(); + ui[1] = ui[1].Negate(); + } + + BigInteger dividend0 = BigInteger.One.Add(ui[1]).ShiftRight(shifts); + BigInteger dividend1 = BigInteger.One.Add(ui[0]).ShiftRight(shifts).Negate(); + + return new BigInteger[] { dividend0, dividend1 }; + } + + protected static int GetShiftsForCofactor(BigInteger h) + { + if (h != null && h.BitLength < 4) + { + int hi = h.IntValue; + if (hi == 2) + return 1; + if (hi == 4) + return 2; + } + + throw new ArgumentException("h (Cofactor) must be 2 or 4"); + } + + /** + * Partial modular reduction modulo + * m - 1)/(τ - 1). + * @param k The integer to be reduced. + * @param m The bitlength of the underlying finite field. + * @param a The parameter a of the elliptic curve. + * @param s The auxiliary values s0 and + * s1. + * @param mu The parameter μ of the elliptic curve. + * @param c The precision (number of bits of accuracy) of the partial + * modular reduction. + * @return ρ := k partmod (τm - 1)/(τ - 1) + */ + public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a, + BigInteger[] s, sbyte mu, sbyte c) + { + // d0 = s[0] + mu*s[1]; mu is either 1 or -1 + BigInteger d0; + if (mu == 1) + { + d0 = s[0].Add(s[1]); + } + else + { + d0 = s[0].Subtract(s[1]); + } + + BigInteger[] v = GetLucas(mu, m, true); + BigInteger vm = v[1]; + + SimpleBigDecimal lambda0 = ApproximateDivisionByN( + k, s[0], vm, a, m, c); + + SimpleBigDecimal lambda1 = ApproximateDivisionByN( + k, s[1], vm, a, m, c); + + ZTauElement q = Round(lambda0, lambda1, mu); + + // r0 = n - d0*q0 - 2*s1*q1 + BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract( + BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v)); + + // r1 = s1*q0 - s0*q1 + BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v)); + + return new ZTauElement(r0, r1); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by a BigInteger using the reduced τ-adic + * NAF (RTNAF) method. + * @param p The AbstractF2mPoint to Multiply. + * @param k The BigInteger by which to Multiply p. + * @return k * p + */ + public static AbstractF2mPoint MultiplyRTnaf(AbstractF2mPoint p, BigInteger k) + { + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + int m = curve.FieldSize; + int a = curve.A.ToBigInteger().IntValue; + sbyte mu = GetMu(a); + BigInteger[] s = curve.GetSi(); + ZTauElement rho = PartModReduction(k, m, (sbyte)a, s, mu, (sbyte)10); + + return MultiplyTnaf(p, rho); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] + * using the τ-adic NAF (TNAF) method. + * @param p The AbstractF2mPoint to Multiply. + * @param lambda The element λ of + * Z[τ]. + * @return λ * p + */ + public static AbstractF2mPoint MultiplyTnaf(AbstractF2mPoint p, ZTauElement lambda) + { + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + sbyte mu = GetMu(curve.A); + sbyte[] u = TauAdicNaf(mu, lambda); + + AbstractF2mPoint q = MultiplyFromTnaf(p, u); + + return q; + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] + * using the τ-adic NAF (TNAF) method, given the TNAF + * of λ. + * @param p The AbstractF2mPoint to Multiply. + * @param u The the TNAF of λ.. + * @return λ * p + */ + public static AbstractF2mPoint MultiplyFromTnaf(AbstractF2mPoint p, sbyte[] u) + { + ECCurve curve = p.Curve; + AbstractF2mPoint q = (AbstractF2mPoint)curve.Infinity; + AbstractF2mPoint pNeg = (AbstractF2mPoint)p.Negate(); + int tauCount = 0; + for (int i = u.Length - 1; i >= 0; i--) + { + ++tauCount; + sbyte ui = u[i]; + if (ui != 0) + { + q = q.TauPow(tauCount); + tauCount = 0; + + ECPoint x = ui > 0 ? p : pNeg; + q = (AbstractF2mPoint)q.Add(x); + } + } + if (tauCount > 0) + { + q = q.TauPow(tauCount); + } + return q; + } + + /** + * Computes the [τ]-adic window NAF of an element + * λ of Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ] of which to compute the + * [τ]-adic NAF. + * @param width The window width of the resulting WNAF. + * @param pow2w 2width. + * @param tw The auxiliary value tw. + * @param alpha The αu's for the window width. + * @return The [τ]-adic window NAF of + * λ. + */ + public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, + sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha) + { + if (!((mu == 1) || (mu == -1))) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger norm = Norm(mu, lambda); + + // Ceiling of log2 of the norm + int log2Norm = norm.BitLength; + + // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 + int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; + + // The array holding the TNAF + sbyte[] u = new sbyte[maxLength]; + + // 2^(width - 1) + BigInteger pow2wMin1 = pow2w.ShiftRight(1); + + // Split lambda into two BigIntegers to simplify calculations + BigInteger r0 = lambda.u; + BigInteger r1 = lambda.v; + int i = 0; + + // while lambda <> (0, 0) + while (!((r0.Equals(BigInteger.Zero))&&(r1.Equals(BigInteger.Zero)))) + { + // if r0 is odd + if (r0.TestBit(0)) + { + // uUnMod = r0 + r1*tw Mod 2^width + BigInteger uUnMod + = r0.Add(r1.Multiply(tw)).Mod(pow2w); + + sbyte uLocal; + // if uUnMod >= 2^(width - 1) + if (uUnMod.CompareTo(pow2wMin1) >= 0) + { + uLocal = (sbyte) uUnMod.Subtract(pow2w).IntValue; + } + else + { + uLocal = (sbyte) uUnMod.IntValue; + } + // uLocal is now in [-2^(width-1), 2^(width-1)-1] + + u[i] = uLocal; + bool s = true; + if (uLocal < 0) + { + s = false; + uLocal = (sbyte)-uLocal; + } + // uLocal is now >= 0 + + if (s) + { + r0 = r0.Subtract(alpha[uLocal].u); + r1 = r1.Subtract(alpha[uLocal].v); + } + else + { + r0 = r0.Add(alpha[uLocal].u); + r1 = r1.Add(alpha[uLocal].v); + } + } + else + { + u[i] = 0; + } + + BigInteger t = r0; + + if (mu == 1) + { + r0 = r1.Add(r0.ShiftRight(1)); + } + else + { + // mu == -1 + r0 = r1.Subtract(r0.ShiftRight(1)); + } + r1 = t.ShiftRight(1).Negate(); + i++; + } + return u; + } + + /** + * Does the precomputation for WTNAF multiplication. + * @param p The ECPoint for which to do the precomputation. + * @param a The parameter a of the elliptic curve. + * @return The precomputation array for p. + */ + public static AbstractF2mPoint[] GetPreComp(AbstractF2mPoint p, sbyte a) + { + sbyte[][] alphaTnaf = (a == 0) ? Tnaf.Alpha0Tnaf : Tnaf.Alpha1Tnaf; + + AbstractF2mPoint[] pu = new AbstractF2mPoint[(uint)(alphaTnaf.Length + 1) >> 1]; + pu[0] = p; + + uint precompLen = (uint)alphaTnaf.Length; + for (uint i = 3; i < precompLen; i += 2) + { + pu[i >> 1] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]); + } + + p.Curve.NormalizeAll(pu); + + return pu; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs.meta new file mode 100644 index 0000000..859f5e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/Tnaf.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c350a1fcb33886749ad8b6d264d92746 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs new file mode 100644 index 0000000..baf9b93 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Abc +{ + /** + * Class representing an element of Z[τ]. Let + * λ be an element of Z[τ]. Then + * λ is given as λ = u + vτ. The + * components u and v may be used directly, there + * are no accessor methods. + * Immutable class. + */ + internal class ZTauElement + { + /** + * The "real" part of λ. + */ + public readonly BigInteger u; + + /** + * The "τ-adic" part of λ. + */ + public readonly BigInteger v; + + /** + * Constructor for an element λ of + * Z[τ]. + * @param u The "real" part of λ. + * @param v The "τ-adic" part of + * λ. + */ + public ZTauElement(BigInteger u, BigInteger v) + { + this.u = u; + this.v = v; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs.meta new file mode 100644 index 0000000..7659efc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/abc/ZTauElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 06f1426762adf7a4a814250bf4084ce7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom.meta new file mode 100644 index 0000000..7aa25e8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f13f8a0df1a5e424796c38a3c077a81c +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb.meta new file mode 100644 index 0000000..350539f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 31334dab2586b6c458754ba0fa30f370 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs new file mode 100644 index 0000000..d606fbe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519 + : AbstractFpCurve + { + public static readonly BigInteger q = Nat256.ToBigInteger(Curve25519Field.P); + + private const int Curve25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + + protected readonly Curve25519Point m_infinity; + + public Curve25519() + : base(q) + { + this.m_infinity = new Curve25519Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864"))); + this.m_order = new BigInteger(1, Hex.Decode("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED")); + this.m_cofactor = BigInteger.ValueOf(8); + this.m_coord = Curve25519_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new Curve25519(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN_MODIFIED: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new Curve25519FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new Curve25519Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new Curve25519Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs.meta new file mode 100644 index 0000000..104dce9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 62c48392045829f409ce2c44bab3f21f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs new file mode 100644 index 0000000..0415110 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs @@ -0,0 +1,257 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519Field + { + // 2^255 - 2^4 - 2^1 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x7FFFFFFF }; + private const uint P7 = 0x7FFFFFFF; + private static readonly uint[] PExt = new uint[]{ 0x00000169, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x3FFFFFFF }; + private const uint PInv = 0x13; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + Nat256.Add(x, y, z); + if (Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + Nat.Add(16, xx, yy, zz); + if (Nat.Gte(16, zz, PExt)) + { + SubPExtFrom(zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + Nat.Inc(8, x, z); + if (Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat256.FromBigInteger(x); + while (Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, 0); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + Nat256.MulAddTo(x, y, zz); + if (Nat.Gte(16, zz, PExt)) + { + SubPExtFrom(zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat256.IsZero(x)) + { + Nat256.Zero(z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + Debug.Assert(xx[15] >> 30 == 0); + + uint xx07 = xx[7]; + Nat.ShiftUpBit(8, xx, 8, xx07, z, 0); + uint c = Nat256.MulByWordAddTo(PInv, xx, z) << 1; + uint z7 = z[7]; + c += (z7 >> 31) - (xx07 >> 31); + z7 &= P7; + z7 += Nat.AddWordTo(7, c * PInv, z); + z[7] = z7; + if (z7 >= P7 && Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static void Reduce27(uint x, uint[] z) + { + Debug.Assert(x >> 26 == 0); + + uint z7 = z[7]; + uint c = (x << 1 | z7 >> 31); + z7 &= P7; + z7 += Nat.AddWordTo(7, c * PInv, z); + z[7] = z7; + if (z7 >= P7 && Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + AddPTo(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + AddPExtTo(zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + Nat.ShiftUpBit(8, x, 0, z); + if (Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + private static uint AddPTo(uint[] z) + { + long c = (long)z[0] - PInv; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.DecAt(7, z, 1); + } + c += (long)z[7] + (P7 + 1); + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + private static uint AddPExtTo(uint[] zz) + { + long c = (long)zz[0] + PExt[0]; + zz[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.IncAt(8, zz, 1); + } + c += (long)zz[8] - PInv; + zz[8] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.DecAt(15, zz, 9); + } + c += (long)zz[15] + (PExt[15] + 1); + zz[15] = (uint)c; + c >>= 32; + return (uint)c; + } + + private static int SubPFrom(uint[] z) + { + long c = (long)z[0] + PInv; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.IncAt(7, z, 1); + } + c += (long)z[7] - (P7 + 1); + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + private static int SubPExtFrom(uint[] zz) + { + long c = (long)zz[0] - PExt[0]; + zz[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.DecAt(8, zz, 1); + } + c += (long)zz[8] + PInv; + zz[8] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.IncAt(15, zz, 9); + } + c += (long)zz[15] - (PExt[15] + 1); + zz[15] = (uint)c; + c >>= 32; + return (int)c; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs.meta new file mode 100644 index 0000000..823c9d9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1890aa1e585a00c46bd4d6e34b72cacd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs new file mode 100644 index 0000000..c563890 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs @@ -0,0 +1,237 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = Curve25519.q; + + // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q) + private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806, + 0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480 }; + + protected internal readonly uint[] x; + + public Curve25519FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for Curve25519FieldElement", "x"); + + this.x = Curve25519Field.FromBigInteger(x); + } + + public Curve25519FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal Curve25519FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "Curve25519Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + Curve25519Field.Add(x, ((Curve25519FieldElement)b).x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + Curve25519Field.AddOne(x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + Curve25519Field.Subtract(x, ((Curve25519FieldElement)b).x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + Curve25519Field.Multiply(x, ((Curve25519FieldElement)b).x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + Mod.Invert(Curve25519Field.P, ((Curve25519FieldElement)b).x, z); + Curve25519Field.Multiply(z, x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + Curve25519Field.Negate(x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + Curve25519Field.Square(x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new Curve25519FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + Mod.Invert(Curve25519Field.P, x, z); + return new Curve25519FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Q == 8m + 5, so we use Pocklington's method for this case. + * + * First, raise this element to the exponent 2^252 - 2^1 (i.e. m + 1) + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 251 1s } { 1 0s } + * + * Therefore we need an addition chain containing 251 (the lengths of the repunits) + * We use: 1, 2, 3, 4, 7, 11, 15, 30, 60, 120, 131, [251] + */ + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + return this; + + uint[] x2 = Nat256.Create(); + Curve25519Field.Square(x1, x2); + Curve25519Field.Multiply(x2, x1, x2); + uint[] x3 = x2; + Curve25519Field.Square(x2, x3); + Curve25519Field.Multiply(x3, x1, x3); + uint[] x4 = Nat256.Create(); + Curve25519Field.Square(x3, x4); + Curve25519Field.Multiply(x4, x1, x4); + uint[] x7 = Nat256.Create(); + Curve25519Field.SquareN(x4, 3, x7); + Curve25519Field.Multiply(x7, x3, x7); + uint[] x11 = x3; + Curve25519Field.SquareN(x7, 4, x11); + Curve25519Field.Multiply(x11, x4, x11); + uint[] x15 = x7; + Curve25519Field.SquareN(x11, 4, x15); + Curve25519Field.Multiply(x15, x4, x15); + uint[] x30 = x4; + Curve25519Field.SquareN(x15, 15, x30); + Curve25519Field.Multiply(x30, x15, x30); + uint[] x60 = x15; + Curve25519Field.SquareN(x30, 30, x60); + Curve25519Field.Multiply(x60, x30, x60); + uint[] x120 = x30; + Curve25519Field.SquareN(x60, 60, x120); + Curve25519Field.Multiply(x120, x60, x120); + uint[] x131 = x60; + Curve25519Field.SquareN(x120, 11, x131); + Curve25519Field.Multiply(x131, x11, x131); + uint[] x251 = x11; + Curve25519Field.SquareN(x131, 120, x251); + Curve25519Field.Multiply(x251, x120, x251); + + uint[] t1 = x251; + Curve25519Field.Square(t1, t1); + + uint[] t2 = x120; + Curve25519Field.Square(t1, t2); + + if (Nat256.Eq(x1, t2)) + { + return new Curve25519FieldElement(t1); + } + + /* + * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess, + * which is ((4x)^(m + 1))/2 mod Q + */ + Curve25519Field.Multiply(t1, PRECOMP_POW2, t1); + + Curve25519Field.Square(t1, t2); + + if (Nat256.Eq(x1, t2)) + { + return new Curve25519FieldElement(t1); + } + + return null; + } + + public override bool Equals(object obj) + { + return Equals(obj as Curve25519FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as Curve25519FieldElement); + } + + public virtual bool Equals(Curve25519FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs.meta new file mode 100644 index 0000000..0ac63f3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 07192861401eab44e845802495e99b0d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs new file mode 100644 index 0000000..fa62e30 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs @@ -0,0 +1,317 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + * @param withCompression if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new Curve25519Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement GetZCoord(int index) + { + if (index == 1) + { + return GetJacobianModifiedW(); + } + + return base.GetZCoord(index); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord, + Z1 = (Curve25519FieldElement)this.RawZCoords[0]; + Curve25519FieldElement X2 = (Curve25519FieldElement)b.RawXCoord, Y2 = (Curve25519FieldElement)b.RawYCoord, + Z2 = (Curve25519FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + Curve25519Field.Square(Z1.x, S2); + + U2 = t2; + Curve25519Field.Multiply(S2, X2.x, U2); + + Curve25519Field.Multiply(S2, Z1.x, S2); + Curve25519Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + Curve25519Field.Square(Z2.x, S1); + + U1 = tt1; + Curve25519Field.Multiply(S1, X1.x, U1); + + Curve25519Field.Multiply(S1, Z2.x, S1); + Curve25519Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + Curve25519Field.Subtract(U1, U2, H); + + uint[] R = t2; + Curve25519Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = Nat256.Create(); + Curve25519Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + Curve25519Field.Multiply(HSquared, H, G); + + uint[] V = t3; + Curve25519Field.Multiply(HSquared, U1, V); + + Curve25519Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + Curve25519Field.Reduce27(c, G); + + Curve25519FieldElement X3 = new Curve25519FieldElement(t4); + Curve25519Field.Square(R, X3.x); + Curve25519Field.Subtract(X3.x, G, X3.x); + + Curve25519FieldElement Y3 = new Curve25519FieldElement(G); + Curve25519Field.Subtract(V, X3.x, Y3.x); + Curve25519Field.MultiplyAddToExt(Y3.x, R, tt1); + Curve25519Field.Reduce(tt1, Y3.x); + + Curve25519FieldElement Z3 = new Curve25519FieldElement(H); + if (!Z1IsOne) + { + Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + Curve25519Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + uint[] Z3Squared = (Z1IsOne && Z2IsOne) ? HSquared : null; + + // TODO If the result will only be used in a subsequent addition, we don't need W3 + Curve25519FieldElement W3 = CalculateJacobianModifiedW((Curve25519FieldElement)Z3, Z3Squared); + + ECFieldElement[] zs = new ECFieldElement[] { Z3, W3 }; + + return new Curve25519Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + return TwiceJacobianModified(true); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return TwiceJacobianModified(false).Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + return TwiceJacobianModified(false).Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new Curve25519Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + + protected virtual Curve25519FieldElement CalculateJacobianModifiedW(Curve25519FieldElement Z, uint[] ZSquared) + { + Curve25519FieldElement a4 = (Curve25519FieldElement)this.Curve.A; + if (Z.IsOne) + return a4; + + Curve25519FieldElement W = new Curve25519FieldElement(); + if (ZSquared == null) + { + ZSquared = W.x; + Curve25519Field.Square(Z.x, ZSquared); + } + Curve25519Field.Square(ZSquared, W.x); + Curve25519Field.Multiply(W.x, a4.x, W.x); + return W; + } + + protected virtual Curve25519FieldElement GetJacobianModifiedW() + { + ECFieldElement[] ZZ = this.RawZCoords; + Curve25519FieldElement W = (Curve25519FieldElement)ZZ[1]; + if (W == null) + { + // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here + ZZ[1] = W = CalculateJacobianModifiedW((Curve25519FieldElement)ZZ[0], null); + } + return W; + } + + protected virtual Curve25519Point TwiceJacobianModified(bool calculateW) + { + Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord, + Z1 = (Curve25519FieldElement)this.RawZCoords[0], W1 = GetJacobianModifiedW(); + + uint c; + + uint[] M = Nat256.Create(); + Curve25519Field.Square(X1.x, M); + c = Nat256.AddBothTo(M, M, M); + c += Nat256.AddTo(W1.x, M); + Curve25519Field.Reduce27(c, M); + + uint[] _2Y1 = Nat256.Create(); + Curve25519Field.Twice(Y1.x, _2Y1); + + uint[] _2Y1Squared = Nat256.Create(); + Curve25519Field.Multiply(_2Y1, Y1.x, _2Y1Squared); + + uint[] S = Nat256.Create(); + Curve25519Field.Multiply(_2Y1Squared, X1.x, S); + Curve25519Field.Twice(S, S); + + uint[] _8T = Nat256.Create(); + Curve25519Field.Square(_2Y1Squared, _8T); + Curve25519Field.Twice(_8T, _8T); + + Curve25519FieldElement X3 = new Curve25519FieldElement(_2Y1Squared); + Curve25519Field.Square(M, X3.x); + Curve25519Field.Subtract(X3.x, S, X3.x); + Curve25519Field.Subtract(X3.x, S, X3.x); + + Curve25519FieldElement Y3 = new Curve25519FieldElement(S); + Curve25519Field.Subtract(S, X3.x, Y3.x); + Curve25519Field.Multiply(Y3.x, M, Y3.x); + Curve25519Field.Subtract(Y3.x, _8T, Y3.x); + + Curve25519FieldElement Z3 = new Curve25519FieldElement(_2Y1); + if (!Nat256.IsOne(Z1.x)) + { + Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + Curve25519FieldElement W3 = null; + if (calculateW) + { + W3 = new Curve25519FieldElement(_8T); + Curve25519Field.Multiply(W3.x, W1.x, W3.x); + Curve25519Field.Twice(W3.x, W3.x); + } + + return new Curve25519Point(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs.meta new file mode 100644 index 0000000..21a75b4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/djb/Curve25519Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5876f88aced697149a82ac6ff3f8e27f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec.meta new file mode 100644 index 0000000..34a9f32 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: edf4874c4cb236144b35b46e9a8037ad +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs new file mode 100644 index 0000000..39295ef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF")); + + private const int SecP128R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP128R1Point m_infinity; + + public SecP128R1Curve() + : base(q) + { + this.m_infinity = new SecP128R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("E87579C11079F43DD824993C2CEE5ED3"))); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFE0000000075A30D1B9038A115")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SecP128R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP128R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP128R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP128R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP128R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs.meta new file mode 100644 index 0000000..0504beb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 07d11740bf1c5f949b70c6663eb822ad +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs new file mode 100644 index 0000000..8c89e64 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs @@ -0,0 +1,222 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1Field + { + // 2^128 - 2^97 - 1 + internal static readonly uint[] P = new uint[] { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD }; + internal static readonly uint[] PExt = new uint[] { 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFE, + 0xFFFFFFFF, 0x00000003, 0xFFFFFFFC }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB, + 0x00000001, 0x00000000, 0xFFFFFFFC, 0x00000003 }; + private const uint P3 = 0xFFFFFFFD; + private const uint PExt7 = 0xFFFFFFFC; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat128.Add(x, y, z); + if (c != 0 || (z[3] == P3 && Nat128.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat256.Add(xx, yy, zz); + if (c != 0 || (zz[7] == PExt7 && Nat256.Gte(zz, PExt))) + { + Nat.AddTo(PExtInv.Length, PExtInv, zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(4, x, z); + if (c != 0 || (z[3] == P3 && Nat128.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat128.FromBigInteger(x); + if (z[3] == P3 && Nat128.Gte(z, P)) + { + Nat128.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(4, x, 0, z); + } + else + { + uint c = Nat128.Add(x, P, z); + Nat.ShiftDownBit(4, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat128.CreateExt(); + Nat128.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat128.MulAddTo(x, y, zz); + if (c != 0 || (zz[7] == PExt7 && Nat256.Gte(zz, PExt))) + { + Nat.AddTo(PExtInv.Length, PExtInv, zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat128.IsZero(x)) + { + Nat128.Zero(z); + } + else + { + Nat128.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7]; + + x3 += x7; x6 += (x7 << 1); + x2 += x6; x5 += (x6 << 1); + x1 += x5; x4 += (x5 << 1); + x0 += x4; x3 += (x4 << 1); + + z[0] = (uint)x0; x1 += (x0 >> 32); + z[1] = (uint)x1; x2 += (x1 >> 32); + z[2] = (uint)x2; x3 += (x2 >> 32); + z[3] = (uint)x3; + + Reduce32((uint)(x3 >> 32), z); + } + + public static void Reduce32(uint x, uint[] z) + { + while (x != 0) + { + ulong c, x4 = x; + + c = (ulong)z[0] + x4; + z[0] = (uint)c; c >>= 32; + if (c != 0) + { + c += (ulong)z[1]; + z[1] = (uint)c; c >>= 32; + c += (ulong)z[2]; + z[2] = (uint)c; c >>= 32; + } + c += (ulong)z[3] + (x4 << 1); + z[3] = (uint)c; c >>= 32; + + Debug.Assert(c >= 0 && c <= 2); + + x = (uint)c; + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat128.CreateExt(); + Nat128.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat128.CreateExt(); + Nat128.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat128.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat128.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(10, xx, yy, zz); + if (c != 0) + { + Nat.SubFrom(PExtInv.Length, PExtInv, zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(4, x, 0, z); + if (c != 0 || (z[3] == P3 && Nat128.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; c >>= 32; + } + c += (long)z[3] + 2; + z[3] = (uint)c; + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; c >>= 32; + } + c += (long)z[3] - 2; + z[3] = (uint)c; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs.meta new file mode 100644 index 0000000..8b31ce7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9d092c55e0cd03418fa2b044ec88ff3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs new file mode 100644 index 0000000..715b63d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs @@ -0,0 +1,202 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP128R1Curve.q; + + protected internal readonly uint[] x; + + public SecP128R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP128R1FieldElement", "x"); + + this.x = SecP128R1Field.FromBigInteger(x); + } + + public SecP128R1FieldElement() + { + this.x = Nat128.Create(); + } + + protected internal SecP128R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat128.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat128.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat128.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat128.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP128R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat128.Create(); + SecP128R1Field.Add(x, ((SecP128R1FieldElement)b).x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat128.Create(); + SecP128R1Field.AddOne(x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat128.Create(); + SecP128R1Field.Subtract(x, ((SecP128R1FieldElement)b).x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat128.Create(); + SecP128R1Field.Multiply(x, ((SecP128R1FieldElement)b).x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + // return multiply(b.invert()); + uint[] z = Nat128.Create(); + Mod.Invert(SecP128R1Field.P, ((SecP128R1FieldElement)b).x, z); + SecP128R1Field.Multiply(z, x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat128.Create(); + SecP128R1Field.Negate(x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat128.Create(); + SecP128R1Field.Square(x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + // return new SecP128R1FieldElement(toBigInteger().modInverse(Q)); + uint[] z = Nat128.Create(); + Mod.Invert(SecP128R1Field.P, x, z); + return new SecP128R1FieldElement(z); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^126 - 2^95 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 31 1s } { 95 0s } + * + * Therefore we need an addition chain containing 31 (the length of the repunit) We use: + * 1, 2, 4, 8, 10, 20, 30, [31] + */ + + uint[] x1 = this.x; + if (Nat128.IsZero(x1) || Nat128.IsOne(x1)) + return this; + + uint[] x2 = Nat128.Create(); + SecP128R1Field.Square(x1, x2); + SecP128R1Field.Multiply(x2, x1, x2); + uint[] x4 = Nat128.Create(); + SecP128R1Field.SquareN(x2, 2, x4); + SecP128R1Field.Multiply(x4, x2, x4); + uint[] x8 = Nat128.Create(); + SecP128R1Field.SquareN(x4, 4, x8); + SecP128R1Field.Multiply(x8, x4, x8); + uint[] x10 = x4; + SecP128R1Field.SquareN(x8, 2, x10); + SecP128R1Field.Multiply(x10, x2, x10); + uint[] x20 = x2; + SecP128R1Field.SquareN(x10, 10, x20); + SecP128R1Field.Multiply(x20, x10, x20); + uint[] x30 = x8; + SecP128R1Field.SquareN(x20, 10, x30); + SecP128R1Field.Multiply(x30, x10, x30); + uint[] x31 = x10; + SecP128R1Field.Square(x30, x31); + SecP128R1Field.Multiply(x31, x1, x31); + + uint[] t1 = x31; + SecP128R1Field.SquareN(t1, 95, t1); + + uint[] t2 = x30; + SecP128R1Field.Square(t1, t2); + + return Nat128.Eq(x1, t2) ? new SecP128R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP128R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP128R1FieldElement); + } + + public virtual bool Equals(SecP128R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat128.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 4); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs.meta new file mode 100644 index 0000000..90d107f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f1b6f52fadd8950438dcf90df281b600 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs new file mode 100644 index 0000000..b26bd8f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(boolean)} + */ + public SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP128R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP128R1FieldElement X1 = (SecP128R1FieldElement)this.RawXCoord, Y1 = (SecP128R1FieldElement)this.RawYCoord; + SecP128R1FieldElement X2 = (SecP128R1FieldElement)b.RawXCoord, Y2 = (SecP128R1FieldElement)b.RawYCoord; + + SecP128R1FieldElement Z1 = (SecP128R1FieldElement)this.RawZCoords[0]; + SecP128R1FieldElement Z2 = (SecP128R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat128.CreateExt(); + uint[] t2 = Nat128.Create(); + uint[] t3 = Nat128.Create(); + uint[] t4 = Nat128.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP128R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP128R1Field.Multiply(S2, X2.x, U2); + + SecP128R1Field.Multiply(S2, Z1.x, S2); + SecP128R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP128R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP128R1Field.Multiply(S1, X1.x, U1); + + SecP128R1Field.Multiply(S1, Z2.x, S1); + SecP128R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat128.Create(); + SecP128R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP128R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat128.IsZero(H)) + { + if (Nat128.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP128R1Field.Square(H, HSquared); + + uint[] G = Nat128.Create(); + SecP128R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP128R1Field.Multiply(HSquared, U1, V); + + SecP128R1Field.Negate(G, G); + Nat128.Mul(S1, G, tt1); + + c = Nat128.AddBothTo(V, V, G); + SecP128R1Field.Reduce32(c, G); + + SecP128R1FieldElement X3 = new SecP128R1FieldElement(t4); + SecP128R1Field.Square(R, X3.x); + SecP128R1Field.Subtract(X3.x, G, X3.x); + + SecP128R1FieldElement Y3 = new SecP128R1FieldElement(G); + SecP128R1Field.Subtract(V, X3.x, Y3.x); + SecP128R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP128R1Field.Reduce(tt1, Y3.x); + + SecP128R1FieldElement Z3 = new SecP128R1FieldElement(H); + if (!Z1IsOne) + { + SecP128R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP128R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP128R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP128R1FieldElement Y1 = (SecP128R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP128R1FieldElement X1 = (SecP128R1FieldElement)this.RawXCoord, Z1 = (SecP128R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat128.Create(); + uint[] t2 = Nat128.Create(); + + uint[] Y1Squared = Nat128.Create(); + SecP128R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat128.Create(); + SecP128R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP128R1Field.Square(Z1.x, Z1Squared); + } + + SecP128R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP128R1Field.Add(X1.x, Z1Squared, M); + SecP128R1Field.Multiply(M, t1, M); + c = Nat128.AddBothTo(M, M, M); + SecP128R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP128R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(4, S, 2, 0); + SecP128R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(4, T, 3, 0, t1); + SecP128R1Field.Reduce32(c, t1); + + SecP128R1FieldElement X3 = new SecP128R1FieldElement(T); + SecP128R1Field.Square(M, X3.x); + SecP128R1Field.Subtract(X3.x, S, X3.x); + SecP128R1Field.Subtract(X3.x, S, X3.x); + + SecP128R1FieldElement Y3 = new SecP128R1FieldElement(S); + SecP128R1Field.Subtract(S, X3.x, Y3.x); + SecP128R1Field.Multiply(Y3.x, M, Y3.x); + SecP128R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP128R1FieldElement Z3 = new SecP128R1FieldElement(M); + SecP128R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP128R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP128R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between twicePlus and threeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP128R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs.meta new file mode 100644 index 0000000..b46fcb0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP128R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b719fcfaca4697a499481a1ec81e4e74 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs new file mode 100644 index 0000000..ef5d4ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs @@ -0,0 +1,78 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP160R2Curve.q; + + private const int SECP160K1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP160K1Point m_infinity; + + public SecP160K1Curve() + : base(q) + { + this.m_infinity = new SecP160K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(7)); + this.m_order = new BigInteger(1, Hex.Decode("0100000000000000000001B8FA16DFAB9ACA16B6B3")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP160K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP160K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP160R2FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP160K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP160K1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs.meta new file mode 100644 index 0000000..00decb4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1150199688daf104cb227e8776202137 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs new file mode 100644 index 0000000..4a21c49 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs @@ -0,0 +1,273 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP160K1Point(null, AffineXCoord, AffineYCoord); + } + + // B.3 pg 62 + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord; + SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord; + + SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat160.CreateExt(); + uint[] t2 = Nat160.Create(); + uint[] t3 = Nat160.Create(); + uint[] t4 = Nat160.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP160R2Field.Square(Z1.x, S2); + + U2 = t2; + SecP160R2Field.Multiply(S2, X2.x, U2); + + SecP160R2Field.Multiply(S2, Z1.x, S2); + SecP160R2Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP160R2Field.Square(Z2.x, S1); + + U1 = tt1; + SecP160R2Field.Multiply(S1, X1.x, U1); + + SecP160R2Field.Multiply(S1, Z2.x, S1); + SecP160R2Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat160.Create(); + SecP160R2Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP160R2Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat160.IsZero(H)) + { + if (Nat160.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP160R2Field.Square(H, HSquared); + + uint[] G = Nat160.Create(); + SecP160R2Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP160R2Field.Multiply(HSquared, U1, V); + + SecP160R2Field.Negate(G, G); + Nat160.Mul(S1, G, tt1); + + c = Nat160.AddBothTo(V, V, G); + SecP160R2Field.Reduce32(c, G); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4); + SecP160R2Field.Square(R, X3.x); + SecP160R2Field.Subtract(X3.x, G, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G); + SecP160R2Field.Subtract(V, X3.x, Y3.x); + SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP160R2Field.Reduce(tt1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H); + if (!Z1IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP160K1Point(curve, X3, Y3, zs, IsCompressed); + } + + // B.3 pg 62 + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP160R2FieldElement Y1 = (SecP160R2FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat160.Create(); + SecP160R2Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat160.Create(); + SecP160R2Field.Square(Y1Squared, T); + + uint[] M = Nat160.Create(); + SecP160R2Field.Square(X1.x, M); + c = Nat160.AddBothTo(M, M, M); + SecP160R2Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP160R2Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(5, S, 2, 0); + SecP160R2Field.Reduce32(c, S); + + uint[] t1 = Nat160.Create(); + c = Nat.ShiftUpBits(5, T, 3, 0, t1); + SecP160R2Field.Reduce32(c, t1); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(T); + SecP160R2Field.Square(M, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(S); + SecP160R2Field.Subtract(S, X3.x, Y3.x); + SecP160R2Field.Multiply(Y3.x, M, Y3.x); + SecP160R2Field.Subtract(Y3.x, t1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(M); + SecP160R2Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP160K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and threeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP160K1Point(Curve, this.RawXCoord, this.RawYCoord.Negate(), this.RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs.meta new file mode 100644 index 0000000..960e8d5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5e8be84848d57df40bf9d4558a98c6e7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs new file mode 100644 index 0000000..9fc778e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")); + + private const int SecP160R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP160R1Point m_infinity; + + public SecP160R1Curve() + : base(q) + { + this.m_infinity = new SecP160R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"))); + this.m_order = new BigInteger(1, Hex.Decode("0100000000000000000001F4C8F927AED3CA752257")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SecP160R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP160R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP160R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP160R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP160R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs.meta new file mode 100644 index 0000000..996b573 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ab70ddacc717f914998f8131af159ac2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs new file mode 100644 index 0000000..0649a62 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs @@ -0,0 +1,190 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1Field + { + // 2^160 - 2^31 - 1 + internal static readonly uint[] P = new uint[] { 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + internal static readonly uint[] PExt = new uint[] { 0x00000001, 0x40000001, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xBFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x00000001, 0x00000001 }; + private const uint P4 = 0xFFFFFFFF; + private const uint PExt9 = 0xFFFFFFFF; + private const uint PInv = 0x80000001; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat160.Add(x, y, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(10, xx, yy, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(5, x, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat160.FromBigInteger(x); + if (z[4] == P4 && Nat160.Gte(z, P)) + { + Nat160.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(5, x, 0, z); + } + else + { + uint c = Nat160.Add(x, P, z); + Nat.ShiftDownBit(5, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat160.MulAddTo(x, y, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat160.IsZero(x)) + { + Nat160.Zero(z); + } + else + { + Nat160.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong x5 = xx[5], x6 = xx[6], x7 = xx[7], x8 = xx[8], x9 = xx[9]; + + ulong c = 0; + c += (ulong)xx[0] + x5 + (x5 << 31); + z[0] = (uint)c; c >>= 32; + c += (ulong)xx[1] + x6 + (x6 << 31); + z[1] = (uint)c; c >>= 32; + c += (ulong)xx[2] + x7 + (x7 << 31); + z[2] = (uint)c; c >>= 32; + c += (ulong)xx[3] + x8 + (x8 << 31); + z[3] = (uint)c; c >>= 32; + c += (ulong)xx[4] + x9 + (x9 << 31); + z[4] = (uint)c; c >>= 32; + + Debug.Assert(c >> 32 == 0); + + Reduce32((uint)c, z); + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat160.MulWordsAdd(PInv, x, z, 0) != 0) + || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat160.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat160.Sub(x, y, z); + if (c != 0) + { + Nat.SubWordFrom(5, PInv, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(10, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(10, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(5, x, 0, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs.meta new file mode 100644 index 0000000..28c7a21 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d444683aade1525409d6f03a80cd747c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs new file mode 100644 index 0000000..85f8e1f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs @@ -0,0 +1,207 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP160R1Curve.q; + + protected internal readonly uint[] x; + + public SecP160R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP160R1FieldElement", "x"); + + this.x = SecP160R1Field.FromBigInteger(x); + } + + public SecP160R1FieldElement() + { + this.x = Nat160.Create(); + } + + protected internal SecP160R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat160.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat160.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat160.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat160.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP160R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R1Field.Add(x, ((SecP160R1FieldElement)b).x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat160.Create(); + SecP160R1Field.AddOne(x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R1Field.Subtract(x, ((SecP160R1FieldElement)b).x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R1Field.Multiply(x, ((SecP160R1FieldElement)b).x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + // return multiply(b.invert()); + uint[] z = Nat160.Create(); + Mod.Invert(SecP160R1Field.P, ((SecP160R1FieldElement)b).x, z); + SecP160R1Field.Multiply(z, x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat160.Create(); + SecP160R1Field.Negate(x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat160.Create(); + SecP160R1Field.Square(x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + // return new SecP160R1FieldElement(ToBigInteger().modInverse(Q)); + uint[] z = Nat160.Create(); + Mod.Invert(SecP160R1Field.P, x, z); + return new SecP160R1FieldElement(z); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^158 - 2^29 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 129 1s } { 29 0s } + * + * Therefore we need an addition chain containing 129 (the length of the repunit) We use: + * 1, 2, 4, 8, 16, 32, 64, 128, [129] + */ + + uint[] x1 = this.x; + if (Nat160.IsZero(x1) || Nat160.IsOne(x1)) + { + return this; + } + + uint[] x2 = Nat160.Create(); + SecP160R1Field.Square(x1, x2); + SecP160R1Field.Multiply(x2, x1, x2); + uint[] x4 = Nat160.Create(); + SecP160R1Field.SquareN(x2, 2, x4); + SecP160R1Field.Multiply(x4, x2, x4); + uint[] x8 = x2; + SecP160R1Field.SquareN(x4, 4, x8); + SecP160R1Field.Multiply(x8, x4, x8); + uint[] x16 = x4; + SecP160R1Field.SquareN(x8, 8, x16); + SecP160R1Field.Multiply(x16, x8, x16); + uint[] x32 = x8; + SecP160R1Field.SquareN(x16, 16, x32); + SecP160R1Field.Multiply(x32, x16, x32); + uint[] x64 = x16; + SecP160R1Field.SquareN(x32, 32, x64); + SecP160R1Field.Multiply(x64, x32, x64); + uint[] x128 = x32; + SecP160R1Field.SquareN(x64, 64, x128); + SecP160R1Field.Multiply(x128, x64, x128); + uint[] x129 = x64; + SecP160R1Field.Square(x128, x129); + SecP160R1Field.Multiply(x129, x1, x129); + + uint[] t1 = x129; + SecP160R1Field.SquareN(t1, 29, t1); + + uint[] t2 = x128; + SecP160R1Field.Square(t1, t2); + + return Nat160.Eq(x1, t2) ? new SecP160R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP160R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP160R1FieldElement); + } + + public virtual bool Equals(SecP160R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat160.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs.meta new file mode 100644 index 0000000..0689ce4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 07c4fed00202a584c88533f83236ec32 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs new file mode 100644 index 0000000..955c492 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP160R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP160R1FieldElement X1 = (SecP160R1FieldElement)this.RawXCoord, Y1 = (SecP160R1FieldElement)this.RawYCoord; + SecP160R1FieldElement X2 = (SecP160R1FieldElement)b.RawXCoord, Y2 = (SecP160R1FieldElement)b.RawYCoord; + + SecP160R1FieldElement Z1 = (SecP160R1FieldElement)this.RawZCoords[0]; + SecP160R1FieldElement Z2 = (SecP160R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat160.CreateExt(); + uint[] t2 = Nat160.Create(); + uint[] t3 = Nat160.Create(); + uint[] t4 = Nat160.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP160R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP160R1Field.Multiply(S2, X2.x, U2); + + SecP160R1Field.Multiply(S2, Z1.x, S2); + SecP160R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP160R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP160R1Field.Multiply(S1, X1.x, U1); + + SecP160R1Field.Multiply(S1, Z2.x, S1); + SecP160R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat160.Create(); + SecP160R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP160R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat160.IsZero(H)) + { + if (Nat160.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP160R1Field.Square(H, HSquared); + + uint[] G = Nat160.Create(); + SecP160R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP160R1Field.Multiply(HSquared, U1, V); + + SecP160R1Field.Negate(G, G); + Nat160.Mul(S1, G, tt1); + + c = Nat160.AddBothTo(V, V, G); + SecP160R1Field.Reduce32(c, G); + + SecP160R1FieldElement X3 = new SecP160R1FieldElement(t4); + SecP160R1Field.Square(R, X3.x); + SecP160R1Field.Subtract(X3.x, G, X3.x); + + SecP160R1FieldElement Y3 = new SecP160R1FieldElement(G); + SecP160R1Field.Subtract(V, X3.x, Y3.x); + SecP160R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP160R1Field.Reduce(tt1, Y3.x); + + SecP160R1FieldElement Z3 = new SecP160R1FieldElement(H); + if (!Z1IsOne) + { + SecP160R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP160R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP160R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP160R1FieldElement Y1 = (SecP160R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP160R1FieldElement X1 = (SecP160R1FieldElement)this.RawXCoord, Z1 = (SecP160R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat160.Create(); + uint[] t2 = Nat160.Create(); + + uint[] Y1Squared = Nat160.Create(); + SecP160R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat160.Create(); + SecP160R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP160R1Field.Square(Z1.x, Z1Squared); + } + + SecP160R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP160R1Field.Add(X1.x, Z1Squared, M); + SecP160R1Field.Multiply(M, t1, M); + c = Nat160.AddBothTo(M, M, M); + SecP160R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP160R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(5, S, 2, 0); + SecP160R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(5, T, 3, 0, t1); + SecP160R1Field.Reduce32(c, t1); + + SecP160R1FieldElement X3 = new SecP160R1FieldElement(T); + SecP160R1Field.Square(M, X3.x); + SecP160R1Field.Subtract(X3.x, S, X3.x); + SecP160R1Field.Subtract(X3.x, S, X3.x); + + SecP160R1FieldElement Y3 = new SecP160R1FieldElement(S); + SecP160R1Field.Subtract(S, X3.x, Y3.x); + SecP160R1Field.Multiply(Y3.x, M, Y3.x); + SecP160R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP160R1FieldElement Z3 = new SecP160R1FieldElement(M); + SecP160R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP160R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP160R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP160R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs.meta new file mode 100644 index 0000000..9cde8fa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 48035112039046c41b2a437840a8014d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs new file mode 100644 index 0000000..4eb7919 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73")); + + private const int SecP160R2_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP160R2Point m_infinity; + + public SecP160R2Curve() + : base(q) + { + this.m_infinity = new SecP160R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("B4E134D3FB59EB8BAB57274904664D5AF50388BA"))); + this.m_order = new BigInteger(1, Hex.Decode("0100000000000000000000351EE786A818F3A1A16B")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SecP160R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP160R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP160R2FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP160R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP160R2Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs.meta new file mode 100644 index 0000000..57b72fa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d36a6056a9fa51946b70dd3977edfb28 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs new file mode 100644 index 0000000..29e8d54 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs @@ -0,0 +1,182 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2Field + { + // 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFAC73, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x1B44BBA9, 0x0000A71A, 0x00000001, 0x00000000, 0x00000000, + 0xFFFF58E6, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xE4BB4457, 0xFFFF58E5, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0x0000A719, 0x00000002 }; + private const uint P4 = 0xFFFFFFFF; + private const uint PExt9 = 0xFFFFFFFF; + private const uint PInv33 = 0x538D; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat160.Add(x, y, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(10, xx, yy, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(5, x, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat160.FromBigInteger(x); + if (z[4] == P4 && Nat160.Gte(z, P)) + { + Nat160.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(5, x, 0, z); + } + else + { + uint c = Nat160.Add(x, P, z); + Nat.ShiftDownBit(5, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat160.MulAddTo(x, y, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat160.IsZero(x)) + { + Nat160.Zero(z); + } + else + { + Nat160.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat160.Mul33Add(PInv33, xx, 5, xx, 0, z, 0); + uint c = Nat160.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat160.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat160.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat160.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(5, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(10, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(10, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(5, x, 0, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs.meta new file mode 100644 index 0000000..95fc55d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e351f45b5e75bb149baf02e11f068f33 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs new file mode 100644 index 0000000..52785b9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs @@ -0,0 +1,222 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP160R2Curve.q; + + protected internal readonly uint[] x; + + public SecP160R2FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP160R2FieldElement", "x"); + + this.x = SecP160R2Field.FromBigInteger(x); + } + + public SecP160R2FieldElement() + { + this.x = Nat160.Create(); + } + + protected internal SecP160R2FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat160.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat160.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat160.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat160.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP160R2Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R2Field.Add(x, ((SecP160R2FieldElement)b).x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat160.Create(); + SecP160R2Field.AddOne(x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R2Field.Subtract(x, ((SecP160R2FieldElement)b).x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R2Field.Multiply(x, ((SecP160R2FieldElement)b).x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + // return Multiply(b.invert()); + uint[] z = Nat160.Create(); + Mod.Invert(SecP160R2Field.P, ((SecP160R2FieldElement)b).x, z); + SecP160R2Field.Multiply(z, x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat160.Create(); + SecP160R2Field.Negate(x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat160.Create(); + SecP160R2Field.Square(x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Invert() + { + // return new SecP160R2FieldElement(ToBigInteger().modInverse(Q)); + uint[] z = Nat160.Create(); + Mod.Invert(SecP160R2Field.P, x, z); + return new SecP160R2FieldElement(z); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^158 - 2^30 - 2^12 - 2^10 - 2^7 - 2^6 - 2^5 - 2^1 - 2^0 + * + * Breaking up the exponent's binary representation into "repunits", we get: { 127 1s } { 1 + * 0s } { 17 1s } { 1 0s } { 1 1s } { 1 0s } { 2 1s } { 3 0s } { 3 1s } { 1 0s } { 1 1s } + * + * Therefore we need an Addition chain containing 1, 2, 3, 17, 127 (the lengths of the repunits) + * We use: [1], [2], [3], 4, 7, 14, [17], 31, 62, 124, [127] + */ + + uint[] x1 = this.x; + if (Nat160.IsZero(x1) || Nat160.IsOne(x1)) + { + return this; + } + + uint[] x2 = Nat160.Create(); + SecP160R2Field.Square(x1, x2); + SecP160R2Field.Multiply(x2, x1, x2); + uint[] x3 = Nat160.Create(); + SecP160R2Field.Square(x2, x3); + SecP160R2Field.Multiply(x3, x1, x3); + uint[] x4 = Nat160.Create(); + SecP160R2Field.Square(x3, x4); + SecP160R2Field.Multiply(x4, x1, x4); + uint[] x7 = Nat160.Create(); + SecP160R2Field.SquareN(x4, 3, x7); + SecP160R2Field.Multiply(x7, x3, x7); + uint[] x14 = x4; + SecP160R2Field.SquareN(x7, 7, x14); + SecP160R2Field.Multiply(x14, x7, x14); + uint[] x17 = x7; + SecP160R2Field.SquareN(x14, 3, x17); + SecP160R2Field.Multiply(x17, x3, x17); + uint[] x31 = Nat160.Create(); + SecP160R2Field.SquareN(x17, 14, x31); + SecP160R2Field.Multiply(x31, x14, x31); + uint[] x62 = x14; + SecP160R2Field.SquareN(x31, 31, x62); + SecP160R2Field.Multiply(x62, x31, x62); + uint[] x124 = x31; + SecP160R2Field.SquareN(x62, 62, x124); + SecP160R2Field.Multiply(x124, x62, x124); + uint[] x127 = x62; + SecP160R2Field.SquareN(x124, 3, x127); + SecP160R2Field.Multiply(x127, x3, x127); + + uint[] t1 = x127; + SecP160R2Field.SquareN(t1, 18, t1); + SecP160R2Field.Multiply(t1, x17, t1); + SecP160R2Field.SquareN(t1, 2, t1); + SecP160R2Field.Multiply(t1, x1, t1); + SecP160R2Field.SquareN(t1, 3, t1); + SecP160R2Field.Multiply(t1, x2, t1); + SecP160R2Field.SquareN(t1, 6, t1); + SecP160R2Field.Multiply(t1, x3, t1); + SecP160R2Field.SquareN(t1, 2, t1); + SecP160R2Field.Multiply(t1, x1, t1); + + uint[] t2 = x2; + SecP160R2Field.Square(t1, t2); + + return Nat160.Eq(x1, t2) ? new SecP160R2FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP160R2FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP160R2FieldElement); + } + + public virtual bool Equals(SecP160R2FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat160.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs.meta new file mode 100644 index 0000000..6748af1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aae5056faf4a481479fc7b296b811965 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs new file mode 100644 index 0000000..f1b0b6c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP160R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord; + SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord; + + SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat160.CreateExt(); + uint[] t2 = Nat160.Create(); + uint[] t3 = Nat160.Create(); + uint[] t4 = Nat160.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP160R2Field.Square(Z1.x, S2); + + U2 = t2; + SecP160R2Field.Multiply(S2, X2.x, U2); + + SecP160R2Field.Multiply(S2, Z1.x, S2); + SecP160R2Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP160R2Field.Square(Z2.x, S1); + + U1 = tt1; + SecP160R2Field.Multiply(S1, X1.x, U1); + + SecP160R2Field.Multiply(S1, Z2.x, S1); + SecP160R2Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat160.Create(); + SecP160R2Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP160R2Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat160.IsZero(H)) + { + if (Nat160.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP160R2Field.Square(H, HSquared); + + uint[] G = Nat160.Create(); + SecP160R2Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP160R2Field.Multiply(HSquared, U1, V); + + SecP160R2Field.Negate(G, G); + Nat160.Mul(S1, G, tt1); + + c = Nat160.AddBothTo(V, V, G); + SecP160R2Field.Reduce32(c, G); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4); + SecP160R2Field.Square(R, X3.x); + SecP160R2Field.Subtract(X3.x, G, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G); + SecP160R2Field.Subtract(V, X3.x, Y3.x); + SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP160R2Field.Reduce(tt1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H); + if (!Z1IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP160R2Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP160R2FieldElement Y1 = (SecP160R2FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat160.Create(); + uint[] t2 = Nat160.Create(); + + uint[] Y1Squared = Nat160.Create(); + SecP160R2Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat160.Create(); + SecP160R2Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP160R2Field.Square(Z1.x, Z1Squared); + } + + SecP160R2Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP160R2Field.Add(X1.x, Z1Squared, M); + SecP160R2Field.Multiply(M, t1, M); + c = Nat160.AddBothTo(M, M, M); + SecP160R2Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP160R2Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(5, S, 2, 0); + SecP160R2Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(5, T, 3, 0, t1); + SecP160R2Field.Reduce32(c, t1); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(T); + SecP160R2Field.Square(M, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(S); + SecP160R2Field.Subtract(S, X3.x, Y3.x); + SecP160R2Field.Multiply(Y3.x, M, Y3.x); + SecP160R2Field.Subtract(Y3.x, t1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(M); + SecP160R2Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP160R2Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP160R2Point(Curve, this.RawXCoord, this.RawYCoord.Negate(), this.RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs.meta new file mode 100644 index 0000000..5f45975 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP160R2Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 052ed3284b9686047ad51492201a07e6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs new file mode 100644 index 0000000..9d442d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs @@ -0,0 +1,79 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37")); + + private const int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP192K1Point m_infinity; + + public SecP192K1Curve() + : base(q) + { + this.m_infinity = new SecP192K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(3)); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP192K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP192K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP192K1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP192K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP192K1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs.meta new file mode 100644 index 0000000..534c135 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4c57242857a693945805fab06e8b8816 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs new file mode 100644 index 0000000..eaf71a4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs @@ -0,0 +1,182 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1Field + { + // 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x00002391, 0x00000002 }; + private const uint P5 = 0xFFFFFFFF; + private const uint PExt11 = 0xFFFFFFFF; + private const uint PInv33 = 0x11C9; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat192.Add(x, y, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(12, xx, yy, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(6, x, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat192.FromBigInteger(x); + if (z[5] == P5 && Nat192.Gte(z, P)) + { + Nat192.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(6, x, 0, z); + } + else + { + uint c = Nat192.Add(x, P, z); + Nat.ShiftDownBit(6, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat192.MulAddTo(x, y, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat192.IsZero(x)) + { + Nat192.Zero(z); + } + else + { + Nat192.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat192.Mul33Add(PInv33, xx, 6, xx, 0, z, 0); + uint c = Nat192.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat192.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat192.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat192.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(6, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(12, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(12, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(6, x, 0, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs.meta new file mode 100644 index 0000000..baf86af --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 218f3d42a4e59cf4a953af9121236128 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs new file mode 100644 index 0000000..085df21 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs @@ -0,0 +1,217 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP192K1Curve.q; + + protected internal readonly uint[] x; + + public SecP192K1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP192K1FieldElement", "x"); + + this.x = SecP192K1Field.FromBigInteger(x); + } + + public SecP192K1FieldElement() + { + this.x = Nat192.Create(); + } + + protected internal SecP192K1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat192.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat192.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat192.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP192K1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192K1Field.Add(x, ((SecP192K1FieldElement)b).x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat192.Create(); + SecP192K1Field.AddOne(x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192K1Field.Subtract(x, ((SecP192K1FieldElement)b).x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192K1Field.Multiply(x, ((SecP192K1FieldElement)b).x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat192.Create(); + Mod.Invert(SecP192K1Field.P, ((SecP192K1FieldElement)b).x, z); + SecP192K1Field.Multiply(z, x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat192.Create(); + SecP192K1Field.Negate(x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat192.Create(); + SecP192K1Field.Square(x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP192K1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat192.Create(); + Mod.Invert(SecP192K1Field.P, x, z); + return new SecP192K1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s} { 3 1s } { 1 0s } + * + * Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits) + * We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159] + */ + + uint[] x1 = this.x; + if (Nat192.IsZero(x1) || Nat192.IsOne(x1)) + return this; + + uint[] x2 = Nat192.Create(); + SecP192K1Field.Square(x1, x2); + SecP192K1Field.Multiply(x2, x1, x2); + uint[] x3 = Nat192.Create(); + SecP192K1Field.Square(x2, x3); + SecP192K1Field.Multiply(x3, x1, x3); + uint[] x6 = Nat192.Create(); + SecP192K1Field.SquareN(x3, 3, x6); + SecP192K1Field.Multiply(x6, x3, x6); + uint[] x8 = x6; + SecP192K1Field.SquareN(x6, 2, x8); + SecP192K1Field.Multiply(x8, x2, x8); + uint[] x16 = x2; + SecP192K1Field.SquareN(x8, 8, x16); + SecP192K1Field.Multiply(x16, x8, x16); + uint[] x19 = x8; + SecP192K1Field.SquareN(x16, 3, x19); + SecP192K1Field.Multiply(x19, x3, x19); + uint[] x35 = Nat192.Create(); + SecP192K1Field.SquareN(x19, 16, x35); + SecP192K1Field.Multiply(x35, x16, x35); + uint[] x70 = x16; + SecP192K1Field.SquareN(x35, 35, x70); + SecP192K1Field.Multiply(x70, x35, x70); + uint[] x140 = x35; + SecP192K1Field.SquareN(x70, 70, x140); + SecP192K1Field.Multiply(x140, x70, x140); + uint[] x159 = x70; + SecP192K1Field.SquareN(x140, 19, x159); + SecP192K1Field.Multiply(x159, x19, x159); + + uint[] t1 = x159; + SecP192K1Field.SquareN(t1, 20, t1); + SecP192K1Field.Multiply(t1, x19, t1); + SecP192K1Field.SquareN(t1, 4, t1); + SecP192K1Field.Multiply(t1, x3, t1); + SecP192K1Field.SquareN(t1, 6, t1); + SecP192K1Field.Multiply(t1, x3, t1); + SecP192K1Field.Square(t1, t1); + + uint[] t2 = x3; + SecP192K1Field.Square(t1, t2); + + return Nat192.Eq(x1, t2) ? new SecP192K1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP192K1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP192K1FieldElement); + } + + public virtual bool Equals(SecP192K1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs.meta new file mode 100644 index 0000000..f569d39 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d5a7a619c061cd24cafd0a7cdbb3a432 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs new file mode 100644 index 0000000..3b5dee2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs @@ -0,0 +1,271 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP192K1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.RawXCoord, Y1 = (SecP192K1FieldElement)this.RawYCoord; + SecP192K1FieldElement X2 = (SecP192K1FieldElement)b.RawXCoord, Y2 = (SecP192K1FieldElement)b.RawYCoord; + + SecP192K1FieldElement Z1 = (SecP192K1FieldElement)this.RawZCoords[0]; + SecP192K1FieldElement Z2 = (SecP192K1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat192.CreateExt(); + uint[] t2 = Nat192.Create(); + uint[] t3 = Nat192.Create(); + uint[] t4 = Nat192.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP192K1Field.Square(Z1.x, S2); + + U2 = t2; + SecP192K1Field.Multiply(S2, X2.x, U2); + + SecP192K1Field.Multiply(S2, Z1.x, S2); + SecP192K1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP192K1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP192K1Field.Multiply(S1, X1.x, U1); + + SecP192K1Field.Multiply(S1, Z2.x, S1); + SecP192K1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat192.Create(); + SecP192K1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP192K1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat192.IsZero(H)) + { + if (Nat192.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP192K1Field.Square(H, HSquared); + + uint[] G = Nat192.Create(); + SecP192K1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP192K1Field.Multiply(HSquared, U1, V); + + SecP192K1Field.Negate(G, G); + Nat192.Mul(S1, G, tt1); + + c = Nat192.AddBothTo(V, V, G); + SecP192K1Field.Reduce32(c, G); + + SecP192K1FieldElement X3 = new SecP192K1FieldElement(t4); + SecP192K1Field.Square(R, X3.x); + SecP192K1Field.Subtract(X3.x, G, X3.x); + + SecP192K1FieldElement Y3 = new SecP192K1FieldElement(G); + SecP192K1Field.Subtract(V, X3.x, Y3.x); + SecP192K1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP192K1Field.Reduce(tt1, Y3.x); + + SecP192K1FieldElement Z3 = new SecP192K1FieldElement(H); + if (!Z1IsOne) + { + SecP192K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP192K1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP192K1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP192K1FieldElement Y1 = (SecP192K1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.RawXCoord, Z1 = (SecP192K1FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat192.Create(); + SecP192K1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat192.Create(); + SecP192K1Field.Square(Y1Squared, T); + + uint[] M = Nat192.Create(); + SecP192K1Field.Square(X1.x, M); + c = Nat192.AddBothTo(M, M, M); + SecP192K1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP192K1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(6, S, 2, 0); + SecP192K1Field.Reduce32(c, S); + + uint[] t1 = Nat192.Create(); + c = Nat.ShiftUpBits(6, T, 3, 0, t1); + SecP192K1Field.Reduce32(c, t1); + + SecP192K1FieldElement X3 = new SecP192K1FieldElement(T); + SecP192K1Field.Square(M, X3.x); + SecP192K1Field.Subtract(X3.x, S, X3.x); + SecP192K1Field.Subtract(X3.x, S, X3.x); + + SecP192K1FieldElement Y3 = new SecP192K1FieldElement(S); + SecP192K1Field.Subtract(S, X3.x, Y3.x); + SecP192K1Field.Multiply(Y3.x, M, Y3.x); + SecP192K1Field.Subtract(Y3.x, t1, Y3.x); + + SecP192K1FieldElement Z3 = new SecP192K1FieldElement(M); + SecP192K1Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP192K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP192K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs.meta new file mode 100644 index 0000000..d112e20 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d94a23a9df7487e4b8647bb414b5c412 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs new file mode 100644 index 0000000..87b6619 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")); + + private const int SecP192R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP192R1Point m_infinity; + + public SecP192R1Curve() + : base(q) + { + this.m_infinity = new SecP192R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"))); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SecP192R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP192R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP192R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP192R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP192R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs.meta new file mode 100644 index 0000000..1bc4be6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9051396fd403a4143a8049754bd784c1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs new file mode 100644 index 0000000..d3ae910 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs @@ -0,0 +1,287 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1Field + { + // 2^192 - 2^64 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, + 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 }; + private const uint P5 = 0xFFFFFFFF; + private const uint PExt11 = 0xFFFFFFFF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat192.Add(x, y, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(12, xx, yy, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(6, x, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat192.FromBigInteger(x); + if (z[5] == P5 && Nat192.Gte(z, P)) + { + Nat192.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(6, x, 0, z); + } + else + { + uint c = Nat192.Add(x, P, z); + Nat.ShiftDownBit(6, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat192.MulAddTo(x, y, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat192.IsZero(x)) + { + Nat192.Zero(z); + } + else + { + Nat192.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong xx06 = xx[6], xx07 = xx[7], xx08 = xx[8]; + ulong xx09 = xx[9], xx10 = xx[10], xx11 = xx[11]; + + ulong t0 = xx06 + xx10; + ulong t1 = xx07 + xx11; + + ulong cc = 0; + cc += (ulong)xx[0] + t0; + uint z0 = (uint)cc; + cc >>= 32; + cc += (ulong)xx[1] + t1; + z[1] = (uint)cc; + cc >>= 32; + + t0 += xx08; + t1 += xx09; + + cc += (ulong)xx[2] + t0; + ulong z2 = (uint)cc; + cc >>= 32; + cc += (ulong)xx[3] + t1; + z[3] = (uint)cc; + cc >>= 32; + + t0 -= xx06; + t1 -= xx07; + + cc += (ulong)xx[4] + t0; + z[4] = (uint)cc; + cc >>= 32; + cc += (ulong)xx[5] + t1; + z[5] = (uint)cc; + cc >>= 32; + + z2 += cc; + + cc += z0; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += z[1]; + z[1] = (uint)cc; + z2 += cc >> 32; + } + z[2] = (uint)z2; + cc = z2 >> 32; + + Debug.Assert(cc == 0 || cc == 1); + + if ((cc != 0 && Nat.IncAt(6, z, 3) != 0) + || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + ulong cc = 0; + + if (x != 0) + { + cc += (ulong)z[0] + x; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (ulong)z[1]; + z[1] = (uint)cc; + cc >>= 32; + } + cc += (ulong)z[2] + x; + z[2] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if ((cc != 0 && Nat.IncAt(6, z, 3) != 0) + || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat192.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat192.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(12, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(12, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(6, x, 0, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + } + c += (long)z[2] + 1; + z[2] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.IncAt(6, z, 3); + } + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + } + c += (long)z[2] - 1; + z[2] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.DecAt(6, z, 3); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs.meta new file mode 100644 index 0000000..b9c45d1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 44fb8f1c5ae47e64caf48325ec0b3902 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs new file mode 100644 index 0000000..a013402 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs @@ -0,0 +1,192 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP192R1Curve.q; + + protected internal readonly uint[] x; + + public SecP192R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP192R1FieldElement", "x"); + + this.x = SecP192R1Field.FromBigInteger(x); + } + + public SecP192R1FieldElement() + { + this.x = Nat192.Create(); + } + + protected internal SecP192R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat192.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat192.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat192.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP192R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192R1Field.Add(x, ((SecP192R1FieldElement)b).x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat192.Create(); + SecP192R1Field.AddOne(x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192R1Field.Subtract(x, ((SecP192R1FieldElement)b).x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192R1Field.Multiply(x, ((SecP192R1FieldElement)b).x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat192.Create(); + Mod.Invert(SecP192R1Field.P, ((SecP192R1FieldElement)b).x, z); + SecP192R1Field.Multiply(z, x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat192.Create(); + SecP192R1Field.Negate(x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat192.Create(); + SecP192R1Field.Square(x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP192R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat192.Create(); + Mod.Invert(SecP192R1Field.P, x, z); + return new SecP192R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^190 - 2^62 + + uint[] x1 = this.x; + if (Nat192.IsZero(x1) || Nat192.IsOne(x1)) + return this; + + uint[] t1 = Nat192.Create(); + uint[] t2 = Nat192.Create(); + + SecP192R1Field.Square(x1, t1); + SecP192R1Field.Multiply(t1, x1, t1); + + SecP192R1Field.SquareN(t1, 2, t2); + SecP192R1Field.Multiply(t2, t1, t2); + + SecP192R1Field.SquareN(t2, 4, t1); + SecP192R1Field.Multiply(t1, t2, t1); + + SecP192R1Field.SquareN(t1, 8, t2); + SecP192R1Field.Multiply(t2, t1, t2); + + SecP192R1Field.SquareN(t2, 16, t1); + SecP192R1Field.Multiply(t1, t2, t1); + + SecP192R1Field.SquareN(t1, 32, t2); + SecP192R1Field.Multiply(t2, t1, t2); + + SecP192R1Field.SquareN(t2, 64, t1); + SecP192R1Field.Multiply(t1, t2, t1); + + SecP192R1Field.SquareN(t1, 62, t1); + SecP192R1Field.Square(t1, t2); + + return Nat192.Eq(x1, t2) ? new SecP192R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP192R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP192R1FieldElement); + } + + public virtual bool Equals(SecP192R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs.meta new file mode 100644 index 0000000..620de03 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d1a07149a2b0efd429eb787280af3bc0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs new file mode 100644 index 0000000..4c6b5bf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP192R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.RawXCoord, Y1 = (SecP192R1FieldElement)this.RawYCoord; + SecP192R1FieldElement X2 = (SecP192R1FieldElement)b.RawXCoord, Y2 = (SecP192R1FieldElement)b.RawYCoord; + + SecP192R1FieldElement Z1 = (SecP192R1FieldElement)this.RawZCoords[0]; + SecP192R1FieldElement Z2 = (SecP192R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat192.CreateExt(); + uint[] t2 = Nat192.Create(); + uint[] t3 = Nat192.Create(); + uint[] t4 = Nat192.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP192R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP192R1Field.Multiply(S2, X2.x, U2); + + SecP192R1Field.Multiply(S2, Z1.x, S2); + SecP192R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP192R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP192R1Field.Multiply(S1, X1.x, U1); + + SecP192R1Field.Multiply(S1, Z2.x, S1); + SecP192R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat192.Create(); + SecP192R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP192R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat192.IsZero(H)) + { + if (Nat192.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP192R1Field.Square(H, HSquared); + + uint[] G = Nat192.Create(); + SecP192R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP192R1Field.Multiply(HSquared, U1, V); + + SecP192R1Field.Negate(G, G); + Nat192.Mul(S1, G, tt1); + + c = Nat192.AddBothTo(V, V, G); + SecP192R1Field.Reduce32(c, G); + + SecP192R1FieldElement X3 = new SecP192R1FieldElement(t4); + SecP192R1Field.Square(R, X3.x); + SecP192R1Field.Subtract(X3.x, G, X3.x); + + SecP192R1FieldElement Y3 = new SecP192R1FieldElement(G); + SecP192R1Field.Subtract(V, X3.x, Y3.x); + SecP192R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP192R1Field.Reduce(tt1, Y3.x); + + SecP192R1FieldElement Z3 = new SecP192R1FieldElement(H); + if (!Z1IsOne) + { + SecP192R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP192R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP192R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP192R1FieldElement Y1 = (SecP192R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.RawXCoord, Z1 = (SecP192R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat192.Create(); + uint[] t2 = Nat192.Create(); + + uint[] Y1Squared = Nat192.Create(); + SecP192R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat192.Create(); + SecP192R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP192R1Field.Square(Z1.x, Z1Squared); + } + + SecP192R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP192R1Field.Add(X1.x, Z1Squared, M); + SecP192R1Field.Multiply(M, t1, M); + c = Nat192.AddBothTo(M, M, M); + SecP192R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP192R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(6, S, 2, 0); + SecP192R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(6, T, 3, 0, t1); + SecP192R1Field.Reduce32(c, t1); + + SecP192R1FieldElement X3 = new SecP192R1FieldElement(T); + SecP192R1Field.Square(M, X3.x); + SecP192R1Field.Subtract(X3.x, S, X3.x); + SecP192R1Field.Subtract(X3.x, S, X3.x); + + SecP192R1FieldElement Y3 = new SecP192R1FieldElement(S); + SecP192R1Field.Subtract(S, X3.x, Y3.x); + SecP192R1Field.Multiply(Y3.x, M, Y3.x); + SecP192R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP192R1FieldElement Z3 = new SecP192R1FieldElement(M); + SecP192R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP192R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP192R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs.meta new file mode 100644 index 0000000..1e620c2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP192R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5084e06d37760694d9392014cb72ba23 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs new file mode 100644 index 0000000..28b7950 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs @@ -0,0 +1,79 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D")); + + private const int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP224K1Point m_infinity; + + public SecP224K1Curve() + : base(q) + { + this.m_infinity = new SecP224K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(5)); + this.m_order = new BigInteger(1, Hex.Decode("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP224K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP224K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP224K1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP224K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP224K1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs.meta new file mode 100644 index 0000000..73c274e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e1233e0816ad5b44f9f27e6b791d2e97 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs new file mode 100644 index 0000000..4102e16 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs @@ -0,0 +1,183 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1Field + { + // 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFD3DCF97, 0xFFFFCAD9, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00003525, 0x00000002 }; + private const uint P6 = 0xFFFFFFFF; + private const uint PExt13 = 0xFFFFFFFF; + private const uint PInv33 = 0x1A93; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat224.Add(x, y, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(14, xx, yy, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(7, x, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat224.FromBigInteger(x); + if (z[6] == P6 && Nat224.Gte(z, P)) + { + Nat224.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(7, x, 0, z); + } + else + { + uint c = Nat224.Add(x, P, z); + Nat.ShiftDownBit(7, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat224.MulAddTo(x, y, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat224.IsZero(x)) + { + Nat224.Zero(z); + } + else + { + Nat224.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat224.Mul33Add(PInv33, xx, 7, xx, 0, z, 0); + uint c = Nat224.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat224.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat224.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat224.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(7, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(14, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(14, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(7, x, 0, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs.meta new file mode 100644 index 0000000..84e4761 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 13c0c039f6103dd4abcd6e56bfe8f54e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs new file mode 100644 index 0000000..07a7ac3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs @@ -0,0 +1,246 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP224K1Curve.q; + + // Calculated as BigInteger.Two.ModPow(Q.ShiftRight(2), Q) + private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8, + 0xa85558fc, 0x1eaef5d7, 0x8edf154c }; + + protected internal readonly uint[] x; + + public SecP224K1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP224K1FieldElement", "x"); + + this.x = SecP224K1Field.FromBigInteger(x); + } + + public SecP224K1FieldElement() + { + this.x = Nat224.Create(); + } + + protected internal SecP224K1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat224.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat224.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat224.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat224.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP224K1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224K1Field.Add(x, ((SecP224K1FieldElement)b).x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat224.Create(); + SecP224K1Field.AddOne(x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224K1Field.Subtract(x, ((SecP224K1FieldElement)b).x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224K1Field.Multiply(x, ((SecP224K1FieldElement)b).x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat224.Create(); + Mod.Invert(SecP224K1Field.P, ((SecP224K1FieldElement)b).x, z); + SecP224K1Field.Multiply(z, x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat224.Create(); + SecP224K1Field.Negate(x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat224.Create(); + SecP224K1Field.Square(x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP224K1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat224.Create(); + Mod.Invert(SecP224K1Field.P, x, z); + return new SecP224K1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Q == 8m + 5, so we use Pocklington's method for this case. + * + * First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1) + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s} { 1 1s } { 1 0s} { 3 1s } { 1 0s} + * + * Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits) + * We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191] + */ + + uint[] x1 = this.x; + if (Nat224.IsZero(x1) || Nat224.IsOne(x1)) + return this; + + uint[] x2 = Nat224.Create(); + SecP224K1Field.Square(x1, x2); + SecP224K1Field.Multiply(x2, x1, x2); + uint[] x3 = x2; + SecP224K1Field.Square(x2, x3); + SecP224K1Field.Multiply(x3, x1, x3); + uint[] x4 = Nat224.Create(); + SecP224K1Field.Square(x3, x4); + SecP224K1Field.Multiply(x4, x1, x4); + uint[] x8 = Nat224.Create(); + SecP224K1Field.SquareN(x4, 4, x8); + SecP224K1Field.Multiply(x8, x4, x8); + uint[] x11 = Nat224.Create(); + SecP224K1Field.SquareN(x8, 3, x11); + SecP224K1Field.Multiply(x11, x3, x11); + uint[] x19 = x11; + SecP224K1Field.SquareN(x11, 8, x19); + SecP224K1Field.Multiply(x19, x8, x19); + uint[] x23 = x8; + SecP224K1Field.SquareN(x19, 4, x23); + SecP224K1Field.Multiply(x23, x4, x23); + uint[] x42 = x4; + SecP224K1Field.SquareN(x23, 19, x42); + SecP224K1Field.Multiply(x42, x19, x42); + uint[] x84 = Nat224.Create(); + SecP224K1Field.SquareN(x42, 42, x84); + SecP224K1Field.Multiply(x84, x42, x84); + uint[] x107 = x42; + SecP224K1Field.SquareN(x84, 23, x107); + SecP224K1Field.Multiply(x107, x23, x107); + uint[] x191 = x23; + SecP224K1Field.SquareN(x107, 84, x191); + SecP224K1Field.Multiply(x191, x84, x191); + + uint[] t1 = x191; + SecP224K1Field.SquareN(t1, 20, t1); + SecP224K1Field.Multiply(t1, x19, t1); + SecP224K1Field.SquareN(t1, 3, t1); + SecP224K1Field.Multiply(t1, x1, t1); + SecP224K1Field.SquareN(t1, 2, t1); + SecP224K1Field.Multiply(t1, x1, t1); + SecP224K1Field.SquareN(t1, 4, t1); + SecP224K1Field.Multiply(t1, x3, t1); + SecP224K1Field.Square(t1, t1); + + uint[] t2 = x84; + SecP224K1Field.Square(t1, t2); + + if (Nat224.Eq(x1, t2)) + { + return new SecP224K1FieldElement(t1); + } + + /* + * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess, + * which is ((4x)^(m + 1))/2 mod Q + */ + SecP224K1Field.Multiply(t1, PRECOMP_POW2, t1); + + SecP224K1Field.Square(t1, t2); + + if (Nat224.Eq(x1, t2)) + { + return new SecP224K1FieldElement(t1); + } + + return null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP224K1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP224K1FieldElement); + } + + public virtual bool Equals(SecP224K1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat224.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs.meta new file mode 100644 index 0000000..90a2cef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 50f96618b2586c142b195292b3fa8f95 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs new file mode 100644 index 0000000..c478722 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs @@ -0,0 +1,271 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP224K1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.RawXCoord, Y1 = (SecP224K1FieldElement)this.RawYCoord; + SecP224K1FieldElement X2 = (SecP224K1FieldElement)b.RawXCoord, Y2 = (SecP224K1FieldElement)b.RawYCoord; + + SecP224K1FieldElement Z1 = (SecP224K1FieldElement)this.RawZCoords[0]; + SecP224K1FieldElement Z2 = (SecP224K1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat224.CreateExt(); + uint[] t2 = Nat224.Create(); + uint[] t3 = Nat224.Create(); + uint[] t4 = Nat224.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP224K1Field.Square(Z1.x, S2); + + U2 = t2; + SecP224K1Field.Multiply(S2, X2.x, U2); + + SecP224K1Field.Multiply(S2, Z1.x, S2); + SecP224K1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP224K1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP224K1Field.Multiply(S1, X1.x, U1); + + SecP224K1Field.Multiply(S1, Z2.x, S1); + SecP224K1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat224.Create(); + SecP224K1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP224K1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat224.IsZero(H)) + { + if (Nat224.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP224K1Field.Square(H, HSquared); + + uint[] G = Nat224.Create(); + SecP224K1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP224K1Field.Multiply(HSquared, U1, V); + + SecP224K1Field.Negate(G, G); + Nat224.Mul(S1, G, tt1); + + c = Nat224.AddBothTo(V, V, G); + SecP224K1Field.Reduce32(c, G); + + SecP224K1FieldElement X3 = new SecP224K1FieldElement(t4); + SecP224K1Field.Square(R, X3.x); + SecP224K1Field.Subtract(X3.x, G, X3.x); + + SecP224K1FieldElement Y3 = new SecP224K1FieldElement(G); + SecP224K1Field.Subtract(V, X3.x, Y3.x); + SecP224K1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP224K1Field.Reduce(tt1, Y3.x); + + SecP224K1FieldElement Z3 = new SecP224K1FieldElement(H); + if (!Z1IsOne) + { + SecP224K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP224K1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP224K1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP224K1FieldElement Y1 = (SecP224K1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.RawXCoord, Z1 = (SecP224K1FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat224.Create(); + SecP224K1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat224.Create(); + SecP224K1Field.Square(Y1Squared, T); + + uint[] M = Nat224.Create(); + SecP224K1Field.Square(X1.x, M); + c = Nat224.AddBothTo(M, M, M); + SecP224K1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP224K1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(7, S, 2, 0); + SecP224K1Field.Reduce32(c, S); + + uint[] t1 = Nat224.Create(); + c = Nat.ShiftUpBits(7, T, 3, 0, t1); + SecP224K1Field.Reduce32(c, t1); + + SecP224K1FieldElement X3 = new SecP224K1FieldElement(T); + SecP224K1Field.Square(M, X3.x); + SecP224K1Field.Subtract(X3.x, S, X3.x); + SecP224K1Field.Subtract(X3.x, S, X3.x); + + SecP224K1FieldElement Y3 = new SecP224K1FieldElement(S); + SecP224K1Field.Subtract(S, X3.x, Y3.x); + SecP224K1Field.Multiply(Y3.x, M, Y3.x); + SecP224K1Field.Subtract(Y3.x, t1, Y3.x); + + SecP224K1FieldElement Z3 = new SecP224K1FieldElement(M); + SecP224K1Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP224K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP224K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs.meta new file mode 100644 index 0000000..c6b9558 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e6dc58928b3a6b349a413bceb4eda1f2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs new file mode 100644 index 0000000..c202f70 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")); + + private const int SecP224R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP224R1Point m_infinity; + + public SecP224R1Curve() + : base(q) + { + this.m_infinity = new SecP224R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"))); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SecP224R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP224R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP224R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP224R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP224R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs.meta new file mode 100644 index 0000000..6ec95d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bb8ec695468ca8a468dc59c7ef35e719 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs new file mode 100644 index 0000000..4da4583 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs @@ -0,0 +1,301 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1Field + { + // 2^224 - 2^96 + 1 + internal static readonly uint[] P = new uint[] { 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 }; + private const uint P6 = 0xFFFFFFFF; + private const uint PExt13 = 0xFFFFFFFF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat224.Add(x, y, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(14, xx, yy, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(7, x, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat224.FromBigInteger(x); + if (z[6] == P6 && Nat224.Gte(z, P)) + { + Nat224.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(7, x, 0, z); + } + else + { + uint c = Nat224.Add(x, P, z); + Nat.ShiftDownBit(7, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat224.MulAddTo(x, y, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat224.IsZero(x)) + { + Nat224.Zero(z); + } + else + { + Nat224.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx10 = xx[10], xx11 = xx[11], xx12 = xx[12], xx13 = xx[13]; + + const long n = 1; + + long t0 = (long)xx[7] + xx11 - n; + long t1 = (long)xx[8] + xx12; + long t2 = (long)xx[9] + xx13; + + long cc = 0; + cc += (long)xx[0] - t0; + long z0 = (uint)cc; + cc >>= 32; + cc += (long)xx[1] - t1; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] - t2; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] + t0 - xx10; + long z3 = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + t1 - xx11; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] + t2 - xx12; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + xx10 - xx13; + z[6] = (uint)cc; + cc >>= 32; + cc += n; + + Debug.Assert(cc >= 0); + + z3 += cc; + + z0 -= cc; + z[0] = (uint)z0; + cc = z0 >> 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)z[2]; + z[2] = (uint)cc; + z3 += cc >> 32; + } + z[3] = (uint)z3; + cc = z3 >> 32; + + Debug.Assert(cc == 0 || cc == 1); + + if ((cc != 0 && Nat.IncAt(7, z, 4) != 0) + || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx07 = x; + + cc += (long)z[0] - xx07; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)z[2]; + z[2] = (uint)cc; + cc >>= 32; + } + cc += (long)z[3] + xx07; + z[3] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if ((cc != 0 && Nat.IncAt(7, z, 4) != 0) + || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat224.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat224.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(14, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(14, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(7, x, 0, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.IncAt(7, z, 4); + } + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.DecAt(7, z, 4); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs.meta new file mode 100644 index 0000000..8d825ef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: abf1e8ca92f9be6419daf86a48e31c77 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs new file mode 100644 index 0000000..0ff7d7b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs @@ -0,0 +1,273 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP224R1Curve.q; + + protected internal readonly uint[] x; + + public SecP224R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP224R1FieldElement", "x"); + + this.x = SecP224R1Field.FromBigInteger(x); + } + + public SecP224R1FieldElement() + { + this.x = Nat224.Create(); + } + + protected internal SecP224R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat224.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat224.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat224.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat224.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP224R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224R1Field.Add(x, ((SecP224R1FieldElement)b).x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat224.Create(); + SecP224R1Field.AddOne(x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224R1Field.Subtract(x, ((SecP224R1FieldElement)b).x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224R1Field.Multiply(x, ((SecP224R1FieldElement)b).x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat224.Create(); + Mod.Invert(SecP224R1Field.P, ((SecP224R1FieldElement)b).x, z); + SecP224R1Field.Multiply(z, x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat224.Create(); + SecP224R1Field.Negate(x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat224.Create(); + SecP224R1Field.Square(x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP224R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat224.Create(); + Mod.Invert(SecP224R1Field.P, x, z); + return new SecP224R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + uint[] c = this.x; + if (Nat224.IsZero(c) || Nat224.IsOne(c)) + return this; + + uint[] nc = Nat224.Create(); + SecP224R1Field.Negate(c, nc); + + uint[] r = Mod.Random(SecP224R1Field.P); + uint[] t = Nat224.Create(); + + if (!IsSquare(c)) + return null; + + while (!TrySqrt(nc, r, t)) + { + SecP224R1Field.AddOne(r, r); + } + + SecP224R1Field.Square(t, r); + + return Nat224.Eq(c, r) ? new SecP224R1FieldElement(t) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP224R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP224R1FieldElement); + } + + public virtual bool Equals(SecP224R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat224.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7); + } + + private static bool IsSquare(uint[] x) + { + uint[] t1 = Nat224.Create(); + uint[] t2 = Nat224.Create(); + Nat224.Copy(x, t1); + + for (int i = 0; i < 7; ++i) + { + Nat224.Copy(t1, t2); + SecP224R1Field.SquareN(t1, 1 << i, t1); + SecP224R1Field.Multiply(t1, t2, t1); + } + + SecP224R1Field.SquareN(t1, 95, t1); + return Nat224.IsOne(t1); + } + + private static void RM(uint[] nc, uint[] d0, uint[] e0, uint[] d1, uint[] e1, uint[] f1, uint[] t) + { + SecP224R1Field.Multiply(e1, e0, t); + SecP224R1Field.Multiply(t, nc, t); + SecP224R1Field.Multiply(d1, d0, f1); + SecP224R1Field.Add(f1, t, f1); + SecP224R1Field.Multiply(d1, e0, t); + Nat224.Copy(f1, d1); + SecP224R1Field.Multiply(e1, d0, e1); + SecP224R1Field.Add(e1, t, e1); + SecP224R1Field.Square(e1, f1); + SecP224R1Field.Multiply(f1, nc, f1); + } + + private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1, uint[] t) + { + Nat224.Copy(nc, f1); + + uint[] d0 = Nat224.Create(); + uint[] e0 = Nat224.Create(); + + for (int i = 0; i < 7; ++i) + { + Nat224.Copy(d1, d0); + Nat224.Copy(e1, e0); + + int j = 1 << i; + while (--j >= 0) + { + RS(d1, e1, f1, t); + } + + RM(nc, d0, e0, d1, e1, f1, t); + } + } + + private static void RS(uint[] d, uint[] e, uint[] f, uint[] t) + { + SecP224R1Field.Multiply(e, d, e); + SecP224R1Field.Twice(e, e); + SecP224R1Field.Square(d, t); + SecP224R1Field.Add(f, t, d); + SecP224R1Field.Multiply(f, t, f); + uint c = Nat.ShiftUpBits(7, f, 2, 0); + SecP224R1Field.Reduce32(c, f); + } + + private static bool TrySqrt(uint[] nc, uint[] r, uint[] t) + { + uint[] d1 = Nat224.Create(); + Nat224.Copy(r, d1); + uint[] e1 = Nat224.Create(); + e1[0] = 1; + uint[] f1 = Nat224.Create(); + RP(nc, d1, e1, f1, t); + + uint[] d0 = Nat224.Create(); + uint[] e0 = Nat224.Create(); + + for (int k = 1; k < 96; ++k) + { + Nat224.Copy(d1, d0); + Nat224.Copy(e1, e0); + + RS(d1, e1, f1, t); + + if (Nat224.IsZero(d1)) + { + Mod.Invert(SecP224R1Field.P, e0, t); + SecP224R1Field.Multiply(t, d0, t); + return true; + } + } + + return false; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs.meta new file mode 100644 index 0000000..9eb5302 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ef2e59a1deebf7d429a3167b9ff6fed8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs new file mode 100644 index 0000000..ebb3d3d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP224R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.RawXCoord, Y1 = (SecP224R1FieldElement)this.RawYCoord; + SecP224R1FieldElement X2 = (SecP224R1FieldElement)b.RawXCoord, Y2 = (SecP224R1FieldElement)b.RawYCoord; + + SecP224R1FieldElement Z1 = (SecP224R1FieldElement)this.RawZCoords[0]; + SecP224R1FieldElement Z2 = (SecP224R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat224.CreateExt(); + uint[] t2 = Nat224.Create(); + uint[] t3 = Nat224.Create(); + uint[] t4 = Nat224.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP224R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP224R1Field.Multiply(S2, X2.x, U2); + + SecP224R1Field.Multiply(S2, Z1.x, S2); + SecP224R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP224R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP224R1Field.Multiply(S1, X1.x, U1); + + SecP224R1Field.Multiply(S1, Z2.x, S1); + SecP224R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat224.Create(); + SecP224R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP224R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat224.IsZero(H)) + { + if (Nat224.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP224R1Field.Square(H, HSquared); + + uint[] G = Nat224.Create(); + SecP224R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP224R1Field.Multiply(HSquared, U1, V); + + SecP224R1Field.Negate(G, G); + Nat224.Mul(S1, G, tt1); + + c = Nat224.AddBothTo(V, V, G); + SecP224R1Field.Reduce32(c, G); + + SecP224R1FieldElement X3 = new SecP224R1FieldElement(t4); + SecP224R1Field.Square(R, X3.x); + SecP224R1Field.Subtract(X3.x, G, X3.x); + + SecP224R1FieldElement Y3 = new SecP224R1FieldElement(G); + SecP224R1Field.Subtract(V, X3.x, Y3.x); + SecP224R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP224R1Field.Reduce(tt1, Y3.x); + + SecP224R1FieldElement Z3 = new SecP224R1FieldElement(H); + if (!Z1IsOne) + { + SecP224R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP224R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP224R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP224R1FieldElement Y1 = (SecP224R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.RawXCoord, Z1 = (SecP224R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat224.Create(); + uint[] t2 = Nat224.Create(); + + uint[] Y1Squared = Nat224.Create(); + SecP224R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat224.Create(); + SecP224R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP224R1Field.Square(Z1.x, Z1Squared); + } + + SecP224R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP224R1Field.Add(X1.x, Z1Squared, M); + SecP224R1Field.Multiply(M, t1, M); + c = Nat224.AddBothTo(M, M, M); + SecP224R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP224R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(7, S, 2, 0); + SecP224R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(7, T, 3, 0, t1); + SecP224R1Field.Reduce32(c, t1); + + SecP224R1FieldElement X3 = new SecP224R1FieldElement(T); + SecP224R1Field.Square(M, X3.x); + SecP224R1Field.Subtract(X3.x, S, X3.x); + SecP224R1Field.Subtract(X3.x, S, X3.x); + + SecP224R1FieldElement Y3 = new SecP224R1FieldElement(S); + SecP224R1Field.Subtract(S, X3.x, Y3.x); + SecP224R1Field.Multiply(Y3.x, M, Y3.x); + SecP224R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP224R1FieldElement Z3 = new SecP224R1FieldElement(M); + SecP224R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP224R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP224R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs.meta new file mode 100644 index 0000000..dd84daa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP224R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: df4725d3321a1f446b488fceaefa3b0d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs new file mode 100644 index 0000000..b057015 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs @@ -0,0 +1,79 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); + + private const int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP256K1Point m_infinity; + + public SecP256K1Curve() + : base(q) + { + this.m_infinity = new SecP256K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(7)); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP256K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP256K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP256K1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP256K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP256K1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs.meta new file mode 100644 index 0000000..e27727a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a3137bda46ccd4c4bb49936df865386e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs new file mode 100644 index 0000000..1a3eee5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs @@ -0,0 +1,184 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1Field + { + // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 }; + private const uint P7 = 0xFFFFFFFF; + private const uint PExt15 = 0xFFFFFFFF; + private const uint PInv33 = 0x3D1; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat256.Add(x, y, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(16, xx, yy, zz); + if (c != 0 || (zz[15] == PExt15 && Nat.Gte(16, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(16, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(8, x, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat256.FromBigInteger(x); + if (z[7] == P7 && Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + uint c = Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat256.MulAddTo(x, y, zz); + if (c != 0 || (zz[15] == PExt15 && Nat.Gte(16, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(16, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat256.IsZero(x)) + { + Nat256.Zero(z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat256.Mul33Add(PInv33, xx, 8, xx, 0, z, 0); + uint c = Nat256.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat256.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(8, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(16, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(8, x, 0, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs.meta new file mode 100644 index 0000000..4a1250a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e5ed5c34ec10613418e2f1623a468b12 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs new file mode 100644 index 0000000..f2aa154 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs @@ -0,0 +1,218 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP256K1Curve.q; + + protected internal readonly uint[] x; + + public SecP256K1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP256K1FieldElement", "x"); + + this.x = SecP256K1Field.FromBigInteger(x); + } + + public SecP256K1FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal SecP256K1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP256K1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256K1Field.Add(x, ((SecP256K1FieldElement)b).x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + SecP256K1Field.AddOne(x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256K1Field.Subtract(x, ((SecP256K1FieldElement)b).x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256K1Field.Multiply(x, ((SecP256K1FieldElement)b).x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + Mod.Invert(SecP256K1Field.P, ((SecP256K1FieldElement)b).x, z); + SecP256K1Field.Multiply(z, x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + SecP256K1Field.Negate(x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + SecP256K1Field.Square(x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP256K1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + Mod.Invert(SecP256K1Field.P, x, z); + return new SecP256K1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s} + * + * Therefore we need an addition chain containing 2, 22, 223 (the lengths of the repunits) + * We use: 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] + */ + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + return this; + + uint[] x2 = Nat256.Create(); + SecP256K1Field.Square(x1, x2); + SecP256K1Field.Multiply(x2, x1, x2); + uint[] x3 = Nat256.Create(); + SecP256K1Field.Square(x2, x3); + SecP256K1Field.Multiply(x3, x1, x3); + uint[] x6 = Nat256.Create(); + SecP256K1Field.SquareN(x3, 3, x6); + SecP256K1Field.Multiply(x6, x3, x6); + uint[] x9 = x6; + SecP256K1Field.SquareN(x6, 3, x9); + SecP256K1Field.Multiply(x9, x3, x9); + uint[] x11 = x9; + SecP256K1Field.SquareN(x9, 2, x11); + SecP256K1Field.Multiply(x11, x2, x11); + uint[] x22 = Nat256.Create(); + SecP256K1Field.SquareN(x11, 11, x22); + SecP256K1Field.Multiply(x22, x11, x22); + uint[] x44 = x11; + SecP256K1Field.SquareN(x22, 22, x44); + SecP256K1Field.Multiply(x44, x22, x44); + uint[] x88 = Nat256.Create(); + SecP256K1Field.SquareN(x44, 44, x88); + SecP256K1Field.Multiply(x88, x44, x88); + uint[] x176 = Nat256.Create(); + SecP256K1Field.SquareN(x88, 88, x176); + SecP256K1Field.Multiply(x176, x88, x176); + uint[] x220 = x88; + SecP256K1Field.SquareN(x176, 44, x220); + SecP256K1Field.Multiply(x220, x44, x220); + uint[] x223 = x44; + SecP256K1Field.SquareN(x220, 3, x223); + SecP256K1Field.Multiply(x223, x3, x223); + + uint[] t1 = x223; + SecP256K1Field.SquareN(t1, 23, t1); + SecP256K1Field.Multiply(t1, x22, t1); + SecP256K1Field.SquareN(t1, 6, t1); + SecP256K1Field.Multiply(t1, x2, t1); + SecP256K1Field.SquareN(t1, 2, t1); + + uint[] t2 = x2; + SecP256K1Field.Square(t1, t2); + + return Nat256.Eq(x1, t2) ? new SecP256K1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP256K1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP256K1FieldElement); + } + + public virtual bool Equals(SecP256K1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs.meta new file mode 100644 index 0000000..379d2ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0f8852f71d5b64f439a369f3df96cd2c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs new file mode 100644 index 0000000..e0d37f7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs @@ -0,0 +1,271 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP256K1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.RawXCoord, Y1 = (SecP256K1FieldElement)this.RawYCoord; + SecP256K1FieldElement X2 = (SecP256K1FieldElement)b.RawXCoord, Y2 = (SecP256K1FieldElement)b.RawYCoord; + + SecP256K1FieldElement Z1 = (SecP256K1FieldElement)this.RawZCoords[0]; + SecP256K1FieldElement Z2 = (SecP256K1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP256K1Field.Square(Z1.x, S2); + + U2 = t2; + SecP256K1Field.Multiply(S2, X2.x, U2); + + SecP256K1Field.Multiply(S2, Z1.x, S2); + SecP256K1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP256K1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP256K1Field.Multiply(S1, X1.x, U1); + + SecP256K1Field.Multiply(S1, Z2.x, S1); + SecP256K1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + SecP256K1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP256K1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP256K1Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + SecP256K1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP256K1Field.Multiply(HSquared, U1, V); + + SecP256K1Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + SecP256K1Field.Reduce32(c, G); + + SecP256K1FieldElement X3 = new SecP256K1FieldElement(t4); + SecP256K1Field.Square(R, X3.x); + SecP256K1Field.Subtract(X3.x, G, X3.x); + + SecP256K1FieldElement Y3 = new SecP256K1FieldElement(G); + SecP256K1Field.Subtract(V, X3.x, Y3.x); + SecP256K1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP256K1Field.Reduce(tt1, Y3.x); + + SecP256K1FieldElement Z3 = new SecP256K1FieldElement(H); + if (!Z1IsOne) + { + SecP256K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP256K1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP256K1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP256K1FieldElement Y1 = (SecP256K1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.RawXCoord, Z1 = (SecP256K1FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat256.Create(); + SecP256K1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat256.Create(); + SecP256K1Field.Square(Y1Squared, T); + + uint[] M = Nat256.Create(); + SecP256K1Field.Square(X1.x, M); + c = Nat256.AddBothTo(M, M, M); + SecP256K1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP256K1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(8, S, 2, 0); + SecP256K1Field.Reduce32(c, S); + + uint[] t1 = Nat256.Create(); + c = Nat.ShiftUpBits(8, T, 3, 0, t1); + SecP256K1Field.Reduce32(c, t1); + + SecP256K1FieldElement X3 = new SecP256K1FieldElement(T); + SecP256K1Field.Square(M, X3.x); + SecP256K1Field.Subtract(X3.x, S, X3.x); + SecP256K1Field.Subtract(X3.x, S, X3.x); + + SecP256K1FieldElement Y3 = new SecP256K1FieldElement(S); + SecP256K1Field.Subtract(S, X3.x, Y3.x); + SecP256K1Field.Multiply(Y3.x, M, Y3.x); + SecP256K1Field.Subtract(Y3.x, t1, Y3.x); + + SecP256K1FieldElement Z3 = new SecP256K1FieldElement(M); + SecP256K1Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP256K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP256K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs.meta new file mode 100644 index 0000000..d784fb9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ee1f2beef4a01324fa3a7977b6e572cd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs new file mode 100644 index 0000000..adf65f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")); + + private const int SecP256R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP256R1Point m_infinity; + + public SecP256R1Curve() + : base(q) + { + this.m_infinity = new SecP256R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")); + this.m_cofactor = BigInteger.One; + this.m_coord = SecP256R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP256R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP256R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP256R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP256R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs.meta new file mode 100644 index 0000000..86b119a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 082371a7f8084154d966a0083ae04fd7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs new file mode 100644 index 0000000..9a21b48 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs @@ -0,0 +1,316 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Field + { + // 2^256 - 2^224 + 2^192 + 2^96 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE, + 0x00000002, 0xFFFFFFFE }; + internal const uint P7 = 0xFFFFFFFF; + internal const uint PExt15 = 0xFFFFFFFE; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat256.Add(x, y, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(16, xx, yy, zz); + if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt))) + { + Nat.SubFrom(16, PExt, zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(8, x, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat256.FromBigInteger(x); + if (z[7] == P7 && Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + uint c = Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat256.MulAddTo(x, y, zz); + if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt))) + { + Nat.SubFrom(16, PExt, zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat256.IsZero(x)) + { + Nat256.Zero(z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx08 = xx[8], xx09 = xx[9], xx10 = xx[10], xx11 = xx[11]; + long xx12 = xx[12], xx13 = xx[13], xx14 = xx[14], xx15 = xx[15]; + + const long n = 6; + + xx08 -= n; + + long t0 = xx08 + xx09; + long t1 = xx09 + xx10; + long t2 = xx10 + xx11 - xx15; + long t3 = xx11 + xx12; + long t4 = xx12 + xx13; + long t5 = xx13 + xx14; + long t6 = xx14 + xx15; + long t7 = t5 - t0; + + long cc = 0; + cc += (long)xx[0] - t3 - t7; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)xx[1] + t1 - t4 - t6; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] + t2 - t5; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] + (t3 << 1) + t7 - t6; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + (t4 << 1) + xx14 - t1; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] + (t5 << 1) - t2; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + (t6 << 1) + t7; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)xx[7] + (xx15 << 1) + xx08 - t2 - t4; + z[7] = (uint)cc; + cc >>= 32; + cc += n; + + Debug.Assert(cc >= 0); + + Reduce32((uint)cc, z); + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx08 = x; + + cc += (long)z[0] + xx08; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)z[2]; + z[2] = (uint)cc; + cc >>= 32; + } + cc += (long)z[3] - xx08; + z[3] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[4]; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)z[5]; + z[5] = (uint)cc; + cc >>= 32; + } + cc += (long)z[6] - xx08; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)z[7] + xx08; + z[7] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if (cc != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + Nat.AddTo(16, PExt, zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(8, x, 0, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5]; + z[5] = (uint)c; + c >>= 32; + } + c += (long)z[6] - 1; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] + 1; + z[7] = (uint)c; + //c >>= 32; + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5]; + z[5] = (uint)c; + c >>= 32; + } + c += (long)z[6] + 1; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] - 1; + z[7] = (uint)c; + //c >>= 32; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs.meta new file mode 100644 index 0000000..759fc83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 47c20e25c05835646935a6ff01c312d0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs new file mode 100644 index 0000000..69cd8d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs @@ -0,0 +1,192 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP256R1Curve.q; + + protected internal readonly uint[] x; + + public SecP256R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP256R1FieldElement", "x"); + + this.x = SecP256R1Field.FromBigInteger(x); + } + + public SecP256R1FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal SecP256R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP256R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256R1Field.Add(x, ((SecP256R1FieldElement)b).x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + SecP256R1Field.AddOne(x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256R1Field.Subtract(x, ((SecP256R1FieldElement)b).x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256R1Field.Multiply(x, ((SecP256R1FieldElement)b).x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + Mod.Invert(SecP256R1Field.P, ((SecP256R1FieldElement)b).x, z); + SecP256R1Field.Multiply(z, x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + SecP256R1Field.Negate(x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + SecP256R1Field.Square(x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP256R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + Mod.Invert(SecP256R1Field.P, x, z); + return new SecP256R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^254 - 2^222 + 2^190 + 2^94 + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + return this; + + uint[] t1 = Nat256.Create(); + uint[] t2 = Nat256.Create(); + + SecP256R1Field.Square(x1, t1); + SecP256R1Field.Multiply(t1, x1, t1); + + SecP256R1Field.SquareN(t1, 2, t2); + SecP256R1Field.Multiply(t2, t1, t2); + + SecP256R1Field.SquareN(t2, 4, t1); + SecP256R1Field.Multiply(t1, t2, t1); + + SecP256R1Field.SquareN(t1, 8, t2); + SecP256R1Field.Multiply(t2, t1, t2); + + SecP256R1Field.SquareN(t2, 16, t1); + SecP256R1Field.Multiply(t1, t2, t1); + + SecP256R1Field.SquareN(t1, 32, t1); + SecP256R1Field.Multiply(t1, x1, t1); + + SecP256R1Field.SquareN(t1, 96, t1); + SecP256R1Field.Multiply(t1, x1, t1); + + SecP256R1Field.SquareN(t1, 94, t1); + SecP256R1Field.Multiply(t1, t1, t2); + + return Nat256.Eq(x1, t2) ? new SecP256R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP256R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP256R1FieldElement); + } + + public virtual bool Equals(SecP256R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs.meta new file mode 100644 index 0000000..a7ab366 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3674fc76d2fd5954ead730124f209893 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs new file mode 100644 index 0000000..529b5e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs @@ -0,0 +1,283 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP256R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.RawXCoord, Y1 = (SecP256R1FieldElement)this.RawYCoord; + SecP256R1FieldElement X2 = (SecP256R1FieldElement)b.RawXCoord, Y2 = (SecP256R1FieldElement)b.RawYCoord; + + SecP256R1FieldElement Z1 = (SecP256R1FieldElement)this.RawZCoords[0]; + SecP256R1FieldElement Z2 = (SecP256R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP256R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP256R1Field.Multiply(S2, X2.x, U2); + + SecP256R1Field.Multiply(S2, Z1.x, S2); + SecP256R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP256R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP256R1Field.Multiply(S1, X1.x, U1); + + SecP256R1Field.Multiply(S1, Z2.x, S1); + SecP256R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + SecP256R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP256R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP256R1Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + SecP256R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP256R1Field.Multiply(HSquared, U1, V); + + SecP256R1Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + SecP256R1Field.Reduce32(c, G); + + SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4); + SecP256R1Field.Square(R, X3.x); + SecP256R1Field.Subtract(X3.x, G, X3.x); + + SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G); + SecP256R1Field.Subtract(V, X3.x, Y3.x); + SecP256R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP256R1Field.Reduce(tt1, Y3.x); + + SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H); + if (!Z1IsOne) + { + SecP256R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP256R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP256R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP256R1FieldElement Y1 = (SecP256R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.RawXCoord, Z1 = (SecP256R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat256.Create(); + uint[] t2 = Nat256.Create(); + + uint[] Y1Squared = Nat256.Create(); + SecP256R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat256.Create(); + SecP256R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP256R1Field.Square(Z1.x, Z1Squared); + } + + SecP256R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP256R1Field.Add(X1.x, Z1Squared, M); + SecP256R1Field.Multiply(M, t1, M); + c = Nat256.AddBothTo(M, M, M); + SecP256R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP256R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(8, S, 2, 0); + SecP256R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(8, T, 3, 0, t1); + SecP256R1Field.Reduce32(c, t1); + + SecP256R1FieldElement X3 = new SecP256R1FieldElement(T); + SecP256R1Field.Square(M, X3.x); + SecP256R1Field.Subtract(X3.x, S, X3.x); + SecP256R1Field.Subtract(X3.x, S, X3.x); + + SecP256R1FieldElement Y3 = new SecP256R1FieldElement(S); + SecP256R1Field.Subtract(S, X3.x, Y3.x); + SecP256R1Field.Multiply(Y3.x, M, Y3.x); + SecP256R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP256R1FieldElement Z3 = new SecP256R1FieldElement(M); + SecP256R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP256R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP256R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs.meta new file mode 100644 index 0000000..a615477 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP256R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 499c5c0285ffb474d88685f7bfadfcd9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs new file mode 100644 index 0000000..ee8d155 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")); + + private const int SecP384R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP384R1Point m_infinity; + + public SecP384R1Curve() + : base(q) + { + this.m_infinity = new SecP384R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"))); + this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")); + this.m_cofactor = BigInteger.One; + this.m_coord = SecP384R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP384R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP384R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP384R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP384R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs.meta new file mode 100644 index 0000000..1f91dc3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 75aff1f4132681d428a0d2eb9daaddfe +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs new file mode 100644 index 0000000..57aeb45 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs @@ -0,0 +1,299 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1Field + { + // 2^384 - 2^128 - 2^96 + 2^32 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + internal static readonly uint[] PExt = new uint[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE, + 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000000, + 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0x00000001, + 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF, + 0x00000001, 0x00000002 }; + private const uint P11 = 0xFFFFFFFF; + private const uint PExt23 = 0xFFFFFFFF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat.Add(12, x, y, z); + if (c != 0 || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(24, xx, yy, zz); + if (c != 0 || (zz[23] == PExt23 && Nat.Gte(24, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(24, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(12, x, z); + if (c != 0 || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(384, x); + if (z[11] == P11 && Nat.Gte(12, z, P)) + { + Nat.SubFrom(12, P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(12, x, 0, z); + } + else + { + uint c = Nat.Add(12, x, P, z); + Nat.ShiftDownBit(12, z, c); + } + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat.Create(24); + Nat384.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat.IsZero(12, x)) + { + Nat.Zero(12, z); + } + else + { + Nat.Sub(12, P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx16 = xx[16], xx17 = xx[17], xx18 = xx[18], xx19 = xx[19]; + long xx20 = xx[20], xx21 = xx[21], xx22 = xx[22], xx23 = xx[23]; + + const long n = 1; + + long t0 = (long)xx[12] + xx20 - n; + long t1 = (long)xx[13] + xx22; + long t2 = (long)xx[14] + xx22 + xx23; + long t3 = (long)xx[15] + xx23; + long t4 = xx17 + xx21; + long t5 = xx21 - xx23; + long t6 = xx22 - xx23; + long t7 = t0 + t5; + + long cc = 0; + cc += (long)xx[0] + t7; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)xx[1] + xx23 - t0 + t1; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] - xx21 - t1 + t2; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] - t2 + t3 + t7; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + xx16 + xx21 + t1 - t3 + t7; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] - xx16 + t1 + t2 + t4; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + xx18 - xx17 + t2 + t3; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)xx[7] + xx16 + xx19 - xx18 + t3; + z[7] = (uint)cc; + cc >>= 32; + cc += (long)xx[8] + xx16 + xx17 + xx20 - xx19; + z[8] = (uint)cc; + cc >>= 32; + cc += (long)xx[9] + xx18 - xx20 + t4; + z[9] = (uint)cc; + cc >>= 32; + cc += (long)xx[10] + xx18 + xx19 - t5 + t6; + z[10] = (uint)cc; + cc >>= 32; + cc += (long)xx[11] + xx19 + xx20 - t6; + z[11] = (uint)cc; + cc >>= 32; + cc += n; + + Debug.Assert(cc >= 0); + + Reduce32((uint)cc, z); + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx12 = x; + + cc += (long)z[0] + xx12; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)z[1] - xx12; + z[1] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[2]; + z[2] = (uint)cc; + cc >>= 32; + } + cc += (long)z[3] + xx12; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)z[4] + xx12; + z[4] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if ((cc != 0 && Nat.IncAt(12, z, 5) != 0) + || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat.Create(24); + Nat384.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat.Create(24); + Nat384.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat384.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat.Sub(12, x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(24, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(24, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(12, x, 0, z); + if (c != 0 || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - 1; + z[1] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] + 1; + z[4] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.IncAt(12, z, 5); + } + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] + 1; + z[1] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - 1; + z[4] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.DecAt(12, z, 5); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs.meta new file mode 100644 index 0000000..69453cb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3b7cb7a5d5e0a1544bce29407d194008 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs new file mode 100644 index 0000000..03904ff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs @@ -0,0 +1,214 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP384R1Curve.q; + + protected internal readonly uint[] x; + + public SecP384R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP384R1FieldElement", "x"); + + this.x = SecP384R1Field.FromBigInteger(x); + } + + public SecP384R1FieldElement() + { + this.x = Nat.Create(12); + } + + protected internal SecP384R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat.IsZero(12, x); } + } + + public override bool IsOne + { + get { return Nat.IsOne(12, x); } + } + + public override bool TestBitZero() + { + return Nat.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat.ToBigInteger(12, x); + } + + public override string FieldName + { + get { return "SecP384R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat.Create(12); + SecP384R1Field.Add(x, ((SecP384R1FieldElement)b).x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat.Create(12); + SecP384R1Field.AddOne(x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat.Create(12); + SecP384R1Field.Subtract(x, ((SecP384R1FieldElement)b).x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat.Create(12); + SecP384R1Field.Multiply(x, ((SecP384R1FieldElement)b).x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat.Create(12); + Mod.Invert(SecP384R1Field.P, ((SecP384R1FieldElement)b).x, z); + SecP384R1Field.Multiply(z, x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat.Create(12); + SecP384R1Field.Negate(x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat.Create(12); + SecP384R1Field.Square(x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP384R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat.Create(12); + Mod.Invert(SecP384R1Field.P, x, z); + return new SecP384R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^382 - 2^126 - 2^94 + 2^30 + + uint[] x1 = this.x; + if (Nat.IsZero(12, x1) || Nat.IsOne(12, x1)) + return this; + + uint[] t1 = Nat.Create(12); + uint[] t2 = Nat.Create(12); + uint[] t3 = Nat.Create(12); + uint[] t4 = Nat.Create(12); + + SecP384R1Field.Square(x1, t1); + SecP384R1Field.Multiply(t1, x1, t1); + + SecP384R1Field.SquareN(t1, 2, t2); + SecP384R1Field.Multiply(t2, t1, t2); + + SecP384R1Field.Square(t2, t2); + SecP384R1Field.Multiply(t2, x1, t2); + + SecP384R1Field.SquareN(t2, 5, t3); + SecP384R1Field.Multiply(t3, t2, t3); + + SecP384R1Field.SquareN(t3, 5, t4); + SecP384R1Field.Multiply(t4, t2, t4); + + SecP384R1Field.SquareN(t4, 15, t2); + SecP384R1Field.Multiply(t2, t4, t2); + + SecP384R1Field.SquareN(t2, 2, t3); + SecP384R1Field.Multiply(t1, t3, t1); + + SecP384R1Field.SquareN(t3, 28, t3); + SecP384R1Field.Multiply(t2, t3, t2); + + SecP384R1Field.SquareN(t2, 60, t3); + SecP384R1Field.Multiply(t3, t2, t3); + + uint[] r = t2; + + SecP384R1Field.SquareN(t3, 120, r); + SecP384R1Field.Multiply(r, t3, r); + + SecP384R1Field.SquareN(r, 15, r); + SecP384R1Field.Multiply(r, t4, r); + + SecP384R1Field.SquareN(r, 33, r); + SecP384R1Field.Multiply(r, t1, r); + + SecP384R1Field.SquareN(r, 64, r); + SecP384R1Field.Multiply(r, x1, r); + + SecP384R1Field.SquareN(r, 30, t1); + SecP384R1Field.Square(t1, t2); + + return Nat.Eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP384R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP384R1FieldElement); + } + + public virtual bool Equals(SecP384R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat.Eq(12, x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 12); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs.meta new file mode 100644 index 0000000..4d74505 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8c177ec57fed4194f86bc4bc12fd3100 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs new file mode 100644 index 0000000..1004731 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs @@ -0,0 +1,284 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP384R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.RawXCoord, Y1 = (SecP384R1FieldElement)this.RawYCoord; + SecP384R1FieldElement X2 = (SecP384R1FieldElement)b.RawXCoord, Y2 = (SecP384R1FieldElement)b.RawYCoord; + + SecP384R1FieldElement Z1 = (SecP384R1FieldElement)this.RawZCoords[0]; + SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat.Create(24); + uint[] tt2 = Nat.Create(24); + uint[] t3 = Nat.Create(12); + uint[] t4 = Nat.Create(12); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP384R1Field.Square(Z1.x, S2); + + U2 = tt2; + SecP384R1Field.Multiply(S2, X2.x, U2); + + SecP384R1Field.Multiply(S2, Z1.x, S2); + SecP384R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP384R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP384R1Field.Multiply(S1, X1.x, U1); + + SecP384R1Field.Multiply(S1, Z2.x, S1); + SecP384R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat.Create(12); + SecP384R1Field.Subtract(U1, U2, H); + + uint[] R = Nat.Create(12); + SecP384R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat.IsZero(12, H)) + { + if (Nat.IsZero(12, R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP384R1Field.Square(H, HSquared); + + uint[] G = Nat.Create(12); + SecP384R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP384R1Field.Multiply(HSquared, U1, V); + + SecP384R1Field.Negate(G, G); + Nat384.Mul(S1, G, tt1); + + c = Nat.AddBothTo(12, V, V, G); + SecP384R1Field.Reduce32(c, G); + + SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4); + SecP384R1Field.Square(R, X3.x); + SecP384R1Field.Subtract(X3.x, G, X3.x); + + SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G); + SecP384R1Field.Subtract(V, X3.x, Y3.x); + Nat384.Mul(Y3.x, R, tt2); + SecP384R1Field.AddExt(tt1, tt2, tt1); + SecP384R1Field.Reduce(tt1, Y3.x); + + SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H); + if (!Z1IsOne) + { + SecP384R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP384R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP384R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP384R1FieldElement Y1 = (SecP384R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.RawXCoord, Z1 = (SecP384R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat.Create(12); + uint[] t2 = Nat.Create(12); + + uint[] Y1Squared = Nat.Create(12); + SecP384R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat.Create(12); + SecP384R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP384R1Field.Square(Z1.x, Z1Squared); + } + + SecP384R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP384R1Field.Add(X1.x, Z1Squared, M); + SecP384R1Field.Multiply(M, t1, M); + c = Nat.AddBothTo(12, M, M, M); + SecP384R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP384R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(12, S, 2, 0); + SecP384R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(12, T, 3, 0, t1); + SecP384R1Field.Reduce32(c, t1); + + SecP384R1FieldElement X3 = new SecP384R1FieldElement(T); + SecP384R1Field.Square(M, X3.x); + SecP384R1Field.Subtract(X3.x, S, X3.x); + SecP384R1Field.Subtract(X3.x, S, X3.x); + + SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S); + SecP384R1Field.Subtract(S, X3.x, Y3.x); + SecP384R1Field.Multiply(Y3.x, M, Y3.x); + SecP384R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M); + SecP384R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP384R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP384R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs.meta new file mode 100644 index 0000000..5b8ffb9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP384R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 533f4a923a033e342854675195b3f0df +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs new file mode 100644 index 0000000..18339f9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs @@ -0,0 +1,81 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = new BigInteger(1, + Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); + + private const int SecP521R1_DEFAULT_COORDS = COORD_JACOBIAN; + + protected readonly SecP521R1Point m_infinity; + + public SecP521R1Curve() + : base(q) + { + this.m_infinity = new SecP521R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.Decode("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"))); + this.m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409")); + this.m_cofactor = BigInteger.One; + this.m_coord = SecP521R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP521R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP521R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP521R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP521R1Point(this, x, y, zs, withCompression); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs.meta new file mode 100644 index 0000000..23488fb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d65d118e58b9f114c9b15094148d033a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs new file mode 100644 index 0000000..705eb4f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs @@ -0,0 +1,159 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1Field + { + // 2^521 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x1FF }; + private const int P16 = 0x1FF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat.Add(16, x, y, z) + x[16] + y[16]; + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(16, x, z) + x[16]; + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(521, x); + if (Nat.Eq(17, z, P)) + { + Nat.Zero(17, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + uint x16 = x[16]; + uint c = Nat.ShiftDownBit(16, x, x16, z); + z[16] = (x16 >> 1) | (c >> 23); + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat.Create(33); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void Negate(uint[] x, uint[] z) + { + if (Nat.IsZero(17, x)) + { + Nat.Zero(17, z); + } + else + { + Nat.Sub(17, P, x, z); + } + } + + public static void Reduce(uint[] xx, uint[] z) + { + Debug.Assert(xx[32] >> 18 == 0); + uint xx32 = xx[32]; + uint c = Nat.ShiftDownBits(16, xx, 16, 9, xx32, z, 0) >> 23; + c += xx32 >> 9; + c += Nat.AddTo(16, xx, z); + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static void Reduce23(uint[] z) + { + uint z16 = z[16]; + uint c = Nat.AddWordTo(16, z16 >> 9, z) + (z16 & P16); + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat.Create(33); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + uint[] tt = Nat.Create(33); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat.Sub(16, x, y, z) + (int)(x[16] - y[16]); + if (c < 0) + { + c += Nat.Dec(16, z); + c &= P16; + } + z[16] = (uint)c; + } + + public static void Twice(uint[] x, uint[] z) + { + uint x16 = x[16]; + uint c = Nat.ShiftUpBit(16, x, x16 << 23, z) | (x16 << 1); + z[16] = c & P16; + } + + protected static void ImplMultiply(uint[] x, uint[] y, uint[] zz) + { + Nat512.Mul(x, y, zz); + + uint x16 = x[16], y16 = y[16]; + zz[32] = Nat.Mul31BothAdd(16, x16, y, y16, x, zz, 16) + (x16 * y16); + } + + protected static void ImplSquare(uint[] x, uint[] zz) + { + Nat512.Square(x, zz); + + uint x16 = x[16]; + zz[32] = Nat.MulWordAddTo(16, x16 << 1, x, 0, zz, 16) + (x16 * x16); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs.meta new file mode 100644 index 0000000..991882d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 825661e6afc41554080a475cc6af4dba +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs new file mode 100644 index 0000000..0423e2f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs @@ -0,0 +1,171 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1FieldElement + : ECFieldElement + { + public static readonly BigInteger Q = SecP521R1Curve.q; + + protected internal readonly uint[] x; + + public SecP521R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP521R1FieldElement", "x"); + + this.x = SecP521R1Field.FromBigInteger(x); + } + + public SecP521R1FieldElement() + { + this.x = Nat.Create(17); + } + + protected internal SecP521R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat.IsZero(17, x); } + } + + public override bool IsOne + { + get { return Nat.IsOne(17, x); } + } + + public override bool TestBitZero() + { + return Nat.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat.ToBigInteger(17, x); + } + + public override string FieldName + { + get { return "SecP521R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat.Create(17); + SecP521R1Field.Add(x, ((SecP521R1FieldElement)b).x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat.Create(17); + SecP521R1Field.AddOne(x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat.Create(17); + SecP521R1Field.Subtract(x, ((SecP521R1FieldElement)b).x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat.Create(17); + SecP521R1Field.Multiply(x, ((SecP521R1FieldElement)b).x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat.Create(17); + Mod.Invert(SecP521R1Field.P, ((SecP521R1FieldElement)b).x, z); + SecP521R1Field.Multiply(z, x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat.Create(17); + SecP521R1Field.Negate(x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat.Create(17); + SecP521R1Field.Square(x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP521R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat.Create(17); + Mod.Invert(SecP521R1Field.P, x, z); + return new SecP521R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^519 + + uint[] x1 = this.x; + if (Nat.IsZero(17, x1) || Nat.IsOne(17, x1)) + return this; + + uint[] t1 = Nat.Create(17); + uint[] t2 = Nat.Create(17); + + SecP521R1Field.SquareN(x1, 519, t1); + SecP521R1Field.Square(t1, t2); + + return Nat.Eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP521R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP521R1FieldElement); + } + + public virtual bool Equals(SecP521R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat.Eq(17, x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 17); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs.meta new file mode 100644 index 0000000..736e9ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5c7adc09b4e3b0e459b5fc6a13d4d040 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs new file mode 100644 index 0000000..32bb56a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs @@ -0,0 +1,279 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP521R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.RawXCoord, Y1 = (SecP521R1FieldElement)this.RawYCoord; + SecP521R1FieldElement X2 = (SecP521R1FieldElement)b.RawXCoord, Y2 = (SecP521R1FieldElement)b.RawYCoord; + + SecP521R1FieldElement Z1 = (SecP521R1FieldElement)this.RawZCoords[0]; + SecP521R1FieldElement Z2 = (SecP521R1FieldElement)b.RawZCoords[0]; + + uint[] t1 = Nat.Create(17); + uint[] t2 = Nat.Create(17); + uint[] t3 = Nat.Create(17); + uint[] t4 = Nat.Create(17); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP521R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP521R1Field.Multiply(S2, X2.x, U2); + + SecP521R1Field.Multiply(S2, Z1.x, S2); + SecP521R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP521R1Field.Square(Z2.x, S1); + + U1 = t1; + SecP521R1Field.Multiply(S1, X1.x, U1); + + SecP521R1Field.Multiply(S1, Z2.x, S1); + SecP521R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat.Create(17); + SecP521R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP521R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat.IsZero(17, H)) + { + if (Nat.IsZero(17, R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP521R1Field.Square(H, HSquared); + + uint[] G = Nat.Create(17); + SecP521R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP521R1Field.Multiply(HSquared, U1, V); + + SecP521R1Field.Multiply(S1, G, t1); + + SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4); + SecP521R1Field.Square(R, X3.x); + SecP521R1Field.Add(X3.x, G, X3.x); + SecP521R1Field.Subtract(X3.x, V, X3.x); + SecP521R1Field.Subtract(X3.x, V, X3.x); + + SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G); + SecP521R1Field.Subtract(V, X3.x, Y3.x); + SecP521R1Field.Multiply(Y3.x, R, t2); + SecP521R1Field.Subtract(t2, t1, Y3.x); + + SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H); + if (!Z1IsOne) + { + SecP521R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP521R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP521R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP521R1FieldElement Y1 = (SecP521R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.RawXCoord, Z1 = (SecP521R1FieldElement)this.RawZCoords[0]; + + uint[] t1 = Nat.Create(17); + uint[] t2 = Nat.Create(17); + + uint[] Y1Squared = Nat.Create(17); + SecP521R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat.Create(17); + SecP521R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP521R1Field.Square(Z1.x, Z1Squared); + } + + SecP521R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP521R1Field.Add(X1.x, Z1Squared, M); + SecP521R1Field.Multiply(M, t1, M); + Nat.AddBothTo(17, M, M, M); + SecP521R1Field.Reduce23(M); + + uint[] S = Y1Squared; + SecP521R1Field.Multiply(Y1Squared, X1.x, S); + Nat.ShiftUpBits(17, S, 2, 0); + SecP521R1Field.Reduce23(S); + + Nat.ShiftUpBits(17, T, 3, 0, t1); + SecP521R1Field.Reduce23(t1); + + SecP521R1FieldElement X3 = new SecP521R1FieldElement(T); + SecP521R1Field.Square(M, X3.x); + SecP521R1Field.Subtract(X3.x, S, X3.x); + SecP521R1Field.Subtract(X3.x, S, X3.x); + + SecP521R1FieldElement Y3 = new SecP521R1FieldElement(S); + SecP521R1Field.Subtract(S, X3.x, Y3.x); + SecP521R1Field.Multiply(Y3.x, M, Y3.x); + SecP521R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP521R1FieldElement Z3 = new SecP521R1FieldElement(M); + SecP521R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP521R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP521R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs.meta new file mode 100644 index 0000000..b73e279 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecP521R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b600c3d896b3dd8488f61361cf3363a9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs new file mode 100644 index 0000000..a7273fa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs @@ -0,0 +1,229 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113Field + { + private const ulong M49 = ulong.MaxValue >> 15; + private const ulong M57 = ulong.MaxValue >> 7; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat128.FromBigInteger64(x); + Reduce15(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat128.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat128.Create64(); + ulong[] t1 = Nat128.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 3, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 7, t0); + Multiply(t0, t1, t0); + SquareN(t0, 14, t1); + Multiply(t1, t0, t1); + SquareN(t1, 28, t0); + Multiply(t0, t1, t0); + SquareN(t0, 56, t1); + Multiply(t1, t0, t1); + Square(t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat128.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat128.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + + x1 ^= (x3 << 15) ^ (x3 << 24); + x2 ^= (x3 >> 49) ^ (x3 >> 40); + + x0 ^= (x2 << 15) ^ (x2 << 24); + x1 ^= (x2 >> 49) ^ (x2 >> 40); + + ulong t = x1 >> 49; + z[0] = x0 ^ t ^ (t << 9); + z[1] = x1 & M49; + } + + public static void Reduce15(ulong[] z, int zOff) + { + ulong z1 = z[zOff + 1], t = z1 >> 49; + z[zOff ] ^= t ^ (t << 9); + z[zOff + 1] = z1 & M49; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0 = Interleave.Unshuffle(x[0]), u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + z[0] = e0 ^ (c0 << 57) ^ (c0 << 5); + z[1] = (c0 >> 7) ^ (c0 >> 59); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat128.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat128.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat128.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0 + return (uint)(x[0]) & 1U; + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong f0 = x[0], f1 = x[1]; + f1 = ((f0 >> 57) ^ (f1 << 7)) & M57; + f0 &= M57; + + ulong g0 = y[0], g1 = y[1]; + g1 = ((g0 >> 57) ^ (g1 << 7)) & M57; + g0 &= M57; + + ulong[] H = new ulong[6]; + + ImplMulw(f0, g0, H, 0); // H(0) 57/56 bits + ImplMulw(f1, g1, H, 2); // H(INF) 57/54 bits + ImplMulw(f0 ^ f1, g0 ^ g1, H, 4); // H(1) 57/56 bits + + ulong r = H[1] ^ H[2]; + ulong z0 = H[0], + z3 = H[3], + z1 = H[4] ^ z0 ^ r, + z2 = H[5] ^ z3 ^ r; + + zz[0] = z0 ^ (z1 << 57); + zz[1] = (z1 >> 7) ^ (z2 << 50); + zz[2] = (z2 >> 14) ^ (z3 << 43); + zz[3] = (z3 >> 21); + } + + protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 57 == 0); + Debug.Assert(y >> 57 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7]; + int k = 48; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 9) > 0); + + h ^= ((x & 0x0100804020100800UL) & (ulong)(((long)y << 7) >> 63)) >> 8; + + Debug.Assert(h >> 49 == 0); + + z[zOff ] = l & M57; + z[zOff + 1] = (l >> 57) ^ (h << 7); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs.meta new file mode 100644 index 0000000..75dfd0a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 11da1b9450f57644fa56b5c007984298 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs new file mode 100644 index 0000000..68521b1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113FieldElement + : ECFieldElement + { + protected internal readonly ulong[] x; + + public SecT113FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 113) + throw new ArgumentException("value invalid for SecT113FieldElement", "x"); + + this.x = SecT113Field.FromBigInteger(x); + } + + public SecT113FieldElement() + { + this.x = Nat128.Create64(); + } + + protected internal SecT113FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat128.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat128.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1L) != 0L; + } + + public override BigInteger ToBigInteger() + { + return Nat128.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT113Field"; } + } + + public override int FieldSize + { + get { return 113; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat128.Create64(); + SecT113Field.Add(x, ((SecT113FieldElement)b).x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat128.Create64(); + SecT113Field.AddOne(x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat128.Create64(); + SecT113Field.Multiply(x, ((SecT113FieldElement)b).x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT113FieldElement)b).x; + ulong[] xx = ((SecT113FieldElement)x).x, yx = ((SecT113FieldElement)y).x; + + ulong[] tt = Nat128.CreateExt64(); + SecT113Field.MultiplyAddToExt(ax, bx, tt); + SecT113Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat128.Create64(); + SecT113Field.Reduce(tt, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat128.Create64(); + SecT113Field.Square(x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT113FieldElement)x).x, yx = ((SecT113FieldElement)y).x; + + ulong[] tt = Nat128.CreateExt64(); + SecT113Field.SquareAddToExt(ax, tt); + SecT113Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat128.Create64(); + SecT113Field.Reduce(tt, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat128.Create64(); + SecT113Field.SquareN(x, pow, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat128.Create64(); + SecT113Field.Invert(x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat128.Create64(); + SecT113Field.Sqrt(x, z); + return new SecT113FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 113; } + } + + public virtual int K1 + { + get { return 9; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT113FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT113FieldElement); + } + + public virtual bool Equals(SecT113FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat128.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 113009 ^ Arrays.GetHashCode(x, 0, 2); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs.meta new file mode 100644 index 0000000..11740ee --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2163552ee3494464490a708ac4a51d7f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs new file mode 100644 index 0000000..33cec8e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs @@ -0,0 +1,192 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R1Curve + : AbstractF2mCurve + { + private const int SecT113R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT113R1Point m_infinity; + + public SecT113R1Curve() + : base(113, 9, 0, 0) + { + this.m_infinity = new SecT113R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("003088250CA6E7C7FE649CE85820F7"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("00E8BEE4D3E2260744188BE0E9C723"))); + this.m_order = new BigInteger(1, Hex.Decode("0100000000000000D9CCEC8A39E56F")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT113R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT113R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 113; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT113FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT113R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT113R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + /** + * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2). + * + * @param yTilde + * ~yp, an indication bit for the decompression of yp. + * @param X1 + * The field element xp. + * @return the decompressed point. + */ + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement x = FromBigInteger(X1), y = null; + if (x.IsZero) + { + y = B.Sqrt(); + } + else + { + ECFieldElement beta = x.Square().Invert().Multiply(B).Add(A).Add(x); + ECFieldElement z = SolveQuadraticEquation(beta); + if (z != null) + { + if (z.TestBitZero() != (yTilde == 1)) + { + z = z.AddOne(); + } + + switch (this.CoordinateSystem) + { + case COORD_LAMBDA_AFFINE: + case COORD_LAMBDA_PROJECTIVE: + { + y = z.Add(x); + break; + } + default: + { + y = z.Multiply(x); + break; + } + } + } + } + + if (y == null) + throw new ArgumentException("Invalid point compression"); + + return this.CreateRawPoint(x, y, true); + } + + /** + * Solves a quadratic equation z2 + z = beta(X9.62 + * D.1.6) The other solution is z + 1. + * + * @param beta + * The value to solve the quadratic equation for. + * @return the solution for z2 + z = beta or + * null if no solution exists. + */ + private ECFieldElement SolveQuadraticEquation(ECFieldElement beta) + { + if (beta.IsZero) + return beta; + + ECFieldElement zeroElement = FromBigInteger(BigInteger.Zero); + + ECFieldElement z = null; + ECFieldElement gamma = null; + + Random rand = new Random(); + do + { + ECFieldElement t = FromBigInteger(new BigInteger(113, rand)); + z = zeroElement; + ECFieldElement w = beta; + for (int i = 1; i < 113; i++) + { + ECFieldElement w2 = w.Square(); + z = z.Square().Add(w2.Multiply(t)); + w = w2.Add(beta); + } + if (!w.IsZero) + return null; + gamma = z.Square().Add(z); + } + while (gamma.IsZero); + + return z; + } + + public virtual int M + { + get { return 113; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 9; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs.meta new file mode 100644 index 0000000..af38d1c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fc69e7fac16cabc41ba1012d78e95f33 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs new file mode 100644 index 0000000..ecbd648 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs @@ -0,0 +1,285 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT113R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT113R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT113R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT113R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT113R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT113R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT113R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT113R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT113R1Point(Curve, X, L.Add(Z), new ECFieldElement[]{ Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs.meta new file mode 100644 index 0000000..9d29414 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a8336d94ed396554ea8064dc7cfddf76 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs new file mode 100644 index 0000000..fe69020 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R2Curve + : AbstractF2mCurve + { + private const int SecT113R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT113R2Point m_infinity; + + public SecT113R2Curve() + : base(113, 9, 0, 0) + { + this.m_infinity = new SecT113R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("00689918DBEC7E5A0DD6DFC0AA55C7"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0095E9A9EC9B297BD4BF36E059184F"))); + this.m_order = new BigInteger(1, Hex.Decode("010000000000000108789B2496AF93")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT113R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT113R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 113; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT113FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT113R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT113R2Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 113; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 9; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs.meta new file mode 100644 index 0000000..bc5ca69 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8a90d133b57e6e747b05545dad95da40 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs new file mode 100644 index 0000000..ebed001 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs @@ -0,0 +1,295 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT113R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT113R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT113R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT113R2Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT113R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT113R2Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return Twice(); + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT113R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT113R2Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT113R2Point(Curve, X, L.Add(Z), new ECFieldElement[]{ Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs.meta new file mode 100644 index 0000000..7fdb379 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT113R2Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 28953e22bdd1e22418f49b57246b6536 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs new file mode 100644 index 0000000..7bd4944 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs @@ -0,0 +1,334 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131Field + { + private const ulong M03 = ulong.MaxValue >> 61; + private const ulong M44 = ulong.MaxValue >> 20; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0x26BC4D789AF13523UL, 0x26BC4D789AF135E2UL, 0x6UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat192.FromBigInteger64(x); + Reduce61(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat192.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat192.Create64(); + ulong[] t1 = Nat192.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + SquareN(t0, 2, t1); + Multiply(t1, t0, t1); + SquareN(t1, 4, t0); + Multiply(t0, t1, t0); + SquareN(t0, 8, t1); + Multiply(t1, t0, t1); + SquareN(t1, 16, t0); + Multiply(t0, t1, t0); + SquareN(t0, 32, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 65, t0); + Multiply(t0, t1, t0); + Square(t0, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat192.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat192.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4]; + + x1 ^= (x4 << 61) ^ (x4 << 63); + x2 ^= (x4 >> 3) ^ (x4 >> 1) ^ x4 ^ (x4 << 5); + x3 ^= (x4 >> 59); + + x0 ^= (x3 << 61) ^ (x3 << 63); + x1 ^= (x3 >> 3) ^ (x3 >> 1) ^ x3 ^ (x3 << 5); + x2 ^= (x3 >> 59); + + ulong t = x2 >> 3; + z[0] = x0 ^ t ^ (t << 2) ^ (t << 3) ^ (t << 8); + z[1] = x1 ^ (t >> 56); + z[2] = x2 & M03; + } + + public static void Reduce61(ulong[] z, int zOff) + { + ulong z2 = z[zOff + 2], t = z2 >> 3; + z[zOff ] ^= t ^ (t << 2) ^ (t << 3) ^ (t << 8); + z[zOff + 1] ^= (t >> 56); + z[zOff + 2] = z2 & M03; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] odd = Nat192.Create64(); + + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[0] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL); + odd[1] = (u0 >> 32); + + Multiply(odd, ROOT_Z, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(5); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat.Create64(5); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat.Create64(5); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 123, 129 + return (uint)(x[0] ^ (x[1] >> 59) ^ (x[2] >> 1)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5]; + zz[0] = z0 ^ (z1 << 44); + zz[1] = (z1 >> 20) ^ (z2 << 24); + zz[2] = (z2 >> 40) ^ (z3 << 4) + ^ (z4 << 48); + zz[3] = (z3 >> 60) ^ (z5 << 28) + ^ (z4 >> 16); + zz[4] = (z5 >> 36); + zz[5] = 0; + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Five-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong f0 = x[0], f1 = x[1], f2 = x[2]; + f2 = ((f1 >> 24) ^ (f2 << 40)) & M44; + f1 = ((f0 >> 44) ^ (f1 << 20)) & M44; + f0 &= M44; + + ulong g0 = y[0], g1 = y[1], g2 = y[2]; + g2 = ((g1 >> 24) ^ (g2 << 40)) & M44; + g1 = ((g0 >> 44) ^ (g1 << 20)) & M44; + g0 &= M44; + + ulong[] H = new ulong[10]; + + ImplMulw(f0, g0, H, 0); // H(0) 44/43 bits + ImplMulw(f2, g2, H, 2); // H(INF) 44/41 bits + + ulong t0 = f0 ^ f1 ^ f2; + ulong t1 = g0 ^ g1 ^ g2; + + ImplMulw(t0, t1, H, 4); // H(1) 44/43 bits + + ulong t2 = (f1 << 1) ^ (f2 << 2); + ulong t3 = (g1 << 1) ^ (g2 << 2); + + ImplMulw(f0 ^ t2, g0 ^ t3, H, 6); // H(t) 44/45 bits + ImplMulw(t0 ^ t2, t1 ^ t3, H, 8); // H(t + 1) 44/45 bits + + ulong t4 = H[6] ^ H[8]; + ulong t5 = H[7] ^ H[9]; + + Debug.Assert(t5 >> 44 == 0); + + // Calculate V + ulong v0 = (t4 << 1) ^ H[6]; + ulong v1 = t4 ^ (t5 << 1) ^ H[7]; + ulong v2 = t5; + + // Calculate U + ulong u0 = H[0]; + ulong u1 = H[1] ^ H[0] ^ H[4]; + ulong u2 = H[1] ^ H[5]; + + // Calculate W + ulong w0 = u0 ^ v0 ^ (H[2] << 4) ^ (H[2] << 1); + ulong w1 = u1 ^ v1 ^ (H[3] << 4) ^ (H[3] << 1); + ulong w2 = u2 ^ v2; + + // Propagate carries + w1 ^= (w0 >> 44); w0 &= M44; + w2 ^= (w1 >> 44); w1 &= M44; + + Debug.Assert((w0 & 1UL) == 0); + + // Divide W by t + + w0 = (w0 >> 1) ^ ((w1 & 1UL) << 43); + w1 = (w1 >> 1) ^ ((w2 & 1UL) << 43); + w2 = (w2 >> 1); + + // Divide W by (t + 1) + + w0 ^= (w0 << 1); + w0 ^= (w0 << 2); + w0 ^= (w0 << 4); + w0 ^= (w0 << 8); + w0 ^= (w0 << 16); + w0 ^= (w0 << 32); + + w0 &= M44; w1 ^= (w0 >> 43); + + w1 ^= (w1 << 1); + w1 ^= (w1 << 2); + w1 ^= (w1 << 4); + w1 ^= (w1 << 8); + w1 ^= (w1 << 16); + w1 ^= (w1 << 32); + + w1 &= M44; w2 ^= (w1 >> 43); + + w2 ^= (w2 << 1); + w2 ^= (w2 << 2); + w2 ^= (w2 << 4); + w2 ^= (w2 << 8); + w2 ^= (w2 << 16); + w2 ^= (w2 << 32); + + Debug.Assert(w2 >> 42 == 0); + + zz[0] = u0; + zz[1] = u1 ^ w0 ^ H[2]; + zz[2] = u2 ^ w1 ^ w0 ^ H[3]; + zz[3] = w2 ^ w1; + zz[4] = w2 ^ H[2]; + zz[5] = H[3]; + + ImplCompactExt(zz); + } + + protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 45 == 0); + Debug.Assert(y >> 45 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + int k = 33; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6 + ^ u[(j >> 9) & 7] << 9; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 12) > 0); + + Debug.Assert(h >> 25 == 0); + + z[zOff ] = l & M44; + z[zOff + 1] = (l >> 44) ^ (h << 20); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + + zz[4] = Interleave.Expand8to16((uint)x[2]); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs.meta new file mode 100644 index 0000000..881521d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 527c1d05582060249ab62c9119ba6f62 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs new file mode 100644 index 0000000..4959964 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131FieldElement + : ECFieldElement + { + protected readonly ulong[] x; + + public SecT131FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 131) + throw new ArgumentException("value invalid for SecT131FieldElement", "x"); + + this.x = SecT131Field.FromBigInteger(x); + } + + public SecT131FieldElement() + { + this.x = Nat192.Create64(); + } + + protected internal SecT131FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat192.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat192.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT131Field"; } + } + + public override int FieldSize + { + get { return 131; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT131Field.Add(x, ((SecT131FieldElement)b).x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat192.Create64(); + SecT131Field.AddOne(x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT131Field.Multiply(x, ((SecT131FieldElement)b).x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT131FieldElement)b).x; + ulong[] xx = ((SecT131FieldElement)x).x, yx = ((SecT131FieldElement)y).x; + + ulong[] tt = Nat.Create64(5); + SecT131Field.MultiplyAddToExt(ax, bx, tt); + SecT131Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT131Field.Reduce(tt, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat192.Create64(); + SecT131Field.Square(x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT131FieldElement)x).x, yx = ((SecT131FieldElement)y).x; + + ulong[] tt = Nat.Create64(5); + SecT131Field.SquareAddToExt(ax, tt); + SecT131Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT131Field.Reduce(tt, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat192.Create64(); + SecT131Field.SquareN(x, pow, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat192.Create64(); + SecT131Field.Invert(x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat192.Create64(); + SecT131Field.Sqrt(x, z); + return new SecT131FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 131; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 3; } + } + + public virtual int K3 + { + get { return 8; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT131FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT131FieldElement); + } + + public virtual bool Equals(SecT131FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 131832 ^ Arrays.GetHashCode(x, 0, 3); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs.meta new file mode 100644 index 0000000..02d92a5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 72de0413a2e13924c819e108bbdaa5e9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs new file mode 100644 index 0000000..c9060e3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R1Curve + : AbstractF2mCurve + { + private const int SecT131R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT131R1Point m_infinity; + + public SecT131R1Curve() + : base(131, 2, 3, 8) + { + this.m_infinity = new SecT131R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("07A11B09A76B562144418FF3FF8C2570B8"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0217C05610884B63B9C6C7291678F9D341"))); + this.m_order = new BigInteger(1, Hex.Decode("0400000000000000023123953A9464B54D")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT131R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT131R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 131; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT131FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT131R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT131R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 131; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 3; } + } + + public virtual int K3 + { + get { return 8; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs.meta new file mode 100644 index 0000000..b0e4d52 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d0261827bffcf40469797c5940ecde2a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs new file mode 100644 index 0000000..50304f0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs @@ -0,0 +1,291 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT131R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT131R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT131R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT131R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT131R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT131R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return Twice(); + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT131R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT131R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT131R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs.meta new file mode 100644 index 0000000..506931f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b724cdc187d68a14ab82743561c8172c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs new file mode 100644 index 0000000..43fa711 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R2Curve + : AbstractF2mCurve + { + private const int SecT131R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT131R2Point m_infinity; + + public SecT131R2Curve() + : base(131, 2, 3, 8) + { + this.m_infinity = new SecT131R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("03E5A88919D7CAFCBF415F07C2176573B2"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("04B8266A46C55657AC734CE38F018F2192"))); + this.m_order = new BigInteger(1, Hex.Decode("0400000000000000016954A233049BA98F")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT131R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT131R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override int FieldSize + { + get { return 131; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT131FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT131R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT131R2Point(this, x, y, zs, withCompression); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 131; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 3; } + } + + public virtual int K3 + { + get { return 8; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs.meta new file mode 100644 index 0000000..47463fb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4921b9560f77c9747861717d70d2afdb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs new file mode 100644 index 0000000..df28052 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs @@ -0,0 +1,287 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT131R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT131R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT131R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT131R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT131R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT131R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT131R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT131R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT131R2Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs.meta new file mode 100644 index 0000000..8e6d0ee --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT131R2Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8cd012eab4ae35f43bc77cf7ee5311e8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs new file mode 100644 index 0000000..1c6a81f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs @@ -0,0 +1,344 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163Field + { + private const ulong M35 = ulong.MaxValue >> 29; + private const ulong M55 = ulong.MaxValue >> 9; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0xB6DB6DB6DB6DB6B0UL, 0x492492492492DB6DUL, 0x492492492UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat192.FromBigInteger64(x); + Reduce29(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat192.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3 } + + ulong[] t0 = Nat192.Create64(); + ulong[] t1 = Nat192.Create64(); + + Square(x, t0); + + // 3 | 162 + SquareN(t0, 1, t1); + Multiply(t0, t1, t0); + SquareN(t1, 1, t1); + Multiply(t0, t1, t0); + + // 3 | 54 + SquareN(t0, 3, t1); + Multiply(t0, t1, t0); + SquareN(t1, 3, t1); + Multiply(t0, t1, t0); + + // 3 | 18 + SquareN(t0, 9, t1); + Multiply(t0, t1, t0); + SquareN(t1, 9, t1); + Multiply(t0, t1, t0); + + // 3 | 6 + SquareN(t0, 27, t1); + Multiply(t0, t1, t0); + SquareN(t1, 27, t1); + Multiply(t0, t1, t0); + + // 2 | 2 + SquareN(t0, 81, t1); + Multiply(t0, t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat192.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat192.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4], x5 = xx[5]; + + x2 ^= (x5 << 29) ^ (x5 << 32) ^ (x5 << 35) ^ (x5 << 36); + x3 ^= (x5 >> 35) ^ (x5 >> 32) ^ (x5 >> 29) ^ (x5 >> 28); + + x1 ^= (x4 << 29) ^ (x4 << 32) ^ (x4 << 35) ^ (x4 << 36); + x2 ^= (x4 >> 35) ^ (x4 >> 32) ^ (x4 >> 29) ^ (x4 >> 28); + + x0 ^= (x3 << 29) ^ (x3 << 32) ^ (x3 << 35) ^ (x3 << 36); + x1 ^= (x3 >> 35) ^ (x3 >> 32) ^ (x3 >> 29) ^ (x3 >> 28); + + ulong t = x2 >> 35; + z[0] = x0 ^ t ^ (t << 3) ^ (t << 6) ^ (t << 7); + z[1] = x1; + z[2] = x2 & M35; + } + + public static void Reduce29(ulong[] z, int zOff) + { + ulong z2 = z[zOff + 2], t = z2 >> 35; + z[zOff ] ^= t ^ (t << 3) ^ (t << 6) ^ (t << 7); + z[zOff + 2] = z2 & M35; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] odd = Nat192.Create64(); + + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[0] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL); + odd[1] = (u0 >> 32); + + Multiply(odd, ROOT_Z, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat192.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat192.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat192.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 157 + return (uint)(x[0] ^ (x[2] >> 29)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5]; + zz[0] = z0 ^ (z1 << 55); + zz[1] = (z1 >> 9) ^ (z2 << 46); + zz[2] = (z2 >> 18) ^ (z3 << 37); + zz[3] = (z3 >> 27) ^ (z4 << 28); + zz[4] = (z4 >> 36) ^ (z5 << 19); + zz[5] = (z5 >> 45); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Five-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong f0 = x[0], f1 = x[1], f2 = x[2]; + f2 = ((f1 >> 46) ^ (f2 << 18)); + f1 = ((f0 >> 55) ^ (f1 << 9)) & M55; + f0 &= M55; + + ulong g0 = y[0], g1 = y[1], g2 = y[2]; + g2 = ((g1 >> 46) ^ (g2 << 18)); + g1 = ((g0 >> 55) ^ (g1 << 9)) & M55; + g0 &= M55; + + ulong[] H = new ulong[10]; + + ImplMulw(f0, g0, H, 0); // H(0) 55/54 bits + ImplMulw(f2, g2, H, 2); // H(INF) 55/50 bits + + ulong t0 = f0 ^ f1 ^ f2; + ulong t1 = g0 ^ g1 ^ g2; + + ImplMulw(t0, t1, H, 4); // H(1) 55/54 bits + + ulong t2 = (f1 << 1) ^ (f2 << 2); + ulong t3 = (g1 << 1) ^ (g2 << 2); + + ImplMulw(f0 ^ t2, g0 ^ t3, H, 6); // H(t) 55/56 bits + ImplMulw(t0 ^ t2, t1 ^ t3, H, 8); // H(t + 1) 55/56 bits + + ulong t4 = H[6] ^ H[8]; + ulong t5 = H[7] ^ H[9]; + + Debug.Assert(t5 >> 55 == 0); + + // Calculate V + ulong v0 = (t4 << 1) ^ H[6]; + ulong v1 = t4 ^ (t5 << 1) ^ H[7]; + ulong v2 = t5; + + // Calculate U + ulong u0 = H[0]; + ulong u1 = H[1] ^ H[0] ^ H[4]; + ulong u2 = H[1] ^ H[5]; + + // Calculate W + ulong w0 = u0 ^ v0 ^ (H[2] << 4) ^ (H[2] << 1); + ulong w1 = u1 ^ v1 ^ (H[3] << 4) ^ (H[3] << 1); + ulong w2 = u2 ^ v2; + + // Propagate carries + w1 ^= (w0 >> 55); w0 &= M55; + w2 ^= (w1 >> 55); w1 &= M55; + + Debug.Assert((w0 & 1UL) == 0UL); + + // Divide W by t + + w0 = (w0 >> 1) ^ ((w1 & 1UL) << 54); + w1 = (w1 >> 1) ^ ((w2 & 1UL) << 54); + w2 = (w2 >> 1); + + // Divide W by (t + 1) + + w0 ^= (w0 << 1); + w0 ^= (w0 << 2); + w0 ^= (w0 << 4); + w0 ^= (w0 << 8); + w0 ^= (w0 << 16); + w0 ^= (w0 << 32); + + w0 &= M55; w1 ^= (w0 >> 54); + + w1 ^= (w1 << 1); + w1 ^= (w1 << 2); + w1 ^= (w1 << 4); + w1 ^= (w1 << 8); + w1 ^= (w1 << 16); + w1 ^= (w1 << 32); + + w1 &= M55; w2 ^= (w1 >> 54); + + w2 ^= (w2 << 1); + w2 ^= (w2 << 2); + w2 ^= (w2 << 4); + w2 ^= (w2 << 8); + w2 ^= (w2 << 16); + w2 ^= (w2 << 32); + + Debug.Assert(w2 >> 52 == 0); + + zz[0] = u0; + zz[1] = u1 ^ w0 ^ H[2]; + zz[2] = u2 ^ w1 ^ w0 ^ H[3]; + zz[3] = w2 ^ w1; + zz[4] = w2 ^ H[2]; + zz[5] = H[3]; + + ImplCompactExt(zz); + } + + protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 56 == 0); + Debug.Assert(y >> 56 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 3]; + int k = 47; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 9) > 0); + + Debug.Assert(h >> 47 == 0); + + z[zOff ] = l & M55; + z[zOff + 1] = (l >> 55) ^ (h << 9); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + + ulong x2 = x[2]; + zz[4] = Interleave.Expand32to64((uint)x2); + zz[5] = Interleave.Expand8to16((uint)(x2 >> 32)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs.meta new file mode 100644 index 0000000..50b5cff --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0b55cdcb57a2bab44be2fb7cc83e0236 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs new file mode 100644 index 0000000..287b309 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163FieldElement + : ECFieldElement + { + protected readonly ulong[] x; + + public SecT163FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 163) + throw new ArgumentException("value invalid for SecT163FieldElement", "x"); + + this.x = SecT163Field.FromBigInteger(x); + } + + public SecT163FieldElement() + { + this.x = Nat192.Create64(); + } + + protected internal SecT163FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat192.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat192.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1L) != 0L; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT163Field"; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT163Field.Add(x, ((SecT163FieldElement)b).x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat192.Create64(); + SecT163Field.AddOne(x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT163Field.Multiply(x, ((SecT163FieldElement)b).x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT163FieldElement)b).x; + ulong[] xx = ((SecT163FieldElement)x).x, yx = ((SecT163FieldElement)y).x; + + ulong[] tt = Nat192.CreateExt64(); + SecT163Field.MultiplyAddToExt(ax, bx, tt); + SecT163Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT163Field.Reduce(tt, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat192.Create64(); + SecT163Field.Square(x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT163FieldElement)x).x, yx = ((SecT163FieldElement)y).x; + + ulong[] tt = Nat192.CreateExt64(); + SecT163Field.SquareAddToExt(ax, tt); + SecT163Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT163Field.Reduce(tt, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat192.Create64(); + SecT163Field.SquareN(x, pow, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat192.Create64(); + SecT163Field.Invert(x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat192.Create64(); + SecT163Field.Sqrt(x, z); + return new SecT163FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT163FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT163FieldElement); + } + + public virtual bool Equals(SecT163FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 163763 ^ Arrays.GetHashCode(x, 0, 3); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs.meta new file mode 100644 index 0000000..42312bc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 08f568b7d3a3b794fb15d90d7d9cf56e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs new file mode 100644 index 0000000..6621e22 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163K1Curve + : AbstractF2mCurve + { + private const int SecT163K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT163K1Point m_infinity; + + public SecT163K1Curve() + : base(163, 3, 6, 7) + { + this.m_infinity = new SecT163K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = this.m_a; + this.m_order = new BigInteger(1, Hex.Decode("04000000000000000000020108A2E0CC0D99F8A5EF")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT163K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT163K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT163FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT163K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT163K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs.meta new file mode 100644 index 0000000..8f0bc4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 976cb761a30ff1a4e80fb9334c6f7175 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs new file mode 100644 index 0000000..1caca11 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs @@ -0,0 +1,293 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT163K1Point(null, this.AffineXCoord, this.AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.getA()); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + //return new SecT163K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT163K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT163K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT163K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + //return new SecT163K1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT163K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(X3); + + return new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.getA().Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.getA().Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT163K1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT163K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT163K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs.meta new file mode 100644 index 0000000..8bd8349 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4644b5025fe7953469fe1de6e795d40e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs new file mode 100644 index 0000000..3ce32e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R1Curve + : AbstractF2mCurve + { + private const int SecT163R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT163R1Point m_infinity; + + public SecT163R1Curve() + : base(163, 3, 6, 7) + { + this.m_infinity = new SecT163R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9"))); + this.m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT163R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT163R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT163FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT163R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT163R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs.meta new file mode 100644 index 0000000..ba80244 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ee61fe945074bfa4c8dc05181ba609d5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs new file mode 100644 index 0000000..2a5070d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs @@ -0,0 +1,287 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT163R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT163R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT163R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT163R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT163R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT163R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT163R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT163R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT163R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs.meta new file mode 100644 index 0000000..38af4c2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fe4ab3e2a058412428aca19b765ca554 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs new file mode 100644 index 0000000..9fb2711 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R2Curve + : AbstractF2mCurve + { + private const int SecT163R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT163R2Point m_infinity; + + public SecT163R2Curve() + : base(163, 3, 6, 7) + { + this.m_infinity = new SecT163R2Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("020A601907B8C953CA1481EB10512F78744A3205FD"))); + this.m_order = new BigInteger(1, Hex.Decode("040000000000000000000292FE77E70C12A4234C33")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT163R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT163R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT163FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT163R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT163R2Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs.meta new file mode 100644 index 0000000..a0dc56a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f69c9a732e5e17244b151ca873d7d6e9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs new file mode 100644 index 0000000..1786e48 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs @@ -0,0 +1,294 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT163R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT163R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT163R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT163R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return Twice(); + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT163R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT163R2Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs.meta new file mode 100644 index 0000000..d4d5aa3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT163R2Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2962527dcabd980428bc4751bd5097b0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs new file mode 100644 index 0000000..a88b0ab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs @@ -0,0 +1,307 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193Field + { + private const ulong M01 = 1UL; + private const ulong M49 = ulong.MaxValue >> 15; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat256.FromBigInteger64(x); + Reduce63(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat256.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3 } + + ulong[] t0 = Nat256.Create64(); + ulong[] t1 = Nat256.Create64(); + + Square(x, t0); + + // 3 | 192 + SquareN(t0, 1, t1); + Multiply(t0, t1, t0); + SquareN(t1, 1, t1); + Multiply(t0, t1, t0); + + // 2 | 64 + SquareN(t0, 3, t1); + Multiply(t0, t1, t0); + + // 2 | 32 + SquareN(t0, 6, t1); + Multiply(t0, t1, t0); + + // 2 | 16 + SquareN(t0, 12, t1); + Multiply(t0, t1, t0); + + // 2 | 8 + SquareN(t0, 24, t1); + Multiply(t0, t1, t0); + + // 2 | 4 + SquareN(t0, 48, t1); + Multiply(t0, t1, t0); + + // 2 | 2 + SquareN(t0, 96, t1); + Multiply(t0, t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4], x5 = xx[5], x6 = xx[6]; + + x2 ^= (x6 << 63); + x3 ^= (x6 >> 1) ^ (x6 << 14); + x4 ^= (x6 >> 50); + + x1 ^= (x5 << 63); + x2 ^= (x5 >> 1) ^ (x5 << 14); + x3 ^= (x5 >> 50); + + x0 ^= (x4 << 63); + x1 ^= (x4 >> 1) ^ (x4 << 14); + x2 ^= (x4 >> 50); + + ulong t = x3 >> 1; + z[0] = x0 ^ t ^ (t << 15); + z[1] = x1 ^ (t >> 49); + z[2] = x2; + z[3] = x3 & M01; + } + + public static void Reduce63(ulong[] z, int zOff) + { + ulong z3 = z[zOff + 3], t = z3 >> 1; + z[zOff ] ^= t ^ (t << 15); + z[zOff + 1] ^= (t >> 49); + z[zOff + 3] = z3 & M01; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) ^ (x[3] << 32); + ulong c1 = (u0 >> 32); + + z[0] = e0 ^ (c0 << 8); + z[1] = e1 ^ (c1 << 8) ^ (c0 >> 56) ^ (c0 << 33); + z[2] = (c1 >> 56) ^ (c1 << 33) ^ (c0 >> 31); + z[3] = (c1 >> 31); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0 + return (uint)(x[0]) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5], z6 = zz[6], z7 = zz[7]; + zz[0] = z0 ^ (z1 << 49); + zz[1] = (z1 >> 15) ^ (z2 << 34); + zz[2] = (z2 >> 30) ^ (z3 << 19); + zz[3] = (z3 >> 45) ^ (z4 << 4) + ^ (z5 << 53); + zz[4] = (z4 >> 60) ^ (z6 << 38) + ^ (z5 >> 11); + zz[5] = (z6 >> 26) ^ (z7 << 23); + zz[6] = (z7 >> 41); + zz[7] = 0; + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = x0 & M49; + z[1] = ((x0 >> 49) ^ (x1 << 15)) & M49; + z[2] = ((x1 >> 34) ^ (x2 << 30)) & M49; + z[3] = ((x2 >> 19) ^ (x3 << 45)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong[] f = new ulong[4], g = new ulong[4]; + ImplExpand(x, f); + ImplExpand(y, g); + + ImplMulwAcc(f[0], g[0], zz, 0); + ImplMulwAcc(f[1], g[1], zz, 1); + ImplMulwAcc(f[2], g[2], zz, 2); + ImplMulwAcc(f[3], g[3], zz, 3); + + // U *= (1 - t^n) + for (int i = 5; i > 0; --i) + { + zz[i] ^= zz[i - 1]; + } + + ImplMulwAcc(f[0] ^ f[1], g[0] ^ g[1], zz, 1); + ImplMulwAcc(f[2] ^ f[3], g[2] ^ g[3], zz, 3); + + // V *= (1 - t^2n) + for (int i = 7; i > 1; --i) + { + zz[i] ^= zz[i - 2]; + } + + // Double-length recursion + { + ulong c0 = f[0] ^ f[2], c1 = f[1] ^ f[3]; + ulong d0 = g[0] ^ g[2], d1 = g[1] ^ g[3]; + ImplMulwAcc(c0 ^ c1, d0 ^ d1, zz, 3); + ulong[] t = new ulong[3]; + ImplMulwAcc(c0, d0, t, 0); + ImplMulwAcc(c1, d1, t, 1); + ulong t0 = t[0], t1 = t[1], t2 = t[2]; + zz[2] ^= t0; + zz[3] ^= t0 ^ t1; + zz[4] ^= t2 ^ t1; + zz[5] ^= t2; + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 49 == 0); + Debug.Assert(y >> 49 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 36; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6 + ^ u[(j >> 9) & 7] << 9 + ^ u[(j >> 12) & 7] << 12; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 15) > 0); + + Debug.Assert(h >> 33 == 0); + + z[zOff ] ^= l & M49; + z[zOff + 1] ^= (l >> 49) ^ (h << 15); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + Interleave.Expand64To128(x[2], zz, 4); + zz[6] = (x[3] & M01); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs.meta new file mode 100644 index 0000000..6ea1d4f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 94e9d639b53e63640920b428ab252952 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs new file mode 100644 index 0000000..1c14bc2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs @@ -0,0 +1,218 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193FieldElement + : ECFieldElement + { + protected readonly ulong[] x; + + public SecT193FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 193) + throw new ArgumentException("value invalid for SecT193FieldElement", "x"); + + this.x = SecT193Field.FromBigInteger(x); + } + + public SecT193FieldElement() + { + this.x = Nat256.Create64(); + } + + protected internal SecT193FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat256.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat256.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT193Field"; } + } + + public override int FieldSize + { + get { return 193; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT193Field.Add(x, ((SecT193FieldElement)b).x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat256.Create64(); + SecT193Field.AddOne(x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT193Field.Multiply(x, ((SecT193FieldElement)b).x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT193FieldElement)b).x; + ulong[] xx = ((SecT193FieldElement)x).x, yx = ((SecT193FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT193Field.MultiplyAddToExt(ax, bx, tt); + SecT193Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT193Field.Reduce(tt, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat256.Create64(); + SecT193Field.Square(x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT193FieldElement)x).x, yx = ((SecT193FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT193Field.SquareAddToExt(ax, tt); + SecT193Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT193Field.Reduce(tt, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat256.Create64(); + SecT193Field.SquareN(x, pow, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat256.Create64(); + SecT193Field.Invert(x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat256.Create64(); + SecT193Field.Sqrt(x, z); + return new SecT193FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 193; } + } + + public virtual int K1 + { + get { return 15; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT193FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT193FieldElement); + } + + public virtual bool Equals(SecT193FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 1930015 ^ Arrays.GetHashCode(x, 0, 4); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs.meta new file mode 100644 index 0000000..4b16a93 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ed86b58b8064a6c448038ebcda1c1b6a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs new file mode 100644 index 0000000..3ed268e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs @@ -0,0 +1,101 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R1Curve + : AbstractF2mCurve + { + private const int SecT193R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT193R1Point m_infinity; + + public SecT193R1Curve() + : base(193, 15, 0, 0) + { + this.m_infinity = new SecT193R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814"))); + this.m_order = new BigInteger(1, Hex.Decode("01000000000000000000000000C7F34A778F443ACC920EBA49")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT193R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT193R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 193; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT193FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT193R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT193R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 193; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 15; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs.meta new file mode 100644 index 0000000..fc94db9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 24847eeab11476b4ba3244a99c0beb7a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs new file mode 100644 index 0000000..2d8281b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs @@ -0,0 +1,286 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT193R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT193R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT193R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT193R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT193R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT193R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT193R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT193R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT193R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs.meta new file mode 100644 index 0000000..9f898f3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6a02a055b55d3a44dbf3364748e26b65 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs new file mode 100644 index 0000000..3fe26a3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs @@ -0,0 +1,100 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R2Curve + : AbstractF2mCurve + { + private const int SecT193R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT193R2Point m_infinity; + + public SecT193R2Curve() + : base(193, 15, 0, 0) + { + this.m_infinity = new SecT193R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.Decode("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE"))); + this.m_order = new BigInteger(1, Hex.Decode("010000000000000000000000015AAB561B005413CCD4EE99D5")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT193R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT193R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 193; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT193FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT193R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT193R2Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 193; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 15; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs.meta new file mode 100644 index 0000000..6e817ad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d2f3ea3cc4118b84db48818f0e79c25a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs new file mode 100644 index 0000000..bb06b07 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs @@ -0,0 +1,285 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT193R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT193R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT193R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT193R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT193R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT193R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT193R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT193R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT193R2Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs.meta new file mode 100644 index 0000000..baf2cef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT193R2Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4b7ab89d88e018047bca78933a467e6d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs new file mode 100644 index 0000000..73b8e31 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs @@ -0,0 +1,321 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233Field + { + private const ulong M41 = ulong.MaxValue >> 23; + private const ulong M59 = ulong.MaxValue >> 5; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + zz[7] = xx[7] ^ yy[7]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat256.FromBigInteger64(x); + Reduce23(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat256.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat256.Create64(); + ulong[] t1 = Nat256.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 3, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 7, t0); + Multiply(t0, t1, t0); + SquareN(t0, 14, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 29, t0); + Multiply(t0, t1, t0); + SquareN(t0, 58, t1); + Multiply(t1, t0, t1); + SquareN(t1, 116, t0); + Multiply(t0, t1, t0); + Square(t0, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7]; + + x3 ^= (x7 << 23); + x4 ^= (x7 >> 41) ^ (x7 << 33); + x5 ^= (x7 >> 31); + + x2 ^= (x6 << 23); + x3 ^= (x6 >> 41) ^ (x6 << 33); + x4 ^= (x6 >> 31); + + x1 ^= (x5 << 23); + x2 ^= (x5 >> 41) ^ (x5 << 33); + x3 ^= (x5 >> 31); + + x0 ^= (x4 << 23); + x1 ^= (x4 >> 41) ^ (x4 << 33); + x2 ^= (x4 >> 31); + + ulong t = x3 >> 41; + z[0] = x0 ^ t; + z[1] = x1 ^ (t << 10); + z[2] = x2; + z[3] = x3 & M41; + } + + public static void Reduce23(ulong[] z, int zOff) + { + ulong z3 = z[zOff + 3], t = z3 >> 41; + z[zOff ] ^= t; + z[zOff + 1] ^= (t << 10); + z[zOff + 3] = z3 & M41; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c1 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + ulong c2; + c2 = (c1 >> 27); + c1 ^= (c0 >> 27) | (c1 << 37); + c0 ^= (c0 << 37); + + ulong[] tt = Nat256.CreateExt64(); + + int[] shifts = { 32, 117, 191 }; + for (int i = 0; i < shifts.Length; ++i) + { + int w = shifts[i] >> 6, s = shifts[i] & 63; + Debug.Assert(s != 0); + tt[w ] ^= (c0 << s); + tt[w + 1] ^= (c1 << s) | (c0 >> -s); + tt[w + 2] ^= (c2 << s) | (c1 >> -s); + tt[w + 3] ^= (c2 >> -s); + } + + Reduce(tt, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 159 + return (uint)(x[0] ^ (x[2] >> 31)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5], z6 = zz[6], z7 = zz[7]; + zz[0] = z0 ^ (z1 << 59); + zz[1] = (z1 >> 5) ^ (z2 << 54); + zz[2] = (z2 >> 10) ^ (z3 << 49); + zz[3] = (z3 >> 15) ^ (z4 << 44); + zz[4] = (z4 >> 20) ^ (z5 << 39); + zz[5] = (z5 >> 25) ^ (z6 << 34); + zz[6] = (z6 >> 30) ^ (z7 << 29); + zz[7] = (z7 >> 35); + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = x0 & M59; + z[1] = ((x0 >> 59) ^ (x1 << 5)) & M59; + z[2] = ((x1 >> 54) ^ (x2 << 10)) & M59; + z[3] = ((x2 >> 49) ^ (x3 << 15)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong[] f = new ulong[4], g = new ulong[4]; + ImplExpand(x, f); + ImplExpand(y, g); + + ImplMulwAcc(f[0], g[0], zz, 0); + ImplMulwAcc(f[1], g[1], zz, 1); + ImplMulwAcc(f[2], g[2], zz, 2); + ImplMulwAcc(f[3], g[3], zz, 3); + + // U *= (1 - t^n) + for (int i = 5; i > 0; --i) + { + zz[i] ^= zz[i - 1]; + } + + ImplMulwAcc(f[0] ^ f[1], g[0] ^ g[1], zz, 1); + ImplMulwAcc(f[2] ^ f[3], g[2] ^ g[3], zz, 3); + + // V *= (1 - t^2n) + for (int i = 7; i > 1; --i) + { + zz[i] ^= zz[i - 2]; + } + + // Double-length recursion + { + ulong c0 = f[0] ^ f[2], c1 = f[1] ^ f[3]; + ulong d0 = g[0] ^ g[2], d1 = g[1] ^ g[3]; + ImplMulwAcc(c0 ^ c1, d0 ^ d1, zz, 3); + ulong[] t = new ulong[3]; + ImplMulwAcc(c0, d0, t, 0); + ImplMulwAcc(c1, d1, t, 1); + ulong t0 = t[0], t1 = t[1], t2 = t[2]; + zz[2] ^= t0; + zz[3] ^= t0 ^ t1; + zz[4] ^= t2 ^ t1; + zz[5] ^= t2; + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 59 == 0); + Debug.Assert(y >> 59 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 54; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 6) > 0); + + Debug.Assert(h >> 53 == 0); + + z[zOff ] ^= l & M59; + z[zOff + 1] ^= (l >> 59) ^ (h << 5); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + Interleave.Expand64To128(x[2], zz, 4); + + ulong x3 = x[3]; + zz[6] = Interleave.Expand32to64((uint)x3); + zz[7] = Interleave.Expand16to32((uint)(x3 >> 32)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs.meta new file mode 100644 index 0000000..994040f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3383a8a7710727f4991e6f2ab078edfa +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs new file mode 100644 index 0000000..09082a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233FieldElement + : ECFieldElement + { + protected readonly ulong[] x; + + public SecT233FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 233) + throw new ArgumentException("value invalid for SecT233FieldElement", "x"); + + this.x = SecT233Field.FromBigInteger(x); + } + + public SecT233FieldElement() + { + this.x = Nat256.Create64(); + } + + protected internal SecT233FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat256.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat256.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT233Field"; } + } + + public override int FieldSize + { + get { return 233; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT233Field.Add(x, ((SecT233FieldElement)b).x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat256.Create64(); + SecT233Field.AddOne(x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT233Field.Multiply(x, ((SecT233FieldElement)b).x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT233FieldElement)b).x; + ulong[] xx = ((SecT233FieldElement)x).x, yx = ((SecT233FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT233Field.MultiplyAddToExt(ax, bx, tt); + SecT233Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT233Field.Reduce(tt, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat256.Create64(); + SecT233Field.Square(x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT233FieldElement)x).x, yx = ((SecT233FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT233Field.SquareAddToExt(ax, tt); + SecT233Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT233Field.Reduce(tt, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat256.Create64(); + SecT233Field.SquareN(x, pow, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat256.Create64(); + SecT233Field.Invert(x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat256.Create64(); + SecT233Field.Sqrt(x, z); + return new SecT233FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 233; } + } + + public virtual int K1 + { + get { return 74; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT233FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT233FieldElement); + } + + public virtual bool Equals(SecT233FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 2330074 ^ Arrays.GetHashCode(x, 0, 4); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs.meta new file mode 100644 index 0000000..5181811 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8eb22946dd4169543b83ef9f11743f5b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs new file mode 100644 index 0000000..70b05d2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233K1Curve + : AbstractF2mCurve + { + private const int SecT233K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT233K1Point m_infinity; + + public SecT233K1Curve() + : base(233, 74, 0, 0) + { + this.m_infinity = new SecT233K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.Decode("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SecT233K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT233K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override int FieldSize + { + get { return 233; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT233FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT233K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT233K1Point(this, x, y, zs, withCompression); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 233; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 74; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs.meta new file mode 100644 index 0000000..b2a94e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: de272d7a6f28ae24f98d3e5a96c7a23e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs new file mode 100644 index 0000000..3d785ec --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs @@ -0,0 +1,306 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT233K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + { + return curve.Infinity; + } + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + //return new SecT233K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT233K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT233K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT233K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT233K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + //return new SecT233K1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT233K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT233K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + { + return b.Twice(); + } + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT233K1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT233K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT233K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT233K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs.meta new file mode 100644 index 0000000..4b3abc2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d28b86257b8af904e8f2390a9b777469 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs new file mode 100644 index 0000000..e44d163 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233R1Curve + : AbstractF2mCurve + { + private const int SecT233R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT233R1Point m_infinity; + + public SecT233R1Curve() + : base(233, 74, 0, 0) + { + this.m_infinity = new SecT233R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD"))); + this.m_order = new BigInteger(1, Hex.Decode("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT233R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT233R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 233; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT233FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT233R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT233R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 233; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 74; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs.meta new file mode 100644 index 0000000..f912446 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 39fcb8d8fd481b744a4edf0d4452c93d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs new file mode 100644 index 0000000..ab1b13d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs @@ -0,0 +1,286 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT233R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT233R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT233R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT233R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT233R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT233R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs.meta new file mode 100644 index 0000000..3d98b67 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT233R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e8bf5c80ccef6464da43af257433fbb2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs new file mode 100644 index 0000000..da46bad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs @@ -0,0 +1,332 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239Field + { + private const ulong M47 = ulong.MaxValue >> 17; + private const ulong M60 = ulong.MaxValue >> 4; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + zz[7] = xx[7] ^ yy[7]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat256.FromBigInteger64(x); + Reduce17(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat256.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat256.Create64(); + ulong[] t1 = Nat256.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 3, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 7, t0); + Multiply(t0, t1, t0); + SquareN(t0, 14, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 29, t0); + Multiply(t0, t1, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 59, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 119, t0); + Multiply(t0, t1, t0); + Square(t0, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7]; + + x3 ^= (x7 << 17); + x4 ^= (x7 >> 47); + x5 ^= (x7 << 47); + x6 ^= (x7 >> 17); + + x2 ^= (x6 << 17); + x3 ^= (x6 >> 47); + x4 ^= (x6 << 47); + x5 ^= (x6 >> 17); + + x1 ^= (x5 << 17); + x2 ^= (x5 >> 47); + x3 ^= (x5 << 47); + x4 ^= (x5 >> 17); + + x0 ^= (x4 << 17); + x1 ^= (x4 >> 47); + x2 ^= (x4 << 47); + x3 ^= (x4 >> 17); + + ulong t = x3 >> 47; + z[0] = x0 ^ t; + z[1] = x1; + z[2] = x2 ^ (t << 30); + z[3] = x3 & M47; + } + + public static void Reduce17(ulong[] z, int zOff) + { + ulong z3 = z[zOff + 3], t = z3 >> 47; + z[zOff ] ^= t; + z[zOff + 2] ^= (t << 30); + z[zOff + 3] = z3 & M47; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c1 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + ulong c2, c3; + c3 = (c1 >> 49); + c2 = (c0 >> 49) | (c1 << 15); + c1 ^= (c0 << 15); + + ulong[] tt = Nat256.CreateExt64(); + + int[] shifts = { 39, 120 }; + for (int i = 0; i < shifts.Length; ++i) + { + int w = shifts[i] >> 6, s = shifts[i] & 63; + Debug.Assert(s != 0); + tt[w ] ^= (c0 << s); + tt[w + 1] ^= (c1 << s) | (c0 >> -s); + tt[w + 2] ^= (c2 << s) | (c1 >> -s); + tt[w + 3] ^= (c3 << s) | (c2 >> -s); + tt[w + 4] ^= (c3 >> -s); + } + + Reduce(tt, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 81, 162 + return (uint)(x[0] ^ (x[1] >> 17) ^ (x[2] >> 34)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5], z6 = zz[6], z7 = zz[7]; + zz[0] = z0 ^ (z1 << 60); + zz[1] = (z1 >> 4) ^ (z2 << 56); + zz[2] = (z2 >> 8) ^ (z3 << 52); + zz[3] = (z3 >> 12) ^ (z4 << 48); + zz[4] = (z4 >> 16) ^ (z5 << 44); + zz[5] = (z5 >> 20) ^ (z6 << 40); + zz[6] = (z6 >> 24) ^ (z7 << 36); + zz[7] = (z7 >> 28); + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = x0 & M60; + z[1] = ((x0 >> 60) ^ (x1 << 4)) & M60; + z[2] = ((x1 >> 56) ^ (x2 << 8)) & M60; + z[3] = ((x2 >> 52) ^ (x3 << 12)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong[] f = new ulong[4], g = new ulong[4]; + ImplExpand(x, f); + ImplExpand(y, g); + + ImplMulwAcc(f[0], g[0], zz, 0); + ImplMulwAcc(f[1], g[1], zz, 1); + ImplMulwAcc(f[2], g[2], zz, 2); + ImplMulwAcc(f[3], g[3], zz, 3); + + // U *= (1 - t^n) + for (int i = 5; i > 0; --i) + { + zz[i] ^= zz[i - 1]; + } + + ImplMulwAcc(f[0] ^ f[1], g[0] ^ g[1], zz, 1); + ImplMulwAcc(f[2] ^ f[3], g[2] ^ g[3], zz, 3); + + // V *= (1 - t^2n) + for (int i = 7; i > 1; --i) + { + zz[i] ^= zz[i - 2]; + } + + // Double-length recursion + { + ulong c0 = f[0] ^ f[2], c1 = f[1] ^ f[3]; + ulong d0 = g[0] ^ g[2], d1 = g[1] ^ g[3]; + ImplMulwAcc(c0 ^ c1, d0 ^ d1, zz, 3); + ulong[] t = new ulong[3]; + ImplMulwAcc(c0, d0, t, 0); + ImplMulwAcc(c1, d1, t, 1); + ulong t0 = t[0], t1 = t[1], t2 = t[2]; + zz[2] ^= t0; + zz[3] ^= t0 ^ t1; + zz[4] ^= t2 ^ t1; + zz[5] ^= t2; + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 60 == 0); + Debug.Assert(y >> 60 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 54; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 6) > 0); + + h ^= ((x & 0x0820820820820820L) & (ulong)(((long)y << 4) >> 63)) >> 5; + + Debug.Assert(h >> 55 == 0); + + z[zOff ] ^= l & M60; + z[zOff + 1] ^= (l >> 60) ^ (h << 4); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x[0], zz, 0); + Interleave.Expand64To128(x[1], zz, 2); + Interleave.Expand64To128(x[2], zz, 4); + + ulong x3 = x[3]; + zz[6] = Interleave.Expand32to64((uint)x3); + zz[7] = Interleave.Expand16to32((uint)(x3 >> 32)); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs.meta new file mode 100644 index 0000000..e5be9b3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7ed9c9a4301e3b3459b6f2d4e1bb4c82 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs new file mode 100644 index 0000000..8a7ff90 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239FieldElement + : ECFieldElement + { + protected ulong[] x; + + public SecT239FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 239) + throw new ArgumentException("value invalid for SecT239FieldElement", "x"); + + this.x = SecT239Field.FromBigInteger(x); + } + + public SecT239FieldElement() + { + this.x = Nat256.Create64(); + } + + protected internal SecT239FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat256.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat256.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1L) != 0L; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT239Field"; } + } + + public override int FieldSize + { + get { return 239; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT239Field.Add(x, ((SecT239FieldElement)b).x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat256.Create64(); + SecT239Field.AddOne(x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT239Field.Multiply(x, ((SecT239FieldElement)b).x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT239FieldElement)b).x; + ulong[] xx = ((SecT239FieldElement)x).x, yx = ((SecT239FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT239Field.MultiplyAddToExt(ax, bx, tt); + SecT239Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT239Field.Reduce(tt, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat256.Create64(); + SecT239Field.Square(x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT239FieldElement)x).x, yx = ((SecT239FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT239Field.SquareAddToExt(ax, tt); + SecT239Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT239Field.Reduce(tt, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat256.Create64(); + SecT239Field.SquareN(x, pow, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat256.Create64(); + SecT239Field.Invert(x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat256.Create64(); + SecT239Field.Sqrt(x, z); + return new SecT239FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 239; } + } + + public virtual int K1 + { + get { return 158; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT239FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT239FieldElement); + } + + public virtual bool Equals(SecT239FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 23900158 ^ Arrays.GetHashCode(x, 0, 4); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs.meta new file mode 100644 index 0000000..9f125f5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d3b2dc73110a51949be2327a20bbd675 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs new file mode 100644 index 0000000..0c2710c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239K1Curve + : AbstractF2mCurve + { + private const int SecT239K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT239K1Point m_infinity; + + public SecT239K1Curve() + : base(239, 158, 0, 0) + { + this.m_infinity = new SecT239K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.Decode("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SecT239K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT239K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 239; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT239FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT239K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT239K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 239; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 158; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs.meta new file mode 100644 index 0000000..c018d7a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 48ebb53c6d3e12e4b8383944559a18c9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs new file mode 100644 index 0000000..299e66a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs @@ -0,0 +1,301 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT239K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + // X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + //return new SecT239K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT239K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT239K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT239K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT239K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + //return new SecT239K1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT239K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT239K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT239K1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT239K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT239K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT239K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs.meta new file mode 100644 index 0000000..029289e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT239K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0d824fd9c896dd549b3a2bded614ddb7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs new file mode 100644 index 0000000..b2cd736 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs @@ -0,0 +1,406 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283Field + { + private const ulong M27 = ulong.MaxValue >> 37; + private const ulong M57 = ulong.MaxValue >> 7; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0x0C30C30C30C30808UL, 0x30C30C30C30C30C3UL, 0x820820820820830CUL, 0x0820820820820820UL, 0x2082082UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + z[4] = x[4] ^ y[4]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + zz[7] = xx[7] ^ yy[7]; + zz[8] = xx[8] ^ yy[8]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat320.FromBigInteger64(x); + Reduce37(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat320.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat320.Create64(); + ulong[] t1 = Nat320.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + SquareN(t0, 2, t1); + Multiply(t1, t0, t1); + SquareN(t1, 4, t0); + Multiply(t0, t1, t0); + SquareN(t0, 8, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 17, t0); + Multiply(t0, t1, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 35, t1); + Multiply(t1, t0, t1); + SquareN(t1, 70, t0); + Multiply(t0, t1, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 141, t1); + Multiply(t1, t0, t1); + Square(t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat320.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat320.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4]; + ulong x5 = xx[5], x6 = xx[6], x7 = xx[7], x8 = xx[8]; + + x3 ^= (x8 << 37) ^ (x8 << 42) ^ (x8 << 44) ^ (x8 << 49); + x4 ^= (x8 >> 27) ^ (x8 >> 22) ^ (x8 >> 20) ^ (x8 >> 15); + + x2 ^= (x7 << 37) ^ (x7 << 42) ^ (x7 << 44) ^ (x7 << 49); + x3 ^= (x7 >> 27) ^ (x7 >> 22) ^ (x7 >> 20) ^ (x7 >> 15); + + x1 ^= (x6 << 37) ^ (x6 << 42) ^ (x6 << 44) ^ (x6 << 49); + x2 ^= (x6 >> 27) ^ (x6 >> 22) ^ (x6 >> 20) ^ (x6 >> 15); + + x0 ^= (x5 << 37) ^ (x5 << 42) ^ (x5 << 44) ^ (x5 << 49); + x1 ^= (x5 >> 27) ^ (x5 >> 22) ^ (x5 >> 20) ^ (x5 >> 15); + + ulong t = x4 >> 27; + z[0] = x0 ^ t ^ (t << 5) ^ (t << 7) ^ (t << 12); + z[1] = x1; + z[2] = x2; + z[3] = x3; + z[4] = x4 & M27; + } + + public static void Reduce37(ulong[] z, int zOff) + { + ulong z4 = z[zOff + 4], t = z4 >> 27; + z[zOff ] ^= t ^ (t << 5) ^ (t << 7) ^ (t << 12); + z[zOff + 4] = z4 & M27; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] odd = Nat320.Create64(); + + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[0] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[1] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[4]); + ulong e2 = (u0 & 0x00000000FFFFFFFFUL); + odd[2] = (u0 >> 32); + + Multiply(odd, ROOT_Z, z); + + z[0] ^= e0; + z[1] ^= e1; + z[2] ^= e2; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(9); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat.Create64(9); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat.Create64(9); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 271 + return (uint)(x[0] ^ (x[4] >> 15)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4]; + ulong z5 = zz[5], z6 = zz[6], z7 = zz[7], z8 = zz[8], z9 = zz[9]; + zz[0] = z0 ^ (z1 << 57); + zz[1] = (z1 >> 7) ^ (z2 << 50); + zz[2] = (z2 >> 14) ^ (z3 << 43); + zz[3] = (z3 >> 21) ^ (z4 << 36); + zz[4] = (z4 >> 28) ^ (z5 << 29); + zz[5] = (z5 >> 35) ^ (z6 << 22); + zz[6] = (z6 >> 42) ^ (z7 << 15); + zz[7] = (z7 >> 49) ^ (z8 << 8); + zz[8] = (z8 >> 56) ^ (z9 << 1); + zz[9] = (z9 >> 63); // Zero! + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4]; + z[0] = x0 & M57; + z[1] = ((x0 >> 57) ^ (x1 << 7)) & M57; + z[2] = ((x1 >> 50) ^ (x2 << 14)) & M57; + z[3] = ((x2 >> 43) ^ (x3 << 21)) & M57; + z[4] = ((x3 >> 36) ^ (x4 << 28)); + } + + //protected static void AddMs(ulong[] zz, int zOff, ulong[] p, params int[] ms) + //{ + // ulong t0 = 0, t1 = 0; + // foreach (int m in ms) + // { + // int i = (m - 1) << 1; + // t0 ^= p[i ]; + // t1 ^= p[i + 1]; + // } + // zz[zOff ] ^= t0; + // zz[zOff + 1] ^= t1; + //} + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * Formula (17) from "Some New Results on Binary Polynomial Multiplication", + * Murat Cenk and M. Anwar Hasan. + * + * The formula as given contained an error in the term t25, as noted below + */ + ulong[] a = new ulong[5], b = new ulong[5]; + ImplExpand(x, a); + ImplExpand(y, b); + + ulong[] p = new ulong[26]; + + ImplMulw(a[0], b[0], p, 0); // m1 + ImplMulw(a[1], b[1], p, 2); // m2 + ImplMulw(a[2], b[2], p, 4); // m3 + ImplMulw(a[3], b[3], p, 6); // m4 + ImplMulw(a[4], b[4], p, 8); // m5 + + ulong u0 = a[0] ^ a[1], v0 = b[0] ^ b[1]; + ulong u1 = a[0] ^ a[2], v1 = b[0] ^ b[2]; + ulong u2 = a[2] ^ a[4], v2 = b[2] ^ b[4]; + ulong u3 = a[3] ^ a[4], v3 = b[3] ^ b[4]; + + ImplMulw(u1 ^ a[3], v1 ^ b[3], p, 18); // m10 + ImplMulw(u2 ^ a[1], v2 ^ b[1], p, 20); // m11 + + ulong A4 = u0 ^ u3 , B4 = v0 ^ v3; + ulong A5 = A4 ^ a[2], B5 = B4 ^ b[2]; + + ImplMulw(A4, B4, p, 22); // m12 + ImplMulw(A5, B5, p, 24); // m13 + + ImplMulw(u0, v0, p, 10); // m6 + ImplMulw(u1, v1, p, 12); // m7 + ImplMulw(u2, v2, p, 14); // m8 + ImplMulw(u3, v3, p, 16); // m9 + + + // Original method, corresponding to formula (16) + //AddMs(zz, 0, p, 1); + //AddMs(zz, 1, p, 1, 2, 6); + //AddMs(zz, 2, p, 1, 2, 3, 7); + //AddMs(zz, 3, p, 1, 3, 4, 5, 8, 10, 12, 13); + //AddMs(zz, 4, p, 1, 2, 4, 5, 6, 9, 10, 11, 13); + //AddMs(zz, 5, p, 1, 2, 3, 5, 7, 11, 12, 13); + //AddMs(zz, 6, p, 3, 4, 5, 8); + //AddMs(zz, 7, p, 4, 5, 9); + //AddMs(zz, 8, p, 5); + + // Improved method factors out common single-word terms + // NOTE: p1,...,p26 in the paper maps to p[0],...,p[25] here + + zz[0] = p[ 0]; + zz[9] = p[ 9]; + + ulong t1 = p[ 0] ^ p[ 1]; + ulong t2 = t1 ^ p[ 2]; + ulong t3 = t2 ^ p[10]; + + zz[1] = t3; + + ulong t4 = p[ 3] ^ p[ 4]; + ulong t5 = p[11] ^ p[12]; + ulong t6 = t4 ^ t5; + ulong t7 = t2 ^ t6; + + zz[2] = t7; + + ulong t8 = t1 ^ t4; + ulong t9 = p[ 5] ^ p[ 6]; + ulong t10 = t8 ^ t9; + ulong t11 = t10 ^ p[ 8]; + ulong t12 = p[13] ^ p[14]; + ulong t13 = t11 ^ t12; + ulong t14 = p[18] ^ p[22]; + ulong t15 = t14 ^ p[24]; + ulong t16 = t13 ^ t15; + + zz[3] = t16; + + ulong t17 = p[ 7] ^ p[ 8]; + ulong t18 = t17 ^ p[ 9]; + ulong t19 = t18 ^ p[17]; + + zz[8] = t19; + + ulong t20 = t18 ^ t9; + ulong t21 = p[15] ^ p[16]; + ulong t22 = t20 ^ t21; + + zz[7] = t22; + + ulong t23 = t22 ^ t3; + ulong t24 = p[19] ^ p[20]; + // ulong t25 = p[23] ^ p[24]; + ulong t25 = p[25] ^ p[24]; // Fixes an error in the paper: p[23] -> p{25] + ulong t26 = p[18] ^ p[23]; + ulong t27 = t24 ^ t25; + ulong t28 = t27 ^ t26; + ulong t29 = t28 ^ t23; + + zz[4] = t29; + + ulong t30 = t7 ^ t19; + ulong t31 = t27 ^ t30; + ulong t32 = p[21] ^ p[22]; + ulong t33 = t31 ^ t32; + + zz[5] = t33; + + ulong t34 = t11 ^ p[0]; + ulong t35 = t34 ^ p[9]; + ulong t36 = t35 ^ t12; + ulong t37 = t36 ^ p[21]; + ulong t38 = t37 ^ p[23]; + ulong t39 = t38 ^ p[25]; + + zz[6] = t39; + + ImplCompactExt(zz); + } + + protected static void ImplMulw(ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 57 == 0); + Debug.Assert(y >> 57 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7]; + int k = 48; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 9) > 0); + + h ^= ((x & 0x0100804020100800L) & (ulong)(((long)y << 7) >> 63)) >> 8; + + Debug.Assert(h >> 49 == 0); + + z[zOff ] = l & M57; + z[zOff + 1] = (l >> 57) ^ (h << 7); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + for (int i = 0; i < 4; ++i) + { + Interleave.Expand64To128(x[i], zz, i << 1); + } + zz[8] = Interleave.Expand32to64((uint)x[4]); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs.meta new file mode 100644 index 0000000..ae987c3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c626a931419b48a45ad8a5ea5f11d47e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs new file mode 100644 index 0000000..57c13d7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283FieldElement + : ECFieldElement + { + protected readonly ulong[] x; + + public SecT283FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 283) + throw new ArgumentException("value invalid for SecT283FieldElement", "x"); + + this.x = SecT283Field.FromBigInteger(x); + } + + public SecT283FieldElement() + { + this.x = Nat320.Create64(); + } + + protected internal SecT283FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat320.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat320.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat320.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT283Field"; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat320.Create64(); + SecT283Field.Add(x, ((SecT283FieldElement)b).x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat320.Create64(); + SecT283Field.AddOne(x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat320.Create64(); + SecT283Field.Multiply(x, ((SecT283FieldElement)b).x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT283FieldElement)b).x; + ulong[] xx = ((SecT283FieldElement)x).x, yx = ((SecT283FieldElement)y).x; + + ulong[] tt = Nat.Create64(9); + SecT283Field.MultiplyAddToExt(ax, bx, tt); + SecT283Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat320.Create64(); + SecT283Field.Reduce(tt, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat320.Create64(); + SecT283Field.Square(x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT283FieldElement)x).x, yx = ((SecT283FieldElement)y).x; + + ulong[] tt = Nat.Create64(9); + SecT283Field.SquareAddToExt(ax, tt); + SecT283Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat320.Create64(); + SecT283Field.Reduce(tt, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat320.Create64(); + SecT283Field.SquareN(x, pow, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat320.Create64(); + SecT283Field.Invert(x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat320.Create64(); + SecT283Field.Sqrt(x, z); + return new SecT283FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 283; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT283FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT283FieldElement); + } + + public virtual bool Equals(SecT283FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat320.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 2831275 ^ Arrays.GetHashCode(x, 0, 5); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs.meta new file mode 100644 index 0000000..e5941c4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 67822c9ac801be245a30abda22a44f29 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs new file mode 100644 index 0000000..1f53246 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283K1Curve + : AbstractF2mCurve + { + private const int SecT283K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT283K1Point m_infinity; + + public SecT283K1Curve() + : base(283, 5, 7, 12) + { + this.m_infinity = new SecT283K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SecT283K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT283K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT283FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT283K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT283K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 283; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs.meta new file mode 100644 index 0000000..de6bc6c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 39307d0f60b169f4a81f23cd2faa883a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs new file mode 100644 index 0000000..c0aa1be --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs @@ -0,0 +1,300 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT283K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + //return new SecT283K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT283K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT283K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT283K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT283K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + //return new SecT283K1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT283K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT283K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT283K1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT283K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT283K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT283K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs.meta new file mode 100644 index 0000000..70b4fc2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 158b153a676c1544985041b1aafbb620 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs new file mode 100644 index 0000000..2bbc375 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283R1Curve + : AbstractF2mCurve + { + private const int SecT283R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT283R1Point m_infinity; + + public SecT283R1Curve() + : base(283, 5, 7, 12) + { + this.m_infinity = new SecT283R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5"))); + this.m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT283R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT283R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT283FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT283R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT283R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 283; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs.meta new file mode 100644 index 0000000..c8cc487 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c3e40474bbba5c647866e91e6a75ba77 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs new file mode 100644 index 0000000..9fe191b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs @@ -0,0 +1,286 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT283R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT283R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT283R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT283R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT283R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT283R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT283R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT283R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT283R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs.meta new file mode 100644 index 0000000..fde584a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT283R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0c42d0860fab3384cb023920e765d0a3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs new file mode 100644 index 0000000..6538fed --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs @@ -0,0 +1,335 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409Field + { + private const ulong M25 = ulong.MaxValue >> 39; + private const ulong M59 = ulong.MaxValue >> 5; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + z[4] = x[4] ^ y[4]; + z[5] = x[5] ^ y[5]; + z[6] = x[6] ^ y[6]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + for (int i = 0; i < 13; ++i) + { + zz[i] = xx[i] ^ yy[i]; + } + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat448.FromBigInteger64(x); + Reduce39(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat448.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3 } + + ulong[] t0 = Nat448.Create64(); + ulong[] t1 = Nat448.Create64(); + ulong[] t2 = Nat448.Create64(); + + Square(x, t0); + + // 3 | 408 + SquareN(t0, 1, t1); + Multiply(t0, t1, t0); + SquareN(t1, 1, t1); + Multiply(t0, t1, t0); + + // 2 | 136 + SquareN(t0, 3, t1); + Multiply(t0, t1, t0); + + // 2 | 68 + SquareN(t0, 6, t1); + Multiply(t0, t1, t0); + + // 2 | 34 + SquareN(t0, 12, t1); + Multiply(t0, t1, t2); + + // ! {2,3} | 17 + SquareN(t2, 24, t0); + SquareN(t0, 24, t1); + Multiply(t0, t1, t0); + + // 2 | 8 + SquareN(t0, 48, t1); + Multiply(t0, t1, t0); + + // 2 | 4 + SquareN(t0, 96, t1); + Multiply(t0, t1, t0); + + // 2 | 2 + SquareN(t0, 192, t1); + Multiply(t0, t1, t0); + + Multiply(t0, t2, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat448.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat448.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x00 = xx[0], x01 = xx[1], x02 = xx[2], x03 = xx[3]; + ulong x04 = xx[4], x05 = xx[5], x06 = xx[6], x07 = xx[7]; + + ulong u = xx[12]; + x05 ^= (u << 39); + x06 ^= (u >> 25) ^ (u << 62); + x07 ^= (u >> 2); + + u = xx[11]; + x04 ^= (u << 39); + x05 ^= (u >> 25) ^ (u << 62); + x06 ^= (u >> 2); + + u = xx[10]; + x03 ^= (u << 39); + x04 ^= (u >> 25) ^ (u << 62); + x05 ^= (u >> 2); + + u = xx[9]; + x02 ^= (u << 39); + x03 ^= (u >> 25) ^ (u << 62); + x04 ^= (u >> 2); + + u = xx[8]; + x01 ^= (u << 39); + x02 ^= (u >> 25) ^ (u << 62); + x03 ^= (u >> 2); + + u = x07; + x00 ^= (u << 39); + x01 ^= (u >> 25) ^ (u << 62); + x02 ^= (u >> 2); + + ulong t = x06 >> 25; + z[0] = x00 ^ t; + z[1] = x01 ^ (t << 23); + z[2] = x02; + z[3] = x03; + z[4] = x04; + z[5] = x05; + z[6] = x06 & M25; + } + + public static void Reduce39(ulong[] z, int zOff) + { + ulong z6 = z[zOff + 6], t = z6 >> 25; + z[zOff ] ^= t; + z[zOff + 1] ^= (t << 23); + z[zOff + 6] = z6 & M25; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c1 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[4]); u1 = Interleave.Unshuffle(x[5]); + ulong e2 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c2 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[6]); + ulong e3 = (u0 & 0x00000000FFFFFFFFUL); + ulong c3 = (u0 >> 32); + + z[0] = e0 ^ (c0 << 44); + z[1] = e1 ^ (c1 << 44) ^ (c0 >> 20); + z[2] = e2 ^ (c2 << 44) ^ (c1 >> 20); + z[3] = e3 ^ (c3 << 44) ^ (c2 >> 20) ^ (c0 << 13); + z[4] = (c3 >> 20) ^ (c1 << 13) ^ (c0 >> 51); + z[5] = (c2 << 13) ^ (c1 >> 51); + z[6] = (c3 << 13) ^ (c2 >> 51); + + Debug.Assert((c3 >> 51) == 0); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(13); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat.Create64(13); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat.Create64(13); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0 + return (uint)(x[0]) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z00 = zz[ 0], z01 = zz[ 1], z02 = zz[ 2], z03 = zz[ 3], z04 = zz[ 4], z05 = zz[ 5], z06 = zz[ 6]; + ulong z07 = zz[ 7], z08 = zz[ 8], z09 = zz[ 9], z10 = zz[10], z11 = zz[11], z12 = zz[12], z13 = zz[13]; + zz[ 0] = z00 ^ (z01 << 59); + zz[ 1] = (z01 >> 5) ^ (z02 << 54); + zz[ 2] = (z02 >> 10) ^ (z03 << 49); + zz[ 3] = (z03 >> 15) ^ (z04 << 44); + zz[ 4] = (z04 >> 20) ^ (z05 << 39); + zz[ 5] = (z05 >> 25) ^ (z06 << 34); + zz[ 6] = (z06 >> 30) ^ (z07 << 29); + zz[ 7] = (z07 >> 35) ^ (z08 << 24); + zz[ 8] = (z08 >> 40) ^ (z09 << 19); + zz[ 9] = (z09 >> 45) ^ (z10 << 14); + zz[10] = (z10 >> 50) ^ (z11 << 9); + zz[11] = (z11 >> 55) ^ (z12 << 4) + ^ (z13 << 63); + zz[12] = (z12 >> 60) + ^ (z13 >> 1); + zz[13] = 0; + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6]; + z[0] = x0 & M59; + z[1] = ((x0 >> 59) ^ (x1 << 5)) & M59; + z[2] = ((x1 >> 54) ^ (x2 << 10)) & M59; + z[3] = ((x2 >> 49) ^ (x3 << 15)) & M59; + z[4] = ((x3 >> 44) ^ (x4 << 20)) & M59; + z[5] = ((x4 >> 39) ^ (x5 << 25)) & M59; + z[6] = ((x5 >> 34) ^ (x6 << 30)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] a = new ulong[7], b = new ulong[7]; + ImplExpand(x, a); + ImplExpand(y, b); + + for (int i = 0; i < 7; ++i) + { + ImplMulwAcc(a, b[i], zz, i); + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong[] xs, ulong y, ulong[] z, int zOff) + { + Debug.Assert(y >> 59 == 0); + + ulong[] u = new ulong[8]; + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + for (int i = 0; i < 7; ++i) + { + ulong x = xs[i]; + + Debug.Assert(x >> 59 == 0); + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 54; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 6) > 0); + + Debug.Assert(h >> 53 == 0); + + z[zOff + i ] ^= l & M59; + z[zOff + i + 1] ^= (l >> 59) ^ (h << 5); + } + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + for (int i = 0; i < 6; ++i) + { + Interleave.Expand64To128(x[i], zz, i << 1); + } + zz[12] = Interleave.Expand32to64((uint)x[6]); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs.meta new file mode 100644 index 0000000..63c407c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9678e96cfd9602a4287cdda4c732d8f3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs new file mode 100644 index 0000000..16f1f93 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409FieldElement + : ECFieldElement + { + protected ulong[] x; + + public SecT409FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 409) + throw new ArgumentException("value invalid for SecT409FieldElement", "x"); + + this.x = SecT409Field.FromBigInteger(x); + } + + public SecT409FieldElement() + { + this.x = Nat448.Create64(); + } + + protected internal SecT409FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat448.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat448.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat448.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT409Field"; } + } + + public override int FieldSize + { + get { return 409; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat448.Create64(); + SecT409Field.Add(x, ((SecT409FieldElement)b).x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat448.Create64(); + SecT409Field.AddOne(x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat448.Create64(); + SecT409Field.Multiply(x, ((SecT409FieldElement)b).x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT409FieldElement)b).x; + ulong[] xx = ((SecT409FieldElement)x).x, yx = ((SecT409FieldElement)y).x; + + ulong[] tt = Nat.Create64(13); + SecT409Field.MultiplyAddToExt(ax, bx, tt); + SecT409Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat448.Create64(); + SecT409Field.Reduce(tt, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat448.Create64(); + SecT409Field.Square(x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT409FieldElement)x).x, yx = ((SecT409FieldElement)y).x; + + ulong[] tt = Nat.Create64(13); + SecT409Field.SquareAddToExt(ax, tt); + SecT409Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat448.Create64(); + SecT409Field.Reduce(tt, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat448.Create64(); + SecT409Field.SquareN(x, pow, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat448.Create64(); + SecT409Field.Invert(x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat448.Create64(); + SecT409Field.Sqrt(x, z); + return new SecT409FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 409; } + } + + public virtual int K1 + { + get { return 87; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT409FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT409FieldElement); + } + + public virtual bool Equals(SecT409FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat448.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 4090087 ^ Arrays.GetHashCode(x, 0, 7); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs.meta new file mode 100644 index 0000000..33ead67 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1e5e0f341731bb140baa0eb9ad0b6ed6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs new file mode 100644 index 0000000..68e48e0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409K1Curve + : AbstractF2mCurve + { + private const int SecT409K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT409K1Point m_infinity; + + public SecT409K1Curve() + : base(409, 87, 0, 0) + { + this.m_infinity = new SecT409K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.Decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SecT409K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT409K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 409; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT409FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT409K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT409K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 409; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 87; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs.meta new file mode 100644 index 0000000..7c1c9af --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cf4755077296bd8448cd4e30aefef694 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs new file mode 100644 index 0000000..0fb984d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs @@ -0,0 +1,300 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT409K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + //return new SecT409K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT409K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT409K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT409K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + //return new SecT409K1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT409K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT409K1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT409K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT409K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs.meta new file mode 100644 index 0000000..6d67155 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dca960a8b177f5041af3ff0e3781a17e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs new file mode 100644 index 0000000..3731ac9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409R1Curve + : AbstractF2mCurve + { + private const int SecT409R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT409R1Point m_infinity; + + public SecT409R1Curve() + : base(409, 87, 0, 0) + { + this.m_infinity = new SecT409R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.Decode("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F"))); + this.m_order = new BigInteger(1, Hex.Decode("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT409R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT409R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 409; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT409FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT409R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT409R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 409; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 87; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs.meta new file mode 100644 index 0000000..b616bf7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1dd1b0669a789ac449e87e655d8b9b78 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs new file mode 100644 index 0000000..0dcb887 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs @@ -0,0 +1,286 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT409R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT409R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT409R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT409R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT409R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT409R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT409R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT409R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT409R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT409R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT409R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT409R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs.meta new file mode 100644 index 0000000..e6c68eb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT409R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9a5dada0af7a6434487b13aa553ebcbd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs new file mode 100644 index 0000000..13adb32 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs @@ -0,0 +1,337 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571Field + { + private const ulong M59 = ulong.MaxValue >> 5; + + private const ulong RM = 0xEF7BDEF7BDEF7BDEUL; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0x2BE1195F08CAFB99UL, 0x95F08CAF84657C23UL, 0xCAF84657C232BE11UL, 0x657C232BE1195F08UL, + 0xF84657C2308CAF84UL, 0x7C232BE1195F08CAUL, 0xBE1195F08CAF8465UL, 0x5F08CAF84657C232UL, 0x784657C232BE119UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + for (int i = 0; i < 9; ++i) + { + z[i] = x[i] ^ y[i]; + } + } + + private static void Add(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { + for (int i = 0; i < 9; ++i) + { + z[zOff + i] = x[xOff + i] ^ y[yOff + i]; + } + } + + private static void AddBothTo(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { + for (int i = 0; i < 9; ++i) + { + z[zOff + i] ^= x[xOff + i] ^ y[yOff + i]; + } + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + for (int i = 0; i < 18; ++i) + { + zz[i] = xx[i] ^ yy[i]; + } + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + for (int i = 1; i < 9; ++i) + { + z[i] = x[i]; + } + } + + public static ulong[] FromBigInteger(BigInteger x) + { + ulong[] z = Nat576.FromBigInteger64(x); + Reduce5(z, 0); + return z; + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat576.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3, 5 } + + ulong[] t0 = Nat576.Create64(); + ulong[] t1 = Nat576.Create64(); + ulong[] t2 = Nat576.Create64(); + + Square(x, t2); + + // 5 | 570 + Square(t2, t0); + Square(t0, t1); + Multiply(t0, t1, t0); + SquareN(t0, 2, t1); + Multiply(t0, t1, t0); + Multiply(t0, t2, t0); + + // 3 | 114 + SquareN(t0, 5, t1); + Multiply(t0, t1, t0); + SquareN(t1, 5, t1); + Multiply(t0, t1, t0); + + // 2 | 38 + SquareN(t0, 15, t1); + Multiply(t0, t1, t2); + + // ! {2,3,5} | 19 + SquareN(t2, 30, t0); + SquareN(t0, 30, t1); + Multiply(t0, t1, t0); + + // 3 | 9 + SquareN(t0, 60, t1); + Multiply(t0, t1, t0); + SquareN(t1, 60, t1); + Multiply(t0, t1, t0); + + // 3 | 3 + SquareN(t0, 180, t1); + Multiply(t0, t1, t0); + SquareN(t1, 180, t1); + Multiply(t0, t1, t0); + + Multiply(t0, t2, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat576.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong xx09 = xx[9]; + ulong u = xx[17], v = xx09; + + xx09 = v ^ (u >> 59) ^ (u >> 57) ^ (u >> 54) ^ (u >> 49); + v = xx[8] ^ (u << 5) ^ (u << 7) ^ (u << 10) ^ (u << 15); + + for (int i = 16; i >= 10; --i) + { + u = xx[i]; + z[i - 8] = v ^ (u >> 59) ^ (u >> 57) ^ (u >> 54) ^ (u >> 49); + v = xx[i - 9] ^ (u << 5) ^ (u << 7) ^ (u << 10) ^ (u << 15); + } + + u = xx09; + z[1] = v ^ (u >> 59) ^ (u >> 57) ^ (u >> 54) ^ (u >> 49); + v = xx[0] ^ (u << 5) ^ (u << 7) ^ (u << 10) ^ (u << 15); + + ulong x08 = z[8]; + ulong t = x08 >> 59; + z[0] = v ^ t ^ (t << 2) ^ (t << 5) ^ (t << 10); + z[8] = x08 & M59; + } + + public static void Reduce5(ulong[] z, int zOff) + { + ulong z8 = z[zOff + 8], t = z8 >> 59; + z[zOff ] ^= t ^ (t << 2) ^ (t << 5) ^ (t << 10); + z[zOff + 8] = z8 & M59; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] evn = Nat576.Create64(), odd = Nat576.Create64(); + + int pos = 0; + for (int i = 0; i < 4; ++i) + { + ulong u0 = Interleave.Unshuffle(x[pos++]); + ulong u1 = Interleave.Unshuffle(x[pos++]); + evn[i] = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[i] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + } + { + ulong u0 = Interleave.Unshuffle(x[pos]); + evn[4] = (u0 & 0x00000000FFFFFFFFUL); + odd[4] = (u0 >> 32); + } + + Multiply(odd, ROOT_Z, z); + Add(z, evn, z); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat576.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat576.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 561, 569 + return (uint)(x[0] ^ (x[8] >> 49) ^ (x[8] >> 57)) & 1U; + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + //for (int i = 0; i < 9; ++i) + //{ + // ImplMulwAcc(x, y[i], zz, i); + //} + + /* + * Precompute table of all 4-bit products of y + */ + ulong[] T0 = new ulong[9 << 4]; + Array.Copy(y, 0, T0, 9, 9); + // Reduce5(T0, 9); + int tOff = 0; + for (int i = 7; i > 0; --i) + { + tOff += 18; + Nat.ShiftUpBit64(9, T0, tOff >> 1, 0UL, T0, tOff); + Reduce5(T0, tOff); + Add(T0, 9, T0, tOff, T0, tOff + 9); + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + ulong[] T1 = new ulong[T0.Length]; + Nat.ShiftUpBits64(T0.Length, T0, 0, 4, 0L, T1, 0); + + uint MASK = 0xF; + + /* + * Lopez-Dahab algorithm + */ + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 1; j < 9; j += 2) + { + uint aVal = (uint)(x[j] >> k); + uint u = aVal & MASK; + uint v = (aVal >> 4) & MASK; + AddBothTo(T0, (int)(9 * u), T1, (int)(9 * v), zz, j - 1); + } + Nat.ShiftUpBits64(16, zz, 0, 8, 0L); + } + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 0; j < 9; j += 2) + { + uint aVal = (uint)(x[j] >> k); + uint u = aVal & MASK; + uint v = (aVal >> 4) & MASK; + AddBothTo(T0, (int)(9 * u), T1, (int)(9 * v), zz, j); + } + if (k > 0) + { + Nat.ShiftUpBits64(18, zz, 0, 8, 0L); + } + } + } + + protected static void ImplMulwAcc(ulong[] xs, ulong y, ulong[] z, int zOff) + { + ulong[] u = new ulong[32]; + //u[0] = 0; + u[1] = y; + for (int i = 2; i < 32; i += 2) + { + u[i ] = u[i >> 1] << 1; + u[i + 1] = u[i ] ^ y; + } + + ulong l = 0; + for (int i = 0; i < 9; ++i) + { + ulong x = xs[i]; + + uint j = (uint)x; + + l ^= u[j & 31]; + + ulong g, h = 0; + int k = 60; + do + { + j = (uint)(x >> k); + g = u[j & 31]; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 5) > 0); + + for (int p = 0; p < 4; ++p) + { + x = (x & RM) >> 1; + h ^= x & (ulong)(((long)y << p) >> 63); + } + + z[zOff + i] ^= l; + + l = h; + } + z[zOff + 9] ^= l; + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + for (int i = 0; i < 9; ++i) + { + Interleave.Expand64To128(x[i], zz, i << 1); + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs.meta new file mode 100644 index 0000000..1dff910 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571Field.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5102c10449efb5a4a85657c5d25f39bc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs new file mode 100644 index 0000000..a90859f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs @@ -0,0 +1,220 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571FieldElement + : ECFieldElement + { + protected readonly ulong[] x; + + public SecT571FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 571) + throw new ArgumentException("value invalid for SecT571FieldElement", "x"); + + this.x = SecT571Field.FromBigInteger(x); + } + + public SecT571FieldElement() + { + this.x = Nat576.Create64(); + } + + protected internal SecT571FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat576.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat576.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat576.ToBigInteger64(x); + } + + public override String FieldName + { + get { return "SecT571Field"; } + } + + public override int FieldSize + { + get { return 571; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat576.Create64(); + SecT571Field.Add(x, ((SecT571FieldElement)b).x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat576.Create64(); + SecT571Field.AddOne(x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat576.Create64(); + SecT571Field.Multiply(x, ((SecT571FieldElement)b).x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT571FieldElement)b).x; + ulong[] xx = ((SecT571FieldElement)x).x, yx = ((SecT571FieldElement)y).x; + + ulong[] tt = Nat576.CreateExt64(); + SecT571Field.MultiplyAddToExt(ax, bx, tt); + SecT571Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat576.Create64(); + SecT571Field.Reduce(tt, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat576.Create64(); + SecT571Field.Square(x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT571FieldElement)x).x, yx = ((SecT571FieldElement)y).x; + + ulong[] tt = Nat576.CreateExt64(); + SecT571Field.SquareAddToExt(ax, tt); + SecT571Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat576.Create64(); + SecT571Field.Reduce(tt, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat576.Create64(); + SecT571Field.SquareN(x, pow, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat576.Create64(); + SecT571Field.Invert(x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat576.Create64(); + SecT571Field.Sqrt(x, z); + return new SecT571FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 571; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 5; } + } + + public virtual int K3 + { + get { return 10; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT571FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT571FieldElement); + } + + public virtual bool Equals(SecT571FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat576.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 5711052 ^ Arrays.GetHashCode(x, 0, 9); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs.meta new file mode 100644 index 0000000..8795e72 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571FieldElement.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9d2a199651f1f154d8ed8d08c7f52f15 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs new file mode 100644 index 0000000..b72df38 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs @@ -0,0 +1,108 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571K1Curve + : AbstractF2mCurve + { + private const int SecT571K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT571K1Point m_infinity; + + public SecT571K1Curve() + : base(571, 2, 5, 10) + { + this.m_infinity = new SecT571K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.Decode("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SecT571K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT571K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 571; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT571FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT571K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT571K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 571; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 5; } + } + + public virtual int K3 + { + get { return 10; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs.meta new file mode 100644 index 0000000..9938a96 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 376e118668ede6543b1a007c453d52a0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs new file mode 100644 index 0000000..b79f3b9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs @@ -0,0 +1,300 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT571K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT571K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT571K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT571K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + //return new SecT571K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT571K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT571K1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT571K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT571K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + //return new SecT571K1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT571K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT571K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT571K1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT571K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT571K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT571K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs.meta new file mode 100644 index 0000000..f47d6b0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571K1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fa7660666cc38b449992eb301ca16b69 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs new file mode 100644 index 0000000..84abdfc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs @@ -0,0 +1,106 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571R1Curve + : AbstractF2mCurve + { + private const int SecT571R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + protected readonly SecT571R1Point m_infinity; + + internal static readonly SecT571FieldElement SecT571R1_B = new SecT571FieldElement( + new BigInteger(1, Hex.Decode("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A"))); + internal static readonly SecT571FieldElement SecT571R1_B_SQRT = (SecT571FieldElement)SecT571R1_B.Sqrt(); + + public SecT571R1Curve() + : base(571, 2, 5, 10) + { + this.m_infinity = new SecT571R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = SecT571R1_B; + this.m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SecT571R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT571R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 571; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT571FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT571R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT571R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 571; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 5; } + } + + public virtual int K3 + { + get { return 10; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs.meta new file mode 100644 index 0000000..a510e60 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Curve.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 287691cba348f94419cbfe05b04d46f5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs new file mode 100644 index 0000000..76a94b9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs @@ -0,0 +1,290 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT571R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT571R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT571R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT571R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + //X3 = L.Square().Add(L).Add(X1).Add(curve.A); + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + //return new SecT571R1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT571R1Point(curve, X3, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + //return new SecT571R1Point(curve, X3, curve.B.sqrt(), IsCompressed); + return new SecT571R1Point(curve, X3, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT571R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + //return new SecT571R1Point(curve, T, curve.B.sqrt(), withCompression); + return new SecT571R1Point(curve, T, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT571R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is it's own Additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + //ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + //ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + //return new SecT571R1Point(curve, A, curve.B.sqrt(), withCompression); + return new SecT571R1Point(curve, A, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT571R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT571R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs.meta new file mode 100644 index 0000000..7c185e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/custom/sec/SecT571R1Point.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a4d049a4596e1c44199a6558ef1880ab +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo.meta new file mode 100644 index 0000000..175db33 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ea3bf8e1c91bc00418e4ba58fef48e8d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs new file mode 100644 index 0000000..981c5ed --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public interface ECEndomorphism + { + ECPointMap PointMap { get; } + + bool HasEfficientPointMap { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs.meta new file mode 100644 index 0000000..d83c286 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/ECEndomorphism.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f3e5470dddbaf9448addcb073ff9da26 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs new file mode 100644 index 0000000..7e486c4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs @@ -0,0 +1,14 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public interface GlvEndomorphism + : ECEndomorphism + { + BigInteger[] DecomposeScalar(BigInteger k); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs.meta new file mode 100644 index 0000000..7190e7f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvEndomorphism.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ef17475fe8bc0ff46ac3012a1bc5a09a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs new file mode 100644 index 0000000..2bafa1b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs @@ -0,0 +1,59 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeBEndomorphism + : GlvEndomorphism + { + protected readonly ECCurve m_curve; + protected readonly GlvTypeBParameters m_parameters; + protected readonly ECPointMap m_pointMap; + + public GlvTypeBEndomorphism(ECCurve curve, GlvTypeBParameters parameters) + { + this.m_curve = curve; + this.m_parameters = parameters; + this.m_pointMap = new ScaleXPointMap(curve.FromBigInteger(parameters.Beta)); + } + + public virtual BigInteger[] DecomposeScalar(BigInteger k) + { + int bits = m_parameters.Bits; + BigInteger b1 = CalculateB(k, m_parameters.G1, bits); + BigInteger b2 = CalculateB(k, m_parameters.G2, bits); + + BigInteger[] v1 = m_parameters.V1, v2 = m_parameters.V2; + BigInteger a = k.Subtract((b1.Multiply(v1[0])).Add(b2.Multiply(v2[0]))); + BigInteger b = (b1.Multiply(v1[1])).Add(b2.Multiply(v2[1])).Negate(); + + return new BigInteger[]{ a, b }; + } + + public virtual ECPointMap PointMap + { + get { return m_pointMap; } + } + + public virtual bool HasEfficientPointMap + { + get { return true; } + } + + protected virtual BigInteger CalculateB(BigInteger k, BigInteger g, int t) + { + bool negative = (g.SignValue < 0); + BigInteger b = k.Multiply(g.Abs()); + bool extra = b.TestBit(t - 1); + b = b.ShiftRight(t); + if (extra) + { + b = b.Add(BigInteger.One); + } + return negative ? b.Negate() : b; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs.meta new file mode 100644 index 0000000..7982394 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBEndomorphism.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d704deeea20becd4daf099cc997710ff +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs new file mode 100644 index 0000000..f46d83e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs @@ -0,0 +1,64 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeBParameters + { + protected readonly BigInteger m_beta; + protected readonly BigInteger m_lambda; + protected readonly BigInteger[] m_v1, m_v2; + protected readonly BigInteger m_g1, m_g2; + protected readonly int m_bits; + + public GlvTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, + BigInteger g1, BigInteger g2, int bits) + { + this.m_beta = beta; + this.m_lambda = lambda; + this.m_v1 = v1; + this.m_v2 = v2; + this.m_g1 = g1; + this.m_g2 = g2; + this.m_bits = bits; + } + + public virtual BigInteger Beta + { + get { return m_beta; } + } + + public virtual BigInteger Lambda + { + get { return m_lambda; } + } + + public virtual BigInteger[] V1 + { + get { return m_v1; } + } + + public virtual BigInteger[] V2 + { + get { return m_v2; } + } + + public virtual BigInteger G1 + { + get { return m_g1; } + } + + public virtual BigInteger G2 + { + get { return m_g2; } + } + + public virtual int Bits + { + get { return m_bits; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs.meta new file mode 100644 index 0000000..2232fcd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/endo/GlvTypeBParameters.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 43a554c9ef493c94592277d57233a060 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier.meta new file mode 100644 index 0000000..15a40f3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a53de973421193c4cbf33dbbaec90811 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs new file mode 100644 index 0000000..74a8ef9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public abstract class AbstractECMultiplier + : ECMultiplier + { + public virtual ECPoint Multiply(ECPoint p, BigInteger k) + { + int sign = k.SignValue; + if (sign == 0 || p.IsInfinity) + return p.Curve.Infinity; + + ECPoint positive = MultiplyPositive(p, k.Abs()); + ECPoint result = sign > 0 ? positive : positive.Negate(); + + /* + * Although the various multipliers ought not to produce invalid output under normal + * circumstances, a final check here is advised to guard against fault attacks. + */ + return ECAlgorithms.ValidatePoint(result); + } + + protected abstract ECPoint MultiplyPositive(ECPoint p, BigInteger k); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs.meta new file mode 100644 index 0000000..7950282 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/AbstractECMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b90b097e4fcebb64a9055665b2062092 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs new file mode 100644 index 0000000..efd5699 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs @@ -0,0 +1,22 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Interface for classes encapsulating a point multiplication algorithm + * for ECPoints. + */ + public interface ECMultiplier + { + /** + * Multiplies the ECPoint p by k, i.e. + * p is added k times to itself. + * @param p The ECPoint to be multiplied. + * @param k The factor by which p is multiplied. + * @return p multiplied by k. + */ + ECPoint Multiply(ECPoint p, BigInteger k); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs.meta new file mode 100644 index 0000000..0d5312b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/ECMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0af0eecaaa213474cb001933d00e041e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs new file mode 100644 index 0000000..6fb653f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs @@ -0,0 +1,63 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public class FixedPointCombMultiplier + : AbstractECMultiplier + { + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECCurve c = p.Curve; + int size = FixedPointUtilities.GetCombSize(c); + + if (k.BitLength > size) + { + /* + * TODO The comb works best when the scalars are less than the (possibly unknown) order. + * Still, if we want to handle larger scalars, we could allow customization of the comb + * size, or alternatively we could deal with the 'extra' bits either by running the comb + * multiple times as necessary, or by using an alternative multiplier as prelude. + */ + throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order"); + } + + int minWidth = GetWidthForCombSize(size); + + FixedPointPreCompInfo info = FixedPointUtilities.Precompute(p, minWidth); + ECPoint[] lookupTable = info.PreComp; + int width = info.Width; + + int d = (size + width - 1) / width; + + ECPoint R = c.Infinity; + + int top = d * width - 1; + for (int i = 0; i < d; ++i) + { + int index = 0; + + for (int j = top - i; j >= 0; j -= d) + { + index <<= 1; + if (k.TestBit(j)) + { + index |= 1; + } + } + + R = R.TwicePlus(lookupTable[index]); + } + + return R; + } + + protected virtual int GetWidthForCombSize(int combSize) + { + return combSize > 257 ? 6 : 5; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs.meta new file mode 100644 index 0000000..9da36a0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointCombMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 063e8c85432309347a8cee70efde8e72 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs new file mode 100644 index 0000000..8635ad2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs @@ -0,0 +1,38 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class holding precomputation data for fixed-point multiplications. + */ + public class FixedPointPreCompInfo + : PreCompInfo + { + /** + * Array holding the precomputed ECPoints used for a fixed + * point multiplication. + */ + protected ECPoint[] m_preComp = null; + + /** + * The width used for the precomputation. If a larger width precomputation + * is already available this may be larger than was requested, so calling + * code should refer to the actual width. + */ + protected int m_width = -1; + + public virtual ECPoint[] PreComp + { + get { return m_preComp; } + set { this.m_preComp = value; } + } + + public virtual int Width + { + get { return m_width; } + set { this.m_width = value; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs.meta new file mode 100644 index 0000000..35ca451 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointPreCompInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5269ffcee0d3b4f459619e7351ac2e2f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs new file mode 100644 index 0000000..c7b6abc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs @@ -0,0 +1,76 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public class FixedPointUtilities + { + public static readonly string PRECOMP_NAME = "bc_fixed_point"; + + public static int GetCombSize(ECCurve c) + { + BigInteger order = c.Order; + return order == null ? c.FieldSize + 1 : order.BitLength; + } + + public static FixedPointPreCompInfo GetFixedPointPreCompInfo(PreCompInfo preCompInfo) + { + if ((preCompInfo != null) && (preCompInfo is FixedPointPreCompInfo)) + { + return (FixedPointPreCompInfo)preCompInfo; + } + + return new FixedPointPreCompInfo(); + } + + public static FixedPointPreCompInfo Precompute(ECPoint p, int minWidth) + { + ECCurve c = p.Curve; + + int n = 1 << minWidth; + FixedPointPreCompInfo info = GetFixedPointPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME)); + ECPoint[] lookupTable = info.PreComp; + + if (lookupTable == null || lookupTable.Length < n) + { + int bits = GetCombSize(c); + int d = (bits + minWidth - 1) / minWidth; + + ECPoint[] pow2Table = new ECPoint[minWidth]; + pow2Table[0] = p; + for (int i = 1; i < minWidth; ++i) + { + pow2Table[i] = pow2Table[i - 1].TimesPow2(d); + } + + c.NormalizeAll(pow2Table); + + lookupTable = new ECPoint[n]; + lookupTable[0] = c.Infinity; + + for (int bit = minWidth - 1; bit >= 0; --bit) + { + ECPoint pow2 = pow2Table[bit]; + + int step = 1 << bit; + for (int i = step; i < n; i += (step << 1)) + { + lookupTable[i] = lookupTable[i - step].Add(pow2); + } + } + + c.NormalizeAll(lookupTable); + + info.PreComp = lookupTable; + info.Width = minWidth; + + c.SetPreCompInfo(p, PRECOMP_NAME, info); + } + + return info; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs.meta new file mode 100644 index 0000000..10f72ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/FixedPointUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 508ed3f5d1e1c934eb8ee7da23677718 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs new file mode 100644 index 0000000..7220e87 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Endo; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public class GlvMultiplier + : AbstractECMultiplier + { + protected readonly ECCurve curve; + protected readonly GlvEndomorphism glvEndomorphism; + + public GlvMultiplier(ECCurve curve, GlvEndomorphism glvEndomorphism) + { + if (curve == null || curve.Order == null) + throw new ArgumentException("Need curve with known group order", "curve"); + + this.curve = curve; + this.glvEndomorphism = glvEndomorphism; + } + + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + if (!curve.Equals(p.Curve)) + throw new InvalidOperationException(); + + BigInteger n = p.Curve.Order; + BigInteger[] ab = glvEndomorphism.DecomposeScalar(k.Mod(n)); + BigInteger a = ab[0], b = ab[1]; + + ECPointMap pointMap = glvEndomorphism.PointMap; + if (glvEndomorphism.HasEfficientPointMap) + { + return ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap, b); + } + + return ECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap.Map(p), b); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs.meta new file mode 100644 index 0000000..bebd7bb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/GlvMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fecaa205dd70b694396480bbad11c16d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs new file mode 100644 index 0000000..ebb7897 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Interface for classes storing precomputation data for multiplication + * algorithms. Used as a Memento (see GOF patterns) for + * WNafMultiplier. + */ + public interface PreCompInfo + { + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs.meta new file mode 100644 index 0000000..35668b2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/PreCompInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7a90a54c7ae87ab48977a5a3aadc1d7c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs new file mode 100644 index 0000000..668930a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the WNAF (Window Non-Adjacent Form) multiplication + * algorithm. + */ + public class WNafL2RMultiplier + : AbstractECMultiplier + { + /** + * Multiplies this by an integer k using the + * Window NAF method. + * @param k The integer by which this is multiplied. + * @return A new ECPoint which equals this + * multiplied by k. + */ + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + // Clamp the window width in the range [2, 16] + int width = System.Math.Max(2, System.Math.Min(16, GetWindowSize(k.BitLength))); + + WNafPreCompInfo wnafPreCompInfo = WNafUtilities.Precompute(p, width, true); + ECPoint[] preComp = wnafPreCompInfo.PreComp; + ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg; + + int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k); + + ECPoint R = p.Curve.Infinity; + + int i = wnaf.Length; + + /* + * NOTE: We try to optimize the first window using the precomputed points to substitute an + * addition for 2 or more doublings. + */ + if (i > 1) + { + int wi = wnaf[--i]; + int digit = wi >> 16, zeroes = wi & 0xFFFF; + + int n = System.Math.Abs(digit); + ECPoint[] table = digit < 0 ? preCompNeg : preComp; + + // Optimization can only be used for values in the lower half of the table + if ((n << 2) < (1 << width)) + { + int highest = LongArray.BitLengths[n]; + + // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting? + int scale = width - highest; + int lowBits = n ^ (1 << (highest - 1)); + + int i1 = ((1 << (width - 1)) - 1); + int i2 = (lowBits << scale) + 1; + R = table[i1 >> 1].Add(table[i2 >> 1]); + + zeroes -= scale; + + //Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2); + } + else + { + R = table[n >> 1]; + } + + R = R.TimesPow2(zeroes); + } + + while (i > 0) + { + int wi = wnaf[--i]; + int digit = wi >> 16, zeroes = wi & 0xFFFF; + + int n = System.Math.Abs(digit); + ECPoint[] table = digit < 0 ? preCompNeg : preComp; + ECPoint r = table[n >> 1]; + + R = R.TwicePlus(r); + R = R.TimesPow2(zeroes); + } + + return R; + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @return the window size to use + */ + protected virtual int GetWindowSize(int bits) + { + return WNafUtilities.GetWindowSize(bits); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs.meta new file mode 100644 index 0000000..5942ea0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafL2RMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e211e4a6b86d3f94fbf2b5ac9c113ad8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs new file mode 100644 index 0000000..088f33a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs @@ -0,0 +1,50 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class holding precomputation data for the WNAF (Window Non-Adjacent Form) + * algorithm. + */ + public class WNafPreCompInfo + : PreCompInfo + { + /** + * Array holding the precomputed ECPoints used for a Window + * NAF multiplication. + */ + protected ECPoint[] m_preComp = null; + + /** + * Array holding the negations of the precomputed ECPoints used + * for a Window NAF multiplication. + */ + protected ECPoint[] m_preCompNeg = null; + + /** + * Holds an ECPoint representing Twice(this). Used for the + * Window NAF multiplication to create or extend the precomputed values. + */ + protected ECPoint m_twice = null; + + public virtual ECPoint[] PreComp + { + get { return m_preComp; } + set { this.m_preComp = value; } + } + + public virtual ECPoint[] PreCompNeg + { + get { return m_preCompNeg; } + set { this.m_preCompNeg = value; } + } + + public virtual ECPoint Twice + { + get { return m_twice; } + set { this.m_twice = value; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs.meta new file mode 100644 index 0000000..2165c73 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafPreCompInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c08f3ff220a86c0449f3d1d62cdfb47c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs new file mode 100644 index 0000000..7c3b60c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs @@ -0,0 +1,528 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public abstract class WNafUtilities + { + public static readonly string PRECOMP_NAME = "bc_wnaf"; + + private static readonly int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 }; + + private static readonly byte[] EMPTY_BYTES = new byte[0]; + private static readonly int[] EMPTY_INTS = new int[0]; + private static readonly ECPoint[] EMPTY_POINTS = new ECPoint[0]; + + public static int[] GenerateCompactNaf(BigInteger k) + { + if ((k.BitLength >> 16) != 0) + throw new ArgumentException("must have bitlength < 2^16", "k"); + if (k.SignValue == 0) + return EMPTY_INTS; + + BigInteger _3k = k.ShiftLeft(1).Add(k); + + int bits = _3k.BitLength; + int[] naf = new int[bits >> 1]; + + BigInteger diff = _3k.Xor(k); + + int highBit = bits - 1, length = 0, zeroes = 0; + for (int i = 1; i < highBit; ++i) + { + if (!diff.TestBit(i)) + { + ++zeroes; + continue; + } + + int digit = k.TestBit(i) ? -1 : 1; + naf[length++] = (digit << 16) | zeroes; + zeroes = 1; + ++i; + } + + naf[length++] = (1 << 16) | zeroes; + + if (naf.Length > length) + { + naf = Trim(naf, length); + } + + return naf; + } + + public static int[] GenerateCompactWindowNaf(int width, BigInteger k) + { + if (width == 2) + { + return GenerateCompactNaf(k); + } + + if (width < 2 || width > 16) + throw new ArgumentException("must be in the range [2, 16]", "width"); + if ((k.BitLength >> 16) != 0) + throw new ArgumentException("must have bitlength < 2^16", "k"); + if (k.SignValue == 0) + return EMPTY_INTS; + + int[] wnaf = new int[k.BitLength / width + 1]; + + // 2^width and a mask and sign bit set accordingly + int pow2 = 1 << width; + int mask = pow2 - 1; + int sign = pow2 >> 1; + + bool carry = false; + int length = 0, pos = 0; + + while (pos <= k.BitLength) + { + if (k.TestBit(pos) == carry) + { + ++pos; + continue; + } + + k = k.ShiftRight(pos); + + int digit = k.IntValue & mask; + if (carry) + { + ++digit; + } + + carry = (digit & sign) != 0; + if (carry) + { + digit -= pow2; + } + + int zeroes = length > 0 ? pos - 1 : pos; + wnaf[length++] = (digit << 16) | zeroes; + pos = width; + } + + // Reduce the WNAF array to its actual length + if (wnaf.Length > length) + { + wnaf = Trim(wnaf, length); + } + + return wnaf; + } + + public static byte[] GenerateJsf(BigInteger g, BigInteger h) + { + int digits = System.Math.Max(g.BitLength, h.BitLength) + 1; + byte[] jsf = new byte[digits]; + + BigInteger k0 = g, k1 = h; + int j = 0, d0 = 0, d1 = 0; + + int offset = 0; + while ((d0 | d1) != 0 || k0.BitLength > offset || k1.BitLength > offset) + { + int n0 = ((int)((uint)k0.IntValue >> offset) + d0) & 7; + int n1 = ((int)((uint)k1.IntValue >> offset) + d1) & 7; + + int u0 = n0 & 1; + if (u0 != 0) + { + u0 -= (n0 & 2); + if ((n0 + u0) == 4 && (n1 & 3) == 2) + { + u0 = -u0; + } + } + + int u1 = n1 & 1; + if (u1 != 0) + { + u1 -= (n1 & 2); + if ((n1 + u1) == 4 && (n0 & 3) == 2) + { + u1 = -u1; + } + } + + if ((d0 << 1) == 1 + u0) + { + d0 ^= 1; + } + if ((d1 << 1) == 1 + u1) + { + d1 ^= 1; + } + + if (++offset == 30) + { + offset = 0; + k0 = k0.ShiftRight(30); + k1 = k1.ShiftRight(30); + } + + jsf[j++] = (byte)((u0 << 4) | (u1 & 0xF)); + } + + // Reduce the JSF array to its actual length + if (jsf.Length > j) + { + jsf = Trim(jsf, j); + } + + return jsf; + } + + public static byte[] GenerateNaf(BigInteger k) + { + if (k.SignValue == 0) + return EMPTY_BYTES; + + BigInteger _3k = k.ShiftLeft(1).Add(k); + + int digits = _3k.BitLength - 1; + byte[] naf = new byte[digits]; + + BigInteger diff = _3k.Xor(k); + + for (int i = 1; i < digits; ++i) + { + if (diff.TestBit(i)) + { + naf[i - 1] = (byte)(k.TestBit(i) ? -1 : 1); + ++i; + } + } + + naf[digits - 1] = 1; + + return naf; + } + + /** + * Computes the Window NAF (non-adjacent Form) of an integer. + * @param width The width w of the Window NAF. The width is + * defined as the minimal number w, such that for any + * w consecutive digits in the resulting representation, at + * most one is non-zero. + * @param k The integer of which the Window NAF is computed. + * @return The Window NAF of the given width, such that the following holds: + * k = &sum;i=0l-1 ki2i + * , where the ki denote the elements of the + * returned byte[]. + */ + public static byte[] GenerateWindowNaf(int width, BigInteger k) + { + if (width == 2) + { + return GenerateNaf(k); + } + + if (width < 2 || width > 8) + throw new ArgumentException("must be in the range [2, 8]", "width"); + if (k.SignValue == 0) + return EMPTY_BYTES; + + byte[] wnaf = new byte[k.BitLength + 1]; + + // 2^width and a mask and sign bit set accordingly + int pow2 = 1 << width; + int mask = pow2 - 1; + int sign = pow2 >> 1; + + bool carry = false; + int length = 0, pos = 0; + + while (pos <= k.BitLength) + { + if (k.TestBit(pos) == carry) + { + ++pos; + continue; + } + + k = k.ShiftRight(pos); + + int digit = k.IntValue & mask; + if (carry) + { + ++digit; + } + + carry = (digit & sign) != 0; + if (carry) + { + digit -= pow2; + } + + length += (length > 0) ? pos - 1 : pos; + wnaf[length++] = (byte)digit; + pos = width; + } + + // Reduce the WNAF array to its actual length + if (wnaf.Length > length) + { + wnaf = Trim(wnaf, length); + } + + return wnaf; + } + + public static int GetNafWeight(BigInteger k) + { + if (k.SignValue == 0) + return 0; + + BigInteger _3k = k.ShiftLeft(1).Add(k); + BigInteger diff = _3k.Xor(k); + + return diff.BitCount; + } + + public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p) + { + return GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, PRECOMP_NAME)); + } + + public static WNafPreCompInfo GetWNafPreCompInfo(PreCompInfo preCompInfo) + { + if ((preCompInfo != null) && (preCompInfo is WNafPreCompInfo)) + { + return (WNafPreCompInfo)preCompInfo; + } + + return new WNafPreCompInfo(); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @return the window size to use + */ + public static int GetWindowSize(int bits) + { + return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width + * @return the window size to use + */ + public static int GetWindowSize(int bits, int[] windowSizeCutoffs) + { + int w = 0; + for (; w < windowSizeCutoffs.Length; ++w) + { + if (bits < windowSizeCutoffs[w]) + { + break; + } + } + return w + 2; + } + + public static ECPoint MapPointWithPrecomp(ECPoint p, int width, bool includeNegated, + ECPointMap pointMap) + { + ECCurve c = p.Curve; + WNafPreCompInfo wnafPreCompP = Precompute(p, width, includeNegated); + + ECPoint q = pointMap.Map(p); + WNafPreCompInfo wnafPreCompQ = GetWNafPreCompInfo(c.GetPreCompInfo(q, PRECOMP_NAME)); + + ECPoint twiceP = wnafPreCompP.Twice; + if (twiceP != null) + { + ECPoint twiceQ = pointMap.Map(twiceP); + wnafPreCompQ.Twice = twiceQ; + } + + ECPoint[] preCompP = wnafPreCompP.PreComp; + ECPoint[] preCompQ = new ECPoint[preCompP.Length]; + for (int i = 0; i < preCompP.Length; ++i) + { + preCompQ[i] = pointMap.Map(preCompP[i]); + } + wnafPreCompQ.PreComp = preCompQ; + + if (includeNegated) + { + ECPoint[] preCompNegQ = new ECPoint[preCompQ.Length]; + for (int i = 0; i < preCompNegQ.Length; ++i) + { + preCompNegQ[i] = preCompQ[i].Negate(); + } + wnafPreCompQ.PreCompNeg = preCompNegQ; + } + + c.SetPreCompInfo(q, PRECOMP_NAME, wnafPreCompQ); + + return q; + } + + public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated) + { + ECCurve c = p.Curve; + WNafPreCompInfo wnafPreCompInfo = GetWNafPreCompInfo(c.GetPreCompInfo(p, PRECOMP_NAME)); + + int iniPreCompLen = 0, reqPreCompLen = 1 << System.Math.Max(0, width - 2); + + ECPoint[] preComp = wnafPreCompInfo.PreComp; + if (preComp == null) + { + preComp = EMPTY_POINTS; + } + else + { + iniPreCompLen = preComp.Length; + } + + if (iniPreCompLen < reqPreCompLen) + { + preComp = ResizeTable(preComp, reqPreCompLen); + + if (reqPreCompLen == 1) + { + preComp[0] = p.Normalize(); + } + else + { + int curPreCompLen = iniPreCompLen; + if (curPreCompLen == 0) + { + preComp[0] = p; + curPreCompLen = 1; + } + + ECFieldElement iso = null; + + if (reqPreCompLen == 2) + { + preComp[1] = p.ThreeTimes(); + } + else + { + ECPoint twiceP = wnafPreCompInfo.Twice, last = preComp[curPreCompLen - 1]; + if (twiceP == null) + { + twiceP = preComp[0].Twice(); + wnafPreCompInfo.Twice = twiceP; + + /* + * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism + * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This + * also requires scaling the initial point's X, Y coordinates, and reversing the + * isomorphism as part of the subsequent normalization. + * + * NOTE: The correctness of this optimization depends on: + * 1) additions do not use the curve's A, B coefficients. + * 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ... + */ + if (ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64) + { + switch (c.CoordinateSystem) + { + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + iso = twiceP.GetZCoord(0); + twiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(), + twiceP.YCoord.ToBigInteger()); + + ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso); + last = last.ScaleX(iso2).ScaleY(iso3); + + if (iniPreCompLen == 0) + { + preComp[0] = last; + } + break; + } + } + } + } + + while (curPreCompLen < reqPreCompLen) + { + /* + * Compute the new ECPoints for the precomputation array. The values 1, 3, + * 5, ..., 2^(width-1)-1 times p are computed + */ + preComp[curPreCompLen++] = last = last.Add(twiceP); + } + } + + /* + * Having oft-used operands in affine form makes operations faster. + */ + c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso); + } + } + + wnafPreCompInfo.PreComp = preComp; + + if (includeNegated) + { + ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg; + + int pos; + if (preCompNeg == null) + { + pos = 0; + preCompNeg = new ECPoint[reqPreCompLen]; + } + else + { + pos = preCompNeg.Length; + if (pos < reqPreCompLen) + { + preCompNeg = ResizeTable(preCompNeg, reqPreCompLen); + } + } + + while (pos < reqPreCompLen) + { + preCompNeg[pos] = preComp[pos].Negate(); + ++pos; + } + + wnafPreCompInfo.PreCompNeg = preCompNeg; + } + + c.SetPreCompInfo(p, PRECOMP_NAME, wnafPreCompInfo); + + return wnafPreCompInfo; + } + + private static byte[] Trim(byte[] a, int length) + { + byte[] result = new byte[length]; + Array.Copy(a, 0, result, 0, result.Length); + return result; + } + + private static int[] Trim(int[] a, int length) + { + int[] result = new int[length]; + Array.Copy(a, 0, result, 0, result.Length); + return result; + } + + private static ECPoint[] ResizeTable(ECPoint[] a, int length) + { + ECPoint[] result = new ECPoint[length]; + Array.Copy(a, 0, result, 0, a.Length); + return result; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs.meta new file mode 100644 index 0000000..e5f4819 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WNafUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3572ce73eb041d6429dc80a09390f1e9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs new file mode 100644 index 0000000..2e7d6ab --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs @@ -0,0 +1,129 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math.EC.Abc; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the WTNAF (Window + * τ-adic Non-Adjacent Form) algorithm. + */ + public class WTauNafMultiplier + : AbstractECMultiplier + { + // TODO Create WTauNafUtilities class and move various functionality into it + internal static readonly string PRECOMP_NAME = "bc_wtnaf"; + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by k using the reduced τ-adic NAF (RTNAF) + * method. + * @param p The AbstractF2mPoint to multiply. + * @param k The integer by which to multiply k. + * @return p multiplied by k. + */ + protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k) + { + if (!(point is AbstractF2mPoint)) + throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier"); + + AbstractF2mPoint p = (AbstractF2mPoint)point; + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + int m = curve.FieldSize; + sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; + sbyte mu = Tnaf.GetMu(a); + BigInteger[] s = curve.GetSi(); + + ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); + + return MultiplyWTnaf(p, rho, curve.GetPreCompInfo(p, PRECOMP_NAME), a, mu); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] using + * the τ-adic NAF (TNAF) method. + * @param p The AbstractF2mPoint to multiply. + * @param lambda The element λ of + * Z[τ] of which to compute the + * [τ]-adic NAF. + * @return p multiplied by λ. + */ + private AbstractF2mPoint MultiplyWTnaf(AbstractF2mPoint p, ZTauElement lambda, + PreCompInfo preCompInfo, sbyte a, sbyte mu) + { + ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1; + + BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width); + + sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width, + BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha); + + return MultiplyFromWTnaf(p, u, preCompInfo); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] + * using the window τ-adic NAF (TNAF) method, given the + * WTNAF of λ. + * @param p The AbstractF2mPoint to multiply. + * @param u The the WTNAF of λ.. + * @return λ * p + */ + private static AbstractF2mPoint MultiplyFromWTnaf(AbstractF2mPoint p, sbyte[] u, PreCompInfo preCompInfo) + { + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; + + AbstractF2mPoint[] pu; + if ((preCompInfo == null) || !(preCompInfo is WTauNafPreCompInfo)) + { + pu = Tnaf.GetPreComp(p, a); + + WTauNafPreCompInfo pre = new WTauNafPreCompInfo(); + pre.PreComp = pu; + curve.SetPreCompInfo(p, PRECOMP_NAME, pre); + } + else + { + pu = ((WTauNafPreCompInfo)preCompInfo).PreComp; + } + + // TODO Include negations in precomp (optionally) and use from here + AbstractF2mPoint[] puNeg = new AbstractF2mPoint[pu.Length]; + for (int i = 0; i < pu.Length; ++i) + { + puNeg[i] = (AbstractF2mPoint)pu[i].Negate(); + } + + + // q = infinity + AbstractF2mPoint q = (AbstractF2mPoint) p.Curve.Infinity; + + int tauCount = 0; + for (int i = u.Length - 1; i >= 0; i--) + { + ++tauCount; + int ui = u[i]; + if (ui != 0) + { + q = q.TauPow(tauCount); + tauCount = 0; + + ECPoint x = ui > 0 ? pu[ui >> 1] : puNeg[(-ui) >> 1]; + q = (AbstractF2mPoint)q.Add(x); + } + } + if (tauCount > 0) + { + q = q.TauPow(tauCount); + } + return q; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs.meta new file mode 100644 index 0000000..003abe8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafMultiplier.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2139991248cc7e04980d36d65b1284b4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs new file mode 100644 index 0000000..ccf5a65 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs @@ -0,0 +1,28 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class holding precomputation data for the WTNAF (Window + * τ-adic Non-Adjacent Form) algorithm. + */ + public class WTauNafPreCompInfo + : PreCompInfo + { + /** + * Array holding the precomputed AbstractF2mPoints used for the + * WTNAF multiplication in + * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply() + * WTauNafMultiplier.multiply()}. + */ + protected AbstractF2mPoint[] m_preComp; + + public virtual AbstractF2mPoint[] PreComp + { + get { return m_preComp; } + set { this.m_preComp = value; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs.meta new file mode 100644 index 0000000..6979654 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/ec/multiplier/WTauNafPreCompInfo.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6adae98f46df50549b03088b3c22b378 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field.meta new file mode 100644 index 0000000..ee2b8a5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8e4af59d5da39324490dcbe72fd54f35 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs new file mode 100644 index 0000000..b66c349 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs @@ -0,0 +1,58 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public abstract class FiniteFields + { + internal static readonly IFiniteField GF_2 = new PrimeField(BigInteger.ValueOf(2)); + internal static readonly IFiniteField GF_3 = new PrimeField(BigInteger.ValueOf(3)); + + public static IPolynomialExtensionField GetBinaryExtensionField(int[] exponents) + { + if (exponents[0] != 0) + { + throw new ArgumentException("Irreducible polynomials in GF(2) must have constant term", "exponents"); + } + for (int i = 1; i < exponents.Length; ++i) + { + if (exponents[i] <= exponents[i - 1]) + { + throw new ArgumentException("Polynomial exponents must be montonically increasing", "exponents"); + } + } + + return new GenericPolynomialExtensionField(GF_2, new GF2Polynomial(exponents)); + } + + // public static IPolynomialExtensionField GetTernaryExtensionField(Term[] terms) + // { + // return new GenericPolynomialExtensionField(GF_3, new GF3Polynomial(terms)); + // } + + public static IFiniteField GetPrimeField(BigInteger characteristic) + { + int bitLength = characteristic.BitLength; + if (characteristic.SignValue <= 0 || bitLength < 2) + { + throw new ArgumentException("Must be >= 2", "characteristic"); + } + + if (bitLength < 3) + { + switch (characteristic.IntValue) + { + case 2: + return GF_2; + case 3: + return GF_3; + } + } + + return new PrimeField(characteristic); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs.meta new file mode 100644 index 0000000..7e2141e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/FiniteFields.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 92b0c0982de25d14ab60b59bec46e670 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs new file mode 100644 index 0000000..4baf327 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs @@ -0,0 +1,50 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Field +{ + internal class GF2Polynomial + : IPolynomial + { + protected readonly int[] exponents; + + internal GF2Polynomial(int[] exponents) + { + this.exponents = Arrays.Clone(exponents); + } + + public virtual int Degree + { + get { return exponents[exponents.Length - 1]; } + } + + public virtual int[] GetExponentsPresent() + { + return Arrays.Clone(exponents); + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + GF2Polynomial other = obj as GF2Polynomial; + if (null == other) + { + return false; + } + return Arrays.AreEqual(exponents, other.exponents); + } + + public override int GetHashCode() + { + return Arrays.GetHashCode(exponents); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs.meta new file mode 100644 index 0000000..5f88a32 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GF2Polynomial.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1f60cfed9db54b1439f939b3bb13603f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs new file mode 100644 index 0000000..4342445 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs @@ -0,0 +1,67 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Field +{ + internal class GenericPolynomialExtensionField + : IPolynomialExtensionField + { + protected readonly IFiniteField subfield; + protected readonly IPolynomial minimalPolynomial; + + internal GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial) + { + this.subfield = subfield; + this.minimalPolynomial = polynomial; + } + + public virtual BigInteger Characteristic + { + get { return subfield.Characteristic; } + } + + public virtual int Dimension + { + get { return subfield.Dimension * minimalPolynomial.Degree; } + } + + public virtual IFiniteField Subfield + { + get { return subfield; } + } + + public virtual int Degree + { + get { return minimalPolynomial.Degree; } + } + + public virtual IPolynomial MinimalPolynomial + { + get { return minimalPolynomial; } + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + GenericPolynomialExtensionField other = obj as GenericPolynomialExtensionField; + if (null == other) + { + return false; + } + return subfield.Equals(other.subfield) && minimalPolynomial.Equals(other.minimalPolynomial); + } + + public override int GetHashCode() + { + return subfield.GetHashCode() ^ Integers.RotateLeft(minimalPolynomial.GetHashCode(), 16); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs.meta new file mode 100644 index 0000000..9ded56f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/GenericPolynomialExtensionField.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 707d2ae0e23b0474db27c4d8028a82be +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs new file mode 100644 index 0000000..87a577b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs @@ -0,0 +1,16 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IExtensionField + : IFiniteField + { + IFiniteField Subfield { get; } + + int Degree { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs.meta new file mode 100644 index 0000000..5db7f43 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IExtensionField.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 46600326fc07cab4fb303ad15b653ce8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs new file mode 100644 index 0000000..fed5ccf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs @@ -0,0 +1,15 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IFiniteField + { + BigInteger Characteristic { get; } + + int Dimension { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs.meta new file mode 100644 index 0000000..58120bd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IFiniteField.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b8081bcebd92cff45a40e33456292c5e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs new file mode 100644 index 0000000..982269f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs @@ -0,0 +1,19 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IPolynomial + { + int Degree { get; } + + //BigInteger[] GetCoefficients(); + + int[] GetExponentsPresent(); + + //Term[] GetNonZeroTerms(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs.meta new file mode 100644 index 0000000..9ef7842 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomial.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 877adb45e13476048948e8911ea91d8a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs new file mode 100644 index 0000000..2157e7b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs @@ -0,0 +1,14 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IPolynomialExtensionField + : IExtensionField + { + IPolynomial MinimalPolynomial { get; } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs.meta new file mode 100644 index 0000000..f9d8da6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/IPolynomialExtensionField.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7d3680e5f8fa00c4fb4365940d546aca +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs new file mode 100644 index 0000000..700404b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Field +{ + internal class PrimeField + : IFiniteField + { + protected readonly BigInteger characteristic; + + internal PrimeField(BigInteger characteristic) + { + this.characteristic = characteristic; + } + + public virtual BigInteger Characteristic + { + get { return characteristic; } + } + + public virtual int Dimension + { + get { return 1; } + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + PrimeField other = obj as PrimeField; + if (null == other) + { + return false; + } + return characteristic.Equals(other.characteristic); + } + + public override int GetHashCode() + { + return characteristic.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs.meta new file mode 100644 index 0000000..8a8f5ac --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/field/PrimeField.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7f446b15eeb02a1458d209b9439c3265 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw.meta new file mode 100644 index 0000000..92268d0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fee958d1244f2734fa72979d647c8b50 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs new file mode 100644 index 0000000..dc32fef --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs @@ -0,0 +1,111 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Interleave + { + private const ulong M32 = 0x55555555UL; + private const ulong M64 = 0x5555555555555555UL; + + /* + * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits. + * In a binary field, this operation is the same as squaring an 8 bit number. + */ + //private static readonly ushort[] INTERLEAVE2_TABLE = new ushort[] + //{ + // 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, + // 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, + // 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, + // 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, + // 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, + // 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, + // 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, + // 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, + // 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, + // 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, + // 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, + // 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, + // 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, + // 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, + // 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, + // 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, + // 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, + // 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, + // 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, + // 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, + // 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, + // 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, + // 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, + // 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, + // 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, + // 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, + // 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, + // 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, + // 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, + // 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, + // 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, + // 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 + //}; + + internal static uint Expand8to16(uint x) + { + x &= 0xFFU; + x = (x | (x << 4)) & 0x0F0FU; + x = (x | (x << 2)) & 0x3333U; + x = (x | (x << 1)) & 0x5555U; + return x; + } + + internal static uint Expand16to32(uint x) + { + x &= 0xFFFFU; + x = (x | (x << 8)) & 0x00FF00FFU; + x = (x | (x << 4)) & 0x0F0F0F0FU; + x = (x | (x << 2)) & 0x33333333U; + x = (x | (x << 1)) & 0x55555555U; + return x; + } + + internal static ulong Expand32to64(uint x) + { + // "shuffle" low half to even bits and high half to odd bits + uint t; + t = (x ^ (x >> 8)) & 0x0000FF00U; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 4)) & 0x00F000F0U; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 2)) & 0x0C0C0C0CU; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 1)) & 0x22222222U; x ^= (t ^ (t << 1)); + + return ((x >> 1) & M32) << 32 | (x & M32); + } + + internal static void Expand64To128(ulong x, ulong[] z, int zOff) + { + // "shuffle" low half to even bits and high half to odd bits + ulong t; + t = (x ^ (x >> 16)) & 0x00000000FFFF0000UL; x ^= (t ^ (t << 16)); + t = (x ^ (x >> 8)) & 0x0000FF000000FF00UL; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 4)) & 0x00F000F000F000F0UL; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CUL; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 1)) & 0x2222222222222222UL; x ^= (t ^ (t << 1)); + + z[zOff ] = (x ) & M64; + z[zOff + 1] = (x >> 1) & M64; + } + + internal static ulong Unshuffle(ulong x) + { + // "unshuffle" even bits to low half and odd bits to high half + ulong t; + t = (x ^ (x >> 1)) & 0x2222222222222222UL; x ^= (t ^ (t << 1)); + t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CUL; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 4)) & 0x00F000F000F000F0UL; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 8)) & 0x0000FF000000FF00UL; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 16)) & 0x00000000FFFF0000UL; x ^= (t ^ (t << 16)); + return x; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs.meta new file mode 100644 index 0000000..ee0beea --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Interleave.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b27f92aaead537f4faa3a35281664181 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs new file mode 100644 index 0000000..1953986 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs @@ -0,0 +1,190 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Mod + { + private static readonly SecureRandom RandomSource = new SecureRandom(); + + public static void Invert(uint[] p, uint[] x, uint[] z) + { + int len = p.Length; + if (Nat.IsZero(len, x)) + throw new ArgumentException("cannot be 0", "x"); + if (Nat.IsOne(len, x)) + { + Array.Copy(x, 0, z, 0, len); + return; + } + + uint[] u = Nat.Copy(len, x); + uint[] a = Nat.Create(len); + a[0] = 1; + int ac = 0; + + if ((u[0] & 1) == 0) + { + InversionStep(p, u, len, a, ref ac); + } + if (Nat.IsOne(len, u)) + { + InversionResult(p, ac, a, z); + return; + } + + uint[] v = Nat.Copy(len, p); + uint[] b = Nat.Create(len); + int bc = 0; + + int uvLen = len; + + for (;;) + { + while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0) + { + --uvLen; + } + + if (Nat.Gte(len, u, v)) + { + Nat.SubFrom(len, v, u); + Debug.Assert((u[0] & 1) == 0); + ac += Nat.SubFrom(len, b, a) - bc; + InversionStep(p, u, uvLen, a, ref ac); + if (Nat.IsOne(len, u)) + { + InversionResult(p, ac, a, z); + return; + } + } + else + { + Nat.SubFrom(len, u, v); + Debug.Assert((v[0] & 1) == 0); + bc += Nat.SubFrom(len, a, b) - ac; + InversionStep(p, v, uvLen, b, ref bc); + if (Nat.IsOne(len, v)) + { + InversionResult(p, bc, b, z); + return; + } + } + } + } + + public static uint[] Random(uint[] p) + { + int len = p.Length; + uint[] s = Nat.Create(len); + + uint m = p[len - 1]; + m |= m >> 1; + m |= m >> 2; + m |= m >> 4; + m |= m >> 8; + m |= m >> 16; + + do + { + byte[] bytes = new byte[len << 2]; + RandomSource.NextBytes(bytes); + Pack.BE_To_UInt32(bytes, 0, s); + s[len - 1] &= m; + } + while (Nat.Gte(len, s, p)); + + return s; + } + + public static void Add(uint[] p, uint[] x, uint[] y, uint[] z) + { + int len = p.Length; + uint c = Nat.Add(len, x, y, z); + if (c != 0) + { + Nat.SubFrom(len, p, z); + } + } + + public static void Subtract(uint[] p, uint[] x, uint[] y, uint[] z) + { + int len = p.Length; + int c = Nat.Sub(len, x, y, z); + if (c != 0) + { + Nat.AddTo(len, p, z); + } + } + + private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z) + { + if (ac < 0) + { + Nat.Add(p.Length, a, p, z); + } + else + { + Array.Copy(a, 0, z, 0, p.Length); + } + } + + private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc) + { + int len = p.Length; + int count = 0; + while (u[0] == 0) + { + Nat.ShiftDownWord(uLen, u, 0); + count += 32; + } + + { + int zeroes = GetTrailingZeroes(u[0]); + if (zeroes > 0) + { + Nat.ShiftDownBits(uLen, u, zeroes, 0); + count += zeroes; + } + } + + for (int i = 0; i < count; ++i) + { + if ((x[0] & 1) != 0) + { + if (xc < 0) + { + xc += (int)Nat.AddTo(len, p, x); + } + else + { + xc += Nat.SubFrom(len, p, x); + } + } + + Debug.Assert(xc == 0 || xc == -1); + Nat.ShiftDownBit(len, x, (uint)xc); + } + } + + private static int GetTrailingZeroes(uint x) + { + Debug.Assert(x != 0); + int count = 0; + while ((x & 1) == 0) + { + x >>= 1; + ++count; + } + return count; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs.meta new file mode 100644 index 0000000..ad97470 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Mod.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 100ea3391c7eed94c8c1715df12ca0d9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs new file mode 100644 index 0000000..9fd6f4d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs @@ -0,0 +1,1057 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(int len, uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint Add33At(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zPos + 0] + x; + z[zPos + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zPos + 1] + 1; + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 2); + } + + public static uint Add33At(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zOff + zPos] + x; + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + zPos + 1] + 1; + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2); + } + + public static uint Add33To(int len, uint x, uint[] z) + { + ulong c = (ulong)z[0] + x; + z[0] = (uint)c; + c >>= 32; + c += (ulong)z[1] + 1; + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, 2); + } + + public static uint Add33To(int len, uint x, uint[] z, int zOff) + { + ulong c = (ulong)z[zOff + 0] + x; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + 1] + 1; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, 2); + } + + public static uint AddBothTo(int len, uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + y[i] + z[i]; + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddBothTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[xOff + i] + y[yOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddDWordAt(int len, ulong x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zPos + 0] + (x & M); + z[zPos + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zPos + 1] + (x >> 32); + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 2); + } + + public static uint AddDWordAt(int len, ulong x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zOff + zPos] + (x & M); + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + zPos + 1] + (x >> 32); + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2); + } + + public static uint AddDWordTo(int len, ulong x, uint[] z) + { + ulong c = (ulong)z[0] + (x & M); + z[0] = (uint)c; + c >>= 32; + c += (ulong)z[1] + (x >> 32); + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, 2); + } + + public static uint AddDWordTo(int len, ulong x, uint[] z, int zOff) + { + ulong c = (ulong)z[zOff + 0] + (x & M); + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + 1] + (x >> 32); + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, 2); + } + + public static uint AddTo(int len, uint[] x, uint[] z) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + z[i]; + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[xOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddWordAt(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + ulong c = (ulong)x + z[zPos]; + z[zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 1); + } + + public static uint AddWordAt(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + ulong c = (ulong)x + z[zOff + zPos]; + z[zOff + zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 1); + } + + public static uint AddWordTo(int len, uint x, uint[] z) + { + ulong c = (ulong)x + z[0]; + z[0] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, 1); + } + + public static uint AddWordTo(int len, uint x, uint[] z, int zOff) + { + ulong c = (ulong)x + z[zOff]; + z[zOff] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, 1); + } + + public static void Copy(int len, uint[] x, uint[] z) + { + Array.Copy(x, 0, z, 0, len); + } + + public static uint[] Copy(int len, uint[] x) + { + uint[] z = new uint[len]; + Array.Copy(x, 0, z, 0, len); + return z; + } + + public static uint[] Create(int len) + { + return new uint[len]; + } + + public static ulong[] Create64(int len) + { + return new ulong[len]; + } + + public static int Dec(int len, uint[] z) + { + for (int i = 0; i < len; ++i) + { + if (--z[i] != uint.MaxValue) + { + return 0; + } + } + return -1; + } + + public static int Dec(int len, uint[] x, uint[] z) + { + int i = 0; + while (i < len) + { + uint c = x[i] - 1; + z[i] = c; + ++i; + if (c != uint.MaxValue) + { + while (i < len) + { + z[i] = x[i]; + ++i; + } + return 0; + } + } + return -1; + } + + public static int DecAt(int len, uint[] z, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (--z[i] != uint.MaxValue) + { + return 0; + } + } + return -1; + } + + public static int DecAt(int len, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (--z[zOff + i] != uint.MaxValue) + { + return 0; + } + } + return -1; + } + + public static bool Eq(int len, uint[] x, uint[] y) + { + for (int i = len - 1; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static uint[] FromBigInteger(int bits, BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > bits) + throw new ArgumentException(); + + int len = (bits + 31) >> 5; + uint[] z = Create(len); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (uint)x.IntValue; + x = x.ShiftRight(32); + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= x.Length) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(int len, uint[] x, uint[] y) + { + for (int i = len - 1; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static uint Inc(int len, uint[] z) + { + for (int i = 0; i < len; ++i) + { + if (++z[i] != uint.MinValue) + { + return 0; + } + } + return 1; + } + + public static uint Inc(int len, uint[] x, uint[] z) + { + int i = 0; + while (i < len) + { + uint c = x[i] + 1; + z[i] = c; + ++i; + if (c != 0) + { + while (i < len) + { + z[i] = x[i]; + ++i; + } + return 0; + } + } + return 1; + } + + public static uint IncAt(int len, uint[] z, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (++z[i] != uint.MinValue) + { + return 0; + } + } + return 1; + } + + public static uint IncAt(int len, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (++z[zOff + i] != uint.MinValue) + { + return 0; + } + } + return 1; + } + + public static bool IsOne(int len, uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < len; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero(int len, uint[] x) + { + if (x[0] != 0) + { + return false; + } + for (int i = 1; i < len; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static void Mul(int len, uint[] x, uint[] y, uint[] zz) + { + zz[len] = (uint)MulWord(len, x[0], y, zz); + + for (int i = 1; i < len; ++i) + { + zz[i + len] = (uint)MulWordAddTo(len, x[i], y, 0, zz, i); + } + } + + public static void Mul(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + zz[zzOff + len] = (uint)MulWord(len, x[xOff], y, yOff, zz, zzOff); + + for (int i = 1; i < len; ++i) + { + zz[zzOff + i + len] = (uint)MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i); + } + } + + public static uint Mul31BothAdd(int len, uint a, uint[] x, uint b, uint[] y, uint[] z, int zOff) + { + ulong c = 0, aVal = (ulong)a, bVal = (ulong)b; + int i = 0; + do + { + c += aVal * x[i] + bVal * y[i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWord(int len, uint x, uint[] y, uint[] z) + { + ulong c = 0, xVal = (ulong)x; + int i = 0; + do + { + c += xVal * y[i]; + z[i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWord(int len, uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x; + int i = 0; + do + { + c += xVal * y[yOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWordAddTo(int len, uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x; + int i = 0; + do + { + c += xVal * y[yOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWordDwordAddAt(int len, uint x, ulong y, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 3)); + ulong c = 0, xVal = (ulong)x; + c += xVal * (uint)y + z[zPos + 0]; + z[zPos + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zPos + 1]; + z[zPos + 1] = (uint)c; + c >>= 32; + c += (ulong)z[zPos + 2]; + z[zPos + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 3); + } + + public static uint ShiftDownBit(int len, uint[] z, uint c) + { + int i = len; + while (--i >= 0) + { + uint next = z[i]; + z[i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBit(int len, uint[] z, int zOff, uint c) + { + int i = len; + while (--i >= 0) + { + uint next = z[zOff + i]; + z[zOff + i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBit(int len, uint[] x, uint c, uint[] z) + { + int i = len; + while (--i >= 0) + { + uint next = x[i]; + z[i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) + { + int i = len; + while (--i >= 0) + { + uint next = x[xOff + i]; + z[zOff + i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBits(int len, uint[] z, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = z[i]; + z[i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownBits(int len, uint[] z, int zOff, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = z[zOff + i]; + z[zOff + i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownBits(int len, uint[] x, int bits, uint c, uint[] z) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = x[i]; + z[i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = x[xOff + i]; + z[zOff + i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownWord(int len, uint[] z, uint c) + { + int i = len; + while (--i >= 0) + { + uint next = z[i]; + z[i] = c; + c = next; + } + return c; + } + + public static uint ShiftUpBit(int len, uint[] z, uint c) + { + for (int i = 0; i < len; ++i) + { + uint next = z[i]; + z[i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static uint ShiftUpBit(int len, uint[] z, int zOff, uint c) + { + for (int i = 0; i < len; ++i) + { + uint next = z[zOff + i]; + z[zOff + i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static uint ShiftUpBit(int len, uint[] x, uint c, uint[] z) + { + for (int i = 0; i < len; ++i) + { + uint next = x[i]; + z[i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static uint ShiftUpBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + uint next = x[xOff + i]; + z[zOff + i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static ulong ShiftUpBit64(int len, ulong[] x, int xOff, ulong c, ulong[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + ulong next = x[xOff + i]; + z[zOff + i] = (next << 1) | (c >> 63); + c = next; + } + return c >> 63; + } + + public static uint ShiftUpBits(int len, uint[] z, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = z[i]; + z[i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static uint ShiftUpBits(int len, uint[] z, int zOff, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = z[zOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c) + { + Debug.Assert(bits > 0 && bits < 64); + for (int i = 0; i < len; ++i) + { + ulong next = z[zOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static uint ShiftUpBits(int len, uint[] x, int bits, uint c, uint[] z) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = x[i]; + z[i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static uint ShiftUpBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = x[xOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff) + { + Debug.Assert(bits > 0 && bits < 64); + for (int i = 0; i < len; ++i) + { + ulong next = x[xOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static void Square(int len, uint[] x, uint[] zz) + { + int extLen = len << 1; + uint c = 0; + int j = len, k = extLen; + do + { + ulong xVal = (ulong)x[--j]; + ulong p = xVal * xVal; + zz[--k] = (c << 31) | (uint)(p >> 33); + zz[--k] = (uint)(p >> 1); + c = (uint)p; + } + while (j > 0); + + for (int i = 1; i < len; ++i) + { + c = SquareWordAdd(x, i, zz); + AddWordAt(extLen, c, zz, i << 1); + } + + ShiftUpBit(extLen, zz, x[0] << 31); + } + + public static void Square(int len, uint[] x, int xOff, uint[] zz, int zzOff) + { + int extLen = len << 1; + uint c = 0; + int j = len, k = extLen; + do + { + ulong xVal = (ulong)x[xOff + --j]; + ulong p = xVal * xVal; + zz[zzOff + --k] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --k] = (uint)(p >> 1); + c = (uint)p; + } + while (j > 0); + + for (int i = 1; i < len; ++i) + { + c = SquareWordAdd(x, xOff, i, zz, zzOff); + AddWordAt(extLen, c, zz, zzOff, i << 1); + } + + ShiftUpBit(extLen, zz, zzOff, x[xOff] << 31); + } + + public static uint SquareWordAdd(uint[] x, int xPos, uint[] z) + { + ulong c = 0, xVal = (ulong)x[xPos]; + int i = 0; + do + { + c += xVal * x[i] + z[xPos + i]; + z[xPos + i] = (uint)c; + c >>= 32; + } + while (++i < xPos); + return (uint)c; + } + + public static uint SquareWordAdd(uint[] x, int xOff, int xPos, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x[xOff + xPos]; + int i = 0; + do + { + c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); + z[xPos + zOff] = (uint)c; + c >>= 32; + ++zOff; + } + while (++i < xPos); + return (uint)c; + } + + public static int Sub(int len, uint[] x, uint[] y, uint[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[i] - y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int Sub(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[xOff + i] - y[yOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + public static int Sub33At(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zPos + 0] - x; + z[zPos + 0] = (uint)c; + c >>= 32; + c += (long)z[zPos + 1] - 1; + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zPos + 2); + } + + public static int Sub33At(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zOff + zPos] - x; + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (long)z[zOff + zPos + 1] - 1; + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2); + } + + public static int Sub33From(int len, uint x, uint[] z) + { + long c = (long)z[0] - x; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - 1; + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, 2); + } + + public static int Sub33From(int len, uint x, uint[] z, int zOff) + { + long c = (long)z[zOff + 0] - x; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - 1; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, 2); + } + + public static int SubBothFrom(int len, uint[] x, uint[] y, uint[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[i] - x[i] - y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubBothFrom(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[zOff + i] - x[xOff + i] - y[yOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubDWordAt(int len, ulong x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zPos + 0] - (long)(x & M); + z[zPos + 0] = (uint)c; + c >>= 32; + c += (long)z[zPos + 1] - (long)(x >> 32); + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zPos + 2); + } + + public static int SubDWordAt(int len, ulong x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zOff + zPos] - (long)(x & M); + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (long)z[zOff + zPos + 1] - (long)(x >> 32); + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2); + } + + public static int SubDWordFrom(int len, ulong x, uint[] z) + { + long c = (long)z[0] - (long)(x & M); + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - (long)(x >> 32); + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, 2); + } + + public static int SubDWordFrom(int len, ulong x, uint[] z, int zOff) + { + long c = (long)z[zOff + 0] - (long)(x & M); + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - (long)(x >> 32); + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, 2); + } + + public static int SubFrom(int len, uint[] x, uint[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[i] - x[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubFrom(int len, uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[zOff + i] - x[xOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubWordAt(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + long c = (long)z[zPos] - x; + z[zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zPos + 1); + } + + public static int SubWordAt(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + long c = (long)z[zOff + zPos] - x; + z[zOff + zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 1); + } + + public static int SubWordFrom(int len, uint x, uint[] z) + { + long c = (long)z[0] - x; + z[0] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, 1); + } + + public static int SubWordFrom(int len, uint x, uint[] z, int zOff) + { + long c = (long)z[zOff + 0] - x; + z[zOff + 0] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, 1); + } + + public static BigInteger ToBigInteger(int len, uint[] x) + { + byte[] bs = new byte[len << 2]; + for (int i = 0; i < len; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (len - 1 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(int len, uint[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] = 0; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs.meta new file mode 100644 index 0000000..158d327 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 67f25ce049bdd324f876627a914e4063 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs new file mode 100644 index 0000000..2732994 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs @@ -0,0 +1,860 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat128 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + } + + public static uint[] Create() + { + return new uint[4]; + } + + public static ulong[] Create64() + { + return new ulong[2]; + } + + public static uint[] CreateExt() + { + return new uint[8]; + } + + public static ulong[] CreateExt64() + { + return new ulong[4]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 3; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 1; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static uint[] FromBigInteger(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 128) + throw new ArgumentException(); + + uint[] z = Create(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (uint)x.IntValue; + x = x.ShiftRight(32); + } + return z; + } + + public static ulong[] FromBigInteger64(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 128) + throw new ArgumentException(); + + ulong[] z = Create64(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + if ((bit & 127) != bit) + { + return 0; + } + int w = bit >> 5; + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 3; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 3; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 4; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 2; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 4; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 2; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + zz[4] = (uint)c; + } + + for (int i = 1; i < 4; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + zz[i + 4] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + zz[zzOff + 4] = (uint)c; + } + + for (int i = 1; i < 4; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + zz[zzOff + 4] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + + ulong zc = 0; + for (int i = 0; i < 4; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += zc + zz[i + 4]; + zz[i + 4] = (uint)c; + zc = c >> 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + + ulong zc = 0; + for (int i = 0; i < 4; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += zc + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + zc = c >> 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += x3; + return c; + } + + public static uint MulWordAddExt(uint x, uint[] yy, int yyOff, uint[] zz, int zzOff) + { + Debug.Assert(yyOff <= 4); + Debug.Assert(zzOff <= 4); + + ulong c = 0, xVal = x; + c += xVal * yy[yyOff + 0] + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 1] + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 2] + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 3] + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 0); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 1); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 1); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 3); + } + + public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 2); + + ulong c = 0, xVal = x, yVal = y; + c += yVal * xVal + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 2); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 4); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 3, j = 8; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5]; + ulong zz_6 = zz[6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_6 += zz_5 >> 32; + } + + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + w = zz[7] + (uint)(zz_6 >> 32); + zz[7] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 3, j = 8; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5]; + ulong zz_6 = zz[zzOff + 6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_6 += zz_5 >> 32; + } + + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 7] + (uint)(zz_6 >> 32); + zz[zzOff + 7] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[16]; + for (int i = 0; i < 4; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (3 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[16]; + for (int i = 0; i < 2; ++i) + { + ulong x_i = x[i]; + if (x_i != 0UL) + { + Pack.UInt64_To_BE(x_i, bs, (1 - i) << 3); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs.meta new file mode 100644 index 0000000..33dc022 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat128.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 139465f650dc3ff47be85e4d1be06c78 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs new file mode 100644 index 0000000..2966e02 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs @@ -0,0 +1,878 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat160 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + } + + public static uint[] Create() + { + return new uint[5]; + } + + public static uint[] CreateExt() + { + return new uint[10]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 4; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static uint[] FromBigInteger(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 160) + throw new ArgumentException(); + + uint[] z = Create(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (uint)x.IntValue; + x = x.ShiftRight(32); + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= 5) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 4; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 4; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 5; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 5; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + zz[5] = (uint)c; + } + + for (int i = 1; i < 5; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + zz[i + 5] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + zz[zzOff + 5] = (uint)c; + } + + for (int i = 1; i < 5; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + zz[zzOff + 5] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + + ulong zc = 0; + for (int i = 0; i < 5; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += zc + zz[i + 5]; + zz[i + 5] = (uint)c; + zc = c >> 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + + ulong zc = 0; + for (int i = 0; i < 5; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += zc + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + zc = c >> 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += x4; + return c; + } + + public static uint MulWordAddExt(uint x, uint[] yy, int yyOff, uint[] zz, int zzOff) + { + Debug.Assert(yyOff <= 5); + Debug.Assert(zzOff <= 5); + + ulong c = 0, xVal = x; + c += xVal * yy[yyOff + 0] + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 1] + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 2] + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 3] + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 4] + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 1); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 2); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 2); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 3); + } + + public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 3); + + ulong c = 0, xVal = x, yVal = y; + c += yVal * xVal + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 2); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 5); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 4, j = 10; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5]; + ulong zz_6 = zz[6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7]; + ulong zz_8 = zz[8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_8 += zz_7 >> 32; + } + + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = zz[9] + (uint)(zz_8 >> 32); + zz[9] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 4, j = 10; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5]; + ulong zz_6 = zz[zzOff + 6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7]; + ulong zz_8 = zz[zzOff + 8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_8 += zz_7 >> 32; + } + + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 9] + (uint)(zz_8 >> 32); + zz[zzOff + 9] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[20]; + for (int i = 0; i < 5; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (4 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs.meta new file mode 100644 index 0000000..270b4b7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat160.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5863c232c0b5d464485955e74011d938 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs new file mode 100644 index 0000000..64b6fbd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs @@ -0,0 +1,1052 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat192 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 5] + v[vOff + 5]; + u[uOff + 5] = (uint)c; + v[vOff + 5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + } + + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + } + + public static uint[] Create() + { + return new uint[6]; + } + + public static ulong[] Create64() + { + return new ulong[3]; + } + + public static uint[] CreateExt() + { + return new uint[12]; + } + + public static ulong[] CreateExt64() + { + return new ulong[6]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 5; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 2; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static uint[] FromBigInteger(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 192) + throw new ArgumentException(); + + uint[] z = Create(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (uint)x.IntValue; + x = x.ShiftRight(32); + } + return z; + } + + public static ulong[] FromBigInteger64(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 192) + throw new ArgumentException(); + + ulong[] z = Create64(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= 6) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 5; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 5; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 6; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 3; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 6; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 3; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[5] = (uint)c; + c >>= 32; + zz[6] = (uint)c; + } + + for (int i = 1; i < 6; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + zz[i + 6] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[zzOff + 5] = (uint)c; + c >>= 32; + zz[zzOff + 6] = (uint)c; + } + + for (int i = 1; i < 6; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + zz[zzOff + 6] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + + ulong zc = 0; + for (int i = 0; i < 6; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += zc + zz[i + 6]; + zz[i + 6] = (uint)c; + zc = c >> 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + + ulong zc = 0; + for (int i = 0; i < 6; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += zc + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + zc = c >> 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + ulong x5 = x[xOff + 5]; + c += wVal * x5 + x4 + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += x5; + return c; + } + + public static uint MulWordAddExt(uint x, uint[] yy, int yyOff, uint[] zz, int zzOff) + { + Debug.Assert(yyOff <= 6); + Debug.Assert(zzOff <= 6); + ulong c = 0, xVal = x; + c += xVal * yy[yyOff + 0] + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 1] + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 2] + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 3] + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 4] + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 5] + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 2); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <=3); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 3); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 3); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 6); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 5, j = 12; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5]; + ulong zz_6 = zz[6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7]; + ulong zz_8 = zz[8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[5]; + ulong zz_9 = zz[9]; + ulong zz_10 = zz[10]; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_10 += zz_9 >> 32; + } + + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[10] = (w << 1) | c; + c = w >> 31; + w = zz[11] + (uint)(zz_10 >> 32); + zz[11] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 5, j = 12; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5]; + ulong zz_6 = zz[zzOff + 6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7]; + ulong zz_8 = zz[zzOff + 8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[xOff + 5]; + ulong zz_9 = zz[zzOff + 9]; + ulong zz_10 = zz[zzOff + 10]; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_10 += zz_9 >> 32; + } + + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[zzOff + 9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[zzOff + 10] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 11] + (uint)(zz_10 >> 32); + zz[zzOff + 11] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)x[xOff + 5] - y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5]; + z[5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)z[zOff + 5] - x[xOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[24]; + for (int i = 0; i < 6; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (5 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[24]; + for (int i = 0; i < 3; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (2 - i) << 3); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + z[5] = 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs.meta new file mode 100644 index 0000000..2bc9614 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat192.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5068ae0f638a4594eb28d3804c58cb91 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs new file mode 100644 index 0000000..fd2b2a1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs @@ -0,0 +1,1180 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat224 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 5] + v[vOff + 5]; + u[uOff + 5] = (uint)c; + v[vOff + 5] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 6] + v[vOff + 6]; + u[uOff + 6] = (uint)c; + v[vOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + } + + public static uint[] Create() + { + return new uint[7]; + } + + public static uint[] CreateExt() + { + return new uint[14]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 6; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static uint[] FromBigInteger(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 224) + throw new ArgumentException(); + + uint[] z = Create(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (uint)x.IntValue; + x = x.ShiftRight(32); + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= 7) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 6; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 6; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 7; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 7; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[6] = (uint)c; + c >>= 32; + zz[7] = (uint)c; + } + + for (int i = 1; i < 7; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + zz[i + 7] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[zzOff + 6] = (uint)c; + c >>= 32; + zz[zzOff + 7] = (uint)c; + } + + for (int i = 1; i < 7; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + zz[zzOff + 7] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + + ulong zc = 0; + for (int i = 0; i < 7; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + c += zc + zz[i + 7]; + zz[i + 7] = (uint)c; + zc = c >> 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + + ulong zc = 0; + for (int i = 0; i < 7; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += zc + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)c; + zc = c >> 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + ulong x5 = x[xOff + 5]; + c += wVal * x5 + x4 + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + ulong x6 = x[xOff + 6]; + c += wVal * x6 + x5 + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += x6; + return c; + } + + public static uint MulByWord(uint x, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulByWordAddTo(uint x, uint[] y, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulWordAddTo(uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + c += xVal * y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 3); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 4); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 4); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 3); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 7); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 6, j = 14; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5]; + ulong zz_6 = zz[6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7]; + ulong zz_8 = zz[8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[5]; + ulong zz_9 = zz[9]; + ulong zz_10 = zz[10]; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[6]; + ulong zz_11 = zz[11]; + ulong zz_12 = zz[12]; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_12 += zz_11 >> 32; + } + + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[12] = (w << 1) | c; + c = w >> 31; + w = zz[13] + (uint)(zz_12 >> 32); + zz[13] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 6, j = 14; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5]; + ulong zz_6 = zz[zzOff + 6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7]; + ulong zz_8 = zz[zzOff + 8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[xOff + 5]; + ulong zz_9 = zz[zzOff + 9]; + ulong zz_10 = zz[zzOff + 10]; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[xOff + 6]; + ulong zz_11 = zz[zzOff + 11]; + ulong zz_12 = zz[zzOff + 12]; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_12 += zz_11 >> 32; + } + + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[zzOff + 9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[zzOff + 10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[zzOff + 11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[zzOff + 12] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 13] + (uint)(zz_12 >> 32); + zz[zzOff + 13] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)x[xOff + 5] - y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)x[xOff + 6] - y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6]; + z[6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)z[zOff + 5] - x[xOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)z[zOff + 6] - x[xOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[28]; + for (int i = 0; i < 7; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (6 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + z[5] = 0; + z[6] = 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs.meta new file mode 100644 index 0000000..0e37c8e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat224.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c67e923674f4df84f992e06eecec940e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs new file mode 100644 index 0000000..17a0b49 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs @@ -0,0 +1,1391 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat256 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + c += (ulong)x[7] + y[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 7] + y[yOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + c += (ulong)x[7] + y[7] + z[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 7] + y[yOff + 7] + z[zOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + c += (ulong)x[7] + z[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 7] + z[zOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 5] + v[vOff + 5]; + u[uOff + 5] = (uint)c; + v[vOff + 5] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 6] + v[vOff + 6]; + u[uOff + 6] = (uint)c; + v[vOff + 6] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 7] + v[vOff + 7]; + u[uOff + 7] = (uint)c; + v[vOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + z[7] = x[7]; + } + + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static uint[] Create() + { + return new uint[8]; + } + + public static ulong[] Create64() + { + return new ulong[4]; + } + + public static uint[] CreateExt() + { + return new uint[16]; + } + + public static ulong[] CreateExt64() + { + return new ulong[8]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 7; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 3; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static uint[] FromBigInteger(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 256) + throw new ArgumentException(); + + uint[] z = Create(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (uint)x.IntValue; + x = x.ShiftRight(32); + } + return z; + } + + public static ulong[] FromBigInteger64(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 256) + throw new ArgumentException(); + + ulong[] z = Create64(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + if ((bit & 255) != bit) + { + return 0; + } + int w = bit >> 5; + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 7; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 7; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 8; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 4; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 8; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 4; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + ulong y_7 = y[7]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[6] = (uint)c; + c >>= 32; + c += x_0 * y_7; + zz[7] = (uint)c; + c >>= 32; + zz[8] = (uint)c; + } + + for (int i = 1; i < 8; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[i + 7]; + zz[i + 7] = (uint)c; + c >>= 32; + zz[i + 8] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + ulong y_7 = y[yOff + 7]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += x_0 * y_7; + zz[zzOff + 7] = (uint)c; + c >>= 32; + zz[zzOff + 8] = (uint)c; + } + + for (int i = 1; i < 8; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)c; + c >>= 32; + zz[zzOff + 8] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + ulong y_7 = y[7]; + + ulong zc = 0; + for (int i = 0; i < 8; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[i + 7]; + zz[i + 7] = (uint)c; + c >>= 32; + c += zc + zz[i + 8]; + zz[i + 8] = (uint)c; + zc = c >> 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + ulong y_7 = y[yOff + 7]; + + ulong zc = 0; + for (int i = 0; i < 8; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)c; + c >>= 32; + c += zc + zz[zzOff + 8]; + zz[zzOff + 8] = (uint)c; + zc = c >> 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + ulong x5 = x[xOff + 5]; + c += wVal * x5 + x4 + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + ulong x6 = x[xOff + 6]; + c += wVal * x6 + x5 + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + ulong x7 = x[xOff + 7]; + c += wVal * x7 + x6 + y[yOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + c += x7; + return c; + } + + public static uint MulByWord(uint x, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6]; + z[6] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulByWordAddTo(uint x, uint[] y, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[7] + y[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulWordAddTo(uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + c += xVal * y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 7] + z[zOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 4); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 5); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 5); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 8); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 7, j = 16; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5]; + ulong zz_6 = zz[6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7]; + ulong zz_8 = zz[8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[5]; + ulong zz_9 = zz[9]; + ulong zz_10 = zz[10]; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[6]; + ulong zz_11 = zz[11]; + ulong zz_12 = zz[12]; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_8 &= M; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_9 &= M; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_10 &= M; + zz_12 += zz_11 >> 32; + zz_11 &= M; + } + + ulong x_7 = x[7]; + ulong zz_13 = zz[13]; + ulong zz_14 = zz[14]; + { + zz_7 += x_7 * x_0; + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + zz_8 += (zz_7 >> 32) + x_7 * x_1; + zz_9 += (zz_8 >> 32) + x_7 * x_2; + zz_10 += (zz_9 >> 32) + x_7 * x_3; + zz_11 += (zz_10 >> 32) + x_7 * x_4; + zz_12 += (zz_11 >> 32) + x_7 * x_5; + zz_13 += (zz_12 >> 32) + x_7 * x_6; + zz_14 += zz_13 >> 32; + } + + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[12] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_13; + zz[13] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_14; + zz[14] = (w << 1) | c; + c = w >> 31; + w = zz[15] + (uint)(zz_14 >> 32); + zz[15] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 7, j = 16; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5]; + ulong zz_6 = zz[zzOff + 6]; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7]; + ulong zz_8 = zz[zzOff + 8]; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[xOff + 5]; + ulong zz_9 = zz[zzOff + 9]; + ulong zz_10 = zz[zzOff + 10]; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[xOff + 6]; + ulong zz_11 = zz[zzOff + 11]; + ulong zz_12 = zz[zzOff + 12]; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_8 &= M; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_9 &= M; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_10 &= M; + zz_12 += zz_11 >> 32; + zz_11 &= M; + } + + ulong x_7 = x[xOff + 7]; + ulong zz_13 = zz[zzOff + 13]; + ulong zz_14 = zz[zzOff + 14]; + { + zz_7 += x_7 * x_0; + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + zz_8 += (zz_7 >> 32) + x_7 * x_1; + zz_9 += (zz_8 >> 32) + x_7 * x_2; + zz_10 += (zz_9 >> 32) + x_7 * x_3; + zz_11 += (zz_10 >> 32) + x_7 * x_4; + zz_12 += (zz_11 >> 32) + x_7 * x_5; + zz_13 += (zz_12 >> 32) + x_7 * x_6; + zz_14 += zz_13 >> 32; + } + + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[zzOff + 9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[zzOff + 10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[zzOff + 11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[zzOff + 12] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_13; + zz[zzOff + 13] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_14; + zz[zzOff + 14] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 15] + (uint)(zz_14 >> 32); + zz[zzOff + 15] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + c += (long)x[7] - y[7]; + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)x[xOff + 5] - y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)x[xOff + 6] - y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (long)x[xOff + 7] - y[yOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] - x[7] - y[7]; + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6]; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] - x[7]; + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)z[zOff + 5] - x[xOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)z[zOff + 6] - x[xOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (long)z[zOff + 7] - x[xOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[32]; + for (int i = 0; i < 8; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (7 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[32]; + for (int i = 0; i < 4; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (3 - i) << 3); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + z[5] = 0; + z[6] = 0; + z[7] = 0; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs.meta new file mode 100644 index 0000000..4561392 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat256.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1d5edac25abdc924b9ca63eb7dd99f1a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs new file mode 100644 index 0000000..c971380 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs @@ -0,0 +1,102 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat320 + { + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + } + + public static ulong[] Create64() + { + return new ulong[5]; + } + + public static ulong[] CreateExt64() + { + return new ulong[10]; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 4; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static ulong[] FromBigInteger64(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 320) + throw new ArgumentException(); + + ulong[] z = Create64(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 5; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 5; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[40]; + for (int i = 0; i < 5; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (4 - i) << 3); + } + } + return new BigInteger(1, bs); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs.meta new file mode 100644 index 0000000..9ad89ca --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat320.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c94e76ab2033ce647ac530c37169bad0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs new file mode 100644 index 0000000..80035f2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs @@ -0,0 +1,50 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat384 + { + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + Nat192.Mul(x, y, zz); + Nat192.Mul(x, 6, y, 6, zz, 12); + + uint c18 = Nat192.AddToEachOther(zz, 6, zz, 12); + uint c12 = c18 + Nat192.AddTo(zz, 0, zz, 6, 0); + c18 += Nat192.AddTo(zz, 18, zz, 12, c12); + + uint[] dx = Nat192.Create(), dy = Nat192.Create(); + bool neg = Nat192.Diff(x, 6, x, 0, dx, 0) != Nat192.Diff(y, 6, y, 0, dy, 0); + + uint[] tt = Nat192.CreateExt(); + Nat192.Mul(dx, dy, tt); + + c18 += neg ? Nat.AddTo(12, tt, 0, zz, 6) : (uint)Nat.SubFrom(12, tt, 0, zz, 6); + Nat.AddWordAt(24, c18, zz, 18); + } + + public static void Square(uint[] x, uint[] zz) + { + Nat192.Square(x, zz); + Nat192.Square(x, 6, zz, 12); + + uint c18 = Nat192.AddToEachOther(zz, 6, zz, 12); + uint c12 = c18 + Nat192.AddTo(zz, 0, zz, 6, 0); + c18 += Nat192.AddTo(zz, 18, zz, 12, c12); + + uint[] dx = Nat192.Create(); + Nat192.Diff(x, 6, x, 0, dx, 0); + + uint[] m = Nat192.CreateExt(); + Nat192.Square(dx, m); + + c18 += (uint)Nat.SubFrom(12, m, 0, zz, 6); + Nat.AddWordAt(24, c18, zz, 18); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs.meta new file mode 100644 index 0000000..dd64b82 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat384.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b8f208f66da7aca4cb1f81fb6372a923 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs new file mode 100644 index 0000000..46f294e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs @@ -0,0 +1,104 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat448 + { + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + } + + public static ulong[] Create64() + { + return new ulong[7]; + } + + public static ulong[] CreateExt64() + { + return new ulong[14]; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 6; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static ulong[] FromBigInteger64(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 448) + throw new ArgumentException(); + + ulong[] z = Create64(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 7; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 7; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[56]; + for (int i = 0; i < 7; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (6 - i) << 3); + } + } + return new BigInteger(1, bs); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs.meta new file mode 100644 index 0000000..a71e5fc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat448.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 231f62a2e5d95c64fb1438455bacbe41 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs new file mode 100644 index 0000000..db9c398 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs @@ -0,0 +1,50 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat512 + { + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + Nat256.Mul(x, y, zz); + Nat256.Mul(x, 8, y, 8, zz, 16); + + uint c24 = Nat256.AddToEachOther(zz, 8, zz, 16); + uint c16 = c24 + Nat256.AddTo(zz, 0, zz, 8, 0); + c24 += Nat256.AddTo(zz, 24, zz, 16, c16); + + uint[] dx = Nat256.Create(), dy = Nat256.Create(); + bool neg = Nat256.Diff(x, 8, x, 0, dx, 0) != Nat256.Diff(y, 8, y, 0, dy, 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(dx, dy, tt); + + c24 += neg ? Nat.AddTo(16, tt, 0, zz, 8) : (uint)Nat.SubFrom(16, tt, 0, zz, 8); + Nat.AddWordAt(32, c24, zz, 24); + } + + public static void Square(uint[] x, uint[] zz) + { + Nat256.Square(x, zz); + Nat256.Square(x, 8, zz, 16); + + uint c24 = Nat256.AddToEachOther(zz, 8, zz, 16); + uint c16 = c24 + Nat256.AddTo(zz, 0, zz, 8, 0); + c24 += Nat256.AddTo(zz, 24, zz, 16, c16); + + uint[] dx = Nat256.Create(); + Nat256.Diff(x, 8, x, 0, dx, 0); + + uint[] m = Nat256.CreateExt(); + Nat256.Square(dx, m); + + c24 += (uint)Nat.SubFrom(16, m, 0, zz, 8); + Nat.AddWordAt(32, c24, zz, 24); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs.meta new file mode 100644 index 0000000..59b4651 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat512.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cd7393016f16a6e429e8e32080996fb4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs new file mode 100644 index 0000000..a1b2439 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs @@ -0,0 +1,106 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat576 + { + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + z[7] = x[7]; + z[8] = x[8]; + } + + public static ulong[] Create64() + { + return new ulong[9]; + } + + public static ulong[] CreateExt64() + { + return new ulong[18]; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 8; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static ulong[] FromBigInteger64(BigInteger x) + { + if (x.SignValue < 0 || x.BitLength > 576) + throw new ArgumentException(); + + ulong[] z = Create64(); + int i = 0; + while (x.SignValue != 0) + { + z[i++] = (ulong)x.LongValue; + x = x.ShiftRight(64); + } + return z; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 9; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 9; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[72]; + for (int i = 0; i < 9; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (8 - i) << 3); + } + } + return new BigInteger(1, bs); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs.meta new file mode 100644 index 0000000..46827c6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/math/raw/Nat576.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ac3cde8a54f23264c80a50850766fe5a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security.meta new file mode 100644 index 0000000..959f274 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2c421ef18ca1f844c8134a15061c4605 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs new file mode 100644 index 0000000..3606134 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs @@ -0,0 +1,226 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Utility class for creating IDigest objects from their names/Oids + /// + public sealed class DigestUtilities + { + private enum DigestAlgorithm { + GOST3411, + KECCAK_224, KECCAK_256, KECCAK_288, KECCAK_384, KECCAK_512, + MD2, MD4, MD5, + RIPEMD128, RIPEMD160, RIPEMD256, RIPEMD320, + SHA_1, SHA_224, SHA_256, SHA_384, SHA_512, + SHA_512_224, SHA_512_256, + SHA3_224, SHA3_256, SHA3_384, SHA3_512, + SHAKE128, SHAKE256, + TIGER, + WHIRLPOOL, + }; + + private DigestUtilities() + { + } + + private static readonly IDictionary algorithms = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + private static readonly IDictionary oids = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + static DigestUtilities() + { + // Signal to obfuscation tools not to change enum constants + ((DigestAlgorithm)Enums.GetArbitraryValue(typeof(DigestAlgorithm))).ToString(); + + algorithms[PkcsObjectIdentifiers.MD2.Id] = "MD2"; + algorithms[PkcsObjectIdentifiers.MD4.Id] = "MD4"; + algorithms[PkcsObjectIdentifiers.MD5.Id] = "MD5"; + + algorithms["SHA1"] = "SHA-1"; + algorithms[OiwObjectIdentifiers.IdSha1.Id] = "SHA-1"; + algorithms["SHA224"] = "SHA-224"; + algorithms[NistObjectIdentifiers.IdSha224.Id] = "SHA-224"; + algorithms["SHA256"] = "SHA-256"; + algorithms[NistObjectIdentifiers.IdSha256.Id] = "SHA-256"; + algorithms["SHA384"] = "SHA-384"; + algorithms[NistObjectIdentifiers.IdSha384.Id] = "SHA-384"; + algorithms["SHA512"] = "SHA-512"; + algorithms[NistObjectIdentifiers.IdSha512.Id] = "SHA-512"; + algorithms["SHA512/224"] = "SHA-512/224"; + algorithms[NistObjectIdentifiers.IdSha512_224.Id] = "SHA-512/224"; + algorithms["SHA512/256"] = "SHA-512/256"; + algorithms[NistObjectIdentifiers.IdSha512_256.Id] = "SHA-512/256"; + + algorithms["RIPEMD-128"] = "RIPEMD128"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "RIPEMD128"; + algorithms["RIPEMD-160"] = "RIPEMD160"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "RIPEMD160"; + algorithms["RIPEMD-256"] = "RIPEMD256"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "RIPEMD256"; + algorithms["RIPEMD-320"] = "RIPEMD320"; +// algorithms[TeleTrusTObjectIdentifiers.RipeMD320.Id] = "RIPEMD320"; + + algorithms[CryptoProObjectIdentifiers.GostR3411.Id] = "GOST3411"; + + algorithms[NistObjectIdentifiers.IdSha3_224.Id] = "SHA3-224"; + algorithms[NistObjectIdentifiers.IdSha3_256.Id] = "SHA3-256"; + algorithms[NistObjectIdentifiers.IdSha3_384.Id] = "SHA3-384"; + algorithms[NistObjectIdentifiers.IdSha3_512.Id] = "SHA3-512"; + algorithms[NistObjectIdentifiers.IdShake128.Id] = "SHAKE128"; + algorithms[NistObjectIdentifiers.IdShake256.Id] = "SHAKE256"; + + oids["MD2"] = PkcsObjectIdentifiers.MD2; + oids["MD4"] = PkcsObjectIdentifiers.MD4; + oids["MD5"] = PkcsObjectIdentifiers.MD5; + oids["SHA-1"] = OiwObjectIdentifiers.IdSha1; + oids["SHA-224"] = NistObjectIdentifiers.IdSha224; + oids["SHA-256"] = NistObjectIdentifiers.IdSha256; + oids["SHA-384"] = NistObjectIdentifiers.IdSha384; + oids["SHA-512"] = NistObjectIdentifiers.IdSha512; + oids["SHA-512/224"] = NistObjectIdentifiers.IdSha512_224; + oids["SHA-512/256"] = NistObjectIdentifiers.IdSha512_256; + oids["SHA3-224"] = NistObjectIdentifiers.IdSha3_224; + oids["SHA3-256"] = NistObjectIdentifiers.IdSha3_256; + oids["SHA3-384"] = NistObjectIdentifiers.IdSha3_384; + oids["SHA3-512"] = NistObjectIdentifiers.IdSha3_512; + oids["SHAKE128"] = NistObjectIdentifiers.IdShake128; + oids["SHAKE256"] = NistObjectIdentifiers.IdShake256; + oids["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128; + oids["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160; + oids["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256; + oids["GOST3411"] = CryptoProObjectIdentifiers.GostR3411; + } + + /// + /// Returns a ObjectIdentifier for a given digest mechanism. + /// + /// A string representation of the digest meanism. + /// A DerObjectIdentifier, null if the Oid is not available. + + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + if (mechanism == null) + throw new System.ArgumentNullException("mechanism"); + + mechanism = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(mechanism); + string aliased = (string) algorithms[mechanism]; + + if (aliased != null) + mechanism = aliased; + + return (DerObjectIdentifier) oids[mechanism]; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static IDigest GetDigest( + DerObjectIdentifier id) + { + return GetDigest(id.Id); + } + + public static IDigest GetDigest( + string algorithm) + { + string upper = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); + string mechanism = (string) algorithms[upper]; + + if (mechanism == null) + { + mechanism = upper; + } + + try + { + DigestAlgorithm digestAlgorithm = (DigestAlgorithm)Enums.GetEnumValue( + typeof(DigestAlgorithm), mechanism); + + switch (digestAlgorithm) + { + case DigestAlgorithm.GOST3411: return new Gost3411Digest(); + case DigestAlgorithm.KECCAK_224: return new KeccakDigest(224); + case DigestAlgorithm.KECCAK_256: return new KeccakDigest(256); + case DigestAlgorithm.KECCAK_288: return new KeccakDigest(288); + case DigestAlgorithm.KECCAK_384: return new KeccakDigest(384); + case DigestAlgorithm.KECCAK_512: return new KeccakDigest(512); + case DigestAlgorithm.MD2: return new MD2Digest(); + case DigestAlgorithm.MD4: return new MD4Digest(); + case DigestAlgorithm.MD5: return new MD5Digest(); + case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest(); + case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest(); + case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest(); + case DigestAlgorithm.RIPEMD320: return new RipeMD320Digest(); + case DigestAlgorithm.SHA_1: return new Sha1Digest(); + case DigestAlgorithm.SHA_224: return new Sha224Digest(); + case DigestAlgorithm.SHA_256: return new Sha256Digest(); + case DigestAlgorithm.SHA_384: return new Sha384Digest(); + case DigestAlgorithm.SHA_512: return new Sha512Digest(); + case DigestAlgorithm.SHA_512_224: return new Sha512tDigest(224); + case DigestAlgorithm.SHA_512_256: return new Sha512tDigest(256); + case DigestAlgorithm.SHA3_224: return new Sha3Digest(224); + case DigestAlgorithm.SHA3_256: return new Sha3Digest(256); + case DigestAlgorithm.SHA3_384: return new Sha3Digest(384); + case DigestAlgorithm.SHA3_512: return new Sha3Digest(512); + case DigestAlgorithm.SHAKE128: return new ShakeDigest(128); + case DigestAlgorithm.SHAKE256: return new ShakeDigest(256); + case DigestAlgorithm.TIGER: return new TigerDigest(); + case DigestAlgorithm.WHIRLPOOL: return new WhirlpoolDigest(); + } + } + catch (ArgumentException) + { + } + + throw new SecurityUtilityException("Digest " + mechanism + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + public static byte[] CalculateDigest(string algorithm, byte[] input) + { + IDigest digest = GetDigest(algorithm); + digest.BlockUpdate(input, 0, input.Length); + return DoFinal(digest); + } + + public static byte[] DoFinal( + IDigest digest) + { + byte[] b = new byte[digest.GetDigestSize()]; + digest.DoFinal(b, 0); + return b; + } + + public static byte[] DoFinal( + IDigest digest, + byte[] input) + { + digest.BlockUpdate(input, 0, input.Length); + return DoFinal(digest); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs.meta new file mode 100644 index 0000000..7ec0347 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/DigestUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e02cda66c755ac94ea2ee882e29a2dfe +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs new file mode 100644 index 0000000..c3e8077 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class GeneralSecurityException + : Exception + { + public GeneralSecurityException() + : base() + { + } + + public GeneralSecurityException( + string message) + : base(message) + { + } + + public GeneralSecurityException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs.meta new file mode 100644 index 0000000..b559e47 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/GeneralSecurityException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b0d8c41189aa7a947b6acbdfbd4f0401 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs new file mode 100644 index 0000000..cffce46 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class InvalidKeyException : KeyException + { + public InvalidKeyException() : base() { } + public InvalidKeyException(string message) : base(message) { } + public InvalidKeyException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs.meta new file mode 100644 index 0000000..0d67d53 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidKeyException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9842e68a8ae8895468c08cc98231c060 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs new file mode 100644 index 0000000..47f9110 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class InvalidParameterException : KeyException + { + public InvalidParameterException() : base() { } + public InvalidParameterException(string message) : base(message) { } + public InvalidParameterException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs.meta new file mode 100644 index 0000000..10b16b4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/InvalidParameterException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a02c4f553fcf8d749801284afc4da77a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs new file mode 100644 index 0000000..3053fcb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class KeyException : GeneralSecurityException + { + public KeyException() : base() { } + public KeyException(string message) : base(message) { } + public KeyException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs.meta new file mode 100644 index 0000000..c2e1595 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/KeyException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 981c3b6a3e40ccc479b9b7c4a5e4568e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs new file mode 100644 index 0000000..0b73cb7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs @@ -0,0 +1,260 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Iana; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Utility class for creating HMac object from their names/Oids + /// + public sealed class MacUtilities + { + private MacUtilities() + { + } + + private static readonly IDictionary algorithms = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + //private static readonly IDictionary oids = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + static MacUtilities() + { + algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5"; + algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160"; + algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1"; + algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER"; + + algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512"; + + // TODO AESMAC? + + algorithms["DES"] = "DESMAC"; + algorithms["DES/CFB8"] = "DESMAC/CFB8"; + algorithms["DES64"] = "DESMAC64"; + algorithms["DESEDE"] = "DESEDEMAC"; + algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC"; + algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8"; + algorithms["DESISO9797MAC"] = "DESWITHISO9797"; + algorithms["DESEDE64"] = "DESEDEMAC64"; + + algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + + algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC"; + algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING"; + + algorithms["SKIPJACK"] = "SKIPJACKMAC"; + algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8"; + algorithms["IDEA"] = "IDEAMAC"; + algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8"; + algorithms["RC2"] = "RC2MAC"; + algorithms["RC2/CFB8"] = "RC2MAC/CFB8"; + algorithms["RC5"] = "RC5MAC"; + algorithms["RC5/CFB8"] = "RC5MAC/CFB8"; + algorithms["GOST28147"] = "GOST28147MAC"; + algorithms["VMPC"] = "VMPCMAC"; + algorithms["VMPC-MAC"] = "VMPCMAC"; + algorithms["SIPHASH"] = "SIPHASH-2-4"; + + algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1"; + algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1"; + } + +// /// +// /// Returns a ObjectIdentifier for a given digest mechanism. +// /// +// /// A string representation of the digest meanism. +// /// A DerObjectIdentifier, null if the Oid is not available. +// public static DerObjectIdentifier GetObjectIdentifier( +// string mechanism) +// { +// mechanism = (string) algorithms[Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(mechanism)]; +// +// if (mechanism != null) +// { +// return (DerObjectIdentifier)oids[mechanism]; +// } +// +// return null; +// } + +// public static ICollection Algorithms +// { +// get { return oids.Keys; } +// } + + public static IMac GetMac( + DerObjectIdentifier id) + { + return GetMac(id.Id); + } + + public static IMac GetMac( + string algorithm) + { + string upper = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); + + string mechanism = (string) algorithms[upper]; + + if (mechanism == null) + { + mechanism = upper; + } + + if (Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "PBEWITH")) + { + mechanism = mechanism.Substring("PBEWITH".Length); + } + + if (Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC")) + { + string digestName; + if (Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC-") || Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC/")) + { + digestName = mechanism.Substring(5); + } + else + { + digestName = mechanism.Substring(4); + } + + return new HMac(DigestUtilities.GetDigest(digestName)); + } + + if (mechanism == "AESCMAC") + { + return new CMac(new AesFastEngine()); + } + if (mechanism == "DESMAC") + { + return new CbcBlockCipherMac(new DesEngine()); + } + if (mechanism == "DESMAC/CFB8") + { + return new CfbBlockCipherMac(new DesEngine()); + } + if (mechanism == "DESMAC64") + { + return new CbcBlockCipherMac(new DesEngine(), 64); + } + if (mechanism == "DESEDECMAC") + { + return new CMac(new DesEdeEngine()); + } + if (mechanism == "DESEDEMAC") + { + return new CbcBlockCipherMac(new DesEdeEngine()); + } + if (mechanism == "DESEDEMAC/CFB8") + { + return new CfbBlockCipherMac(new DesEdeEngine()); + } + if (mechanism == "DESEDEMAC64") + { + return new CbcBlockCipherMac(new DesEdeEngine(), 64); + } + if (mechanism == "DESEDEMAC64WITHISO7816-4PADDING") + { + return new CbcBlockCipherMac(new DesEdeEngine(), 64, new ISO7816d4Padding()); + } + if (mechanism == "DESWITHISO9797" + || mechanism == "ISO9797ALG3MAC") + { + return new ISO9797Alg3Mac(new DesEngine()); + } + if (mechanism == "ISO9797ALG3WITHISO7816-4PADDING") + { + return new ISO9797Alg3Mac(new DesEngine(), new ISO7816d4Padding()); + } + if (mechanism == "SKIPJACKMAC") + { + return new CbcBlockCipherMac(new SkipjackEngine()); + } + if (mechanism == "SKIPJACKMAC/CFB8") + { + return new CfbBlockCipherMac(new SkipjackEngine()); + } + if (mechanism == "IDEAMAC") + { + return new CbcBlockCipherMac(new IdeaEngine()); + } + if (mechanism == "IDEAMAC/CFB8") + { + return new CfbBlockCipherMac(new IdeaEngine()); + } + if (mechanism == "RC2MAC") + { + return new CbcBlockCipherMac(new RC2Engine()); + } + if (mechanism == "RC2MAC/CFB8") + { + return new CfbBlockCipherMac(new RC2Engine()); + } + if (mechanism == "RC5MAC") + { + return new CbcBlockCipherMac(new RC532Engine()); + } + if (mechanism == "RC5MAC/CFB8") + { + return new CfbBlockCipherMac(new RC532Engine()); + } + if (mechanism == "GOST28147MAC") + { + return new Gost28147Mac(); + } + if (mechanism == "VMPCMAC") + { + return new VmpcMac(); + } + if (mechanism == "SIPHASH-2-4") + { + return new SipHash(); + } + throw new SecurityUtilityException("Mac " + mechanism + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input) + { + IMac mac = GetMac(algorithm); + mac.Init(cp); + mac.BlockUpdate(input, 0, input.Length); + return DoFinal(mac); + } + + public static byte[] DoFinal(IMac mac) + { + byte[] b = new byte[mac.GetMacSize()]; + mac.DoFinal(b, 0); + return b; + } + + public static byte[] DoFinal(IMac mac, byte[] input) + { + mac.BlockUpdate(input, 0, input.Length); + return DoFinal(mac); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs.meta new file mode 100644 index 0000000..a00bf24 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/MacUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dc8314b890aed0843acbd81d9e6db0cc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs new file mode 100644 index 0000000..d44702f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs @@ -0,0 +1,257 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Security +{ + public sealed class PublicKeyFactory + { + private PublicKeyFactory() + { + } + + public static AsymmetricKeyParameter CreateKey( + byte[] keyInfoData) + { + return CreateKey( + SubjectPublicKeyInfo.GetInstance( + Asn1Object.FromByteArray(keyInfoData))); + } + + public static AsymmetricKeyParameter CreateKey( + Stream inStr) + { + return CreateKey( + SubjectPublicKeyInfo.GetInstance( + Asn1Object.FromStream(inStr))); + } + + public static AsymmetricKeyParameter CreateKey( + SubjectPublicKeyInfo keyInfo) + { + AlgorithmIdentifier algID = keyInfo.AlgorithmID; + DerObjectIdentifier algOid = algID.Algorithm; + + // TODO See RSAUtil.isRsaOid in Java build + if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) + || algOid.Equals(X509ObjectIdentifiers.IdEARsa) + || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) + || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) + { + RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance( + keyInfo.GetPublicKey()); + + return new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent); + } + else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber)) + { + Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); + + DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.GetPublicKey()); + + BigInteger y = dhPublicKey.Y.Value; + + if (IsPkcsDHParam(seq)) + return ReadPkcsDHParam(algOid, y, seq); + + DHDomainParameters dhParams = DHDomainParameters.GetInstance(seq); + + BigInteger p = dhParams.P.Value; + BigInteger g = dhParams.G.Value; + BigInteger q = dhParams.Q.Value; + + BigInteger j = null; + if (dhParams.J != null) + { + j = dhParams.J.Value; + } + + DHValidationParameters validation = null; + DHValidationParms dhValidationParms = dhParams.ValidationParms; + if (dhValidationParms != null) + { + byte[] seed = dhValidationParms.Seed.GetBytes(); + BigInteger pgenCounter = dhValidationParms.PgenCounter.Value; + + // TODO Check pgenCounter size? + + validation = new DHValidationParameters(seed, pgenCounter.IntValue); + } + + return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)); + } + else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement)) + { + Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); + + DerInteger derY = (DerInteger) keyInfo.GetPublicKey(); + + return ReadPkcsDHParam(algOid, derY.Value, seq); + } + else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm)) + { + ElGamalParameter para = new ElGamalParameter( + Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); + DerInteger derY = (DerInteger) keyInfo.GetPublicKey(); + + return new ElGamalPublicKeyParameters( + derY.Value, + new ElGamalParameters(para.P, para.G)); + } + else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) + || algOid.Equals(OiwObjectIdentifiers.DsaWithSha1)) + { + DerInteger derY = (DerInteger) keyInfo.GetPublicKey(); + Asn1Encodable ae = algID.Parameters; + + DsaParameters parameters = null; + if (ae != null) + { + DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object()); + parameters = new DsaParameters(para.P, para.Q, para.G); + } + + return new DsaPublicKeyParameters(derY.Value, parameters); + } + else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey)) + { + X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object()); + + X9ECParameters x9; + if (para.IsNamedCurve) + { + x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters); + } + else + { + x9 = new X9ECParameters((Asn1Sequence)para.Parameters); + } + + Asn1OctetString key = new DerOctetString(keyInfo.PublicKeyData.GetBytes()); + X9ECPoint derQ = new X9ECPoint(x9.Curve, key); + ECPoint q = derQ.Point; + + if (para.IsNamedCurve) + { + return new ECPublicKeyParameters("EC", q, (DerObjectIdentifier)para.Parameters); + } + + ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); + return new ECPublicKeyParameters(q, dParams); + } + else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) + { + Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( + (Asn1Sequence) algID.Parameters); + + Asn1OctetString key; + try + { + key = (Asn1OctetString) keyInfo.GetPublicKey(); + } + catch (IOException) + { + throw new ArgumentException("invalid info structure in GOST3410 public key"); + } + + byte[] keyEnc = key.GetOctets(); + byte[] x = new byte[32]; + byte[] y = new byte[32]; + + for (int i = 0; i != y.Length; i++) + { + x[i] = keyEnc[32 - 1 - i]; + } + + for (int i = 0; i != x.Length; i++) + { + y[i] = keyEnc[64 - 1 - i]; + } + + ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet); + + if (ecP == null) + return null; + + ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y)); + + return new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet); + } + else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94)) + { + Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( + (Asn1Sequence) algID.Parameters); + + DerOctetString derY; + try + { + derY = (DerOctetString) keyInfo.GetPublicKey(); + } + catch (IOException) + { + throw new ArgumentException("invalid info structure in GOST3410 public key"); + } + + byte[] keyEnc = derY.GetOctets(); + byte[] keyBytes = new byte[keyEnc.Length]; + + for (int i = 0; i != keyEnc.Length; i++) + { + keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian + } + + BigInteger y = new BigInteger(1, keyBytes); + + return new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet); + } + else + { + throw new SecurityUtilityException("algorithm identifier in key not recognised: " + algOid); + } + } + + private static bool IsPkcsDHParam(Asn1Sequence seq) + { + if (seq.Count == 2) + return true; + + if (seq.Count > 3) + return false; + + DerInteger l = DerInteger.GetInstance(seq[2]); + DerInteger p = DerInteger.GetInstance(seq[0]); + + return l.Value.CompareTo(BigInteger.ValueOf(p.Value.BitLength)) <= 0; + } + + private static DHPublicKeyParameters ReadPkcsDHParam(DerObjectIdentifier algOid, + BigInteger y, Asn1Sequence seq) + { + DHParameter para = new DHParameter(seq); + + BigInteger lVal = para.L; + int l = lVal == null ? 0 : lVal.IntValue; + DHParameters dhParams = new DHParameters(para.P, para.G, null, l); + + return new DHPublicKeyParameters(y, dhParams, algOid); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs.meta new file mode 100644 index 0000000..d061e2d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/PublicKeyFactory.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bd0cb884524a32c429146ce48d62f30d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs new file mode 100644 index 0000000..9097186 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs @@ -0,0 +1,266 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Threading; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + public class SecureRandom + : Random + { + private static long counter = Times.NanoTime(); + +#if NETCF_1_0 || PORTABLE + private static object counterLock = new object(); + private static long NextCounterValue() + { + lock (counterLock) + { + return ++counter; + } + } + + private static readonly SecureRandom[] master = { null }; + private static SecureRandom Master + { + get + { + lock (master) + { + if (master[0] == null) + { + SecureRandom sr = master[0] = GetInstance("SHA256PRNG", false); + + // Even though Ticks has at most 8 or 14 bits of entropy, there's no harm in adding it. + sr.SetSeed(DateTime.Now.Ticks); + + // 32 will be enough when ThreadedSeedGenerator is fixed. Until then, ThreadedSeedGenerator returns low + // entropy, and this is not sufficient to be secure. http://www.bouncycastle.org/csharpdevmailarchive/msg00814.html + sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(32, true)); + } + + return master[0]; + } + } + } +#else + private static long NextCounterValue() + { + return Interlocked.Increment(ref counter); + } + + private static readonly SecureRandom master = new SecureRandom(new CryptoApiRandomGenerator()); + private static SecureRandom Master + { + get { return master; } + } +#endif + + private static DigestRandomGenerator CreatePrng(string digestName, bool autoSeed) + { + IDigest digest = DigestUtilities.GetDigest(digestName); + if (digest == null) + return null; + DigestRandomGenerator prng = new DigestRandomGenerator(digest); + if (autoSeed) + { + prng.AddSeedMaterial(NextCounterValue()); + prng.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize())); + } + return prng; + } + + public static byte[] GetNextBytes(SecureRandom secureRandom, int length) + { + byte[] result = new byte[length]; + secureRandom.NextBytes(result); + return result; + } + + /// + /// Create and auto-seed an instance based on the given algorithm. + /// + /// Equivalent to GetInstance(algorithm, true) + /// e.g. "SHA256PRNG" + public static SecureRandom GetInstance(string algorithm) + { + return GetInstance(algorithm, true); + } + + /// + /// Create an instance based on the given algorithm, with optional auto-seeding + /// + /// e.g. "SHA256PRNG" + /// If true, the instance will be auto-seeded. + public static SecureRandom GetInstance(string algorithm, bool autoSeed) + { + string upper = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); + if (Org.BouncyCastle.Utilities.Platform.EndsWith(upper, "PRNG")) + { + string digestName = upper.Substring(0, upper.Length - "PRNG".Length); + DigestRandomGenerator prng = CreatePrng(digestName, autoSeed); + if (prng != null) + { + return new SecureRandom(prng); + } + } + + throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm"); + } + + [Obsolete("Call GenerateSeed() on a SecureRandom instance instead")] + public static byte[] GetSeed(int length) + { + return GetNextBytes(Master, length); + } + + protected readonly IRandomGenerator generator; + + public SecureRandom() + : this(CreatePrng("SHA256", true)) + { + } + + /// + /// To replicate existing predictable output, replace with GetInstance("SHA1PRNG", false), followed by SetSeed(seed) + /// + [Obsolete("Use GetInstance/SetSeed instead")] + public SecureRandom(byte[] seed) + : this(CreatePrng("SHA1", false)) + { + SetSeed(seed); + } + + /// Use the specified instance of IRandomGenerator as random source. + /// + /// This constructor performs no seeding of either the IRandomGenerator or the + /// constructed SecureRandom. It is the responsibility of the client to provide + /// proper seed material as necessary/appropriate for the given IRandomGenerator + /// implementation. + /// + /// The source to generate all random bytes from. + public SecureRandom(IRandomGenerator generator) + : base(0) + { + this.generator = generator; + } + + public virtual byte[] GenerateSeed(int length) + { + return GetNextBytes(Master, length); + } + + public virtual void SetSeed(byte[] seed) + { + generator.AddSeedMaterial(seed); + } + + public virtual void SetSeed(long seed) + { + generator.AddSeedMaterial(seed); + } + + public override int Next() + { + return NextInt() & int.MaxValue; + } + + public override int Next(int maxValue) + { + + if (maxValue < 2) + { + if (maxValue < 0) + throw new ArgumentOutOfRangeException("maxValue", "cannot be negative"); + + return 0; + } + + int bits; + + // Test whether maxValue is a power of 2 + if ((maxValue & (maxValue - 1)) == 0) + { + bits = NextInt() & int.MaxValue; + return (int)(((long)bits * maxValue) >> 31); + } + + int result; + do + { + bits = NextInt() & int.MaxValue; + result = bits % maxValue; + } + while (bits - result + (maxValue - 1) < 0); // Ignore results near overflow + + return result; + } + + public override int Next(int minValue, int maxValue) + { + if (maxValue <= minValue) + { + if (maxValue == minValue) + return minValue; + + throw new ArgumentException("maxValue cannot be less than minValue"); + } + + int diff = maxValue - minValue; + if (diff > 0) + return minValue + Next(diff); + + for (;;) + { + int i = NextInt(); + + if (i >= minValue && i < maxValue) + return i; + } + } + + public override void NextBytes(byte[] buf) + { + generator.NextBytes(buf); + } + + public virtual void NextBytes(byte[] buf, int off, int len) + { + generator.NextBytes(buf, off, len); + } + + private static readonly double DoubleScale = System.Math.Pow(2.0, 64.0); + + public override double NextDouble() + { + return Convert.ToDouble((ulong) NextLong()) / DoubleScale; + } + + public virtual int NextInt() + { + byte[] bytes = new byte[4]; + NextBytes(bytes); + + uint result = bytes[0]; + result <<= 8; + result |= bytes[1]; + result <<= 8; + result |= bytes[2]; + result <<= 8; + result |= bytes[3]; + return (int)result; + } + + public virtual long NextLong() + { + return ((long)(uint) NextInt() << 32) | (long)(uint) NextInt(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs.meta new file mode 100644 index 0000000..ff62411 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecureRandom.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dad6d1b180992fa4bbefb141195487f5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs new file mode 100644 index 0000000..606d246 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class SecurityUtilityException + : Exception + { + /** + * base constructor. + */ + public SecurityUtilityException() + { + } + + /** + * create a SecurityUtilityException with the given message. + * + * @param message the message to be carried with the exception. + */ + public SecurityUtilityException( + string message) + : base(message) + { + } + + public SecurityUtilityException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs.meta new file mode 100644 index 0000000..db19daa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SecurityUtilityException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 776c8efaf8c3b3843aa42677ef63afd3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs new file mode 100644 index 0000000..a845664 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class SignatureException : GeneralSecurityException + { + public SignatureException() : base() { } + public SignatureException(string message) : base(message) { } + public SignatureException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs.meta new file mode 100644 index 0000000..0123710 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignatureException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 464c53a8485e7d44e828bede8f580c3b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs new file mode 100644 index 0000000..1ab65a7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs @@ -0,0 +1,570 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Signer Utility class contains methods that can not be specifically grouped into other classes. + /// + public sealed class SignerUtilities + { + private SignerUtilities() + { + } + + internal static readonly IDictionary algorithms = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + internal static readonly IDictionary oids = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + static SignerUtilities() + { + algorithms["MD2WITHRSA"] = "MD2withRSA"; + algorithms["MD2WITHRSAENCRYPTION"] = "MD2withRSA"; + algorithms[PkcsObjectIdentifiers.MD2WithRsaEncryption.Id] = "MD2withRSA"; + + algorithms["MD4WITHRSA"] = "MD4withRSA"; + algorithms["MD4WITHRSAENCRYPTION"] = "MD4withRSA"; + algorithms[PkcsObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA"; + + algorithms["MD5WITHRSA"] = "MD5withRSA"; + algorithms["MD5WITHRSAENCRYPTION"] = "MD5withRSA"; + algorithms[PkcsObjectIdentifiers.MD5WithRsaEncryption.Id] = "MD5withRSA"; + + algorithms["SHA1WITHRSA"] = "SHA-1withRSA"; + algorithms["SHA1WITHRSAENCRYPTION"] = "SHA-1withRSA"; + algorithms[PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id] = "SHA-1withRSA"; + algorithms["SHA-1WITHRSA"] = "SHA-1withRSA"; + + algorithms["SHA224WITHRSA"] = "SHA-224withRSA"; + algorithms["SHA224WITHRSAENCRYPTION"] = "SHA-224withRSA"; + algorithms[PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id] = "SHA-224withRSA"; + algorithms["SHA-224WITHRSA"] = "SHA-224withRSA"; + + algorithms["SHA256WITHRSA"] = "SHA-256withRSA"; + algorithms["SHA256WITHRSAENCRYPTION"] = "SHA-256withRSA"; + algorithms[PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id] = "SHA-256withRSA"; + algorithms["SHA-256WITHRSA"] = "SHA-256withRSA"; + + algorithms["SHA384WITHRSA"] = "SHA-384withRSA"; + algorithms["SHA384WITHRSAENCRYPTION"] = "SHA-384withRSA"; + algorithms[PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id] = "SHA-384withRSA"; + algorithms["SHA-384WITHRSA"] = "SHA-384withRSA"; + + algorithms["SHA512WITHRSA"] = "SHA-512withRSA"; + algorithms["SHA512WITHRSAENCRYPTION"] = "SHA-512withRSA"; + algorithms[PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id] = "SHA-512withRSA"; + algorithms["SHA-512WITHRSA"] = "SHA-512withRSA"; + + algorithms["PSSWITHRSA"] = "PSSwithRSA"; + algorithms["RSASSA-PSS"] = "PSSwithRSA"; + algorithms[PkcsObjectIdentifiers.IdRsassaPss.Id] = "PSSwithRSA"; + algorithms["RSAPSS"] = "PSSwithRSA"; + + algorithms["SHA1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1"; + algorithms["SHA-1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1"; + algorithms["SHA1WITHRSA/PSS"] = "SHA-1withRSAandMGF1"; + algorithms["SHA-1WITHRSA/PSS"] = "SHA-1withRSAandMGF1"; + + algorithms["SHA224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1"; + algorithms["SHA-224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1"; + algorithms["SHA224WITHRSA/PSS"] = "SHA-224withRSAandMGF1"; + algorithms["SHA-224WITHRSA/PSS"] = "SHA-224withRSAandMGF1"; + + algorithms["SHA256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1"; + algorithms["SHA-256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1"; + algorithms["SHA256WITHRSA/PSS"] = "SHA-256withRSAandMGF1"; + algorithms["SHA-256WITHRSA/PSS"] = "SHA-256withRSAandMGF1"; + + algorithms["SHA384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1"; + algorithms["SHA-384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1"; + algorithms["SHA384WITHRSA/PSS"] = "SHA-384withRSAandMGF1"; + algorithms["SHA-384WITHRSA/PSS"] = "SHA-384withRSAandMGF1"; + + algorithms["SHA512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1"; + algorithms["SHA-512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1"; + algorithms["SHA512WITHRSA/PSS"] = "SHA-512withRSAandMGF1"; + algorithms["SHA-512WITHRSA/PSS"] = "SHA-512withRSAandMGF1"; + + algorithms["RIPEMD128WITHRSA"] = "RIPEMD128withRSA"; + algorithms["RIPEMD128WITHRSAENCRYPTION"] = "RIPEMD128withRSA"; + algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128.Id] = "RIPEMD128withRSA"; + + algorithms["RIPEMD160WITHRSA"] = "RIPEMD160withRSA"; + algorithms["RIPEMD160WITHRSAENCRYPTION"] = "RIPEMD160withRSA"; + algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160.Id] = "RIPEMD160withRSA"; + + algorithms["RIPEMD256WITHRSA"] = "RIPEMD256withRSA"; + algorithms["RIPEMD256WITHRSAENCRYPTION"] = "RIPEMD256withRSA"; + algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256.Id] = "RIPEMD256withRSA"; + + algorithms["NONEWITHRSA"] = "RSA"; + algorithms["RSAWITHNONE"] = "RSA"; + algorithms["RAWRSA"] = "RSA"; + + algorithms["RAWRSAPSS"] = "RAWRSASSA-PSS"; + algorithms["NONEWITHRSAPSS"] = "RAWRSASSA-PSS"; + algorithms["NONEWITHRSASSA-PSS"] = "RAWRSASSA-PSS"; + + algorithms["NONEWITHDSA"] = "NONEwithDSA"; + algorithms["DSAWITHNONE"] = "NONEwithDSA"; + algorithms["RAWDSA"] = "NONEwithDSA"; + + algorithms["DSA"] = "SHA-1withDSA"; + algorithms["DSAWITHSHA1"] = "SHA-1withDSA"; + algorithms["DSAWITHSHA-1"] = "SHA-1withDSA"; + algorithms["SHA/DSA"] = "SHA-1withDSA"; + algorithms["SHA1/DSA"] = "SHA-1withDSA"; + algorithms["SHA-1/DSA"] = "SHA-1withDSA"; + algorithms["SHA1WITHDSA"] = "SHA-1withDSA"; + algorithms["SHA-1WITHDSA"] = "SHA-1withDSA"; + algorithms[X9ObjectIdentifiers.IdDsaWithSha1.Id] = "SHA-1withDSA"; + + algorithms["DSAWITHSHA224"] = "SHA-224withDSA"; + algorithms["DSAWITHSHA-224"] = "SHA-224withDSA"; + algorithms["SHA224/DSA"] = "SHA-224withDSA"; + algorithms["SHA-224/DSA"] = "SHA-224withDSA"; + algorithms["SHA224WITHDSA"] = "SHA-224withDSA"; + algorithms["SHA-224WITHDSA"] = "SHA-224withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha224.Id] = "SHA-224withDSA"; + + algorithms["DSAWITHSHA256"] = "SHA-256withDSA"; + algorithms["DSAWITHSHA-256"] = "SHA-256withDSA"; + algorithms["SHA256/DSA"] = "SHA-256withDSA"; + algorithms["SHA-256/DSA"] = "SHA-256withDSA"; + algorithms["SHA256WITHDSA"] = "SHA-256withDSA"; + algorithms["SHA-256WITHDSA"] = "SHA-256withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha256.Id] = "SHA-256withDSA"; + + algorithms["DSAWITHSHA384"] = "SHA-384withDSA"; + algorithms["DSAWITHSHA-384"] = "SHA-384withDSA"; + algorithms["SHA384/DSA"] = "SHA-384withDSA"; + algorithms["SHA-384/DSA"] = "SHA-384withDSA"; + algorithms["SHA384WITHDSA"] = "SHA-384withDSA"; + algorithms["SHA-384WITHDSA"] = "SHA-384withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha384.Id] = "SHA-384withDSA"; + + algorithms["DSAWITHSHA512"] = "SHA-512withDSA"; + algorithms["DSAWITHSHA-512"] = "SHA-512withDSA"; + algorithms["SHA512/DSA"] = "SHA-512withDSA"; + algorithms["SHA-512/DSA"] = "SHA-512withDSA"; + algorithms["SHA512WITHDSA"] = "SHA-512withDSA"; + algorithms["SHA-512WITHDSA"] = "SHA-512withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha512.Id] = "SHA-512withDSA"; + + algorithms["NONEWITHECDSA"] = "NONEwithECDSA"; + algorithms["ECDSAWITHNONE"] = "NONEwithECDSA"; + + algorithms["ECDSA"] = "SHA-1withECDSA"; + algorithms["SHA1/ECDSA"] = "SHA-1withECDSA"; + algorithms["SHA-1/ECDSA"] = "SHA-1withECDSA"; + algorithms["ECDSAWITHSHA1"] = "SHA-1withECDSA"; + algorithms["ECDSAWITHSHA-1"] = "SHA-1withECDSA"; + algorithms["SHA1WITHECDSA"] = "SHA-1withECDSA"; + algorithms["SHA-1WITHECDSA"] = "SHA-1withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha1.Id] = "SHA-1withECDSA"; + algorithms[TeleTrusTObjectIdentifiers.ECSignWithSha1.Id] = "SHA-1withECDSA"; + + algorithms["SHA224/ECDSA"] = "SHA-224withECDSA"; + algorithms["SHA-224/ECDSA"] = "SHA-224withECDSA"; + algorithms["ECDSAWITHSHA224"] = "SHA-224withECDSA"; + algorithms["ECDSAWITHSHA-224"] = "SHA-224withECDSA"; + algorithms["SHA224WITHECDSA"] = "SHA-224withECDSA"; + algorithms["SHA-224WITHECDSA"] = "SHA-224withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha224.Id] = "SHA-224withECDSA"; + + algorithms["SHA256/ECDSA"] = "SHA-256withECDSA"; + algorithms["SHA-256/ECDSA"] = "SHA-256withECDSA"; + algorithms["ECDSAWITHSHA256"] = "SHA-256withECDSA"; + algorithms["ECDSAWITHSHA-256"] = "SHA-256withECDSA"; + algorithms["SHA256WITHECDSA"] = "SHA-256withECDSA"; + algorithms["SHA-256WITHECDSA"] = "SHA-256withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha256.Id] = "SHA-256withECDSA"; + + algorithms["SHA384/ECDSA"] = "SHA-384withECDSA"; + algorithms["SHA-384/ECDSA"] = "SHA-384withECDSA"; + algorithms["ECDSAWITHSHA384"] = "SHA-384withECDSA"; + algorithms["ECDSAWITHSHA-384"] = "SHA-384withECDSA"; + algorithms["SHA384WITHECDSA"] = "SHA-384withECDSA"; + algorithms["SHA-384WITHECDSA"] = "SHA-384withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha384.Id] = "SHA-384withECDSA"; + + algorithms["SHA512/ECDSA"] = "SHA-512withECDSA"; + algorithms["SHA-512/ECDSA"] = "SHA-512withECDSA"; + algorithms["ECDSAWITHSHA512"] = "SHA-512withECDSA"; + algorithms["ECDSAWITHSHA-512"] = "SHA-512withECDSA"; + algorithms["SHA512WITHECDSA"] = "SHA-512withECDSA"; + algorithms["SHA-512WITHECDSA"] = "SHA-512withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha512.Id] = "SHA-512withECDSA"; + + algorithms["RIPEMD160/ECDSA"] = "RIPEMD160withECDSA"; + algorithms["ECDSAWITHRIPEMD160"] = "RIPEMD160withECDSA"; + algorithms["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA"; + algorithms[TeleTrusTObjectIdentifiers.ECSignWithRipeMD160.Id] = "RIPEMD160withECDSA"; + + algorithms["GOST-3410"] = "GOST3410"; + algorithms["GOST-3410-94"] = "GOST3410"; + algorithms["GOST3411WITHGOST3410"] = "GOST3410"; + algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94.Id] = "GOST3410"; + + algorithms["ECGOST-3410"] = "ECGOST3410"; + algorithms["ECGOST-3410-2001"] = "ECGOST3410"; + algorithms["GOST3411WITHECGOST3410"] = "ECGOST3410"; + algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.Id] = "ECGOST3410"; + + + + oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption; + oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption; + oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption; + + oids["SHA-1withRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption; + oids["SHA-224withRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption; + oids["SHA-256withRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption; + oids["SHA-384withRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption; + oids["SHA-512withRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption; + + oids["PSSwithRSA"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-1withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-224withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-256withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-384withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-512withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + + oids["RIPEMD128withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128; + oids["RIPEMD160withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160; + oids["RIPEMD256withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256; + + oids["SHA-1withDSA"] = X9ObjectIdentifiers.IdDsaWithSha1; + + oids["SHA-1withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1; + oids["SHA-224withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224; + oids["SHA-256withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256; + oids["SHA-384withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384; + oids["SHA-512withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512; + + oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94; + oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001; + } + + /// + /// Returns an ObjectIdentifier for a given encoding. + /// + /// A string representation of the encoding. + /// A DerObjectIdentifier, null if the OID is not available. + // TODO Don't really want to support this + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + if (mechanism == null) + throw new ArgumentNullException("mechanism"); + + mechanism = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(mechanism); + string aliased = (string) algorithms[mechanism]; + + if (aliased != null) + mechanism = aliased; + + return (DerObjectIdentifier) oids[mechanism]; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static Asn1Encodable GetDefaultX509Parameters( + DerObjectIdentifier id) + { + return GetDefaultX509Parameters(id.Id); + } + + public static Asn1Encodable GetDefaultX509Parameters( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + algorithm = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); + + string mechanism = (string) algorithms[algorithm]; + + if (mechanism == null) + mechanism = algorithm; + + if (mechanism == "PSSwithRSA") + { + // TODO The Sha1Digest here is a default. In JCE version, the actual digest + // to be used can be overridden by subsequent parameter settings. + return GetPssX509Parameters("SHA-1"); + } + + if (Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withRSAandMGF1")) + { + string digestName = mechanism.Substring(0, mechanism.Length - "withRSAandMGF1".Length); + return GetPssX509Parameters(digestName); + } + + return DerNull.Instance; + } + + private static Asn1Encodable GetPssX509Parameters( + string digestName) + { + AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier( + DigestUtilities.GetObjectIdentifier(digestName), DerNull.Instance); + + // TODO Is it possible for the MGF hash alg to be different from the PSS one? + AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdMgf1, hashAlgorithm); + + int saltLen = DigestUtilities.GetDigest(digestName).GetDigestSize(); + return new RsassaPssParameters(hashAlgorithm, maskGenAlgorithm, + new DerInteger(saltLen), new DerInteger(1)); + } + + public static ISigner GetSigner( + DerObjectIdentifier id) + { + return GetSigner(id.Id); + } + + public static ISigner GetSigner( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + algorithm = Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); + + string mechanism = (string) algorithms[algorithm]; + + if (mechanism == null) + mechanism = algorithm; + + if (mechanism.Equals("RSA")) + { + return (new RsaDigestSigner(new NullDigest(), (AlgorithmIdentifier)null)); + } + if (mechanism.Equals("MD2withRSA")) + { + return (new RsaDigestSigner(new MD2Digest())); + } + if (mechanism.Equals("MD4withRSA")) + { + return (new RsaDigestSigner(new MD4Digest())); + } + if (mechanism.Equals("MD5withRSA")) + { + return (new RsaDigestSigner(new MD5Digest())); + } + if (mechanism.Equals("SHA-1withRSA")) + { + return (new RsaDigestSigner(new Sha1Digest())); + } + if (mechanism.Equals("SHA-224withRSA")) + { + return (new RsaDigestSigner(new Sha224Digest())); + } + if (mechanism.Equals("SHA-256withRSA")) + { + return (new RsaDigestSigner(new Sha256Digest())); + } + if (mechanism.Equals("SHA-384withRSA")) + { + return (new RsaDigestSigner(new Sha384Digest())); + } + if (mechanism.Equals("SHA-512withRSA")) + { + return (new RsaDigestSigner(new Sha512Digest())); + } + if (mechanism.Equals("RIPEMD128withRSA")) + { + return (new RsaDigestSigner(new RipeMD128Digest())); + } + if (mechanism.Equals("RIPEMD160withRSA")) + { + return (new RsaDigestSigner(new RipeMD160Digest())); + } + if (mechanism.Equals("RIPEMD256withRSA")) + { + return (new RsaDigestSigner(new RipeMD256Digest())); + } + + if (mechanism.Equals("RAWRSASSA-PSS")) + { + // TODO Add support for other parameter settings + return PssSigner.CreateRawSigner(new RsaBlindedEngine(), new Sha1Digest()); + } + if (mechanism.Equals("PSSwithRSA")) + { + // TODO The Sha1Digest here is a default. In JCE version, the actual digest + // to be used can be overridden by subsequent parameter settings. + return (new PssSigner(new RsaBlindedEngine(), new Sha1Digest())); + } + if (mechanism.Equals("SHA-1withRSAandMGF1")) + { + return (new PssSigner(new RsaBlindedEngine(), new Sha1Digest())); + } + if (mechanism.Equals("SHA-224withRSAandMGF1")) + { + return (new PssSigner(new RsaBlindedEngine(), new Sha224Digest())); + } + if (mechanism.Equals("SHA-256withRSAandMGF1")) + { + return (new PssSigner(new RsaBlindedEngine(), new Sha256Digest())); + } + if (mechanism.Equals("SHA-384withRSAandMGF1")) + { + return (new PssSigner(new RsaBlindedEngine(), new Sha384Digest())); + } + if (mechanism.Equals("SHA-512withRSAandMGF1")) + { + return (new PssSigner(new RsaBlindedEngine(), new Sha512Digest())); + } + + if (mechanism.Equals("NONEwithDSA")) + { + return (new DsaDigestSigner(new DsaSigner(), new NullDigest())); + } + if (mechanism.Equals("SHA-1withDSA")) + { + return (new DsaDigestSigner(new DsaSigner(), new Sha1Digest())); + } + if (mechanism.Equals("SHA-224withDSA")) + { + return (new DsaDigestSigner(new DsaSigner(), new Sha224Digest())); + } + if (mechanism.Equals("SHA-256withDSA")) + { + return (new DsaDigestSigner(new DsaSigner(), new Sha256Digest())); + } + if (mechanism.Equals("SHA-384withDSA")) + { + return (new DsaDigestSigner(new DsaSigner(), new Sha384Digest())); + } + if (mechanism.Equals("SHA-512withDSA")) + { + return (new DsaDigestSigner(new DsaSigner(), new Sha512Digest())); + } + + if (mechanism.Equals("NONEwithECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new NullDigest())); + } + if (mechanism.Equals("SHA-1withECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new Sha1Digest())); + } + if (mechanism.Equals("SHA-224withECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new Sha224Digest())); + } + if (mechanism.Equals("SHA-256withECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest())); + } + if (mechanism.Equals("SHA-384withECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new Sha384Digest())); + } + if (mechanism.Equals("SHA-512withECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest())); + } + + if (mechanism.Equals("RIPEMD160withECDSA")) + { + return (new DsaDigestSigner(new ECDsaSigner(), new RipeMD160Digest())); + } + + if (mechanism.Equals("SHA1WITHECNR")) + { + return (new DsaDigestSigner(new ECNRSigner(), new Sha1Digest())); + } + if (mechanism.Equals("SHA224WITHECNR")) + { + return (new DsaDigestSigner(new ECNRSigner(), new Sha224Digest())); + } + if (mechanism.Equals("SHA256WITHECNR")) + { + return (new DsaDigestSigner(new ECNRSigner(), new Sha256Digest())); + } + if (mechanism.Equals("SHA384WITHECNR")) + { + return (new DsaDigestSigner(new ECNRSigner(), new Sha384Digest())); + } + if (mechanism.Equals("SHA512WITHECNR")) + { + return (new DsaDigestSigner(new ECNRSigner(), new Sha512Digest())); + } + + if (mechanism.Equals("GOST3410")) + { + return new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()); + } + if (mechanism.Equals("ECGOST3410")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()); + } + + if (mechanism.Equals("SHA1WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true); + } + if (mechanism.Equals("MD5WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true); + } + if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true); + } + + if (Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "/X9.31")) + { + string x931 = mechanism.Substring(0, mechanism.Length - "/X9.31".Length); + int withPos = Org.BouncyCastle.Utilities.Platform.IndexOf(x931, "WITH"); + if (withPos > 0) + { + int endPos = withPos + "WITH".Length; + + string digestName = x931.Substring(0, withPos); + IDigest digest = DigestUtilities.GetDigest(digestName); + + string cipherName = x931.Substring(endPos, x931.Length - endPos); + if (cipherName.Equals("RSA")) + { + IAsymmetricBlockCipher cipher = new RsaBlindedEngine(); + return new X931Signer(cipher, digest); + } + } + } + + throw new SecurityUtilityException("Signer " + algorithm + " not recognised."); + } + + public static string GetEncodingName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs.meta new file mode 100644 index 0000000..6efe8a9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/SignerUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 06997fffd3bfe604f912392f70471c57 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert.meta new file mode 100644 index 0000000..5edfc3e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d73ca49e92fed5341b3ab5351606b988 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs new file mode 100644 index 0000000..c1d694e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CertificateEncodingException : CertificateException + { + public CertificateEncodingException() : base() { } + public CertificateEncodingException(string msg) : base(msg) { } + public CertificateEncodingException(string msg, Exception e) : base(msg, e) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs.meta new file mode 100644 index 0000000..5acaeb5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateEncodingException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7d13d171e5bd63a43857b59678c5b634 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs new file mode 100644 index 0000000..7387c1d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CertificateException : GeneralSecurityException + { + public CertificateException() : base() { } + public CertificateException(string message) : base(message) { } + public CertificateException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs.meta new file mode 100644 index 0000000..7a9df02 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 312dba7b3b4d2b64f9f51f95db4ee1ca +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs new file mode 100644 index 0000000..1424fa2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CertificateExpiredException : CertificateException + { + public CertificateExpiredException() : base() { } + public CertificateExpiredException(string message) : base(message) { } + public CertificateExpiredException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs.meta new file mode 100644 index 0000000..fae7778 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateExpiredException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 94e5534bd782d1d4aa1d9cdf658ef365 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs new file mode 100644 index 0000000..7abad1d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CertificateNotYetValidException : CertificateException + { + public CertificateNotYetValidException() : base() { } + public CertificateNotYetValidException(string message) : base(message) { } + public CertificateNotYetValidException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs.meta new file mode 100644 index 0000000..d9659b1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateNotYetValidException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1c062f71e1e45684aaa24f6ec45dc08c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs new file mode 100644 index 0000000..8ea1fb0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CertificateParsingException : CertificateException + { + public CertificateParsingException() : base() { } + public CertificateParsingException(string message) : base(message) { } + public CertificateParsingException(string message, Exception exception) : base(message, exception) { } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs.meta new file mode 100644 index 0000000..787d94e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CertificateParsingException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cf1c2ef4e5eeedd4aac155d8a36837c3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs new file mode 100644 index 0000000..3b50717 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class CrlException : GeneralSecurityException + { + public CrlException() : base() { } + public CrlException(string msg) : base(msg) {} + public CrlException(string msg, Exception e) : base(msg, e) {} + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs.meta new file mode 100644 index 0000000..8468ec0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/security/cert/CrlException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b0c28bc603c44ba4cae418797434e798 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util.meta new file mode 100644 index 0000000..d3cc9ad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ba5cad752407f8545a6d90f346edc648 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs new file mode 100644 index 0000000..096d3b0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs @@ -0,0 +1,701 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Utilities +{ + /// General array utilities. + public abstract class Arrays + { + public static bool AreEqual( + bool[] a, + bool[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + public static bool AreEqual( + char[] a, + char[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + /// + /// Are two arrays equal. + /// + /// Left side. + /// Right side. + /// True if equal. + public static bool AreEqual( + byte[] a, + byte[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + [Obsolete("Use 'AreEqual' method instead")] + public static bool AreSame( + byte[] a, + byte[] b) + { + return AreEqual(a, b); + } + + /// + /// A constant time equals comparison - does not terminate early if + /// test will fail. + /// + /// first array + /// second array + /// true if arrays equal, false otherwise. + public static bool ConstantTimeAreEqual( + byte[] a, + byte[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + int cmp = 0; + while (i != 0) + { + --i; + cmp |= (a[i] ^ b[i]); + } + return cmp == 0; + } + + public static bool AreEqual( + int[] a, + int[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + public static bool AreEqual(uint[] a, uint[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + private static bool HaveSameContents( + bool[] a, + bool[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents( + char[] a, + char[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents( + byte[] a, + byte[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents( + int[] a, + int[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents(uint[] a, uint[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + public static string ToString( + object[] a) + { + StringBuilder sb = new StringBuilder('['); + if (a.Length > 0) + { + sb.Append(a[0]); + for (int index = 1; index < a.Length; ++index) + { + sb.Append(", ").Append(a[index]); + } + } + sb.Append(']'); + return sb.ToString(); + } + + public static int GetHashCode(byte[] data) + { + if (data == null) + { + return 0; + } + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[i]; + } + + return hc; + } + + public static int GetHashCode(byte[] data, int off, int len) + { + if (data == null) + { + return 0; + } + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[off + i]; + } + + return hc; + } + + public static int GetHashCode(int[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[i]; + } + + return hc; + } + + public static int GetHashCode(int[] data, int off, int len) + { + if (data == null) + return 0; + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[off + i]; + } + + return hc; + } + + public static int GetHashCode(uint[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= (int)data[i]; + } + + return hc; + } + + public static int GetHashCode(uint[] data, int off, int len) + { + if (data == null) + return 0; + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= (int)data[off + i]; + } + + return hc; + } + + public static int GetHashCode(ulong[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + ulong di = data[i]; + hc *= 257; + hc ^= (int)di; + hc *= 257; + hc ^= (int)(di >> 32); + } + + return hc; + } + + public static int GetHashCode(ulong[] data, int off, int len) + { + if (data == null) + return 0; + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + ulong di = data[off + i]; + hc *= 257; + hc ^= (int)di; + hc *= 257; + hc ^= (int)(di >> 32); + } + + return hc; + } + + public static byte[] Clone( + byte[] data) + { + return data == null ? null : (byte[])data.Clone(); + } + + public static byte[] Clone( + byte[] data, + byte[] existing) + { + if (data == null) + { + return null; + } + if ((existing == null) || (existing.Length != data.Length)) + { + return Clone(data); + } + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; + } + + public static int[] Clone( + int[] data) + { + return data == null ? null : (int[])data.Clone(); + } + + internal static uint[] Clone(uint[] data) + { + return data == null ? null : (uint[])data.Clone(); + } + + public static long[] Clone(long[] data) + { + return data == null ? null : (long[])data.Clone(); + } + + public static ulong[] Clone( + ulong[] data) + { + return data == null ? null : (ulong[]) data.Clone(); + } + + public static ulong[] Clone( + ulong[] data, + ulong[] existing) + { + if (data == null) + { + return null; + } + if ((existing == null) || (existing.Length != data.Length)) + { + return Clone(data); + } + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; + } + + public static bool Contains(byte[] a, byte n) + { + for (int i = 0; i < a.Length; ++i) + { + if (a[i] == n) + return true; + } + return false; + } + + public static bool Contains(short[] a, short n) + { + for (int i = 0; i < a.Length; ++i) + { + if (a[i] == n) + return true; + } + return false; + } + + public static bool Contains(int[] a, int n) + { + for (int i = 0; i < a.Length; ++i) + { + if (a[i] == n) + return true; + } + return false; + } + + public static void Fill( + byte[] buf, + byte b) + { + int i = buf.Length; + while (i > 0) + { + buf[--i] = b; + } + } + + public static byte[] CopyOf(byte[] data, int newLength) + { + byte[] tmp = new byte[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static char[] CopyOf(char[] data, int newLength) + { + char[] tmp = new char[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static int[] CopyOf(int[] data, int newLength) + { + int[] tmp = new int[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static long[] CopyOf(long[] data, int newLength) + { + long[] tmp = new long[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static BigInteger[] CopyOf(BigInteger[] data, int newLength) + { + BigInteger[] tmp = new BigInteger[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + /** + * Make a copy of a range of bytes from the passed in data array. The range can + * extend beyond the end of the input array, in which case the return array will + * be padded with zeroes. + * + * @param data the array from which the data is to be copied. + * @param from the start index at which the copying should take place. + * @param to the final index of the range (exclusive). + * + * @return a new byte array containing the range given. + */ + public static byte[] CopyOfRange(byte[] data, int from, int to) + { + int newLength = GetLength(from, to); + byte[] tmp = new byte[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + public static int[] CopyOfRange(int[] data, int from, int to) + { + int newLength = GetLength(from, to); + int[] tmp = new int[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + public static long[] CopyOfRange(long[] data, int from, int to) + { + int newLength = GetLength(from, to); + long[] tmp = new long[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + public static BigInteger[] CopyOfRange(BigInteger[] data, int from, int to) + { + int newLength = GetLength(from, to); + BigInteger[] tmp = new BigInteger[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + private static int GetLength(int from, int to) + { + int newLength = to - from; + if (newLength < 0) + throw new ArgumentException(from + " > " + to); + return newLength; + } + + public static byte[] Append(byte[] a, byte b) + { + if (a == null) + return new byte[] { b }; + + int length = a.Length; + byte[] result = new byte[length + 1]; + Array.Copy(a, 0, result, 0, length); + result[length] = b; + return result; + } + + public static short[] Append(short[] a, short b) + { + if (a == null) + return new short[] { b }; + + int length = a.Length; + short[] result = new short[length + 1]; + Array.Copy(a, 0, result, 0, length); + result[length] = b; + return result; + } + + public static int[] Append(int[] a, int b) + { + if (a == null) + return new int[] { b }; + + int length = a.Length; + int[] result = new int[length + 1]; + Array.Copy(a, 0, result, 0, length); + result[length] = b; + return result; + } + + public static byte[] Concatenate(byte[] a, byte[] b) + { + if (a == null) + return Clone(b); + if (b == null) + return Clone(a); + + byte[] rv = new byte[a.Length + b.Length]; + Array.Copy(a, 0, rv, 0, a.Length); + Array.Copy(b, 0, rv, a.Length, b.Length); + return rv; + } + + public static byte[] ConcatenateAll(params byte[][] vs) + { + byte[][] nonNull = new byte[vs.Length][]; + int count = 0; + int totalLength = 0; + + for (int i = 0; i < vs.Length; ++i) + { + byte[] v = vs[i]; + if (v != null) + { + nonNull[count++] = v; + totalLength += v.Length; + } + } + + byte[] result = new byte[totalLength]; + int pos = 0; + + for (int j = 0; j < count; ++j) + { + byte[] v = nonNull[j]; + Array.Copy(v, 0, result, pos, v.Length); + pos += v.Length; + } + + return result; + } + + public static int[] Concatenate(int[] a, int[] b) + { + if (a == null) + return Clone(b); + if (b == null) + return Clone(a); + + int[] rv = new int[a.Length + b.Length]; + Array.Copy(a, 0, rv, 0, a.Length); + Array.Copy(b, 0, rv, a.Length, b.Length); + return rv; + } + + public static byte[] Prepend(byte[] a, byte b) + { + if (a == null) + return new byte[] { b }; + + int length = a.Length; + byte[] result = new byte[length + 1]; + Array.Copy(a, 0, result, 1, length); + result[0] = b; + return result; + } + + public static short[] Prepend(short[] a, short b) + { + if (a == null) + return new short[] { b }; + + int length = a.Length; + short[] result = new short[length + 1]; + Array.Copy(a, 0, result, 1, length); + result[0] = b; + return result; + } + + public static int[] Prepend(int[] a, int b) + { + if (a == null) + return new int[] { b }; + + int length = a.Length; + int[] result = new int[length + 1]; + Array.Copy(a, 0, result, 1, length); + result[0] = b; + return result; + } + + public static byte[] Reverse(byte[] a) + { + if (a == null) + return null; + + int p1 = 0, p2 = a.Length; + byte[] result = new byte[p2]; + + while (--p2 >= 0) + { + result[p2] = a[p1++]; + } + + return result; + } + + public static int[] Reverse(int[] a) + { + if (a == null) + return null; + + int p1 = 0, p2 = a.Length; + int[] result = new int[p2]; + + while (--p2 >= 0) + { + result[p2] = a[p1++]; + } + + return result; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs.meta new file mode 100644 index 0000000..41828da --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Arrays.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5ba8c42c46160a54db30a3ddfae9ed76 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs new file mode 100644 index 0000000..4e012d3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs @@ -0,0 +1,94 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Utilities +{ + /** + * BigInteger utilities. + */ + public abstract class BigIntegers + { + private const int MaxIterations = 1000; + + /** + * Return the passed in value as an unsigned byte array. + * + * @param value value to be converted. + * @return a byte array without a leading zero byte if present in the signed encoding. + */ + public static byte[] AsUnsignedByteArray( + BigInteger n) + { + return n.ToByteArrayUnsigned(); + } + + /** + * Return the passed in value as an unsigned byte array of specified length, zero-extended as necessary. + * + * @param length desired length of result array. + * @param n value to be converted. + * @return a byte array of specified length, with leading zeroes as necessary given the size of n. + */ + public static byte[] AsUnsignedByteArray(int length, BigInteger n) + { + byte[] bytes = n.ToByteArrayUnsigned(); + + if (bytes.Length > length) + throw new ArgumentException("standard length exceeded", "n"); + + if (bytes.Length == length) + return bytes; + + byte[] tmp = new byte[length]; + Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length); + return tmp; + } + + /** + * Return a random BigInteger not less than 'min' and not greater than 'max' + * + * @param min the least value that may be generated + * @param max the greatest value that may be generated + * @param random the source of randomness + * @return a random BigInteger value in the range [min,max] + */ + public static BigInteger CreateRandomInRange( + BigInteger min, + BigInteger max, + // TODO Should have been just Random class + SecureRandom random) + { + int cmp = min.CompareTo(max); + if (cmp >= 0) + { + if (cmp > 0) + throw new ArgumentException("'min' may not be greater than 'max'"); + + return min; + } + + if (min.BitLength > max.BitLength / 2) + { + return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min); + } + + for (int i = 0; i < MaxIterations; ++i) + { + BigInteger x = new BigInteger(max.BitLength, random); + if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0) + { + return x; + } + } + + // fall back to a faster (restricted) method + return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs.meta new file mode 100644 index 0000000..d8251d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/BigIntegers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ebdb832f8f30d6c44a1a40e88b4f3b17 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs new file mode 100644 index 0000000..1132751 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs @@ -0,0 +1,86 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +//#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE +using System.Collections; +using System.Reflection; +//#endif + +using Org.BouncyCastle.Utilities.Date; + +#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP +using System.TypeFix; +#endif + +namespace Org.BouncyCastle.Utilities +{ + internal abstract class Enums + { + internal static Enum GetEnumValue(System.Type enumType, string s) + { + /*if (!enumType.IsEnum) + throw new ArgumentException("Not an enumeration type", "enumType");*/ + + // We only want to parse single named constants + if (s.Length > 0 && char.IsLetter(s[0]) && s.IndexOf(',') < 0) + { + s = s.Replace('-', '_'); + s = s.Replace('/', '_'); + +#if NETCF_1_0 + FieldInfo field = enumType.GetField(s, BindingFlags.Static | BindingFlags.Public); + if (field != null) + { + return (Enum)field.GetValue(null); + } +#else + return (Enum)Enum.Parse(enumType, s, false); +#endif + } + + throw new ArgumentException(); + } + + internal static Array GetEnumValues(System.Type enumType) + { + /*if (!enumType.IsEnum) + throw new ArgumentException("Not an enumeration type", "enumType");*/ + +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT + IList result = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (FieldInfo field in fields) + { + // Note: Argument to GetValue() ignored since the fields are static, + // but Silverlight for Windows Phone throws exception if we pass null + result.Add(field.GetValue(enumType)); + } + object[] arr = new object[result.Count]; + result.CopyTo(arr, 0); + return arr; +#else + return Enum.GetValues(enumType); +#endif + } + + internal static Enum GetArbitraryValue(System.Type enumType) + { + Array values = GetEnumValues(enumType); + int pos = (int)(DateTimeUtilities.CurrentUnixMs() & int.MaxValue) % values.Length; + return (Enum)values.GetValue(pos); + } + + internal static bool IsEnumType(System.Type t) + { +#if NEW_REFLECTION || NETFX_CORE + return t.GetTypeInfo().IsEnum; +#else + return t.IsEnum; +#endif + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs.meta new file mode 100644 index 0000000..70ea28c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Enums.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5bc960ec18e889148ae2e52c6be70ec4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs new file mode 100644 index 0000000..1e72fa2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities +{ + public interface IMemoable + { + /// + /// Produce a copy of this object with its configuration and in its current state. + /// + /// + /// The returned object may be used simply to store the state, or may be used as a similar object + /// starting from the copied state. + /// + IMemoable Copy(); + + /// + /// Restore a copied object state into this object. + /// + /// + /// Implementations of this method should try to avoid or minimise memory allocation to perform the reset. + /// + /// an object originally {@link #copy() copied} from an object of the same type as this instance. + /// if the provided object is not of the correct type. + /// if the other parameter is in some other way invalid. + void Reset(IMemoable other); + } + +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs.meta new file mode 100644 index 0000000..a3a9d61 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/IMemoable.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e5094da18f6285e498789845689aac6f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs new file mode 100644 index 0000000..c62438f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities +{ + public abstract class Integers + { + public static int RotateLeft(int i, int distance) + { + return (i << distance) ^ (int)((uint)i >> -distance); + } + + public static int RotateRight(int i, int distance) + { + return (int)((uint)i >> distance) ^ (i << -distance); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs.meta new file mode 100644 index 0000000..eeb990a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Integers.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3188e9987cc8be145a324b947c7e7475 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs new file mode 100644 index 0000000..6a885e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs @@ -0,0 +1,31 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities +{ + /** + * Exception to be thrown on a failure to reset an object implementing Memoable. + *

    + * The exception extends InvalidCastException to enable users to have a single handling case, + * only introducing specific handling of this one if required. + *

    + */ + public class MemoableResetException + : InvalidCastException + { + /** + * Basic Constructor. + * + * @param msg message to be associated with this exception. + */ + public MemoableResetException(string msg) + : base(msg) + { + } + } + +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs.meta new file mode 100644 index 0000000..e1f8835 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/MemoableResetException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 20a8024aade27594aacfebde1c7c76f3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs new file mode 100644 index 0000000..a340d19 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs @@ -0,0 +1,229 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Globalization; +using System.IO; +using System.Text; + +#if SILVERLIGHT || NETFX_CORE || UNITY_WP8 || PORTABLE +using System.Collections.Generic; +#else +using System.Collections; +#endif + +namespace Org.BouncyCastle.Utilities +{ + internal abstract class Platform + { + private static readonly CompareInfo InvariantCompareInfo = CultureInfo.InvariantCulture.CompareInfo; + +#if NETCF_1_0 || NETCF_2_0 + private static string GetNewLine() + { + MemoryStream buf = new MemoryStream(); + StreamWriter w = new StreamWriter(buf, Encoding.UTF8); + w.WriteLine(); + Dispose(w); + byte[] bs = buf.ToArray(); + return Encoding.UTF8.GetString(bs, 0, bs.Length); + } +#else + private static string GetNewLine() + { + return Environment.NewLine; + } +#endif + + internal static bool EqualsIgnoreCase(string a, string b) + { + return String.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0; + } + +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE + internal static string GetEnvironmentVariable( + string variable) + { + return null; + } +#else + internal static string GetEnvironmentVariable( + string variable) + { + try + { + return Environment.GetEnvironmentVariable(variable); + } + catch (System.Security.SecurityException) + { + // We don't have the required permission to read this environment variable, + // which is fine, just act as if it's not set + return null; + } + } +#endif + +#if NETCF_1_0 + internal static Exception CreateNotImplementedException( + string message) + { + return new Exception("Not implemented: " + message); + } + + internal static bool Equals( + object a, + object b) + { + return a == b || (a != null && b != null && a.Equals(b)); + } +#else + internal static Exception CreateNotImplementedException( + string message) + { + return new NotImplementedException(message); + } +#endif + +#if SILVERLIGHT || NETFX_CORE || UNITY_WP8 || PORTABLE + internal static System.Collections.IList CreateArrayList() + { + return new List(); + } + internal static System.Collections.IList CreateArrayList(int capacity) + { + return new List(capacity); + } + internal static System.Collections.IList CreateArrayList(System.Collections.ICollection collection) + { + System.Collections.IList result = new List(collection.Count); + foreach (object o in collection) + { + result.Add(o); + } + return result; + } + internal static System.Collections.IList CreateArrayList(System.Collections.IEnumerable collection) + { + System.Collections.IList result = new List(); + foreach (object o in collection) + { + result.Add(o); + } + return result; + } + internal static System.Collections.IDictionary CreateHashtable() + { + return new Dictionary(); + } + internal static System.Collections.IDictionary CreateHashtable(int capacity) + { + return new Dictionary(capacity); + } + internal static System.Collections.IDictionary CreateHashtable(System.Collections.IDictionary dictionary) + { + System.Collections.IDictionary result = new Dictionary(dictionary.Count); + foreach (System.Collections.DictionaryEntry entry in dictionary) + { + result.Add(entry.Key, entry.Value); + } + return result; + } +#else + internal static System.Collections.IList CreateArrayList() + { + return new ArrayList(); + } + internal static System.Collections.IList CreateArrayList(int capacity) + { + return new ArrayList(capacity); + } + internal static System.Collections.IList CreateArrayList(System.Collections.ICollection collection) + { + return new ArrayList(collection); + } + internal static System.Collections.IList CreateArrayList(System.Collections.IEnumerable collection) + { + ArrayList result = new ArrayList(); + foreach (object o in collection) + { + result.Add(o); + } + return result; + } + internal static System.Collections.IDictionary CreateHashtable() + { + return new Hashtable(); + } + internal static System.Collections.IDictionary CreateHashtable(int capacity) + { + return new Hashtable(capacity); + } + internal static System.Collections.IDictionary CreateHashtable(System.Collections.IDictionary dictionary) + { + return new Hashtable(dictionary); + } +#endif + + internal static string ToLowerInvariant(string s) + { +#if NETFX_CORE || PORTABLE + return s.ToLower(); +#else + return s.ToLower(CultureInfo.InvariantCulture); +#endif + } + + internal static string ToUpperInvariant(string s) + { +#if NETFX_CORE || PORTABLE + return s.ToUpper(); +#else + return s.ToUpper(CultureInfo.InvariantCulture); +#endif + } + + internal static readonly string NewLine = GetNewLine(); + +#if PORTABLE || NETFX_CORE + internal static void Dispose(IDisposable d) + { + d.Dispose(); + } +#else + internal static void Dispose(Stream s) + { + s.Close(); + } + internal static void Dispose(TextWriter t) + { + t.Close(); + } +#endif + + internal static int IndexOf(string source, string value) + { + return InvariantCompareInfo.IndexOf(source, value, CompareOptions.Ordinal); + } + + internal static int LastIndexOf(string source, string value) + { + return InvariantCompareInfo.LastIndexOf(source, value, CompareOptions.Ordinal); + } + + internal static bool StartsWith(string source, string prefix) + { + return InvariantCompareInfo.IsPrefix(source, prefix, CompareOptions.Ordinal); + } + + internal static bool EndsWith(string source, string suffix) + { + return InvariantCompareInfo.IsSuffix(source, suffix, CompareOptions.Ordinal); + } + + internal static string GetTypeName(object obj) + { + return obj.GetType().FullName; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs.meta new file mode 100644 index 0000000..dd48088 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Platform.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 34ac2529ba9563b4b95ceece9c95095a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs new file mode 100644 index 0000000..65faf9a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs @@ -0,0 +1,107 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Text; + +namespace Org.BouncyCastle.Utilities +{ + /// General string utilities. + public abstract class Strings + { + internal static bool IsOneOf(string s, params string[] candidates) + { + foreach (string candidate in candidates) + { + if (s == candidate) + return true; + } + return false; + } + + public static string FromByteArray( + byte[] bs) + { + char[] cs = new char[bs.Length]; + for (int i = 0; i < cs.Length; ++i) + { + cs[i] = Convert.ToChar(bs[i]); + } + return new string(cs); + } + + public static byte[] ToByteArray( + char[] cs) + { + byte[] bs = new byte[cs.Length]; + for (int i = 0; i < bs.Length; ++i) + { + bs[i] = Convert.ToByte(cs[i]); + } + return bs; + } + + public static byte[] ToByteArray( + string s) + { + byte[] bs = new byte[s.Length]; + for (int i = 0; i < bs.Length; ++i) + { + bs[i] = Convert.ToByte(s[i]); + } + return bs; + } + + public static string FromAsciiByteArray( + byte[] bytes) + { +#if SILVERLIGHT || NETFX_CORE || UNITY_WP8 || PORTABLE + // TODO Check for non-ASCII bytes in input? + return Encoding.UTF8.GetString(bytes, 0, bytes.Length); +#else + return Encoding.ASCII.GetString(bytes, 0, bytes.Length); +#endif + } + + public static byte[] ToAsciiByteArray( + char[] cs) + { +#if SILVERLIGHT || NETFX_CORE || UNITY_WP8 || PORTABLE + // TODO Check for non-ASCII characters in input? + return Encoding.UTF8.GetBytes(cs); +#else + return Encoding.ASCII.GetBytes(cs); +#endif + } + + public static byte[] ToAsciiByteArray( + string s) + { +#if SILVERLIGHT || NETFX_CORE || UNITY_WP8 || PORTABLE + // TODO Check for non-ASCII characters in input? + return Encoding.UTF8.GetBytes(s); +#else + return Encoding.ASCII.GetBytes(s); +#endif + } + + public static string FromUtf8ByteArray( + byte[] bytes) + { + return Encoding.UTF8.GetString(bytes, 0, bytes.Length); + } + + public static byte[] ToUtf8ByteArray( + char[] cs) + { + return Encoding.UTF8.GetBytes(cs); + } + + public static byte[] ToUtf8ByteArray( + string s) + { + return Encoding.UTF8.GetBytes(s); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs.meta new file mode 100644 index 0000000..25b875f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Strings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1102d66cf36a07545b4ef549eb96e85e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs new file mode 100644 index 0000000..54087f2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs @@ -0,0 +1,18 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities +{ + public sealed class Times + { + private static long NanosecondsPerTick = 100L; + + public static long NanoTime() + { + return DateTime.UtcNow.Ticks * NanosecondsPerTick; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs.meta new file mode 100644 index 0000000..af9a0c3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/Times.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0836244bbd72b0c439240b98b61f7c5b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections.meta new file mode 100644 index 0000000..f3aa649 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0b0797c2616cd4f4bbc6332490d85557 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs new file mode 100644 index 0000000..c83c861 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs @@ -0,0 +1,72 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.Text; + +#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP +using System.TypeFix; +#endif + +namespace Org.BouncyCastle.Utilities.Collections +{ + public abstract class CollectionUtilities + { + public static void AddRange(IList to, IEnumerable range) + { + foreach (object o in range) + { + to.Add(o); + } + } + + public static bool CheckElementsAreOfType(IEnumerable e, Type t) + { + foreach (object o in e) + { + if (!t.IsInstanceOfType(o)) + return false; + } + return true; + } + + public static IDictionary ReadOnly(IDictionary d) + { + return d; + } + + public static IList ReadOnly(IList l) + { + return l; + } + + public static ISet ReadOnly(ISet s) + { + return s; + } + + public static string ToString(IEnumerable c) + { + StringBuilder sb = new StringBuilder("["); + + IEnumerator e = c.GetEnumerator(); + + if (e.MoveNext()) + { + sb.Append(e.Current.ToString()); + + while (e.MoveNext()) + { + sb.Append(", "); + sb.Append(e.Current.ToString()); + } + } + + sb.Append(']'); + + return sb.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs.meta new file mode 100644 index 0000000..0d510cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/CollectionUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4d30cc7795a67b547845658234e4bed0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs new file mode 100644 index 0000000..0559a0d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public sealed class EmptyEnumerable + : IEnumerable + { + public static readonly IEnumerable Instance = new EmptyEnumerable(); + + private EmptyEnumerable() + { + } + + public IEnumerator GetEnumerator() + { + return EmptyEnumerator.Instance; + } + } + + public sealed class EmptyEnumerator + : IEnumerator + { + public static readonly IEnumerator Instance = new EmptyEnumerator(); + + private EmptyEnumerator() + { + } + + public bool MoveNext() + { + return false; + } + + public void Reset() + { + } + + public object Current + { + get { throw new InvalidOperationException("No elements"); } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs.meta new file mode 100644 index 0000000..8d217f9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EmptyEnumerable.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9fe693b6994f69f4ab3719bf470e98d2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs new file mode 100644 index 0000000..9e1bbd2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs @@ -0,0 +1,29 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public sealed class EnumerableProxy + : IEnumerable + { + private readonly IEnumerable inner; + + public EnumerableProxy( + IEnumerable inner) + { + if (inner == null) + throw new ArgumentNullException("inner"); + + this.inner = inner; + } + + public IEnumerator GetEnumerator() + { + return inner.GetEnumerator(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs.meta new file mode 100644 index 0000000..1fb6263 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/EnumerableProxy.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7473b1e62cdb7be449f354cbedddd3b5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs new file mode 100644 index 0000000..def0cfd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs @@ -0,0 +1,103 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public class HashSet + : ISet + { + private readonly IDictionary impl = Org.BouncyCastle.Utilities.Platform.CreateHashtable(); + + public HashSet() + { + } + + public HashSet(IEnumerable s) + { + foreach (object o in s) + { + Add(o); + } + } + + public virtual void Add(object o) + { + impl[o] = null; + } + + public virtual void AddAll(IEnumerable e) + { + foreach (object o in e) + { + Add(o); + } + } + + public virtual void Clear() + { + impl.Clear(); + } + + public virtual bool Contains(object o) + { + return impl.Contains(o); + } + + public virtual void CopyTo(Array array, int index) + { + impl.Keys.CopyTo(array, index); + } + + public virtual int Count + { + get { return impl.Count; } + } + + public virtual IEnumerator GetEnumerator() + { + return impl.Keys.GetEnumerator(); + } + + public virtual bool IsEmpty + { + get { return impl.Count == 0; } + } + + public virtual bool IsFixedSize + { + get { return impl.IsFixedSize; } + } + + public virtual bool IsReadOnly + { + get { return impl.IsReadOnly; } + } + + public virtual bool IsSynchronized + { + get { return impl.IsSynchronized; } + } + + public virtual void Remove(object o) + { + impl.Remove(o); + } + + public virtual void RemoveAll(IEnumerable e) + { + foreach (object o in e) + { + Remove(o); + } + } + + public virtual object SyncRoot + { + get { return impl.SyncRoot; } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs.meta new file mode 100644 index 0000000..2d04470 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/HashSet.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7324bf9bc59776949bf134abc958ddeb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs new file mode 100644 index 0000000..85bd43e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs @@ -0,0 +1,23 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public interface ISet + : ICollection + { + void Add(object o); + void AddAll(IEnumerable e); + void Clear(); + bool Contains(object o); + bool IsEmpty { get; } + bool IsFixedSize { get; } + bool IsReadOnly { get; } + void Remove(object o); + void RemoveAll(IEnumerable e); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs.meta new file mode 100644 index 0000000..a945666 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/collections/ISet.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e2f3dcb73a056604e8efd46a0ba3875a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date.meta new file mode 100644 index 0000000..c41e37b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 519a28f7f784fe741926e76c222b9da5 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs new file mode 100644 index 0000000..a7e74d1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs @@ -0,0 +1,29 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities.Date +{ + public sealed class DateTimeObject + { + private readonly DateTime dt; + + public DateTimeObject( + DateTime dt) + { + this.dt = dt; + } + + public DateTime Value + { + get { return dt; } + } + + public override string ToString() + { + return dt.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs.meta new file mode 100644 index 0000000..0f7210d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeObject.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 98e7fe4e769121b419a4d266709cd137 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs new file mode 100644 index 0000000..1cd8010 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs @@ -0,0 +1,51 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities.Date +{ + public class DateTimeUtilities + { + public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1); + + private DateTimeUtilities() + { + } + + /// + /// Return the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC) for a given DateTime value. + /// + /// A UTC DateTime value not before epoch. + /// Number of whole milliseconds after epoch. + /// 'dateTime' is before epoch. + public static long DateTimeToUnixMs( + DateTime dateTime) + { + if (dateTime.CompareTo(UnixEpoch) < 0) + throw new ArgumentException("DateTime value may not be before the epoch", "dateTime"); + + return (dateTime.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond; + } + + /// + /// Create a DateTime value from the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC). + /// + /// Number of milliseconds since the epoch. + /// A UTC DateTime value + public static DateTime UnixMsToDateTime( + long unixMs) + { + return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks); + } + + /// + /// Return the current number of milliseconds since the Unix epoch (1 Jan., 1970 UTC). + /// + public static long CurrentUnixMs() + { + return DateTimeToUnixMs(DateTime.UtcNow); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs.meta new file mode 100644 index 0000000..b3ff275 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/date/DateTimeUtilities.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 85931186ecac6fa43a89af5ddc60b835 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders.meta new file mode 100644 index 0000000..50803a7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a1c695eec32cfe44ba8bb5c6b6230161 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs new file mode 100644 index 0000000..6c2ea83 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs @@ -0,0 +1,124 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; +using System.Text; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + public sealed class Base64 + { + private Base64() + { + } + + public static string ToBase64String( + byte[] data) + { + return Convert.ToBase64String(data, 0, data.Length); + } + + public static string ToBase64String( + byte[] data, + int off, + int length) + { + return Convert.ToBase64String(data, off, length); + } + + /** + * encode the input data producing a base 64 encoded byte array. + * + * @return a byte array containing the base 64 encoded data. + */ + public static byte[] Encode( + byte[] data) + { + return Encode(data, 0, data.Length); + } + + /** + * encode the input data producing a base 64 encoded byte array. + * + * @return a byte array containing the base 64 encoded data. + */ + public static byte[] Encode( + byte[] data, + int off, + int length) + { + string s = Convert.ToBase64String(data, off, length); + return Strings.ToAsciiByteArray(s); + } + + /** + * Encode the byte data to base 64 writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + Stream outStream) + { + byte[] encoded = Encode(data); + outStream.Write(encoded, 0, encoded.Length); + return encoded.Length; + } + + /** + * Encode the byte data to base 64 writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + int off, + int length, + Stream outStream) + { + byte[] encoded = Encode(data, off, length); + outStream.Write(encoded, 0, encoded.Length); + return encoded.Length; + } + + /** + * decode the base 64 encoded input data. It is assumed the input data is valid. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + byte[] data) + { + string s = Strings.FromAsciiByteArray(data); + return Convert.FromBase64String(s); + } + + /** + * decode the base 64 encoded string data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + string data) + { + return Convert.FromBase64String(data); + } + + /** + * decode the base 64 encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + string data, + Stream outStream) + { + byte[] decoded = Decode(data); + outStream.Write(decoded, 0, decoded.Length); + return decoded.Length; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs.meta new file mode 100644 index 0000000..86d0dbd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2d6f9d60f7dc61d48babd61d65e4a234 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs new file mode 100644 index 0000000..66df483 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs @@ -0,0 +1,328 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + public class Base64Encoder + : IEncoder + { + protected readonly byte[] encodingTable = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', + (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', + (byte)'+', (byte)'/' + }; + + protected byte padding = (byte)'='; + + /* + * set up the decoding table. + */ + protected readonly byte[] decodingTable = new byte[128]; + + protected void InitialiseDecodingTable() + { + Arrays.Fill(decodingTable, (byte)0xff); + + for (int i = 0; i < encodingTable.Length; i++) + { + decodingTable[encodingTable[i]] = (byte)i; + } + } + + public Base64Encoder() + { + InitialiseDecodingTable(); + } + + /** + * encode the input data producing a base 64 output stream. + * + * @return the number of bytes produced. + */ + public int Encode( + byte[] data, + int off, + int length, + Stream outStream) + { + int modulus = length % 3; + int dataLength = (length - modulus); + int a1, a2, a3; + + for (int i = off; i < off + dataLength; i += 3) + { + a1 = data[i] & 0xff; + a2 = data[i + 1] & 0xff; + a3 = data[i + 2] & 0xff; + + outStream.WriteByte(encodingTable[(int) ((uint) a1 >> 2) & 0x3f]); + outStream.WriteByte(encodingTable[((a1 << 4) | (int) ((uint) a2 >> 4)) & 0x3f]); + outStream.WriteByte(encodingTable[((a2 << 2) | (int) ((uint) a3 >> 6)) & 0x3f]); + outStream.WriteByte(encodingTable[a3 & 0x3f]); + } + + /* + * process the tail end. + */ + int b1, b2, b3; + int d1, d2; + + switch (modulus) + { + case 0: /* nothing left to do */ + break; + case 1: + d1 = data[off + dataLength] & 0xff; + b1 = (d1 >> 2) & 0x3f; + b2 = (d1 << 4) & 0x3f; + + outStream.WriteByte(encodingTable[b1]); + outStream.WriteByte(encodingTable[b2]); + outStream.WriteByte(padding); + outStream.WriteByte(padding); + break; + case 2: + d1 = data[off + dataLength] & 0xff; + d2 = data[off + dataLength + 1] & 0xff; + + b1 = (d1 >> 2) & 0x3f; + b2 = ((d1 << 4) | (d2 >> 4)) & 0x3f; + b3 = (d2 << 2) & 0x3f; + + outStream.WriteByte(encodingTable[b1]); + outStream.WriteByte(encodingTable[b2]); + outStream.WriteByte(encodingTable[b3]); + outStream.WriteByte(padding); + break; + } + + return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4); + } + + private bool ignore( + char c) + { + return (c == '\n' || c =='\r' || c == '\t' || c == ' '); + } + + /** + * decode the base 64 encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int Decode( + byte[] data, + int off, + int length, + Stream outStream) + { + byte b1, b2, b3, b4; + int outLen = 0; + + int end = off + length; + + while (end > off) + { + if (!ignore((char)data[end - 1])) + { + break; + } + + end--; + } + + int i = off; + int finish = end - 4; + + i = nextI(data, i, finish); + + while (i < finish) + { + b1 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b2 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b3 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b4 = decodingTable[data[i++]]; + + if ((b1 | b2 | b3 | b4) >= 0x80) + throw new IOException("invalid characters encountered in base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + outStream.WriteByte((byte)((b3 << 6) | b4)); + + outLen += 3; + + i = nextI(data, i, finish); + } + + outLen += decodeLastBlock(outStream, (char)data[end - 4], (char)data[end - 3], (char)data[end - 2], (char)data[end - 1]); + + return outLen; + } + + private int nextI( + byte[] data, + int i, + int finish) + { + while ((i < finish) && ignore((char)data[i])) + { + i++; + } + return i; + } + + /** + * decode the base 64 encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int DecodeString( + string data, + Stream outStream) + { + // Platform Implementation +// byte[] bytes = Convert.FromBase64String(data); +// outStream.Write(bytes, 0, bytes.Length); +// return bytes.Length; + + byte b1, b2, b3, b4; + int length = 0; + + int end = data.Length; + + while (end > 0) + { + if (!ignore(data[end - 1])) + { + break; + } + + end--; + } + + int i = 0; + int finish = end - 4; + + i = nextI(data, i, finish); + + while (i < finish) + { + b1 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b2 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b3 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b4 = decodingTable[data[i++]]; + + if ((b1 | b2 | b3 | b4) >= 0x80) + throw new IOException("invalid characters encountered in base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + outStream.WriteByte((byte)((b3 << 6) | b4)); + + length += 3; + + i = nextI(data, i, finish); + } + + length += decodeLastBlock(outStream, data[end - 4], data[end - 3], data[end - 2], data[end - 1]); + + return length; + } + + private int decodeLastBlock( + Stream outStream, + char c1, + char c2, + char c3, + char c4) + { + if (c3 == padding) + { + byte b1 = decodingTable[c1]; + byte b2 = decodingTable[c2]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered at end of base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + + return 1; + } + + if (c4 == padding) + { + byte b1 = decodingTable[c1]; + byte b2 = decodingTable[c2]; + byte b3 = decodingTable[c3]; + + if ((b1 | b2 | b3) >= 0x80) + throw new IOException("invalid characters encountered at end of base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + + return 2; + } + + { + byte b1 = decodingTable[c1]; + byte b2 = decodingTable[c2]; + byte b3 = decodingTable[c3]; + byte b4 = decodingTable[c4]; + + if ((b1 | b2 | b3 | b4) >= 0x80) + throw new IOException("invalid characters encountered at end of base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + outStream.WriteByte((byte)((b3 << 6) | b4)); + + return 3; + } + } + + private int nextI(string data, int i, int finish) + { + while ((i < finish) && ignore(data[i])) + { + i++; + } + return i; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs.meta new file mode 100644 index 0000000..2a6c66a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Base64Encoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f905b3d88fa2c734fb7553270ac7e0b3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs new file mode 100644 index 0000000..44aabfb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs @@ -0,0 +1,134 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; +using System.Text; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /// + /// Class to decode and encode Hex. + /// + public sealed class Hex + { + private static readonly IEncoder encoder = new HexEncoder(); + + private Hex() + { + } + + public static string ToHexString( + byte[] data) + { + return ToHexString(data, 0, data.Length); + } + + public static string ToHexString( + byte[] data, + int off, + int length) + { + byte[] hex = Encode(data, off, length); + return Strings.FromAsciiByteArray(hex); + } + + /** + * encode the input data producing a Hex encoded byte array. + * + * @return a byte array containing the Hex encoded data. + */ + public static byte[] Encode( + byte[] data) + { + return Encode(data, 0, data.Length); + } + + /** + * encode the input data producing a Hex encoded byte array. + * + * @return a byte array containing the Hex encoded data. + */ + public static byte[] Encode( + byte[] data, + int off, + int length) + { + MemoryStream bOut = new MemoryStream(length * 2); + + encoder.Encode(data, off, length, bOut); + + return bOut.ToArray(); + } + + /** + * Hex encode the byte data writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + Stream outStream) + { + return encoder.Encode(data, 0, data.Length, outStream); + } + + /** + * Hex encode the byte data writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + int off, + int length, + Stream outStream) + { + return encoder.Encode(data, off, length, outStream); + } + + /** + * decode the Hex encoded input data. It is assumed the input data is valid. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + byte[] data) + { + MemoryStream bOut = new MemoryStream((data.Length + 1) / 2); + + encoder.Decode(data, 0, data.Length, bOut); + + return bOut.ToArray(); + } + + /** + * decode the Hex encoded string data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + string data) + { + MemoryStream bOut = new MemoryStream((data.Length + 1) / 2); + + encoder.DecodeString(data, bOut); + + return bOut.ToArray(); + } + + /** + * decode the Hex encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + string data, + Stream outStream) + { + return encoder.DecodeString(data, outStream); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs.meta new file mode 100644 index 0000000..42c1f68 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/Hex.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5ed222e1db807254592957eb36667273 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs new file mode 100644 index 0000000..d0d62cc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs @@ -0,0 +1,180 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + public class HexEncoder + : IEncoder + { + protected readonly byte[] encodingTable = + { + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', + (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' + }; + + /* + * set up the decoding table. + */ + protected readonly byte[] decodingTable = new byte[128]; + + protected void InitialiseDecodingTable() + { + Arrays.Fill(decodingTable, (byte)0xff); + + for (int i = 0; i < encodingTable.Length; i++) + { + decodingTable[encodingTable[i]] = (byte)i; + } + + decodingTable['A'] = decodingTable['a']; + decodingTable['B'] = decodingTable['b']; + decodingTable['C'] = decodingTable['c']; + decodingTable['D'] = decodingTable['d']; + decodingTable['E'] = decodingTable['e']; + decodingTable['F'] = decodingTable['f']; + } + + public HexEncoder() + { + InitialiseDecodingTable(); + } + + /** + * encode the input data producing a Hex output stream. + * + * @return the number of bytes produced. + */ + public int Encode( + byte[] data, + int off, + int length, + Stream outStream) + { + for (int i = off; i < (off + length); i++) + { + int v = data[i]; + + outStream.WriteByte(encodingTable[v >> 4]); + outStream.WriteByte(encodingTable[v & 0xf]); + } + + return length * 2; + } + + private static bool Ignore(char c) + { + return c == '\n' || c =='\r' || c == '\t' || c == ' '; + } + + /** + * decode the Hex encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int Decode( + byte[] data, + int off, + int length, + Stream outStream) + { + byte b1, b2; + int outLen = 0; + int end = off + length; + + while (end > off) + { + if (!Ignore((char)data[end - 1])) + { + break; + } + + end--; + } + + int i = off; + while (i < end) + { + while (i < end && Ignore((char)data[i])) + { + i++; + } + + b1 = decodingTable[data[i++]]; + + while (i < end && Ignore((char)data[i])) + { + i++; + } + + b2 = decodingTable[data[i++]]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered in Hex data"); + + outStream.WriteByte((byte)((b1 << 4) | b2)); + + outLen++; + } + + return outLen; + } + + /** + * decode the Hex encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int DecodeString( + string data, + Stream outStream) + { + byte b1, b2; + int length = 0; + + int end = data.Length; + + while (end > 0) + { + if (!Ignore(data[end - 1])) + { + break; + } + + end--; + } + + int i = 0; + while (i < end) + { + while (i < end && Ignore(data[i])) + { + i++; + } + + b1 = decodingTable[data[i++]]; + + while (i < end && Ignore(data[i])) + { + i++; + } + + b2 = decodingTable[data[i++]]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered in Hex data"); + + outStream.WriteByte((byte)((b1 << 4) | b2)); + + length++; + } + + return length; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs.meta new file mode 100644 index 0000000..0672804 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/HexEncoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 05d0f6c3caab0a549b8c1067b01bcbb2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs new file mode 100644 index 0000000..88b161d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs @@ -0,0 +1,22 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /** + * Encode and decode byte arrays (typically from binary to 7-bit ASCII + * encodings). + */ + public interface IEncoder + { + int Encode(byte[] data, int off, int length, Stream outStream); + + int Decode(byte[] data, int off, int length, Stream outStream); + + int DecodeString(string data, Stream outStream); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs.meta new file mode 100644 index 0000000..12641fe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/encoders/IEncoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2e240a99386c56d4c833831f5247b554 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io.meta new file mode 100644 index 0000000..3f85610 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8d0ebd9539721c34daaadeafccd8ed9d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs new file mode 100644 index 0000000..a81ec91 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs @@ -0,0 +1,68 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public abstract class BaseInputStream : Stream + { + private bool closed; + + public sealed override bool CanRead { get { return !closed; } } + public sealed override bool CanSeek { get { return false; } } + public sealed override bool CanWrite { get { return false; } } + +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + closed = true; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + closed = true; + base.Close(); + } +#endif + + public sealed override void Flush() {} + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buffer, int offset, int count) + { + int pos = offset; + try + { + int end = offset + count; + while (pos < end) + { + int b = ReadByte(); + if (b == -1) break; + buffer[pos++] = (byte) b; + } + } + catch (IOException) + { + if (pos == offset) throw; + } + return pos - offset; + } + + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs.meta new file mode 100644 index 0000000..d097434 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseInputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c55c7018496d63408687d3da511e3ea +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs new file mode 100644 index 0000000..ebe89dd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs @@ -0,0 +1,68 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public abstract class BaseOutputStream : Stream + { + private bool closed; + + public sealed override bool CanRead { get { return false; } } + public sealed override bool CanSeek { get { return false; } } + public sealed override bool CanWrite { get { return !closed; } } + +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + closed = true; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + closed = true; + base.Close(); + } +#endif + + public override void Flush() { } + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + + public override void Write(byte[] buffer, int offset, int count) + { + Debug.Assert(buffer != null); + Debug.Assert(0 <= offset && offset <= buffer.Length); + Debug.Assert(count >= 0); + + int end = offset + count; + + Debug.Assert(0 <= end && end <= buffer.Length); + + for (int i = offset; i < end; ++i) + { + this.WriteByte(buffer[i]); + } + } + + public virtual void Write(params byte[] buffer) + { + Write(buffer, 0, buffer.Length); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs.meta new file mode 100644 index 0000000..40aa2a0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/BaseOutputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8a6aa30f111ed30408694c452b3e0947 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs new file mode 100644 index 0000000..f304ef0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs @@ -0,0 +1,82 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class FilterStream : Stream + { + public FilterStream(Stream s) + { + this.s = s; + } + public override bool CanRead + { + get { return s.CanRead; } + } + public override bool CanSeek + { + get { return s.CanSeek; } + } + public override bool CanWrite + { + get { return s.CanWrite; } + } + public override long Length + { + get { return s.Length; } + } + public override long Position + { + get { return s.Position; } + set { s.Position = value; } + } +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Org.BouncyCastle.Utilities.Platform.Dispose(s); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Org.BouncyCastle.Utilities.Platform.Dispose(s); + base.Close(); + } +#endif + public override void Flush() + { + s.Flush(); + } + public override long Seek(long offset, SeekOrigin origin) + { + return s.Seek(offset, origin); + } + public override void SetLength(long value) + { + s.SetLength(value); + } + public override int Read(byte[] buffer, int offset, int count) + { + return s.Read(buffer, offset, count); + } + public override int ReadByte() + { + return s.ReadByte(); + } + public override void Write(byte[] buffer, int offset, int count) + { + s.Write(buffer, offset, count); + } + public override void WriteByte(byte value) + { + s.WriteByte(value); + } + protected readonly Stream s; + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs.meta new file mode 100644 index 0000000..10a87a2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/FilterStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3fce67f814432d848a840ddec287f366 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs new file mode 100644 index 0000000..bef6939 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs @@ -0,0 +1,56 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Utilities; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class PushbackStream + : FilterStream + { + private int buf = -1; + + public PushbackStream( + Stream s) + : base(s) + { + } + + public override int ReadByte() + { + if (buf != -1) + { + int tmp = buf; + buf = -1; + return tmp; + } + + return base.ReadByte(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (buf != -1 && count > 0) + { + // TODO Can this case be made more efficient? + buffer[offset] = (byte) buf; + buf = -1; + return 1; + } + + return base.Read(buffer, offset, count); + } + + public virtual void Unread(int b) + { + if (buf != -1) + throw new InvalidOperationException("Can only push back one byte"); + + buf = b & 0xFF; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs.meta new file mode 100644 index 0000000..cd34089 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/PushbackStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 43f5f3bf52001c342945b5bb8fd8fa9f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs new file mode 100644 index 0000000..39f45e6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs @@ -0,0 +1,34 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE) + [Serializable] +#endif + public class StreamOverflowException + : IOException + { + public StreamOverflowException() + : base() + { + } + + public StreamOverflowException( + string message) + : base(message) + { + } + + public StreamOverflowException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs.meta new file mode 100644 index 0000000..52b8517 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/StreamOverflowException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9bebbf770f250c4ab5bd25ef8f384a7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs new file mode 100644 index 0000000..72af798 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs @@ -0,0 +1,98 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public sealed class Streams + { + private const int BufferSize = 512; + + private Streams() + { + } + + public static void Drain(Stream inStr) + { + byte[] bs = new byte[BufferSize]; + while (inStr.Read(bs, 0, bs.Length) > 0) + { + } + } + + public static byte[] ReadAll(Stream inStr) + { + MemoryStream buf = new MemoryStream(); + PipeAll(inStr, buf); + return buf.ToArray(); + } + + public static byte[] ReadAllLimited(Stream inStr, int limit) + { + MemoryStream buf = new MemoryStream(); + PipeAllLimited(inStr, limit, buf); + return buf.ToArray(); + } + + public static int ReadFully(Stream inStr, byte[] buf) + { + return ReadFully(inStr, buf, 0, buf.Length); + } + + public static int ReadFully(Stream inStr, byte[] buf, int off, int len) + { + int totalRead = 0; + while (totalRead < len) + { + int numRead = inStr.Read(buf, off + totalRead, len - totalRead); + if (numRead < 1) + break; + totalRead += numRead; + } + return totalRead; + } + + public static void PipeAll(Stream inStr, Stream outStr) + { + byte[] bs = new byte[BufferSize]; + int numRead; + while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0) + { + outStr.Write(bs, 0, numRead); + } + } + + /// + /// Pipe all bytes from inStr to outStr, throwing StreamFlowException if greater + /// than limit bytes in inStr. + /// + /// + /// A + /// + /// + /// A + /// + /// + /// A + /// + /// The number of bytes actually transferred, if not greater than limit + /// + public static long PipeAllLimited(Stream inStr, long limit, Stream outStr) + { + byte[] bs = new byte[BufferSize]; + long total = 0; + int numRead; + while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0) + { + if ((limit - total) < numRead) + throw new StreamOverflowException("Data Overflow"); + total += numRead; + outStr.Write(bs, 0, numRead); + } + return total; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs.meta new file mode 100644 index 0000000..cfd412c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/Streams.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7009443e85a87f4499c540687b6cb8c4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs new file mode 100644 index 0000000..1c8007b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs @@ -0,0 +1,68 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class TeeInputStream + : BaseInputStream + { + private readonly Stream input, tee; + + public TeeInputStream(Stream input, Stream tee) + { + Debug.Assert(input.CanRead); + Debug.Assert(tee.CanWrite); + + this.input = input; + this.tee = tee; + } + +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Org.BouncyCastle.Utilities.Platform.Dispose(input); + Org.BouncyCastle.Utilities.Platform.Dispose(tee); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Org.BouncyCastle.Utilities.Platform.Dispose(input); + Org.BouncyCastle.Utilities.Platform.Dispose(tee); + base.Close(); + } +#endif + + public override int Read(byte[] buf, int off, int len) + { + int i = input.Read(buf, off, len); + + if (i > 0) + { + tee.Write(buf, off, i); + } + + return i; + } + + public override int ReadByte() + { + int i = input.ReadByte(); + + if (i >= 0) + { + tee.WriteByte((byte)i); + } + + return i; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs.meta new file mode 100644 index 0000000..b40a919 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeInputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ae88e55e5d7dac54aa31654c14619f10 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs new file mode 100644 index 0000000..0e4b4be --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs @@ -0,0 +1,56 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class TeeOutputStream + : BaseOutputStream + { + private readonly Stream output, tee; + + public TeeOutputStream(Stream output, Stream tee) + { + Debug.Assert(output.CanWrite); + Debug.Assert(tee.CanWrite); + + this.output = output; + this.tee = tee; + } + +#if PORTABLE || NETFX_CORE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Org.BouncyCastle.Utilities.Platform.Dispose(output); + Org.BouncyCastle.Utilities.Platform.Dispose(tee); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Org.BouncyCastle.Utilities.Platform.Dispose(output); + Org.BouncyCastle.Utilities.Platform.Dispose(tee); + base.Close(); + } +#endif + + public override void Write(byte[] buffer, int offset, int count) + { + output.Write(buffer, offset, count); + tee.Write(buffer, offset, count); + } + + public override void WriteByte(byte b) + { + output.WriteByte(b); + tee.WriteByte(b); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs.meta new file mode 100644 index 0000000..5d7186b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/TeeOutputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 94d20141b69679e4293e7365906dbe4b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem.meta new file mode 100644 index 0000000..6f21b64 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: facfbd283a257c247b7788a4852da32a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs new file mode 100644 index 0000000..0878653 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs @@ -0,0 +1,33 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [Serializable] +#endif + public class PemGenerationException + : Exception + { + public PemGenerationException() + : base() + { + } + + public PemGenerationException( + string message) + : base(message) + { + } + + public PemGenerationException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs.meta new file mode 100644 index 0000000..441f236 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemGenerationException.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d64f3f17b41a69c4e9f8146e9a630aa6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs new file mode 100644 index 0000000..9c53dd6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs @@ -0,0 +1,59 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public class PemHeader + { + private string name; + private string val; + + public PemHeader(string name, string val) + { + this.name = name; + this.val = val; + } + + public virtual string Name + { + get { return name; } + } + + public virtual string Value + { + get { return val; } + } + + public override int GetHashCode() + { + return GetHashCode(this.name) + 31 * GetHashCode(this.val); + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + if (!(obj is PemHeader)) + return false; + + PemHeader other = (PemHeader)obj; + + return Org.BouncyCastle.Utilities.Platform.Equals(this.name, other.name) + && Org.BouncyCastle.Utilities.Platform.Equals(this.val, other.val); + } + + private int GetHashCode(string s) + { + if (s == null) + { + return 1; + } + + return s.GetHashCode(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs.meta new file mode 100644 index 0000000..5aacb12 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemHeader.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6145fa38ebb0c79458ea0c15c317525d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs new file mode 100644 index 0000000..121b398 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs @@ -0,0 +1,51 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public class PemObject + : PemObjectGenerator + { + private string type; + private IList headers; + private byte[] content; + + public PemObject(string type, byte[] content) + : this(type, Org.BouncyCastle.Utilities.Platform.CreateArrayList(), content) + { + } + + public PemObject(String type, IList headers, byte[] content) + { + this.type = type; + this.headers = Org.BouncyCastle.Utilities.Platform.CreateArrayList(headers); + this.content = content; + } + + public string Type + { + get { return type; } + } + + public IList Headers + { + get { return headers; } + } + + public byte[] Content + { + get { return content; } + } + + public PemObject Generate() + { + return this; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs.meta new file mode 100644 index 0000000..1ca5499 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObject.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: dd96e7dbd869965419cb9e8ee3aad2ec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs new file mode 100644 index 0000000..4e1a76b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs @@ -0,0 +1,17 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public interface PemObjectGenerator + { + /// + /// A + /// + /// + PemObject Generate(); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs.meta new file mode 100644 index 0000000..5cd82e8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemObjectGenerator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ae784c7acdea52e429e2586f22f7d6ec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs new file mode 100644 index 0000000..1b93b1b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs @@ -0,0 +1,100 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public class PemReader + { + private const string BeginString = "-----BEGIN "; + private const string EndString = "-----END "; + + private readonly TextReader reader; + + public PemReader(TextReader reader) + { + if (reader == null) + throw new ArgumentNullException("reader"); + + this.reader = reader; + } + + public TextReader Reader + { + get { return reader; } + } + + /// + /// A + /// + /// + public PemObject ReadPemObject() + { + string line = reader.ReadLine(); + + if (line != null && Org.BouncyCastle.Utilities.Platform.StartsWith(line, BeginString)) + { + line = line.Substring(BeginString.Length); + int index = line.IndexOf('-'); + string type = line.Substring(0, index); + + if (index > 0) + return LoadObject(type); + } + + return null; + } + + private PemObject LoadObject(string type) + { + string endMarker = EndString + type; + IList headers = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + StringBuilder buf = new StringBuilder(); + + string line; + while ((line = reader.ReadLine()) != null + && Org.BouncyCastle.Utilities.Platform.IndexOf(line, endMarker) == -1) + { + int colonPos = line.IndexOf(':'); + + if (colonPos == -1) + { + buf.Append(line.Trim()); + } + else + { + // Process field + string fieldName = line.Substring(0, colonPos).Trim(); + + if (Org.BouncyCastle.Utilities.Platform.StartsWith(fieldName, "X-")) + { + fieldName = fieldName.Substring(2); + } + + string fieldValue = line.Substring(colonPos + 1).Trim(); + + headers.Add(new PemHeader(fieldName, fieldValue)); + } + } + + if (line == null) + { + throw new IOException(endMarker + " not found"); + } + + if (buf.Length % 4 != 0) + { + throw new IOException("base64 data appears to be truncated"); + } + + return new PemObject(type, headers, Base64.Decode(buf.ToString())); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs.meta new file mode 100644 index 0000000..4d3df77 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemReader.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f26fdb1978588c94ba940413500381e6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs new file mode 100644 index 0000000..3c3f5e4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs @@ -0,0 +1,124 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + /** + * A generic PEM writer, based on RFC 1421 + */ + public class PemWriter + { + private const int LineLength = 64; + + private readonly TextWriter writer; + private readonly int nlLength; + private char[] buf = new char[LineLength]; + + /** + * Base constructor. + * + * @param out output stream to use. + */ + public PemWriter(TextWriter writer) + { + if (writer == null) + throw new ArgumentNullException("writer"); + + this.writer = writer; + this.nlLength = Org.BouncyCastle.Utilities.Platform.NewLine.Length; + } + + public TextWriter Writer + { + get { return writer; } + } + + /** + * Return the number of bytes or characters required to contain the + * passed in object if it is PEM encoded. + * + * @param obj pem object to be output + * @return an estimate of the number of bytes + */ + public int GetOutputSize(PemObject obj) + { + // BEGIN and END boundaries. + int size = (2 * (obj.Type.Length + 10 + nlLength)) + 6 + 4; + + if (obj.Headers.Count > 0) + { + foreach (PemHeader header in obj.Headers) + { + size += header.Name.Length + ": ".Length + header.Value.Length + nlLength; + } + + size += nlLength; + } + + // base64 encoding + int dataLen = ((obj.Content.Length + 2) / 3) * 4; + + size += dataLen + (((dataLen + LineLength - 1) / LineLength) * nlLength); + + return size; + } + + public void WriteObject(PemObjectGenerator objGen) + { + PemObject obj = objGen.Generate(); + + WritePreEncapsulationBoundary(obj.Type); + + if (obj.Headers.Count > 0) + { + foreach (PemHeader header in obj.Headers) + { + writer.Write(header.Name); + writer.Write(": "); + writer.WriteLine(header.Value); + } + + writer.WriteLine(); + } + + WriteEncoded(obj.Content); + WritePostEncapsulationBoundary(obj.Type); + } + + private void WriteEncoded(byte[] bytes) + { + bytes = Base64.Encode(bytes); + + for (int i = 0; i < bytes.Length; i += buf.Length) + { + int index = 0; + while (index != buf.Length) + { + if ((i + index) >= bytes.Length) + break; + + buf[index] = (char)bytes[i + index]; + index++; + } + writer.WriteLine(buf, 0, index); + } + } + + private void WritePreEncapsulationBoundary(string type) + { + writer.WriteLine("-----BEGIN " + type + "-----"); + } + + private void WritePostEncapsulationBoundary(string type) + { + writer.WriteLine("-----END " + type + "-----"); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs.meta new file mode 100644 index 0000000..ebbd408 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/io/pem/PemWriter.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32f18cc53c19448418b7b334997da7a4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net.meta new file mode 100644 index 0000000..8a8f586 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ef95faa5f016dcf42829616d382ec0fd +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs new file mode 100644 index 0000000..13e2751 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs @@ -0,0 +1,201 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Globalization; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Utilities.Net +{ + public class IPAddress + { + /** + * Validate the given IPv4 or IPv6 address. + * + * @param address the IP address as a string. + * + * @return true if a valid address, false otherwise + */ + public static bool IsValid( + string address) + { + return IsValidIPv4(address) || IsValidIPv6(address); + } + + /** + * Validate the given IPv4 or IPv6 address and netmask. + * + * @param address the IP address as a string. + * + * @return true if a valid address with netmask, false otherwise + */ + public static bool IsValidWithNetMask( + string address) + { + return IsValidIPv4WithNetmask(address) || IsValidIPv6WithNetmask(address); + } + + /** + * Validate the given IPv4 address. + * + * @param address the IP address as a string. + * + * @return true if a valid IPv4 address, false otherwise + */ + public static bool IsValidIPv4( + string address) + { + try + { + return unsafeIsValidIPv4(address); + } + catch (FormatException) {} + catch (OverflowException) {} + return false; + } + + private static bool unsafeIsValidIPv4( + string address) + { + if (address.Length == 0) + return false; + + int octets = 0; + string temp = address + "."; + + int pos; + int start = 0; + while (start < temp.Length + && (pos = temp.IndexOf('.', start)) > start) + { + if (octets == 4) + return false; + + string octetStr = temp.Substring(start, pos - start); + int octet = Int32.Parse(octetStr); + + if (octet < 0 || octet > 255) + return false; + + start = pos + 1; + octets++; + } + + return octets == 4; + } + + public static bool IsValidIPv4WithNetmask( + string address) + { + int index = address.IndexOf('/'); + string mask = address.Substring(index + 1); + + return (index > 0) && IsValidIPv4(address.Substring(0, index)) + && (IsValidIPv4(mask) || IsMaskValue(mask, 32)); + } + + public static bool IsValidIPv6WithNetmask( + string address) + { + int index = address.IndexOf('/'); + string mask = address.Substring(index + 1); + + return (index > 0) && (IsValidIPv6(address.Substring(0, index)) + && (IsValidIPv6(mask) || IsMaskValue(mask, 128))); + } + + private static bool IsMaskValue( + string component, + int size) + { + int val = Int32.Parse(component); + try + { + return val >= 0 && val <= size; + } + catch (FormatException) {} + catch (OverflowException) {} + return false; + } + + /** + * Validate the given IPv6 address. + * + * @param address the IP address as a string. + * + * @return true if a valid IPv4 address, false otherwise + */ + public static bool IsValidIPv6( + string address) + { + try + { + return unsafeIsValidIPv6(address); + } + catch (FormatException) {} + catch (OverflowException) {} + return false; + } + + private static bool unsafeIsValidIPv6( + string address) + { + if (address.Length == 0) + { + return false; + } + + int octets = 0; + + string temp = address + ":"; + bool doubleColonFound = false; + int pos; + int start = 0; + while (start < temp.Length + && (pos = temp.IndexOf(':', start)) >= start) + { + if (octets == 8) + { + return false; + } + + if (start != pos) + { + string value = temp.Substring(start, pos - start); + + if (pos == (temp.Length - 1) && value.IndexOf('.') > 0) + { + if (!IsValidIPv4(value)) + { + return false; + } + + octets++; // add an extra one as address covers 2 words. + } + else + { + string octetStr = temp.Substring(start, pos - start); + int octet = Int32.Parse(octetStr, NumberStyles.AllowHexSpecifier); + + if (octet < 0 || octet > 0xffff) + return false; + } + } + else + { + if (pos != 1 && pos != temp.Length - 1 && doubleColonFound) + { + return false; + } + doubleColonFound = true; + } + start = pos + 1; + octets++; + } + + return octets == 8 || doubleColonFound; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs.meta new file mode 100644 index 0000000..6cc1fba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/net/IPAddress.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c829f456cc2252e4da1989ca55f8c0b8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib.meta new file mode 100644 index 0000000..31aedd7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4d3c9d4702c5ca34fa5b819f8f2c5850 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs new file mode 100644 index 0000000..f1a554e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs @@ -0,0 +1,92 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: Adler32.cs,v 1.1 2006-07-31 13:59:25 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class Adler32{ + + // largest prime smaller than 65536 + private const int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + private const int NMAX=5552; + + internal long adler32(long adler, byte[] buf, int index, int len){ + if(buf == null){ return 1L; } + + long s1=adler&0xffff; + long s2=(adler>>16)&0xffff; + int k; + + while(len > 0) { + k=len=16){ + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + k-=16; + } + if(k!=0){ + do{ + s1+=buf[index++]&0xff; s2+=s1; + } + while(--k!=0); + } + s1%=BASE; + s2%=BASE; + } + return (s2<<16)|s1; + } + + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs.meta new file mode 100644 index 0000000..0ee7045 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Adler32.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2cfff793e226e3941b78bc3b1d5a873b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs new file mode 100644 index 0000000..e3ad91f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs @@ -0,0 +1,1644 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: Deflate.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + public sealed class Deflate{ + + private const int MAX_MEM_LEVEL=9; + + private const int Z_DEFAULT_COMPRESSION=-1; + + private const int MAX_WBITS=15; // 32K LZ77 window + private const int DEF_MEM_LEVEL=8; + + internal class Config{ + internal int good_length; // reduce lazy search above this match length + internal int max_lazy; // do not perform lazy search above this match length + internal int nice_length; // quit search above this match length + internal int max_chain; + internal int func; + internal Config(int good_length, int max_lazy, + int nice_length, int max_chain, int func){ + this.good_length=good_length; + this.max_lazy=max_lazy; + this.nice_length=nice_length; + this.max_chain=max_chain; + this.func=func; + } + } + + private const int STORED=0; + private const int FAST=1; + private const int SLOW=2; + private static readonly Config[] config_table; + + static Deflate(){ + config_table=new Config[10]; + // good lazy nice chain + config_table[0]=new Config(0, 0, 0, 0, STORED); + config_table[1]=new Config(4, 4, 8, 4, FAST); + config_table[2]=new Config(4, 5, 16, 8, FAST); + config_table[3]=new Config(4, 6, 32, 32, FAST); + + config_table[4]=new Config(4, 4, 16, 16, SLOW); + config_table[5]=new Config(8, 16, 32, 32, SLOW); + config_table[6]=new Config(8, 16, 128, 128, SLOW); + config_table[7]=new Config(8, 32, 128, 256, SLOW); + config_table[8]=new Config(32, 128, 258, 1024, SLOW); + config_table[9]=new Config(32, 258, 258, 4096, SLOW); + } + + private static readonly String[] z_errmsg = { + "need dictionary", // Z_NEED_DICT 2 + "stream end", // Z_STREAM_END 1 + "", // Z_OK 0 + "file error", // Z_ERRNO (-1) + "stream error", // Z_STREAM_ERROR (-2) + "data error", // Z_DATA_ERROR (-3) + "insufficient memory", // Z_MEM_ERROR (-4) + "buffer error", // Z_BUF_ERROR (-5) + "incompatible version",// Z_VERSION_ERROR (-6) + "" + }; + + // block not completed, need more input or more output + private const int NeedMore=0; + + // block flush performed + private const int BlockDone=1; + + // finish started, need only more output at next deflate + private const int FinishStarted=2; + + // finish done, accept no more input or output + private const int FinishDone=3; + + // preset dictionary flag in zlib header + private const int PRESET_DICT=0x20; + + private const int Z_FILTERED=1; + private const int Z_HUFFMAN_ONLY=2; + private const int Z_DEFAULT_STRATEGY=0; + + private const int Z_NO_FLUSH=0; + private const int Z_PARTIAL_FLUSH=1; + private const int Z_SYNC_FLUSH=2; + private const int Z_FULL_FLUSH=3; + private const int Z_FINISH=4; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + private const int INIT_STATE=42; + private const int BUSY_STATE=113; + private const int FINISH_STATE=666; + + // The deflate compression method + private const int Z_DEFLATED=8; + + private const int STORED_BLOCK=0; + private const int STATIC_TREES=1; + private const int DYN_TREES=2; + + // The three kinds of block type + private const int Z_BINARY=0; + private const int Z_ASCII=1; + private const int Z_UNKNOWN=2; + + private const int Buf_size=8*2; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + private const int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + private const int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + private const int REPZ_11_138=18; + + private const int MIN_MATCH=3; + private const int MAX_MATCH=258; + private const int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); + + private const int MAX_BITS=15; + private const int D_CODES=30; + private const int BL_CODES=19; + private const int LENGTH_CODES=29; + private const int LITERALS=256; + private const int L_CODES=(LITERALS+1+LENGTH_CODES); + private const int HEAP_SIZE=(2*L_CODES+1); + + private const int END_BLOCK=256; + + internal ZStream strm; // pointer back to this zlib stream + internal int status; // as the name implies + internal byte[] pending_buf; // output still pending + internal int pending_buf_size; // size of pending_buf + internal int pending_out; // next pending byte to output to the stream + internal int pending; // nb of bytes in the pending buffer + internal int noheader; // suppress zlib header and adler32 + internal byte data_type; // UNKNOWN, BINARY or ASCII + internal byte method; // STORED (for zip only) or DEFLATED + internal int last_flush; // value of flush param for previous deflate call + + internal int w_size; // LZ77 window size (32K by default) + internal int w_bits; // log2(w_size) (8..16) + internal int w_mask; // w_size - 1 + + internal byte[] window; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: use the user input buffer as sliding window. + + internal int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + internal short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + internal short[] head; // Heads of the hash chains or NIL. + + internal int ins_h; // hash index of string to be inserted + internal int hash_size; // number of elements in hash table + internal int hash_bits; // log2(hash_size) + internal int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + internal int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + internal int block_start; + + internal int match_length; // length of best match + internal int prev_match; // previous match + internal int match_available; // set if previous match exists + internal int strstart; // start of string to insert + internal int match_start; // start of matching string + internal int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + internal int prev_length; + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + internal int max_chain_length; + + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + internal int max_lazy_match; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + internal int level; // compression level (1..9) + internal int strategy; // favor or force Huffman coding + + // Use a faster search when the previous match is longer than this + internal int good_match; + + // Stop searching when current match exceeds this + internal int nice_match; + + internal short[] dyn_ltree; // literal and length tree + internal short[] dyn_dtree; // distance tree + internal short[] bl_tree; // Huffman tree for bit lengths + + internal ZTree l_desc=new ZTree(); // desc for literal tree + internal ZTree d_desc=new ZTree(); // desc for distance tree + internal ZTree bl_desc=new ZTree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + internal short[] bl_count=new short[MAX_BITS+1]; + + // heap used to build the Huffman trees + internal int[] heap=new int[2*L_CODES+1]; + + internal int heap_len; // number of elements in the heap + internal int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + internal byte[] depth=new byte[2*L_CODES+1]; + + internal int l_buf; // index for literals or lengths */ + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + // - I can't count above 4 + internal int lit_bufsize; + + internal int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + internal int d_buf; // index of pendig_buf + + internal int opt_len; // bit length of current block with optimal trees + internal int static_len; // bit length of current block with static trees + internal int matches; // number of string matches in current block + internal int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + internal uint bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + internal int bi_valid; + + internal Deflate(){ + dyn_ltree=new short[HEAP_SIZE*2]; + dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree + bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths + } + + internal void lm_init() { + window_size=2*w_size; + + head[hash_size-1]=0; + for(int i=0; i= 3; max_blindex--) { + if (bl_tree[ZTree.bl_order[max_blindex]*2+1] != 0) break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + internal void send_all_trees(int lcodes, int dcodes, int blcodes){ + int rank; // index in bl_order + + send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes-1, 5); + send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + send_bits(bl_tree[ZTree.bl_order[rank]*2+1], 3); + } + send_tree(dyn_ltree, lcodes-1); // literal tree + send_tree(dyn_dtree, dcodes-1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + internal void send_tree (short[] tree,// the tree to be sent + int max_code // and its largest code of non zero frequency + ){ + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0*2+1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0){ max_count = 138; min_count = 3; } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[(n+1)*2+1]; + if(++count < max_count && curlen == nextlen) { + continue; + } + else if(count < min_count) { + do { send_code(curlen, bl_tree); } while (--count != 0); + } + else if(curlen != 0){ + if(curlen != prevlen){ + send_code(curlen, bl_tree); count--; + } + send_code(REP_3_6, bl_tree); + send_bits(count-3, 2); + } + else if(count <= 10){ + send_code(REPZ_3_10, bl_tree); + send_bits(count-3, 3); + } + else{ + send_code(REPZ_11_138, bl_tree); + send_bits(count-11, 7); + } + count = 0; prevlen = curlen; + if(nextlen == 0){ + max_count = 138; min_count = 3; + } + else if(curlen == nextlen){ + max_count = 6; min_count = 3; + } + else{ + max_count = 7; min_count = 4; + } + } + } + + // Output a byte on the stream. + // IN assertion: there is enough room in pending_buf. + internal void put_byte(byte[] p, int start, int len){ + System.Array.Copy(p, start, pending_buf, pending, len); + pending+=len; + } + + internal void put_byte(byte c){ + pending_buf[pending++]=c; + } + internal void put_short(int w) { + pending_buf[pending++]=(byte)(w/*&0xff*/); + pending_buf[pending++]=(byte)(w>>8); + } + internal void putShortMSB(int b){ + pending_buf[pending++]=(byte)(b>>8); + pending_buf[pending++]=(byte)(b/*&0xff*/); + } + + internal void send_code(int c, short[] tree){ + int c2=c*2; + send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); + } + + internal void send_bits(int val, int length){ + if (bi_valid > Buf_size - length) { + bi_buf |= (uint)(val << bi_valid); + pending_buf[pending++]=(byte)(bi_buf/*&0xff*/); + pending_buf[pending++]=(byte)(bi_buf>>8); + bi_buf = ((uint)val) >> (Buf_size - bi_valid); + bi_valid += length - Buf_size; + } else { + bi_buf |= (uint)(val << bi_valid); + bi_valid += length; + } +// int len = length; +// if (bi_valid > (int)Buf_size - len) { +// int val = value; +// // bi_buf |= (val << bi_valid); +// bi_buf = (short)((ushort)bi_buf | (ushort)((val << bi_valid)&0xffff)); +// put_short(bi_buf); +// bi_buf = (short)(((uint)val) >> (Buf_size - bi_valid)); +// bi_valid += len - Buf_size; +// } else { +// // bi_buf |= (value) << bi_valid; +// bi_buf = (short)((ushort)bi_buf | (ushort)(((value) << bi_valid)&0xffff)); +// bi_valid += len; +// } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + internal void _tr_align(){ + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) { + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + internal bool _tr_tally (int dist, // distance of matched string + int lc // match length-MIN_MATCH or unmatched char (if dist==0) + ){ + + pending_buf[d_buf+last_lit*2] = (byte)(dist>>8); + pending_buf[d_buf+last_lit*2+1] = (byte)dist; + + pending_buf[l_buf+last_lit] = (byte)lc; last_lit++; + + if (dist == 0) { + // lc is the unmatched char + dyn_ltree[lc*2]++; + } + else { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(ZTree._length_code[lc]+LITERALS+1)*2]++; + dyn_dtree[ZTree.d_code(dist)*2]++; + } + + if ((last_lit & 0x1fff) == 0 && level > 2) { + // Compute an upper bound for the compressed length + int out_length = last_lit*8; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (int)((int)dyn_dtree[dcode*2] * + (5L+ZTree.extra_dbits[dcode])); + } + out_length >>= 3; + if ((matches < (last_lit/2)) && out_length < in_length/2) return true; + } + + return (last_lit == lit_bufsize-1); + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + // Send the block data compressed using the given Huffman trees + internal void compress_block(short[] ltree, short[] dtree){ + int dist; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0){ + do{ + dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| + (pending_buf[d_buf+lx*2+1]&0xff); + lc=(pending_buf[l_buf+lx])&0xff; lx++; + + if(dist == 0){ + send_code(lc, ltree); // send a literal byte + } + else{ + // Here, lc is the match length - MIN_MATCH + code = ZTree._length_code[lc]; + + send_code(code+LITERALS+1, ltree); // send the length code + extra = ZTree.extra_lbits[code]; + if(extra != 0){ + lc -= ZTree.base_length[code]; + send_bits(lc, extra); // send the extra length bits + } + dist--; // dist is now the match distance - 1 + code = ZTree.d_code(dist); + + send_code(code, dtree); // send the distance code + extra = ZTree.extra_dbits[code]; + if (extra != 0) { + dist -= ZTree.base_dist[code]; + send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + + // Check that the overlay between pending_buf and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK*2+1]; + } + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + internal void set_data_type(){ + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} + while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} + while(n (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); + } + + // Flush the bit buffer, keeping at most 7 bits in it. + internal void bi_flush(){ + if (bi_valid == 16) { + pending_buf[pending++]=(byte)(bi_buf/*&0xff*/); + pending_buf[pending++]=(byte)(bi_buf>>8); + bi_buf=0; + bi_valid=0; + } + else if (bi_valid >= 8) { + pending_buf[pending++]=(byte)(bi_buf); + bi_buf>>=8; + bi_buf &= 0x00ff; + bi_valid-=8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + internal void bi_windup(){ + if (bi_valid > 8) { + pending_buf[pending++]=(byte)(bi_buf); + pending_buf[pending++]=(byte)(bi_buf>>8); + } else if (bi_valid > 0) { + pending_buf[pending++]=(byte)(bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + internal void copy_block(int buf, // the input data + int len, // its length + bool header // true if block header must be written + ){ + //int index=0; + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) { + put_short((short)len); + put_short((short)~len); + } + + // while(len--!=0) { + // put_byte(window[buf+index]); + // index++; + // } + put_byte(window, buf, len); + } + + internal void flush_block_only(bool eof){ + _tr_flush_block(block_start>=0 ? block_start : -1, + strstart-block_start, + eof); + block_start=strstart; + strm.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + internal int deflate_stored(int flush){ + // Stored blocks are limited to 0xffff bytes, pending_buf is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if(max_block_size > pending_buf_size - 5) { + max_block_size = pending_buf_size - 5; + } + + // Copy as much as possible from input to output: + while(true){ + // Fill the window as much as possible: + if(lookahead<=1){ + fill_window(); + if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; + if(lookahead==0) break; // flush the current block + } + + strstart+=lookahead; + lookahead=0; + + // Emit a stored block if pending_buf will be full: + max_start=block_start+max_block_size; + if(strstart==0|| strstart>=max_start) { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart-max_start); + strstart = (int)max_start; + + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + } + } + + flush_block_only(flush == Z_FINISH); + if(strm.avail_out==0) + return (flush == Z_FINISH) ? FinishStarted : NeedMore; + + return flush == Z_FINISH ? FinishDone : BlockDone; + } + + // Send a stored block + internal void _tr_stored_block(int buf, // input block + int stored_len, // length of input block + bool eof // true if this is the last block for a file + ){ + send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + internal void _tr_flush_block(int buf, // input block, or NULL if too old + int stored_len, // length of input block + bool eof // true if this is the last block for a file + ) { + int opt_lenb, static_lenb;// opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if(level > 0) { + // Check if the file is ascii or binary + if(data_type == Z_UNKNOWN) set_data_type(); + + // Construct the literal and distance trees + l_desc.build_tree(this); + + d_desc.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex=build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb=(opt_len+3+7)>>3; + static_lenb=(static_len+3+7)>>3; + + if(static_lenb<=opt_lenb) opt_lenb=static_lenb; + } + else { + opt_lenb=static_lenb=stored_len+5; // force a stored block + } + + if(stored_len+4<=opt_lenb && buf != -1){ + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if(static_lenb == opt_lenb){ + send_bits((STATIC_TREES<<1)+(eof?1:0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else{ + send_bits((DYN_TREES<<1)+(eof?1:0), 3); + send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); + compress_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + init_block(); + + if(eof){ + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + internal void fill_window(){ + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do{ + more = (window_size-lookahead-strstart); + + // Deal with !@#$% 64K limit: + if(more==0 && strstart==0 && lookahead==0){ + more = w_size; + } + else if(more==-1) { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { + System.Array.Copy(window, w_size, window, 0, w_size); + match_start-=w_size; + strstart-=w_size; // we now have strstart >= MAX_DIST + block_start-=w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p=n; + do { + m = (head[--p]&0xffff); + head[p]=(short)(m>=w_size ? (m-w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do { + m = (prev[--p]&0xffff); + prev[p] = (short)(m >= w_size ? (m-w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n!=0); + more += w_size; + } + + if (strm.avail_in == 0) return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = strm.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if(lookahead >= MIN_MATCH) { + ins_h = window[strstart]&0xff; + ins_h=(((ins_h)<= MIN_MATCH){ + ins_h=(((ins_h)<=MIN_MATCH){ + // check_match(strstart, match_start, match_length); + + bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if(match_length <= max_lazy_match && + lookahead >= MIN_MATCH) { + match_length--; // string at strstart already in hash table + do{ + strstart++; + + ins_h=((ins_h<= MIN_MATCH) { + ins_h=(((ins_h)< 4096))) { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH-1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if(prev_length >= MIN_MATCH && match_length <= prev_length) { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= prev_length-1; + prev_length -= 2; + do{ + if(++strstart <= max_insert) { + ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? + strstart-(w_size-MIN_LOOKAHEAD) : 0; + int nice_match=this.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan+best_len-1]; + byte scan_end = window[scan+best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= good_match) { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (nice_match > lookahead) nice_match = lookahead; + + do { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match+best_len] != scan_end || + window[match+best_len-1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan+1]) continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do { + } while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if(len>best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; + scan_end1 = window[scan+best_len-1]; + scan_end = window[scan+best_len]; + } + + } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit + && --chain_length != 0); + + if (best_len <= lookahead) return best_len; + return lookahead; + } + + internal int deflateInit(ZStream strm, int level, int bits){ + return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY); + } + internal int deflateInit(ZStream strm, int level){ + return deflateInit(strm, level, MAX_WBITS); + } + internal int deflateInit2(ZStream strm, int level, int method, int windowBits, + int memLevel, int strategy){ + int noheader = 0; + // byte[] my_version=ZLIB_VERSION; + + // + // if (version == null || version[0] != my_version[0] + // || stream_size != sizeof(z_stream)) { + // return Z_VERSION_ERROR; + // } + + strm.msg = null; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { // undocumented feature: suppress zlib header + noheader = 1; + windowBits = -windowBits; + } + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || + method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + strm.dstate = (Deflate)this; + + this.noheader = noheader; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); + + window = new byte[w_size*2]; + prev = new short[w_size]; + head = new short[hash_size]; + + lit_bufsize = 1 << (memLevel + 6); // 16K elements by default + + // We overlay pending_buf and d_buf+l_buf. This works since the average + // output size for (length,distance) codes is <= 24 bits. + pending_buf = new byte[lit_bufsize*4]; + pending_buf_size = lit_bufsize*4; + + d_buf = lit_bufsize/2; + l_buf = (1+2)*lit_bufsize; + + this.level = level; + + //System.out.println("level="+level); + + this.strategy = strategy; + this.method = (byte)method; + + return deflateReset(strm); + } + + internal int deflateReset(ZStream strm){ + strm.total_in = strm.total_out = 0; + strm.msg = null; // + strm.data_type = Z_UNKNOWN; + + pending = 0; + pending_out = 0; + + if(noheader < 0) { + noheader = 0; // was set to -1 by deflate(..., Z_FINISH); + } + status = (noheader!=0) ? BUSY_STATE : INIT_STATE; + strm.adler=strm._adler.adler32(0, null, 0, 0); + + last_flush = Z_NO_FLUSH; + + tr_init(); + lm_init(); + return Z_OK; + } + + internal int deflateEnd(){ + if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ + return Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending_buf=null; + head=null; + prev=null; + window=null; + // free + // dstate=null; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + } + + internal int deflateParams(ZStream strm, int _level, int _strategy){ + int err=Z_OK; + + if(_level == Z_DEFAULT_COMPRESSION){ + _level = 6; + } + if(_level < 0 || _level > 9 || + _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + if(config_table[level].func!=config_table[_level].func && + strm.total_in != 0) { + // Flush the last buffer: + err = strm.deflate(Z_PARTIAL_FLUSH); + } + + if(level != _level) { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return err; + } + + internal int deflateSetDictionary (ZStream strm, byte[] dictionary, int dictLength){ + int length = dictLength; + int index=0; + + if(dictionary == null || status != INIT_STATE) + return Z_STREAM_ERROR; + + strm.adler=strm._adler.adler32(strm.adler, dictionary, 0, dictLength); + + if(length < MIN_MATCH) return Z_OK; + if(length > w_size-MIN_LOOKAHEAD){ + length = w_size-MIN_LOOKAHEAD; + index=dictLength-length; // use the tail of the dictionary + } + System.Array.Copy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0]&0xff; + ins_h=(((ins_h)<Z_FINISH || flush<0){ + return Z_STREAM_ERROR; + } + + if(strm.next_out == null || + (strm.next_in == null && strm.avail_in != 0) || + (status == FINISH_STATE && flush != Z_FINISH)) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; + return Z_STREAM_ERROR; + } + if(strm.avail_out == 0){ + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + this.strm = strm; // just in case + old_flush = last_flush; + last_flush = flush; + + // Write the zlib header + if(status == INIT_STATE) { + int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; + int level_flags=((level-1)&0xff)>>1; + + if(level_flags>3) level_flags=3; + header |= (level_flags<<6); + if(strstart!=0) header |= PRESET_DICT; + header+=31-(header % 31); + + status=BUSY_STATE; + putShortMSB(header); + + + // Save the adler32 of the preset dictionary: + if(strstart!=0){ + putShortMSB((int)(strm.adler>>16)); + putShortMSB((int)(strm.adler&0xffff)); + } + strm.adler=strm._adler.adler32(0, null, 0, 0); + } + + // Flush as much pending output as possible + if(pending != 0) { + strm.flush_pending(); + if(strm.avail_out == 0) { + //System.out.println(" avail_out==0"); + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if(strm.avail_in==0 && flush <= old_flush && + flush != Z_FINISH) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // User must not provide more input after the first FINISH: + if(status == FINISH_STATE && strm.avail_in != 0) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // Start a new block or continue the current one. + if(strm.avail_in!=0 || lookahead!=0 || + (flush != Z_NO_FLUSH && status != FINISH_STATE)) { + int bstate=-1; + switch(config_table[level].func){ + case STORED: + bstate = deflate_stored(flush); + break; + case FAST: + bstate = deflate_fast(flush); + break; + case SLOW: + bstate = deflate_slow(flush); + break; + default: + break; + } + + if (bstate==FinishStarted || bstate==FinishDone) { + status = FINISH_STATE; + } + if (bstate==NeedMore || bstate==FinishStarted) { + if(strm.avail_out == 0) { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate==BlockDone) { + if(flush == Z_PARTIAL_FLUSH) { + _tr_align(); + } + else { // FULL_FLUSH or SYNC_FLUSH + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if(flush == Z_FULL_FLUSH) { + //state.head[s.hash_size-1]=0; + for(int i=0; i>16)); + putShortMSB((int)(strm.adler&0xffff)); + strm.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + noheader = -1; // write the trailer only once! + return pending != 0 ? Z_OK : Z_STREAM_END; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs.meta new file mode 100644 index 0000000..9e81730 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/Deflate.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d29c091390e4c924b9c9cd53bc19b4e9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs new file mode 100644 index 0000000..6256e07 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs @@ -0,0 +1,622 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: InfBlocks.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class InfBlocks{ + private const int MANY=1440; + + // And'ing with mask[n] masks the lower n bits + private static readonly int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + // Table for deflate from PKZIP's appnote.txt. + static readonly int[] border = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + private const int TYPE=0; // get type bits (3, including end bit) + private const int LENS=1; // get lengths for stored + private const int STORED=2;// processing stored block + private const int TABLE=3; // get table lengths + private const int BTREE=4; // get bit lengths tree for a dynamic block + private const int DTREE=5; // get length, distance trees for a dynamic block + private const int CODES=6; // processing fixed or dynamic block + private const int DRY=7; // output remaining window bytes + private const int DONE=8; // finished last block, done + private const int BAD=9; // ot a data error--stuck here + + internal int mode; // current inflate_block mode + + internal int left; // if STORED, bytes left to copy + + internal int table; // table lengths (14 bits) + internal int index; // index into blens (or border) + internal int[] blens; // bit lengths of codes + internal int[] bb=new int[1]; // bit length tree depth + internal int[] tb=new int[1]; // bit length decoding tree + + internal InfCodes codes=new InfCodes(); // if CODES, current state + + int last; // true if this block is the last block + + // mode independent information + internal int bitk; // bits in bit buffer + internal int bitb; // bit buffer + internal int[] hufts; // single malloc for tree space + internal byte[] window; // sliding window + internal int end; // one byte after sliding window + internal int read; // window read pointer + internal int write; // window write pointer + internal Object checkfn; // check function + internal long check; // check on output + + internal InfTree inftree=new InfTree(); + + internal InfBlocks(ZStream z, Object checkfn, int w){ + hufts=new int[MANY*3]; + window=new byte[w]; + end=w; + this.checkfn = checkfn; + mode = TYPE; + reset(z, null); + } + + internal void reset(ZStream z, long[] c){ + if(c!=null) c[0]=check; + if(mode==BTREE || mode==DTREE){ + } + if(mode==CODES){ + codes.free(z); + } + mode=TYPE; + bitk=0; + bitb=0; + read=write=0; + + if(checkfn != null) + z.adler=check=z._adler.adler32(0L, null, 0, 0); + } + + internal int proc(ZStream z, int r){ + int t; // temporary storage + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; { // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;} { + q=write;m=(int)(q> 1){ + case 0: { // stored + b>>=(3);k-=(3);} + t = k & 7; { // go to byte boundary + + b>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: { // fixed + int[] bl=new int[1]; + int[] bd=new int[1]; + int[][] tl=new int[1][]; + int[][] td=new int[1][]; + + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z); + } { + + b>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: { // dynamic + + b>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: { // illegal + + b>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(int)(qn) t = n; + if(t>m) t = m; + System.Array.Copy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.Length>=(14);k-=(14);} + + index = 0; + mode = BTREE; + goto case BTREE; + case BTREE: + while (index < 4 + (table >> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + + index = 0; + mode = DTREE; + goto case DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; { + int[] bl=new int[1]; + int[] bd=new int[1]; + int[] tl=new int[1]; + int[] td=new int[1]; + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tl, td, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + codes.init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); + } + mode = CODES; + goto case CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(this, z, r)) != Z_STREAM_END){ + return inflate_flush(z, r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(int)(q z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(checkfn != null) + z.adler=check=z._adler.adler32(check, window, q, n); + + // copy as far as end of window + System.Array.Copy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(checkfn != null) + z.adler=check=z._adler.adler32(check, window, q, n); + + // copy + System.Array.Copy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs.meta new file mode 100644 index 0000000..c864710 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfBlocks.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 39991dab49f0a85419083ecf2f53dc90 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs new file mode 100644 index 0000000..7b18d89 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs @@ -0,0 +1,615 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: InfCodes.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class InfCodes{ + + private static readonly int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + private const int START=0; // x: set up for LEN + private const int LEN=1; // i: get length/literal/eob next + private const int LENEXT=2; // i: getting length extra (have base) + private const int DIST=3; // i: get distance next + private const int DISTEXT=4;// i: getting distance extra + private const int COPY=5; // o: copying bytes in window, waiting for space + private const int LIT=6; // o: got literal, waiting for output space + private const int WASH=7; // o: got eob, possibly still output waiting + private const int END=8; // x: got eob and all data flushed + private const int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + internal InfCodes(){ + } + internal void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index, ZStream z){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + internal int proc(InfBlocks s, ZStream z, int r){ + int j; // temporary storage + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + goto case DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + goto case COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(z,r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + System.Array.Copy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + System.Array.Copy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + System.Array.Copy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs.meta new file mode 100644 index 0000000..1d7e041 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfCodes.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5900c7f6a2d2b704596f30b1ff8334c8 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfTree.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfTree.cs new file mode 100644 index 0000000..50a1300 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/InfTree.cs @@ -0,0 +1,527 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: InfTree.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class InfTree{ + + private const int MANY=1440; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + private const int fixed_bl = 9; + private const int fixed_bd = 5; + + static readonly int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static readonly int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static readonly int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static readonly int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static readonly int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static readonly int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + const int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>(w - l); + r[2] = (int)(q - u[h-1] - j); // offset to this table + System.Array.Copy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>w;j>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + internal int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + internal int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + internal static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.Lengthstate); + return Z_OK; + } + + internal int inflateInit(ZStream z, int w){ + z.msg = null; + blocks = null; + + // handle undocumented nowrap option (no zlib header or check) + nowrap = 0; + if(w < 0){ + w = - w; + nowrap = 1; + } + + // set window size + if(w<8 ||w>15){ + inflateEnd(z); + return Z_STREAM_ERROR; + } + wbits=w; + + z.istate.blocks=new InfBlocks(z, + z.istate.nowrap!=0 ? null : this, + 1<>4)+8>z.istate.wbits){ + z.istate.mode = BAD; + z.msg="invalid window size"; + z.istate.marker = 5; // can't try inflateSync + break; + } + z.istate.mode=FLAG; + goto case FLAG; + case FLAG: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + b = (z.next_in[z.next_in_index++])&0xff; + + if((((z.istate.method << 8)+b) % 31)!=0){ + z.istate.mode = BAD; + z.msg = "incorrect header check"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + if((b&PRESET_DICT)==0){ + z.istate.mode = BLOCKS; + break; + } + z.istate.mode = DICT4; + goto case DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + z.istate.mode=DICT3; + goto case DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + z.istate.mode=DICT2; + goto case DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + z.istate.mode=DICT1; + goto case DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler = z.istate.need; + z.istate.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z.istate.mode = BAD; + z.msg = "need dictionary"; + z.istate.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + + r = z.istate.blocks.proc(z, r); + if(r == Z_DATA_ERROR){ + z.istate.mode = BAD; + z.istate.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + z.istate.blocks.reset(z, z.istate.was); + if(z.istate.nowrap!=0){ + z.istate.mode=DONE; + break; + } + z.istate.mode=CHECK4; + goto case CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + z.istate.mode=CHECK3; + goto case CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + z.istate.mode = CHECK2; + goto case CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + z.istate.mode = CHECK1; + goto case CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(((int)(z.istate.was[0])) != ((int)(z.istate.need))){ + z.istate.mode = BAD; + z.msg = "incorrect data check"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + z.istate.mode = DONE; + goto case DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } + } + } + + + internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength){ + int index=0; + int length = dictLength; + if(z==null || z.istate == null|| z.istate.mode != DICT0) + return Z_STREAM_ERROR; + + if(z._adler.adler32(1L, dictionary, 0, dictLength)!=z.adler){ + return Z_DATA_ERROR; + } + + z.adler = z._adler.adler32(0, null, 0, 0); + + if(length >= (1< 0) + { + output.Write(buf, 0, count); + } + } + while (z.avail_in > 0 || z.avail_out == 0); + + Flush(); + } + + public override void Flush() + { + output.Flush(); + } + + public virtual int FlushMode + { + get { return flushLevel; } + set { this.flushLevel = value; } + } + + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + + public virtual long TotalIn + { + get { return z.total_in; } + } + + public virtual long TotalOut + { + get { return z.total_out; } + } + + public override void Write(byte[] b, int off, int len) + { + if (len == 0) + return; + + z.next_in = b; + z.next_in_index = off; + z.avail_in = len; + + do + { + z.next_out = buf; + z.next_out_index = 0; + z.avail_out = buf.Length; + + int err = compress + ? z.deflate(flushLevel) + : z.inflate(flushLevel); + + if (err != JZlib.Z_OK) + // TODO +// throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); + + output.Write(buf, 0, buf.Length - z.avail_out); + } + while (z.avail_in > 0 || z.avail_out == 0); + } + + public override void WriteByte(byte b) + { + buf1[0] = b; + Write(buf1, 0, 1); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZOutputStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZOutputStream.cs.meta new file mode 100644 index 0000000..b658ae8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZOutputStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7184782482afa5f43b30b456f1930268 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs new file mode 100644 index 0000000..7864f74 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs @@ -0,0 +1,218 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: ZStream.cs,v 1.1 2006-07-31 13:59:26 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + public sealed class ZStream{ + + private const int MAX_WBITS=15; // 32K LZ77 window + private const int DEF_WBITS=MAX_WBITS; + + private const int Z_NO_FLUSH=0; + private const int Z_PARTIAL_FLUSH=1; + private const int Z_SYNC_FLUSH=2; + private const int Z_FULL_FLUSH=3; + private const int Z_FINISH=4; + + private const int MAX_MEM_LEVEL=9; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + public byte[] next_in; // next input byte + public int next_in_index; + public int avail_in; // number of bytes available at next_in + public long total_in; // total nb of input bytes read so far + + public byte[] next_out; // next output byte should be put there + public int next_out_index; + public int avail_out; // remaining free space at next_out + public long total_out; // total nb of bytes output so far + + public String msg; + + internal Deflate dstate; + internal Inflate istate; + + internal int data_type; // best guess about the data type: ascii or binary + + public long adler; + internal Adler32 _adler=new Adler32(); + + public int inflateInit(){ + return inflateInit(DEF_WBITS); + } + public int inflateInit(bool nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + public int inflateInit(int w){ + return inflateInit(w, false); + } + + public int inflateInit(int w, bool nowrap){ + istate=new Inflate(); + return istate.inflateInit(this, nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(this, f); + } + public int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(this); + istate = null; + return ret; + } + public int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(this); + } + public int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(this, dictionary, dictLength); + } + + public int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + public int deflateInit(int level, bool nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + public int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + public int deflateInit(int level, int bits, bool nowrap){ + dstate=new Deflate(); + return dstate.deflateInit(this, level, nowrap?-bits:bits); + } + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(this, flush); + } + public int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + public int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(this, level, strategy); + } + public int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(this, dictionary, dictLength); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + internal void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.Length<=dstate.pending_out || + next_out.Length<=next_out_index || + dstate.pending_buf.Length<(dstate.pending_out+len) || + next_out.Length<(next_out_index+len)){ + // System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + // System.out.println("avail_out="+avail_out); + } + + System.Array.Copy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + internal int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.noheader==0) { + adler=_adler.adler32(adler, next_in, next_in_index, len); + } + System.Array.Copy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + _adler=null; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs.meta new file mode 100644 index 0000000..52c208d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZStream.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8ddcf6fa74a82c246a547246aefee100 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs new file mode 100644 index 0000000..8d3f53c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs @@ -0,0 +1,371 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +/* + * $Id: Tree.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class ZTree{ + private const int MAX_BITS=15; + private const int BL_CODES=19; + private const int D_CODES=30; + private const int LITERALS=256; + private const int LENGTH_CODES=29; + private const int L_CODES=(LITERALS+1+LENGTH_CODES); + private const int HEAP_SIZE=(2*L_CODES+1); + + // Bit length codes must not exceed MAX_BL_BITS bits + internal const int MAX_BL_BITS=7; + + // end of block literal code + internal const int END_BLOCK=256; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + internal const int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + internal const int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + internal const int REPZ_11_138=18; + + // extra bits for each length code + internal static readonly int[] extra_lbits={ + 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 + }; + + // extra bits for each distance code + internal static readonly int[] extra_dbits={ + 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 + }; + + // extra bits for each bit length code + internal static readonly int[] extra_blbits={ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 + }; + + internal static readonly byte[] bl_order={ + 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + internal const int Buf_size=8*2; + + // see definition of array dist_code below + internal const int DIST_CODE_LEN=512; + + internal static readonly byte[] _dist_code = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + internal static readonly byte[] _length_code={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + internal static readonly int[] base_length = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + internal static readonly int[] base_dist = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + // Mapping from a distance to a distance code. dist is the distance - 1 and + // must not have side effects. _dist_code[256] and _dist_code[257] are never + // used. + internal static int d_code(int dist){ + return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]); + } + + internal short[] dyn_tree; // the dynamic tree + internal int max_code; // largest code with non zero frequency + internal StaticTree stat_desc; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + internal void gen_bitlen(Deflate s){ + short[] tree = dyn_tree; + short[] stree = stat_desc.static_tree; + int[] extra = stat_desc.extra_bits; + int based = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap + + for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } + tree[n*2+1] = (short)bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= based) xbits = extra[n-based]; + f = tree[n*2]; + s.opt_len += f * (bits + xbits); + if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); + } + if (overflow == 0) return; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do { + bits = max_length-1; + while(s.bl_count[bits]==0) bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits+1]+=2; // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = s.bl_count[bits]; + while (n != 0) { + m = s.heap[--h]; + if (m > max_code) continue; + if (tree[m*2+1] != bits) { + s.opt_len += (int)(((long)bits - (long)tree[m*2+1])*(long)tree[m*2]); + tree[m*2+1] = (short)bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + internal void build_tree(Deflate s){ + short[] tree=dyn_tree; + short[] stree=stat_desc.static_tree; + int elems=stat_desc.elems; + int n, m; // iterate over heap elements + int max_code=-1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for(n=0; n=1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node=elems; // next internal node of the tree + do{ + // n = node of least frequency + n=s.heap[1]; + s.heap[1]=s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m=s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node*2] = (short)(tree[n*2] + tree[m*2]); + s.depth[node] = (byte)(System.Math.Max(s.depth[n],s.depth[m])+1); + tree[n*2+1] = tree[m*2+1] = (short)node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while(s.heap_len>=2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + internal static void gen_codes(short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count // number of codes at each bit length + ){ + short[] next_code=new short[MAX_BITS+1]; // next code value for each bit length + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>=1; + res<<=1; + } + while(--len>0); + return res>>1; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs.meta new file mode 100644 index 0000000..51eba6c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/util/zlib/ZTree.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 26a073157aad41647855017694f8a7cc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509.meta new file mode 100644 index 0000000..1b5af61 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c54419453e5665246b78dd2cc005e17a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs new file mode 100644 index 0000000..8dff056 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs @@ -0,0 +1,31 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + public interface IX509Extension + { + /// + /// Get all critical extension values, by oid + /// + /// IDictionary with string (OID) keys and Asn1OctetString values + ISet GetCriticalExtensionOids(); + + /// + /// Get all non-critical extension values, by oid + /// + /// IDictionary with string (OID) keys and Asn1OctetString values + ISet GetNonCriticalExtensionOids(); + + [Obsolete("Use version taking a DerObjectIdentifier instead")] + Asn1OctetString GetExtensionValue(string oid); + + Asn1OctetString GetExtensionValue(DerObjectIdentifier oid); + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs.meta new file mode 100644 index 0000000..8c65b38 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/IX509Extension.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8a0d122875ecdab4796b2617ab2d97eb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs new file mode 100644 index 0000000..c5270c0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs @@ -0,0 +1,99 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.X509 +{ + class PemParser + { + private readonly string _header1; + private readonly string _header2; + private readonly string _footer1; + private readonly string _footer2; + + internal PemParser( + string type) + { + _header1 = "-----BEGIN " + type + "-----"; + _header2 = "-----BEGIN X509 " + type + "-----"; + _footer1 = "-----END " + type + "-----"; + _footer2 = "-----END X509 " + type + "-----"; + } + + private string ReadLine( + Stream inStream) + { + int c; + StringBuilder l = new StringBuilder(); + + do + { + while (((c = inStream.ReadByte()) != '\r') && c != '\n' && (c >= 0)) + { + if (c == '\r') + { + continue; + } + + l.Append((char)c); + } + } + while (c >= 0 && l.Length == 0); + + if (c < 0) + { + return null; + } + + return l.ToString(); + } + + internal Asn1Sequence ReadPemObject( + Stream inStream) + { + string line; + StringBuilder pemBuf = new StringBuilder(); + + while ((line = ReadLine(inStream)) != null) + { + if (Org.BouncyCastle.Utilities.Platform.StartsWith(line, _header1) || Org.BouncyCastle.Utilities.Platform.StartsWith(line, _header2)) + { + break; + } + } + + while ((line = ReadLine(inStream)) != null) + { + if (Org.BouncyCastle.Utilities.Platform.StartsWith(line, _footer1) || Org.BouncyCastle.Utilities.Platform.StartsWith(line, _footer2)) + { + break; + } + + pemBuf.Append(line); + } + + if (pemBuf.Length != 0) + { + Asn1Object o = Asn1Object.FromByteArray(Base64.Decode(pemBuf.ToString())); + + if (!(o is Asn1Sequence)) + { + throw new IOException("malformed PEM data encountered"); + } + + return (Asn1Sequence) o; + } + + return null; + } + } +} + + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs.meta new file mode 100644 index 0000000..1626e9d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/PEMParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6c0af44d6133b484fad764d838af9600 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs new file mode 100644 index 0000000..3d59549 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs @@ -0,0 +1,608 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509.Extension; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.X509 +{ + /// + /// An Object representing an X509 Certificate. + /// Has static methods for loading Certificates encoded in many forms that return X509Certificate Objects. + /// + public class X509Certificate + : X509ExtensionBase +// , PKCS12BagAttributeCarrier + { + private readonly X509CertificateStructure c; +// private Hashtable pkcs12Attributes = new Hashtable(); +// private ArrayList pkcs12Ordering = new ArrayList(); + private readonly BasicConstraints basicConstraints; + private readonly bool[] keyUsage; + + private bool hashValueSet; + private int hashValue; + + protected X509Certificate() + { + } + + public X509Certificate( + X509CertificateStructure c) + { + this.c = c; + + try + { + Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.19")); + + if (str != null) + { + basicConstraints = BasicConstraints.GetInstance( + X509ExtensionUtilities.FromExtensionValue(str)); + } + } + catch (Exception e) + { + throw new CertificateParsingException("cannot construct BasicConstraints: " + e); + } + + try + { + Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.15")); + + if (str != null) + { + DerBitString bits = DerBitString.GetInstance( + X509ExtensionUtilities.FromExtensionValue(str)); + + byte[] bytes = bits.GetBytes(); + int length = (bytes.Length * 8) - bits.PadBits; + + keyUsage = new bool[(length < 9) ? 9 : length]; + + for (int i = 0; i != length; i++) + { +// keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; + keyUsage[i] = (bytes[i / 8] & (0x80 >> (i % 8))) != 0; + } + } + else + { + keyUsage = null; + } + } + catch (Exception e) + { + throw new CertificateParsingException("cannot construct KeyUsage: " + e); + } + } + +// internal X509Certificate( +// Asn1Sequence seq) +// { +// this.c = X509CertificateStructure.GetInstance(seq); +// } + +// /// +// /// Load certificate from byte array. +// /// +// /// Byte array containing encoded X509Certificate. +// public X509Certificate( +// byte[] encoded) +// : this((Asn1Sequence) new Asn1InputStream(encoded).ReadObject()) +// { +// } +// +// /// +// /// Load certificate from Stream. +// /// Must be positioned at start of certificate. +// /// +// /// +// public X509Certificate( +// Stream input) +// : this((Asn1Sequence) new Asn1InputStream(input).ReadObject()) +// { +// } + + public virtual X509CertificateStructure CertificateStructure + { + get { return c; } + } + + /// + /// Return true if the current time is within the start and end times nominated on the certificate. + /// + /// true id certificate is valid for the current time. + public virtual bool IsValidNow + { + get { return IsValid(DateTime.UtcNow); } + } + + /// + /// Return true if the nominated time is within the start and end times nominated on the certificate. + /// + /// The time to test validity against. + /// True if certificate is valid for nominated time. + public virtual bool IsValid( + DateTime time) + { + return time.CompareTo(NotBefore) >= 0 && time.CompareTo(NotAfter) <= 0; + } + + /// + /// Checks if the current date is within certificate's validity period. + /// + public virtual void CheckValidity() + { + this.CheckValidity(DateTime.UtcNow); + } + + /// + /// Checks if the given date is within certificate's validity period. + /// + /// if the certificate is expired by given date + /// if the certificate is not yet valid on given date + public virtual void CheckValidity( + DateTime time) + { + if (time.CompareTo(NotAfter) > 0) + throw new CertificateExpiredException("certificate expired on " + c.EndDate.GetTime()); + if (time.CompareTo(NotBefore) < 0) + throw new CertificateNotYetValidException("certificate not valid until " + c.StartDate.GetTime()); + } + + /// + /// Return the certificate's version. + /// + /// An integer whose value Equals the version of the cerficate. + public virtual int Version + { + get { return c.Version; } + } + + /// + /// Return a BigInteger containing the serial number. + /// + /// The Serial number. + public virtual BigInteger SerialNumber + { + get { return c.SerialNumber.Value; } + } + + /// + /// Get the Issuer Distinguished Name. (Who signed the certificate.) + /// + /// And X509Object containing name and value pairs. +// public IPrincipal IssuerDN + public virtual X509Name IssuerDN + { + get { return c.Issuer; } + } + + /// + /// Get the subject of this certificate. + /// + /// An X509Name object containing name and value pairs. +// public IPrincipal SubjectDN + public virtual X509Name SubjectDN + { + get { return c.Subject; } + } + + /// + /// The time that this certificate is valid from. + /// + /// A DateTime object representing that time in the local time zone. + public virtual DateTime NotBefore + { + get { return c.StartDate.ToDateTime(); } + } + + /// + /// The time that this certificate is valid up to. + /// + /// A DateTime object representing that time in the local time zone. + public virtual DateTime NotAfter + { + get { return c.EndDate.ToDateTime(); } + } + + /// + /// Return the Der encoded TbsCertificate data. + /// This is the certificate component less the signature. + /// To Get the whole certificate call the GetEncoded() member. + /// + /// A byte array containing the Der encoded Certificate component. + public virtual byte[] GetTbsCertificate() + { + return c.TbsCertificate.GetDerEncoded(); + } + + /// + /// The signature. + /// + /// A byte array containg the signature of the certificate. + public virtual byte[] GetSignature() + { + return c.GetSignatureOctets(); + } + + /// + /// A meaningful version of the Signature Algorithm. (EG SHA1WITHRSA) + /// + /// A sting representing the signature algorithm. + public virtual string SigAlgName + { + get { return SignerUtilities.GetEncodingName(c.SignatureAlgorithm.Algorithm); } + } + + /// + /// Get the Signature Algorithms Object ID. + /// + /// A string containg a '.' separated object id. + public virtual string SigAlgOid + { + get { return c.SignatureAlgorithm.Algorithm.Id; } + } + + /// + /// Get the signature algorithms parameters. (EG DSA Parameters) + /// + /// A byte array containing the Der encoded version of the parameters or null if there are none. + public virtual byte[] GetSigAlgParams() + { + if (c.SignatureAlgorithm.Parameters != null) + { + return c.SignatureAlgorithm.Parameters.GetDerEncoded(); + } + + return null; + } + + /// + /// Get the issuers UID. + /// + /// A DerBitString. + public virtual DerBitString IssuerUniqueID + { + get { return c.TbsCertificate.IssuerUniqueID; } + } + + /// + /// Get the subjects UID. + /// + /// A DerBitString. + public virtual DerBitString SubjectUniqueID + { + get { return c.TbsCertificate.SubjectUniqueID; } + } + + /// + /// Get a key usage guidlines. + /// + public virtual bool[] GetKeyUsage() + { + return keyUsage == null ? null : (bool[]) keyUsage.Clone(); + } + + // TODO Replace with something that returns a list of DerObjectIdentifier + public virtual IList GetExtendedKeyUsage() + { + Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.37")); + + if (str == null) + return null; + + try + { + Asn1Sequence seq = Asn1Sequence.GetInstance( + X509ExtensionUtilities.FromExtensionValue(str)); + + IList list = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + foreach (DerObjectIdentifier oid in seq) + { + list.Add(oid.Id); + } + + return list; + } + catch (Exception e) + { + throw new CertificateParsingException("error processing extended key usage extension", e); + } + } + + public virtual int GetBasicConstraints() + { + if (basicConstraints != null && basicConstraints.IsCA()) + { + if (basicConstraints.PathLenConstraint == null) + { + return int.MaxValue; + } + + return basicConstraints.PathLenConstraint.IntValue; + } + + return -1; + } + + public virtual ICollection GetSubjectAlternativeNames() + { + return GetAlternativeNames("2.5.29.17"); + } + + public virtual ICollection GetIssuerAlternativeNames() + { + return GetAlternativeNames("2.5.29.18"); + } + + protected virtual ICollection GetAlternativeNames( + string oid) + { + Asn1OctetString altNames = GetExtensionValue(new DerObjectIdentifier(oid)); + + if (altNames == null) + return null; + + Asn1Object asn1Object = X509ExtensionUtilities.FromExtensionValue(altNames); + + GeneralNames gns = GeneralNames.GetInstance(asn1Object); + + IList result = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + foreach (GeneralName gn in gns.GetNames()) + { + IList entry = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + entry.Add(gn.TagNo); + entry.Add(gn.Name.ToString()); + result.Add(entry); + } + return result; + } + + protected override X509Extensions GetX509Extensions() + { + return c.Version >= 3 + ? c.TbsCertificate.Extensions + : null; + } + + /// + /// Get the public key of the subject of the certificate. + /// + /// The public key parameters. + public virtual AsymmetricKeyParameter GetPublicKey() + { + return PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo); + } + + /// + /// Return a Der encoded version of this certificate. + /// + /// A byte array. + public virtual byte[] GetEncoded() + { + return c.GetDerEncoded(); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + X509Certificate other = obj as X509Certificate; + + if (other == null) + return false; + + return c.Equals(other.c); + + // NB: May prefer this implementation of Equals if more than one certificate implementation in play +// return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded()); + } + + public override int GetHashCode() + { + lock (this) + { + if (!hashValueSet) + { + hashValue = c.GetHashCode(); + hashValueSet = true; + } + } + + return hashValue; + } + +// public void setBagAttribute( +// DERObjectIdentifier oid, +// DEREncodable attribute) +// { +// pkcs12Attributes.put(oid, attribute); +// pkcs12Ordering.addElement(oid); +// } +// +// public DEREncodable getBagAttribute( +// DERObjectIdentifier oid) +// { +// return (DEREncodable)pkcs12Attributes.get(oid); +// } +// +// public Enumeration getBagAttributeKeys() +// { +// return pkcs12Ordering.elements(); +// } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string nl = Org.BouncyCastle.Utilities.Platform.NewLine; + + buf.Append(" [0] Version: ").Append(this.Version).Append(nl); + buf.Append(" SerialNumber: ").Append(this.SerialNumber).Append(nl); + buf.Append(" IssuerDN: ").Append(this.IssuerDN).Append(nl); + buf.Append(" Start Date: ").Append(this.NotBefore).Append(nl); + buf.Append(" Final Date: ").Append(this.NotAfter).Append(nl); + buf.Append(" SubjectDN: ").Append(this.SubjectDN).Append(nl); + buf.Append(" Public Key: ").Append(this.GetPublicKey()).Append(nl); + buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).Append(nl); + + byte[] sig = this.GetSignature(); + buf.Append(" Signature: ").Append(Hex.ToHexString(sig, 0, 20)).Append(nl); + + for (int i = 20; i < sig.Length; i += 20) + { + int len = System.Math.Min(20, sig.Length - i); + buf.Append(" ").Append(Hex.ToHexString(sig, i, len)).Append(nl); + } + + X509Extensions extensions = c.TbsCertificate.Extensions; + + if (extensions != null) + { + IEnumerator e = extensions.ExtensionOids.GetEnumerator(); + + if (e.MoveNext()) + { + buf.Append(" Extensions: \n"); + } + + do + { + DerObjectIdentifier oid = (DerObjectIdentifier)e.Current; + X509Extension ext = extensions.GetExtension(oid); + + if (ext.Value != null) + { + byte[] octs = ext.Value.GetOctets(); + Asn1Object obj = Asn1Object.FromByteArray(octs); + buf.Append(" critical(").Append(ext.IsCritical).Append(") "); + try + { + if (oid.Equals(X509Extensions.BasicConstraints)) + { + buf.Append(BasicConstraints.GetInstance(obj)); + } + else if (oid.Equals(X509Extensions.KeyUsage)) + { + buf.Append(KeyUsage.GetInstance(obj)); + } + else if (oid.Equals(MiscObjectIdentifiers.NetscapeCertType)) + { + buf.Append(new NetscapeCertType((DerBitString) obj)); + } + else if (oid.Equals(MiscObjectIdentifiers.NetscapeRevocationUrl)) + { + buf.Append(new NetscapeRevocationUrl((DerIA5String) obj)); + } + else if (oid.Equals(MiscObjectIdentifiers.VerisignCzagExtension)) + { + buf.Append(new VerisignCzagExtension((DerIA5String) obj)); + } + else + { + buf.Append(oid.Id); + buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj)); + //buf.Append(" value = ").Append("*****").Append(nl); + } + } + catch (Exception) + { + buf.Append(oid.Id); + //buf.Append(" value = ").Append(new string(Hex.encode(ext.getValue().getOctets()))).Append(nl); + buf.Append(" value = ").Append("*****"); + } + } + + buf.Append(nl); + } + while (e.MoveNext()); + } + + return buf.ToString(); + } + + /// + /// Verify the certificate's signature using the nominated public key. + /// + /// An appropriate public key parameter object, RsaPublicKeyParameters, DsaPublicKeyParameters or ECDsaPublicKeyParameters + /// True if the signature is valid. + /// If key submitted is not of the above nominated types. + public virtual void Verify( + AsymmetricKeyParameter key) + { + CheckSignature(new Asn1VerifierFactory(c.SignatureAlgorithm, key)); + } + + /// + /// Verify the certificate's signature using a verifier created using the passed in verifier provider. + /// + /// An appropriate provider for verifying the certificate's signature. + /// True if the signature is valid. + /// If verifier provider is not appropriate or the certificate algorithm is invalid. + public virtual void Verify( + IVerifierFactoryProvider verifierProvider) + { + CheckSignature(verifierProvider.CreateVerifierFactory (c.SignatureAlgorithm)); + } + + protected virtual void CheckSignature( + IVerifierFactory verifier) + { + if (!IsAlgIDEqual(c.SignatureAlgorithm, c.TbsCertificate.Signature)) + throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); + + //Asn1Encodable parameters = c.SignatureAlgorithm.Parameters; + + IStreamCalculator streamCalculator = verifier.CreateCalculator(); + + byte[] b = this.GetTbsCertificate(); + + streamCalculator.Stream.Write(b, 0, b.Length); + + Org.BouncyCastle.Utilities.Platform.Dispose(streamCalculator.Stream); + + if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) + { + throw new InvalidKeyException("Public key presented not for certificate signature"); + } + } + + private static bool IsAlgIDEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) + { + if (!id1.Algorithm.Equals(id2.Algorithm)) + return false; + + Asn1Encodable p1 = id1.Parameters; + Asn1Encodable p2 = id2.Parameters; + + if ((p1 == null) == (p2 == null)) + return Org.BouncyCastle.Utilities.Platform.Equals(p1, p2); + + // Exactly one of p1, p2 is null at this point + return p1 == null + ? p2.ToAsn1Object() is Asn1Null + : p1.ToAsn1Object() is Asn1Null; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs.meta new file mode 100644 index 0000000..181da2f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Certificate.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6beadff9e85279b4e98431dba56a094f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs new file mode 100644 index 0000000..657f385 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs @@ -0,0 +1,187 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.X509 +{ + /** + * class for dealing with X509 certificates. + *

    + * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" + * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 + * objects.

    + */ + public class X509CertificateParser + { + private static readonly PemParser PemCertParser = new PemParser("CERTIFICATE"); + + private Asn1Set sData; + private int sDataObjectCount; + private Stream currentStream; + + private X509Certificate ReadDerCertificate( + Asn1InputStream dIn) + { + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + + if (seq.Count > 1 && seq[0] is DerObjectIdentifier) + { + if (seq[0].Equals(PkcsObjectIdentifiers.SignedData)) + { + sData = SignedData.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Certificates; + + return GetCertificate(); + } + } + + return CreateX509Certificate(X509CertificateStructure.GetInstance(seq)); + } + + private X509Certificate GetCertificate() + { + if (sData != null) + { + while (sDataObjectCount < sData.Count) + { + object obj = sData[sDataObjectCount++]; + + if (obj is Asn1Sequence) + { + return CreateX509Certificate( + X509CertificateStructure.GetInstance(obj)); + } + } + } + + return null; + } + + private X509Certificate ReadPemCertificate( + Stream inStream) + { + Asn1Sequence seq = PemCertParser.ReadPemObject(inStream); + + return seq == null + ? null + : CreateX509Certificate(X509CertificateStructure.GetInstance(seq)); + } + + protected virtual X509Certificate CreateX509Certificate( + X509CertificateStructure c) + { + return new X509Certificate(c); + } + + /// + /// Create loading data from byte array. + /// + /// + public X509Certificate ReadCertificate( + byte[] input) + { + return ReadCertificate(new MemoryStream(input, false)); + } + + /// + /// Create loading data from byte array. + /// + /// + public ICollection ReadCertificates( + byte[] input) + { + return ReadCertificates(new MemoryStream(input, false)); + } + + /** + * Generates a certificate object and initializes it with the data + * read from the input stream inStream. + */ + public X509Certificate ReadCertificate( + Stream inStream) + { + if (inStream == null) + throw new ArgumentNullException("inStream"); + if (!inStream.CanRead) + throw new ArgumentException("inStream must be read-able", "inStream"); + + if (currentStream == null) + { + currentStream = inStream; + sData = null; + sDataObjectCount = 0; + } + else if (currentStream != inStream) // reset if input stream has changed + { + currentStream = inStream; + sData = null; + sDataObjectCount = 0; + } + + try + { + if (sData != null) + { + if (sDataObjectCount != sData.Count) + { + return GetCertificate(); + } + + sData = null; + sDataObjectCount = 0; + return null; + } + + PushbackStream pis = new PushbackStream(inStream); + int tag = pis.ReadByte(); + + if (tag < 0) + return null; + + pis.Unread(tag); + + if (tag != 0x30) // assume ascii PEM encoded. + { + return ReadPemCertificate(pis); + } + + return ReadDerCertificate(new Asn1InputStream(pis)); + } + catch (Exception e) + { + throw new CertificateException("Failed to read certificate", e); + } + } + + /** + * Returns a (possibly empty) collection view of the certificates + * read from the given input stream inStream. + */ + public ICollection ReadCertificates( + Stream inStream) + { + X509Certificate cert; + IList certs = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + while ((cert = ReadCertificate(inStream)) != null) + { + certs.Add(cert); + } + + return certs; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs.meta new file mode 100644 index 0000000..70e5722 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d7c29c36b4684094d864d3cae4db30f7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs new file mode 100644 index 0000000..0939210 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs @@ -0,0 +1,430 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509.Extension; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.X509 +{ + /** + * The following extensions are listed in RFC 2459 as relevant to CRLs + * + * Authority Key Identifier + * Issuer Alternative Name + * CRL Number + * Delta CRL Indicator (critical) + * Issuing Distribution Point (critical) + */ + public class X509Crl + : X509ExtensionBase + // TODO Add interface Crl? + { + private readonly CertificateList c; + private readonly string sigAlgName; + private readonly byte[] sigAlgParams; + private readonly bool isIndirect; + + public X509Crl( + CertificateList c) + { + this.c = c; + + try + { + this.sigAlgName = X509SignatureUtilities.GetSignatureName(c.SignatureAlgorithm); + + if (c.SignatureAlgorithm.Parameters != null) + { + this.sigAlgParams = ((Asn1Encodable)c.SignatureAlgorithm.Parameters).GetDerEncoded(); + } + else + { + this.sigAlgParams = null; + } + + this.isIndirect = IsIndirectCrl; + } + catch (Exception e) + { + throw new CrlException("CRL contents invalid: " + e); + } + } + + protected override X509Extensions GetX509Extensions() + { + return c.Version >= 2 + ? c.TbsCertList.Extensions + : null; + } + + public virtual byte[] GetEncoded() + { + try + { + return c.GetDerEncoded(); + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + public virtual void Verify( + AsymmetricKeyParameter publicKey) + { + Verify(new Asn1VerifierFactoryProvider(publicKey)); + } + + /// + /// Verify the CRL's signature using a verifier created using the passed in verifier provider. + /// + /// An appropriate provider for verifying the CRL's signature. + /// True if the signature is valid. + /// If verifier provider is not appropriate or the CRL algorithm is invalid. + public virtual void Verify( + IVerifierFactoryProvider verifierProvider) + { + CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm)); + } + + protected virtual void CheckSignature( + IVerifierFactory verifier) + { + if (!c.SignatureAlgorithm.Equals(c.TbsCertList.Signature)) + { + throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList."); + } + + //Asn1Encodable parameters = c.SignatureAlgorithm.Parameters; + + IStreamCalculator streamCalculator = verifier.CreateCalculator(); + + byte[] b = this.GetTbsCertList(); + + streamCalculator.Stream.Write(b, 0, b.Length); + + Org.BouncyCastle.Utilities.Platform.Dispose(streamCalculator.Stream); + + if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) + { + throw new InvalidKeyException("CRL does not verify with supplied public key."); + } + } + + public virtual int Version + { + get { return c.Version; } + } + + public virtual X509Name IssuerDN + { + get { return c.Issuer; } + } + + public virtual DateTime ThisUpdate + { + get { return c.ThisUpdate.ToDateTime(); } + } + + public virtual DateTimeObject NextUpdate + { + get + { + return c.NextUpdate == null + ? null + : new DateTimeObject(c.NextUpdate.ToDateTime()); + } + } + + private ISet LoadCrlEntries() + { + ISet entrySet = new HashSet(); + IEnumerable certs = c.GetRevokedCertificateEnumeration(); + + X509Name previousCertificateIssuer = IssuerDN; + foreach (CrlEntry entry in certs) + { + X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer); + entrySet.Add(crlEntry); + previousCertificateIssuer = crlEntry.GetCertificateIssuer(); + } + + return entrySet; + } + + public virtual X509CrlEntry GetRevokedCertificate( + BigInteger serialNumber) + { + IEnumerable certs = c.GetRevokedCertificateEnumeration(); + + X509Name previousCertificateIssuer = IssuerDN; + foreach (CrlEntry entry in certs) + { + X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer); + + if (serialNumber.Equals(entry.UserCertificate.Value)) + { + return crlEntry; + } + + previousCertificateIssuer = crlEntry.GetCertificateIssuer(); + } + + return null; + } + + public virtual ISet GetRevokedCertificates() + { + ISet entrySet = LoadCrlEntries(); + + if (entrySet.Count > 0) + { + return entrySet; // TODO? Collections.unmodifiableSet(entrySet); + } + + return null; + } + + public virtual byte[] GetTbsCertList() + { + try + { + return c.TbsCertList.GetDerEncoded(); + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + public virtual byte[] GetSignature() + { + return c.GetSignatureOctets(); + } + + public virtual string SigAlgName + { + get { return sigAlgName; } + } + + public virtual string SigAlgOid + { + get { return c.SignatureAlgorithm.Algorithm.Id; } + } + + public virtual byte[] GetSigAlgParams() + { + return Arrays.Clone(sigAlgParams); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + X509Crl other = obj as X509Crl; + + if (other == null) + return false; + + return c.Equals(other.c); + + // NB: May prefer this implementation of Equals if more than one certificate implementation in play + //return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded()); + } + + public override int GetHashCode() + { + return c.GetHashCode(); + } + + /** + * Returns a string representation of this CRL. + * + * @return a string representation of this CRL. + */ + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string nl = Org.BouncyCastle.Utilities.Platform.NewLine; + + buf.Append(" Version: ").Append(this.Version).Append(nl); + buf.Append(" IssuerDN: ").Append(this.IssuerDN).Append(nl); + buf.Append(" This update: ").Append(this.ThisUpdate).Append(nl); + buf.Append(" Next update: ").Append(this.NextUpdate).Append(nl); + buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).Append(nl); + + byte[] sig = this.GetSignature(); + + buf.Append(" Signature: "); + buf.Append(Hex.ToHexString(sig, 0, 20)).Append(nl); + + for (int i = 20; i < sig.Length; i += 20) + { + int count = System.Math.Min(20, sig.Length - i); + buf.Append(" "); + buf.Append(Hex.ToHexString(sig, i, count)).Append(nl); + } + + X509Extensions extensions = c.TbsCertList.Extensions; + + if (extensions != null) + { + IEnumerator e = extensions.ExtensionOids.GetEnumerator(); + + if (e.MoveNext()) + { + buf.Append(" Extensions: ").Append(nl); + } + + do + { + DerObjectIdentifier oid = (DerObjectIdentifier) e.Current; + X509Extension ext = extensions.GetExtension(oid); + + if (ext.Value != null) + { + Asn1Object asn1Value = X509ExtensionUtilities.FromExtensionValue(ext.Value); + + buf.Append(" critical(").Append(ext.IsCritical).Append(") "); + try + { + if (oid.Equals(X509Extensions.CrlNumber)) + { + buf.Append(new CrlNumber(DerInteger.GetInstance(asn1Value).PositiveValue)).Append(nl); + } + else if (oid.Equals(X509Extensions.DeltaCrlIndicator)) + { + buf.Append( + "Base CRL: " + + new CrlNumber(DerInteger.GetInstance( + asn1Value).PositiveValue)) + .Append(nl); + } + else if (oid.Equals(X509Extensions.IssuingDistributionPoint)) + { + buf.Append(IssuingDistributionPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl); + } + else if (oid.Equals(X509Extensions.CrlDistributionPoints)) + { + buf.Append(CrlDistPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl); + } + else if (oid.Equals(X509Extensions.FreshestCrl)) + { + buf.Append(CrlDistPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl); + } + else + { + buf.Append(oid.Id); + buf.Append(" value = ").Append( + Asn1Dump.DumpAsString(asn1Value)) + .Append(nl); + } + } + catch (Exception) + { + buf.Append(oid.Id); + buf.Append(" value = ").Append("*****").Append(nl); + } + } + else + { + buf.Append(nl); + } + } + while (e.MoveNext()); + } + + ISet certSet = GetRevokedCertificates(); + if (certSet != null) + { + foreach (X509CrlEntry entry in certSet) + { + buf.Append(entry); + buf.Append(nl); + } + } + + return buf.ToString(); + } + + /** + * Checks whether the given certificate is on this CRL. + * + * @param cert the certificate to check for. + * @return true if the given certificate is on this CRL, + * false otherwise. + */ +// public bool IsRevoked( +// Certificate cert) +// { +// if (!cert.getType().Equals("X.509")) +// { +// throw new RuntimeException("X.509 CRL used with non X.509 Cert"); +// } + public virtual bool IsRevoked( + X509Certificate cert) + { + CrlEntry[] certs = c.GetRevokedCertificates(); + + if (certs != null) + { +// BigInteger serial = ((X509Certificate)cert).SerialNumber; + BigInteger serial = cert.SerialNumber; + + for (int i = 0; i < certs.Length; i++) + { + if (certs[i].UserCertificate.Value.Equals(serial)) + { + return true; + } + } + } + + return false; + } + + protected virtual bool IsIndirectCrl + { + get + { + Asn1OctetString idp = GetExtensionValue(X509Extensions.IssuingDistributionPoint); + bool isIndirect = false; + + try + { + if (idp != null) + { + isIndirect = IssuingDistributionPoint.GetInstance( + X509ExtensionUtilities.FromExtensionValue(idp)).IsIndirectCrl; + } + } + catch (Exception e) + { + // TODO +// throw new ExtCrlException("Exception reading IssuingDistributionPoint", e); + throw new CrlException("Exception reading IssuingDistributionPoint" + e); + } + + return isIndirect; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs.meta new file mode 100644 index 0000000..0643de3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509Crl.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9a154750ed1601f4b80aa4d215d54e31 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs new file mode 100644 index 0000000..6011cad --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs @@ -0,0 +1,205 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509 +{ + /** + * The following extensions are listed in RFC 2459 as relevant to CRL Entries + * + * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer + * (critical) + */ + public class X509CrlEntry + : X509ExtensionBase + { + private CrlEntry c; + private bool isIndirect; + private X509Name previousCertificateIssuer; + private X509Name certificateIssuer; + + public X509CrlEntry( + CrlEntry c) + { + this.c = c; + this.certificateIssuer = loadCertificateIssuer(); + } + + /** + * Constructor for CRLEntries of indirect CRLs. If isIndirect + * is false {@link #getCertificateIssuer()} will always + * return null, previousCertificateIssuer is + * ignored. If this isIndirect is specified and this CrlEntry + * has no certificate issuer CRL entry extension + * previousCertificateIssuer is returned by + * {@link #getCertificateIssuer()}. + * + * @param c + * TbsCertificateList.CrlEntry object. + * @param isIndirect + * true if the corresponding CRL is a indirect + * CRL. + * @param previousCertificateIssuer + * Certificate issuer of the previous CrlEntry. + */ + public X509CrlEntry( + CrlEntry c, + bool isIndirect, + X509Name previousCertificateIssuer) + { + this.c = c; + this.isIndirect = isIndirect; + this.previousCertificateIssuer = previousCertificateIssuer; + this.certificateIssuer = loadCertificateIssuer(); + } + + private X509Name loadCertificateIssuer() + { + if (!isIndirect) + { + return null; + } + + Asn1OctetString ext = GetExtensionValue(X509Extensions.CertificateIssuer); + if (ext == null) + { + return previousCertificateIssuer; + } + + try + { + GeneralName[] names = GeneralNames.GetInstance( + X509ExtensionUtilities.FromExtensionValue(ext)).GetNames(); + + for (int i = 0; i < names.Length; i++) + { + if (names[i].TagNo == GeneralName.DirectoryName) + { + return X509Name.GetInstance(names[i].Name); + } + } + } + catch (Exception) + { + } + + return null; + } + + public X509Name GetCertificateIssuer() + { + return certificateIssuer; + } + + protected override X509Extensions GetX509Extensions() + { + return c.Extensions; + } + + public byte[] GetEncoded() + { + try + { + return c.GetDerEncoded(); + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + public BigInteger SerialNumber + { + get { return c.UserCertificate.Value; } + } + + public DateTime RevocationDate + { + get { return c.RevocationDate.ToDateTime(); } + } + + public bool HasExtensions + { + get { return c.Extensions != null; } + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string nl = Org.BouncyCastle.Utilities.Platform.NewLine; + + buf.Append(" userCertificate: ").Append(this.SerialNumber).Append(nl); + buf.Append(" revocationDate: ").Append(this.RevocationDate).Append(nl); + buf.Append(" certificateIssuer: ").Append(this.GetCertificateIssuer()).Append(nl); + + X509Extensions extensions = c.Extensions; + + if (extensions != null) + { + IEnumerator e = extensions.ExtensionOids.GetEnumerator(); + if (e.MoveNext()) + { + buf.Append(" crlEntryExtensions:").Append(nl); + + do + { + DerObjectIdentifier oid = (DerObjectIdentifier)e.Current; + X509Extension ext = extensions.GetExtension(oid); + + if (ext.Value != null) + { + Asn1Object obj = Asn1Object.FromByteArray(ext.Value.GetOctets()); + + buf.Append(" critical(") + .Append(ext.IsCritical) + .Append(") "); + try + { + if (oid.Equals(X509Extensions.ReasonCode)) + { + buf.Append(new CrlReason(DerEnumerated.GetInstance(obj))); + } + else if (oid.Equals(X509Extensions.CertificateIssuer)) + { + buf.Append("Certificate issuer: ").Append( + GeneralNames.GetInstance((Asn1Sequence)obj)); + } + else + { + buf.Append(oid.Id); + buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj)); + } + buf.Append(nl); + } + catch (Exception) + { + buf.Append(oid.Id); + buf.Append(" value = ").Append("*****").Append(nl); + } + } + else + { + buf.Append(nl); + } + } + while (e.MoveNext()); + } + } + + return buf.ToString(); + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs.meta new file mode 100644 index 0000000..07528eb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bc6c6a5eead859647b11f57143e492fb +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs new file mode 100644 index 0000000..41b1576 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs @@ -0,0 +1,199 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.X509 +{ + public class X509CrlParser + { + private static readonly PemParser PemCrlParser = new PemParser("CRL"); + + private readonly bool lazyAsn1; + + private Asn1Set sCrlData; + private int sCrlDataObjectCount; + private Stream currentCrlStream; + + public X509CrlParser() + : this(false) + { + } + + public X509CrlParser( + bool lazyAsn1) + { + this.lazyAsn1 = lazyAsn1; + } + + private X509Crl ReadPemCrl( + Stream inStream) + { + Asn1Sequence seq = PemCrlParser.ReadPemObject(inStream); + + return seq == null + ? null + : CreateX509Crl(CertificateList.GetInstance(seq)); + } + + private X509Crl ReadDerCrl( + Asn1InputStream dIn) + { + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + + if (seq.Count > 1 && seq[0] is DerObjectIdentifier) + { + if (seq[0].Equals(PkcsObjectIdentifiers.SignedData)) + { + sCrlData = SignedData.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Crls; + + return GetCrl(); + } + } + + return CreateX509Crl(CertificateList.GetInstance(seq)); + } + + private X509Crl GetCrl() + { + if (sCrlData == null || sCrlDataObjectCount >= sCrlData.Count) + { + return null; + } + + return CreateX509Crl( + CertificateList.GetInstance( + sCrlData[sCrlDataObjectCount++])); + } + + protected virtual X509Crl CreateX509Crl( + CertificateList c) + { + return new X509Crl(c); + } + + /// + /// Create loading data from byte array. + /// + /// + public X509Crl ReadCrl( + byte[] input) + { + return ReadCrl(new MemoryStream(input, false)); + } + + /// + /// Create loading data from byte array. + /// + /// + public ICollection ReadCrls( + byte[] input) + { + return ReadCrls(new MemoryStream(input, false)); + } + + /** + * Generates a certificate revocation list (CRL) object and initializes + * it with the data read from the input stream inStream. + */ + public X509Crl ReadCrl( + Stream inStream) + { + if (inStream == null) + throw new ArgumentNullException("inStream"); + if (!inStream.CanRead) + throw new ArgumentException("inStream must be read-able", "inStream"); + + if (currentCrlStream == null) + { + currentCrlStream = inStream; + sCrlData = null; + sCrlDataObjectCount = 0; + } + else if (currentCrlStream != inStream) // reset if input stream has changed + { + currentCrlStream = inStream; + sCrlData = null; + sCrlDataObjectCount = 0; + } + + try + { + if (sCrlData != null) + { + if (sCrlDataObjectCount != sCrlData.Count) + { + return GetCrl(); + } + + sCrlData = null; + sCrlDataObjectCount = 0; + return null; + } + + PushbackStream pis = new PushbackStream(inStream); + int tag = pis.ReadByte(); + + if (tag < 0) + return null; + + pis.Unread(tag); + + if (tag != 0x30) // assume ascii PEM encoded. + { + return ReadPemCrl(pis); + } + + Asn1InputStream asn1 = lazyAsn1 + ? new LazyAsn1InputStream(pis) + : new Asn1InputStream(pis); + + return ReadDerCrl(asn1); + } + catch (CrlException e) + { + throw e; + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + /** + * Returns a (possibly empty) collection view of the CRLs read from + * the given input stream inStream. + * + * The inStream may contain a sequence of DER-encoded CRLs, or + * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the + * only significant field being crls. In particular the signature + * and the contents are ignored. + */ + public ICollection ReadCrls( + Stream inStream) + { + X509Crl crl; + IList crls = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + while ((crl = ReadCrl(inStream)) != null) + { + crls.Add(crl); + } + + return crls; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs.meta new file mode 100644 index 0000000..f89b117 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509CrlParser.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e3886777ef4aa57469f8e79b6e1c14ac +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs new file mode 100644 index 0000000..0b69fc0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs @@ -0,0 +1,86 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + public abstract class X509ExtensionBase + : IX509Extension + { + protected abstract X509Extensions GetX509Extensions(); + + protected virtual ISet GetExtensionOids( + bool critical) + { + X509Extensions extensions = GetX509Extensions(); + if (extensions != null) + { + HashSet set = new HashSet(); + foreach (DerObjectIdentifier oid in extensions.ExtensionOids) + { + X509Extension ext = extensions.GetExtension(oid); + if (ext.IsCritical == critical) + { + set.Add(oid.Id); + } + } + + return set; + } + + return null; + } + + /// + /// Get non critical extensions. + /// + /// A set of non critical extension oids. + public virtual ISet GetNonCriticalExtensionOids() + { + return GetExtensionOids(false); + } + + /// + /// Get any critical extensions. + /// + /// A sorted list of critical entension. + public virtual ISet GetCriticalExtensionOids() + { + return GetExtensionOids(true); + } + + /// + /// Get the value of a given extension. + /// + /// The object ID of the extension. + /// An Asn1OctetString object if that extension is found or null if not. + [Obsolete("Use version taking a DerObjectIdentifier instead")] + public Asn1OctetString GetExtensionValue( + string oid) + { + return GetExtensionValue(new DerObjectIdentifier(oid)); + } + + public virtual Asn1OctetString GetExtensionValue( + DerObjectIdentifier oid) + { + X509Extensions exts = GetX509Extensions(); + if (exts != null) + { + X509Extension ext = exts.GetExtension(oid); + if (ext != null) + { + return ext.Value; + } + } + + return null; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs.meta new file mode 100644 index 0000000..3e49e5b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c9d43943931445544867d6e0c63383f6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs new file mode 100644 index 0000000..09d06bc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs @@ -0,0 +1,132 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.X509 +{ + internal class X509SignatureUtilities + { + private static readonly Asn1Null derNull = DerNull.Instance; + + internal static void SetSignatureParameters( + ISigner signature, + Asn1Encodable parameters) + { + if (parameters != null && !derNull.Equals(parameters)) + { + // TODO Put back in +// AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm()); +// +// try +// { +// sigParams.Init(parameters.ToAsn1Object().GetDerEncoded()); +// } +// catch (IOException e) +// { +// throw new SignatureException("IOException decoding parameters: " + e.Message); +// } +// +// if (Org.BouncyCastle.Utilities.Platform.EndsWith(signature.getAlgorithm(), "MGF1")) +// { +// try +// { +// signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); +// } +// catch (GeneralSecurityException e) +// { +// throw new SignatureException("Exception extracting parameters: " + e.Message); +// } +// } + } + } + + internal static string GetSignatureName( + AlgorithmIdentifier sigAlgId) + { + Asn1Encodable parameters = sigAlgId.Parameters; + + if (parameters != null && !derNull.Equals(parameters)) + { + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters); + + return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1"; + } + if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2)) + { + Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters); + + return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA"; + } + } + + return sigAlgId.Algorithm.Id; + } + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs.meta new file mode 100644 index 0000000..2a51c3b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 622a207c30957f04fb37399eac610155 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension.meta new file mode 100644 index 0000000..66a6b2b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 26902280df03e254eb103b0cc513363f +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs new file mode 100644 index 0000000..4538ff6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs @@ -0,0 +1,93 @@ +#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509.Extension +{ + public class X509ExtensionUtilities + { + public static Asn1Object FromExtensionValue( + Asn1OctetString extensionValue) + { + return Asn1Object.FromByteArray(extensionValue.GetOctets()); + } + + public static ICollection GetIssuerAlternativeNames( + X509Certificate cert) + { + Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName); + + return GetAlternativeName(extVal); + } + + public static ICollection GetSubjectAlternativeNames( + X509Certificate cert) + { + Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName); + + return GetAlternativeName(extVal); + } + + private static ICollection GetAlternativeName( + Asn1OctetString extVal) + { + IList temp = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + + if (extVal != null) + { + try + { + Asn1Sequence seq = DerSequence.GetInstance(FromExtensionValue(extVal)); + + foreach (GeneralName genName in seq) + { + IList list = Org.BouncyCastle.Utilities.Platform.CreateArrayList(); + list.Add(genName.TagNo); + + switch (genName.TagNo) + { + case GeneralName.EdiPartyName: + case GeneralName.X400Address: + case GeneralName.OtherName: + list.Add(genName.Name.ToAsn1Object()); + break; + case GeneralName.DirectoryName: + list.Add(X509Name.GetInstance(genName.Name).ToString()); + break; + case GeneralName.DnsName: + case GeneralName.Rfc822Name: + case GeneralName.UniformResourceIdentifier: + list.Add(((IAsn1String)genName.Name).GetString()); + break; + case GeneralName.RegisteredID: + list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id); + break; + case GeneralName.IPAddress: + list.Add(DerOctetString.GetInstance(genName.Name).GetOctets()); + break; + default: + throw new IOException("Bad tag number: " + genName.TagNo); + } + + temp.Add(list); + } + } + catch (Exception e) + { + throw new CertificateParsingException(e.Message); + } + } + + return temp; + } + } +} + +#endif diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs.meta new file mode 100644 index 0000000..3da61f1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SecureProtocol/x509/extension/X509ExtensionUtil.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c1e9b9d84df723247b8211204f278332 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents.meta b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents.meta new file mode 100644 index 0000000..628329f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c39b33f2c686550498ca5741c9e33690 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs new file mode 100644 index 0000000..d3653cb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs @@ -0,0 +1,649 @@ +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + +using System; +using System.Collections.Generic; + +using BestHTTP.Extensions; + +#if UNITY_WEBGL && !UNITY_EDITOR + using System.Runtime.InteropServices; +#endif + +namespace BestHTTP.ServerSentEvents +{ + /// + /// Possible states of an EventSource object. + /// + public enum States + { + Initial, + Connecting, + Open, + Retrying, + Closing, + Closed + } + + public delegate void OnGeneralEventDelegate(EventSource eventSource); + public delegate void OnMessageDelegate(EventSource eventSource, BestHTTP.ServerSentEvents.Message message); + public delegate void OnErrorDelegate(EventSource eventSource, string error); + public delegate bool OnRetryDelegate(EventSource eventSource); + public delegate void OnEventDelegate(EventSource eventSource, BestHTTP.ServerSentEvents.Message message); + public delegate void OnStateChangedDelegate(EventSource eventSource, States oldState, States newState); + +#if UNITY_WEBGL && !UNITY_EDITOR + + delegate void OnWebGLEventSourceOpenDelegate(uint id); + delegate void OnWebGLEventSourceMessageDelegate(uint id, string eventStr, string data, string eventId, int retry); + delegate void OnWebGLEventSourceErrorDelegate(uint id, string reason); +#endif + + /// + /// http://www.w3.org/TR/eventsource/ + /// + public class EventSource +#if !UNITY_WEBGL || UNITY_EDITOR + : IHeartbeat +#endif + { +#region Public Properties + + /// + /// Uri of the remote endpoint. + /// + public Uri Uri { get; private set; } + + /// + /// Current state of the EventSource object. + /// + public States State + { + get + { + return _state; + } + private set + { + States oldState = _state; + _state = value; + + if (OnStateChanged != null) + { + try + { + OnStateChanged(this, oldState, _state); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "OnStateChanged", ex); + } + } + } + } + private States _state; + + /// + /// Time to wait to do a reconnect attempt. Default to 2 sec. The server can overwrite this setting. + /// + public TimeSpan ReconnectionTime { get; set; } + + /// + /// The last successfully received event's id. + /// + public string LastEventId { get; private set; } + +#if !UNITY_WEBGL || UNITY_EDITOR + /// + /// The internal request object of the EventSource. + /// + public HTTPRequest InternalRequest { get; private set; } +#else + public bool WithCredentials { get; set; } +#endif + +#endregion + +#region Public Events + + /// + /// Called when successfully connected to the server. + /// + public event OnGeneralEventDelegate OnOpen; + + /// + /// Called on every message received from the server. + /// + public event OnMessageDelegate OnMessage; + + /// + /// Called when an error occurs. + /// + public event OnErrorDelegate OnError; + +#if !UNITY_WEBGL || UNITY_EDITOR + /// + /// Called when the EventSource will try to do a retry attempt. If this function returns with false, it will cancel the attempt. + /// + public event OnRetryDelegate OnRetry; +#endif + + /// + /// Called when the EventSource object closed. + /// + public event OnGeneralEventDelegate OnClosed; + + /// + /// Called every time when the State property changed. + /// + public event OnStateChangedDelegate OnStateChanged; + +#endregion + +#region Privates + + /// + /// A dictionary to store eventName => delegate mapping. + /// + private Dictionary EventTable; + +#if !UNITY_WEBGL || UNITY_EDITOR + /// + /// Number of retry attempts made. + /// + private byte RetryCount; + + /// + /// When we called the Retry function. We will delay the Open call from here. + /// + private DateTime RetryCalled; +#else + private static Dictionary EventSources = new Dictionary(); + private uint Id; +#endif + +#endregion + + public EventSource(Uri uri) + { + this.Uri = uri; + this.ReconnectionTime = TimeSpan.FromMilliseconds(2000); + +#if !UNITY_WEBGL || UNITY_EDITOR + this.InternalRequest = new HTTPRequest(Uri, HTTPMethods.Get, true, true, OnRequestFinished); + + // Set headers + this.InternalRequest.SetHeader("Accept", "text/event-stream"); + this.InternalRequest.SetHeader("Cache-Control", "no-cache"); + this.InternalRequest.SetHeader("Accept-Encoding", "identity"); + + // Set protocol stuff + this.InternalRequest.ProtocolHandler = SupportedProtocols.ServerSentEvents; + this.InternalRequest.OnUpgraded = OnUpgraded; + + // Disable internal retry + this.InternalRequest.DisableRetry = true; +#else + if (!ES_IsSupported()) + throw new NotSupportedException("This browser isn't support the EventSource protocol!"); + + this.Id = ES_Create(this.Uri.ToString(), WithCredentials, OnOpenCallback, OnMessageCallback, OnErrorCallback); + + EventSources.Add(this.Id, this); +#endif + } + +#region Public Functions + + /// + /// Start to connect to the remote server. + /// + public void Open() + { + if (this.State != States.Initial && + this.State != States.Retrying && + this.State != States.Closed) + return; + + this.State = States.Connecting; + +#if !UNITY_WEBGL || UNITY_EDITOR + if (!string.IsNullOrEmpty(this.LastEventId)) + this.InternalRequest.SetHeader("Last-Event-ID", this.LastEventId); + + this.InternalRequest.Send(); +#endif + } + + /// + /// Start to close the connection. + /// + public void Close() + { + if (this.State == States.Closing || + this.State == States.Closed) + return; + + this.State = States.Closing; +#if !UNITY_WEBGL || UNITY_EDITOR + if (this.InternalRequest != null) + this.InternalRequest.Abort(); + else + this.State = States.Closed; +#else + ES_Close(this.Id); + + SetClosed("Close"); + + EventSources.Remove(this.Id); + + ES_Release(this.Id); +#endif + } + + /// + /// With this function an event handler can be subscribed for an event name. + /// + public void On(string eventName, OnEventDelegate action) + { + if (EventTable == null) + EventTable = new Dictionary(); + + EventTable[eventName] = action; +#if UNITY_WEBGL && !UNITY_EDITOR + ES_AddEventHandler(this.Id, eventName); +#endif + } + + /// + /// With this function the event handler can be removed for the given event name. + /// + /// + public void Off(string eventName) + { + if (eventName == null || EventTable == null) + return; + + EventTable.Remove(eventName); + } + +#endregion + +#region Private Helper Functions + + private void CallOnError(string error, string msg) + { + if (OnError != null) + { + try + { + OnError(this, error); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("EventSource", msg + " - OnError", ex); + } + } + } + +#if !UNITY_WEBGL || UNITY_EDITOR + private bool CallOnRetry() + { + if (OnRetry != null) + { + try + { + return OnRetry(this); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "CallOnRetry", ex); + } + } + + return true; + } +#endif + + private void SetClosed(string msg) + { + this.State = States.Closed; + + if (OnClosed != null) + { + try + { + OnClosed(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("EventSource", msg + " - OnClosed", ex); + } + } + } + +#if !UNITY_WEBGL || UNITY_EDITOR + private void Retry() + { + if (RetryCount > 0 || + !CallOnRetry()) + { + SetClosed("Retry"); + return; + } + + RetryCount++; + RetryCalled = DateTime.UtcNow; + + HTTPManager.Heartbeats.Subscribe(this); + + this.State = States.Retrying; + } +#endif + +#endregion + +#region HTTP Request Implementation +#if !UNITY_WEBGL || UNITY_EDITOR + + /// + /// We are successfully upgraded to the EventSource protocol, we can start to receive and parse the incoming data. + /// + private void OnUpgraded(HTTPRequest originalRequest, HTTPResponse response) + { + EventSourceResponse esResponse = response as EventSourceResponse; + + if (esResponse == null) + { + CallOnError("Not an EventSourceResponse!", "OnUpgraded"); + return; + } + + if (OnOpen != null) + { + try + { + OnOpen(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "OnOpen", ex); + } + } + + esResponse.OnMessage += OnMessageReceived; + esResponse.StartReceive(); + + this.RetryCount = 0; + this.State = States.Open; + } + + private void OnRequestFinished(HTTPRequest req, HTTPResponse resp) + { + if (this.State == States.Closed) + return; + + if (this.State == States.Closing || + req.State == HTTPRequestStates.Aborted) + { + SetClosed("OnRequestFinished"); + + return; + } + + string reason = string.Empty; + + // In some cases retry is prohibited + bool canRetry = true; + + switch (req.State) + { + // The server sent all the data it's wanted. + case HTTPRequestStates.Processing: + canRetry = !resp.HasHeader("content-length"); + break; + + // The request finished without any problem. + case HTTPRequestStates.Finished: + // HTTP 200 OK responses that have a Content-Type specifying an unsupported type, or that have no Content-Type at all, must cause the user agent to fail the connection. + if (resp.StatusCode == 200 && !resp.HasHeaderWithValue("content-type", "text/event-stream")) + { + reason = "No Content-Type header with value 'text/event-stream' present."; + canRetry = false; + } + + // HTTP 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, and 504 Gateway Timeout responses, and any network error that prevents the connection + // from being established in the first place (e.g. DNS errors), must cause the user agent to asynchronously reestablish the connection. + // Any other HTTP response code not listed here must cause the user agent to fail the connection. + if (canRetry && + resp.StatusCode != 500 && + resp.StatusCode != 502 && + resp.StatusCode != 503 && + resp.StatusCode != 504) + { + canRetry = false; + + reason = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + } + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + reason = "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + // If the state is Closing, then it's a normal behaviour, and we close the EventSource + reason = "OnRequestFinished - Aborted without request. EventSource's State: " + this.State; + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + reason = "Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + reason = "Processing the request Timed Out!"; + break; + } + + // If we are not closing the EventSource, then we will try to reconnect. + if (this.State < States.Closing) + { + if (!string.IsNullOrEmpty(reason)) + CallOnError(reason, "OnRequestFinished"); + + if (canRetry) + Retry(); + else + SetClosed("OnRequestFinished"); + } + else + SetClosed("OnRequestFinished"); + } +#endif +#endregion + +#region EventStreamResponse Event Handlers + + private void OnMessageReceived( +#if !UNITY_WEBGL || UNITY_EDITOR + EventSourceResponse resp, +#endif + BestHTTP.ServerSentEvents.Message message) + { + if (this.State >= States.Closing) + return; + + // 1.) Set the last event ID string of the event source to value of the last event ID buffer. + // The buffer does not get reset, so the last event ID string of the event source remains set to this value until the next time it is set by the server. + // We check here only for null, because it can be a non-null but empty string. + if (message.Id != null) + this.LastEventId = message.Id; + + if (message.Retry.TotalMilliseconds > 0) + this.ReconnectionTime = message.Retry; + + // 2.) If the data buffer is an empty string, set the data buffer and the event type buffer to the empty string and abort these steps. + if (string.IsNullOrEmpty(message.Data)) + return; + + // 3.) If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer. + // This step can be ignored. We constructed the string to be able to skip this step. + + if (OnMessage != null) + { + try + { + OnMessage(this, message); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "OnMessageReceived - OnMessage", ex); + } + } + + if (EventTable != null && !string.IsNullOrEmpty(message.Event)) + { + OnEventDelegate action; + if (EventTable.TryGetValue(message.Event, out action)) + { + if (action != null) + { + try + { + action(this, message); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "OnMessageReceived - action", ex); + } + } + } + } + } + +#endregion + +#region IHeartbeat Implementation +#if !UNITY_WEBGL || UNITY_EDITOR + + void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif) + { + if (this.State != States.Retrying) + { + HTTPManager.Heartbeats.Unsubscribe(this); + + return; + } + + if (DateTime.UtcNow - RetryCalled >= ReconnectionTime) + { + Open(); + + if (this.State != States.Connecting) + SetClosed("OnHeartbeatUpdate"); + + HTTPManager.Heartbeats.Unsubscribe(this); + } + } +#endif +#endregion + +#region WebGL Static Callbacks +#if UNITY_WEBGL && !UNITY_EDITOR + + [AOT.MonoPInvokeCallback(typeof(OnWebGLEventSourceOpenDelegate))] + static void OnOpenCallback(uint id) + { + EventSource es; + if (EventSources.TryGetValue(id, out es)) + { + if (es.OnOpen != null) + { + try + { + es.OnOpen(es); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "OnOpen", ex); + } + } + + es.State = States.Open; + } + else + HTTPManager.Logger.Warning("EventSource", "OnOpenCallback - No EventSource found for id: " + id.ToString()); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLEventSourceMessageDelegate))] + static void OnMessageCallback(uint id, string eventStr, string data, string eventId, int retry) + { + EventSource es; + if (EventSources.TryGetValue(id, out es)) + { + var msg = new BestHTTP.ServerSentEvents.Message(); + msg.Id = eventId; + msg.Data = data; + msg.Event = eventStr; + msg.Retry = TimeSpan.FromSeconds(retry); + + es.OnMessageReceived(msg); + } + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLEventSourceErrorDelegate))] + static void OnErrorCallback(uint id, string reason) + { + EventSource es; + if (EventSources.TryGetValue(id, out es)) + { + es.CallOnError(reason, "OnErrorCallback"); + es.SetClosed("OnError"); + + EventSources.Remove(id); + } + + try + { + ES_Release(id); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("EventSource", "ES_Release", ex); + } + } + +#endif +#endregion + +#region WebGL Interface +#if UNITY_WEBGL && !UNITY_EDITOR + + [DllImport("__Internal")] + static extern bool ES_IsSupported(); + + [DllImport("__Internal")] + static extern uint ES_Create(string url, bool withCred, OnWebGLEventSourceOpenDelegate onOpen, OnWebGLEventSourceMessageDelegate onMessage, OnWebGLEventSourceErrorDelegate onError); + + [DllImport("__Internal")] + static extern void ES_AddEventHandler(uint id, string eventName); + + [DllImport("__Internal")] + static extern void ES_Close(uint id); + + [DllImport("__Internal")] + static extern void ES_Release(uint id); + +#endif +#endregion + + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs.meta new file mode 100644 index 0000000..6a2ba68 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSource.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 49e4cc3acf485d644887e96e5a2d1219 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs new file mode 100644 index 0000000..2fccaee --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs @@ -0,0 +1,380 @@ +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; +using System.Threading; + +using System.Text; +using System.Collections.Generic; + +namespace BestHTTP.ServerSentEvents +{ + /// + /// A low-level class to receive and parse an EventSource(http://www.w3.org/TR/eventsource/) stream. + /// Higher level protocol representation is implemented in the EventSource class. + /// + public sealed class EventSourceResponse : HTTPResponse, IProtocol + { + public bool IsClosed { get; private set; } + + #region Public Events + + public Action OnMessage; + public Action OnClosed; + + #endregion + + #region Privates + + /// + /// Thread sync object + /// + private object FrameLock = new object(); + + /// + /// Buffer for the read data. + /// + private byte[] LineBuffer = new byte[1024]; + + /// + /// Buffer position. + /// + private int LineBufferPos = 0; + + /// + /// The currently receiving and parsing message + /// + private BestHTTP.ServerSentEvents.Message CurrentMessage; + + /// + /// Completed messages that waiting to be dispatched + /// + private List CompletedMessages = new List(); + + #endregion + + public EventSourceResponse(HTTPRequest request, Stream stream, bool isStreamed, bool isFromCache) + :base(request, stream, isStreamed, isFromCache) + { + base.IsClosedManually = true; + } + + public override bool Receive(int forceReadRawContentLength = -1, bool readPayloadData = true) + { + bool received = base.Receive(forceReadRawContentLength, false); + + string contentType = this.GetFirstHeaderValue("content-type"); + base.IsUpgraded = received && + this.StatusCode == 200 && + !string.IsNullOrEmpty(contentType) && + contentType.ToLower().StartsWith("text/event-stream"); + + // If we didn't upgraded to the protocol we have to read all the sent payload because + // next requests may read these datas as HTTP headers and will fail + if (!IsUpgraded) + ReadPayload(forceReadRawContentLength); + + return received; + } + + internal void StartReceive() + { + if (IsUpgraded) + { +#if NETFX_CORE + #pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(ReceiveThreadFunc); + #pragma warning restore 4014 +#else + ThreadPool.QueueUserWorkItem(ReceiveThreadFunc); + //new Thread(ReceiveThreadFunc) + // .Start(); +#endif + } + } + + #region Private Threading Functions + + private void ReceiveThreadFunc(object param) + { + try + { + if (HasHeaderWithValue("transfer-encoding", "chunked")) + ReadChunked(Stream); + else + ReadRaw(Stream, -1); + } +#if !NETFX_CORE + catch (ThreadAbortException) + { + this.baseRequest.State = HTTPRequestStates.Aborted; + } +#endif + catch (Exception e) + { + if (HTTPUpdateDelegator.IsCreated) + { + this.baseRequest.Exception = e; + this.baseRequest.State = HTTPRequestStates.Error; + } + else + this.baseRequest.State = HTTPRequestStates.Aborted; + } + finally + { + IsClosed = true; + } + } + + #endregion + + #region Read Implementations + + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 + private new void ReadChunked(Stream stream) + { + int chunkLength = ReadChunkLength(stream); + byte[] buffer = new byte[chunkLength]; + + while (chunkLength != 0) + { + // To avoid more GC garbage we use only one buffer, and resize only if the next chunk doesn't fit. + if (buffer.Length < chunkLength) + Array.Resize(ref buffer, chunkLength); + + int readBytes = 0; + + // Fill up the buffer + do + { + int bytes = stream.Read(buffer, readBytes, chunkLength - readBytes); + if (bytes == 0) + throw new Exception("The remote server closed the connection unexpectedly!"); + + readBytes += bytes; + } while (readBytes < chunkLength); + + FeedData(buffer, readBytes); + + // Every chunk data has a trailing CRLF + ReadTo(stream, LF); + + // read the next chunk's length + chunkLength = ReadChunkLength(stream); + } + + // Read the trailing headers or the CRLF + ReadHeaders(stream); + } + + private new void ReadRaw(Stream stream, long contentLength) + { + byte[] buffer = new byte[1024]; + int bytes; + + do + { + bytes = stream.Read(buffer, 0, buffer.Length); + + FeedData(buffer, bytes); + } while(bytes > 0); + } + + #endregion + + #region Data Parsing + + public void FeedData(byte[] buffer, int count) + { + if (count == -1) + count = buffer.Length; + + if (count == 0) + return; + + int newlineIdx; + int pos = 0; + + do { + + newlineIdx = -1; + int skipCount = 1; // to skip CR and/or LF + + for (int i = pos; i < count && newlineIdx == -1; ++i) + { + // Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single U+000A LINE FEED (LF) character, or a single U+000D CARRIAGE RETURN (CR) character. + if (buffer[i] == HTTPResponse.CR) + { + if (i + 1 < count && buffer[i + 1] == HTTPResponse.LF) + skipCount = 2; + newlineIdx = i; + } + else if (buffer[i] == HTTPResponse.LF) + newlineIdx = i; + } + + int copyIndex = newlineIdx == -1 ? count : newlineIdx; + + if (LineBuffer.Length < LineBufferPos + (copyIndex - pos)) + Array.Resize(ref LineBuffer, LineBufferPos + (copyIndex - pos)); + + Array.Copy(buffer, pos, LineBuffer, LineBufferPos, copyIndex - pos); + + LineBufferPos += copyIndex - pos; + + if (newlineIdx == -1) + return; + + ParseLine(LineBuffer, LineBufferPos); + + LineBufferPos = 0; + //pos += newlineIdx + skipCount; + pos = newlineIdx + skipCount; + + }while(newlineIdx != -1 && pos < count); + } + + void ParseLine(byte[] buffer, int count) + { + // If the line is empty (a blank line) => Dispatch the event + if (count == 0) + { + if (CurrentMessage != null) + { + lock (FrameLock) + CompletedMessages.Add(CurrentMessage); + CurrentMessage = null; + } + + return; + } + + // If the line starts with a U+003A COLON character (:) => Ignore the line. + if (buffer[0] == 0x3A) + return; + + //If the line contains a U+003A COLON character (:) + int colonIdx = -1; + for (int i = 0; i < count && colonIdx == -1; ++i) + if (buffer[i] == 0x3A) + colonIdx = i; + + string field; + string value; + + if (colonIdx != -1) + { + // Collect the characters on the line before the first U+003A COLON character (:), and let field be that string. + field = Encoding.UTF8.GetString(buffer, 0, colonIdx); + + //Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value. + if (colonIdx + 1 < count && buffer[colonIdx + 1] == 0x20) + colonIdx++; + + colonIdx++; + + // discarded because it is not followed by a blank line + if (colonIdx >= count) + return; + + value = Encoding.UTF8.GetString(buffer, colonIdx, count - colonIdx); + } + else + { + // Otherwise, the string is not empty but does not contain a U+003A COLON character (:) => + // Process the field using the whole line as the field name, and the empty string as the field value. + field = Encoding.UTF8.GetString(buffer, 0, count); + value = string.Empty; + } + + if (CurrentMessage == null) + CurrentMessage = new BestHTTP.ServerSentEvents.Message(); + + switch(field) + { + // If the field name is "id" => Set the last event ID buffer to the field value. + case "id": + CurrentMessage.Id = value; + break; + + // If the field name is "event" => Set the event type buffer to field value. + case "event": + CurrentMessage.Event = value; + break; + + // If the field name is "data" => Append the field value to the data buffer, then append a single U+000A LINE FEED (LF) character to the data buffer. + case "data": + // Append a new line if we already have some data. This way we can skip step 3.) in the EventSource's OnMessageReceived. + // We do only null check, because empty string can be valid payload + if (CurrentMessage.Data != null) + CurrentMessage.Data += Environment.NewLine; + + CurrentMessage.Data += value; + break; + + // If the field name is "retry" => If the field value consists of only ASCII digits, then interpret the field value as an integer in base ten, + // and set the event stream's reconnection time to that integer. Otherwise, ignore the field. + case "retry": + int result; + if (int.TryParse(value, out result)) + CurrentMessage.Retry = TimeSpan.FromMilliseconds(result); + break; + + // Otherwise: The field is ignored. + default: + break; + } + } + + #endregion + + void IProtocol.HandleEvents() + { + lock(FrameLock) + { + // Send out messages. + if (CompletedMessages.Count > 0) + { + if (OnMessage != null) + for (int i = 0; i < CompletedMessages.Count; ++i) + { + try + { + OnMessage(this, CompletedMessages[i]); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("EventSourceMessage", "HandleEvents - OnMessage", ex); + } + } + + CompletedMessages.Clear(); + } + } + + // We are closed + if (IsClosed) + { + CompletedMessages.Clear(); + + if (OnClosed != null) + { + try + { + OnClosed(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("EventSourceMessage", "HandleEvents - OnClosed", ex); + } + finally + { + OnClosed = null; + } + } + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs.meta new file mode 100644 index 0000000..9dfa393 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/EventSourceResponse.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f1346db7284d3a04e8edd33864f9231c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs new file mode 100644 index 0000000..7679052 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs @@ -0,0 +1,36 @@ +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + +using System; + +namespace BestHTTP.ServerSentEvents +{ + public sealed class Message + { + /// + /// Event Id of the message. If it's null, then it's not present. + /// + public string Id { get; internal set; } + + /// + /// Name of the event, or an empty string. + /// + public string Event { get; internal set; } + + /// + /// The actual payload of the message. + /// + public string Data { get; internal set; } + + /// + /// A reconnection time, in milliseconds. This must initially be a user-agent-defined value, probably in the region of a few seconds. + /// + public TimeSpan Retry { get; internal set; } + + public override string ToString() + { + return string.Format("\"{0}\": \"{1}\"", Event, Data); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs.meta new file mode 100644 index 0000000..0541838 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/ServerSentEvents/Message.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9a3820c17c331374a82799277eb9ede0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR.meta new file mode 100644 index 0000000..121d893 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e2d987f043f34ae48a80a57c82fa4193 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication.meta new file mode 100644 index 0000000..38db037 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 008d5591a2cd6704fb39796bd33ff71a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs new file mode 100644 index 0000000..a632f05 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs @@ -0,0 +1,37 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +namespace BestHTTP.SignalR.Authentication +{ + public delegate void OnAuthenticationSuccededDelegate(IAuthenticationProvider provider); + public delegate void OnAuthenticationFailedDelegate(IAuthenticationProvider provider, string reason); + + public interface IAuthenticationProvider + { + /// + /// The authentication must be run before any request made to build up the SignalR protocol + /// + bool IsPreAuthRequired { get; } + + /// + /// This event must be called when the pre-authentication succeded. When IsPreAuthRequired is false, no-one will subscribe to this event. + /// + event OnAuthenticationSuccededDelegate OnAuthenticationSucceded; + + /// + /// This event must be called when the pre-authentication failed. When IsPreAuthRequired is false, no-one will subscribe to this event. + /// + event OnAuthenticationFailedDelegate OnAuthenticationFailed; + + /// + /// This function called once, when the before the SignalR negotiation begins. If IsPreAuthRequired is false, then this step will be skipped. + /// + void StartAuthentication(); + + /// + /// This function will be called for every request before sending it. + /// + void PrepareRequest(HTTPRequest request, RequestTypes type); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs.meta new file mode 100644 index 0000000..94bb950 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Authentication/IAuthenticationProvider.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e95e3e74ee7feaf4b872a3d4d23dc0a6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs new file mode 100644 index 0000000..acf658b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs @@ -0,0 +1,1306 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; +using System.Text; +using System.Collections.Generic; + +using BestHTTP.Extensions; +using BestHTTP.SignalR.Hubs; +using BestHTTP.SignalR.Messages; +using BestHTTP.SignalR.Transports; +using BestHTTP.SignalR.JsonEncoders; +using BestHTTP.SignalR.Authentication; + +using PlatformSupport.Collections.ObjectModel; + +#if !NETFX_CORE + using PlatformSupport.Collections.Specialized; +#else + using System.Collections.Specialized; +#endif + +namespace BestHTTP.SignalR +{ + public delegate void OnNonHubMessageDelegate(Connection connection, object data); + public delegate void OnConnectedDelegate(Connection connection); + public delegate void OnClosedDelegate(Connection connection); + public delegate void OnErrorDelegate(Connection connection, string error); + public delegate void OnStateChanged(Connection connection, ConnectionStates oldState, ConnectionStates newState); + public delegate void OnPrepareRequestDelegate(Connection connection, HTTPRequest req, RequestTypes type); + + /// + /// Interface to be able to hide internally used functions and properties. + /// + public interface IConnection + { + ProtocolVersions Protocol { get; } + NegotiationData NegotiationResult { get; } + IJsonEncoder JsonEncoder { get; set; } + + void OnMessage(IServerMessage msg); + void TransportStarted(); + void TransportReconnected(); + void TransportAborted(); + void Error(string reason); + Uri BuildUri(RequestTypes type); + Uri BuildUri(RequestTypes type, TransportBase transport); + HTTPRequest PrepareRequest(HTTPRequest req, RequestTypes type); + string ParseResponse(string responseStr); + } + + /// + /// Supported versions of the SignalR protocol. + /// + public enum ProtocolVersions : byte + { + Protocol_2_0, + Protocol_2_1, + Protocol_2_2 + } + + /// + /// The main SignalR class. This is the entry point to connect to a SignalR service. + /// + public sealed class Connection : IHeartbeat, IConnection + { + #region Public Properties + + /// + /// The default Json encode/decoder that will be used to encode/decode the event arguments. + /// + public static IJsonEncoder DefaultEncoder = +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + new JSonDotnetEncoder(); +#else + new DefaultJsonEncoder(); +#endif + + /// + /// The base url endpoint where the SignalR service can be found. + /// + public Uri Uri { get; private set; } + + /// + /// Current State of the SignalR connection. + /// + public ConnectionStates State + { + get { return _state; } + private set + { + ConnectionStates old = _state; + _state = value; + + if (OnStateChanged != null) + OnStateChanged(this, old, _state); + } + } + private ConnectionStates _state; + + /// + /// Result of the negotiation request from the server. + /// + public NegotiationData NegotiationResult { get; private set; } + + /// + /// The hubs that the client is connected to. + /// + public Hub[] Hubs { get; private set; } + + /// + /// The transport that is used to send and receive messages. + /// + public TransportBase Transport { get; private set; } + + /// + /// Current client protocol in use. + /// + public ProtocolVersions Protocol { get; private set; } + + /// + /// Additional query parameters that will be passed for the handshake uri. If the value is null, or an empty string it will be not appended to the query only the key. + /// The keys and values must be escaped properly, as the plugin will not escape these. + /// + public ObservableDictionary AdditionalQueryParams + { + get { return additionalQueryParams; } + set + { + // Unsubscribe from previous dictionary's events + if (additionalQueryParams != null) + additionalQueryParams.CollectionChanged -= AdditionalQueryParams_CollectionChanged; + + additionalQueryParams = value; + + // Clear out the cached value + BuiltQueryParams = null; + + // Subscribe to the collection changed event + if (value != null) + value.CollectionChanged += AdditionalQueryParams_CollectionChanged; + } + } + private ObservableDictionary additionalQueryParams; + + /// + /// If it's false, the parameters in the AdditionalQueryParams will be passed for all http requests. Its default value is true. + /// + public bool QueryParamsOnlyForHandshake { get; set; } + + /// + /// The Json encoder that will be used by the connection and the transport. + /// + public IJsonEncoder JsonEncoder { get; set; } + + /// + /// An IAuthenticationProvider implementation that will be used to authenticate the connection. + /// + public IAuthenticationProvider AuthenticationProvider { get; set; } + + /// + /// How much time we have to wait between two pings. + /// + public TimeSpan PingInterval { get; set; } + + /// + /// Wait time before the plugin should do a reconnect attempt. Its default value is 5 seconds. + /// + public TimeSpan ReconnectDelay { get; set; } + + #endregion + + #region Public Events + + /// + /// Called when the protocol is open for communication. + /// + public event OnConnectedDelegate OnConnected; + + /// + /// Called when the connection is closed, and no further messages are sent or received. + /// + public event OnClosedDelegate OnClosed; + + /// + /// Called when an error occures. If the connection is already Started, it will try to do a reconnect, otherwise it will close the connection. + /// + public event OnErrorDelegate OnError; + + /// + /// This event called when a reconnection attempt are started. If fails to reconnect an OnError and OnClosed events are called. + /// + public event OnConnectedDelegate OnReconnecting; + + /// + /// This event called when the reconnection attempt succeded. + /// + public event OnConnectedDelegate OnReconnected; + + /// + /// Called every time when the connection's state changes. + /// + public event OnStateChanged OnStateChanged; + + /// + /// It's called when a non-Hub message received. The data can be anything from primitive types to array of complex objects. + /// + public event OnNonHubMessageDelegate OnNonHubMessage; + + /// + /// With this delegate all requests can be further customized. + /// + public OnPrepareRequestDelegate RequestPreparator { get; set; } + + #endregion + + #region Indexers + + /// + /// Indexer property the access hubs by index. + /// + public Hub this[int idx] { get { return Hubs[idx] as Hub; } } + + /// + /// Indexer property the access hubs by name. + /// + public Hub this[string hubName] + { + get + { + for (int i = 0; i < Hubs.Length; ++i) + { + Hub hub = Hubs[i] as Hub; + if (hub.Name.Equals(hubName, StringComparison.OrdinalIgnoreCase)) + return hub; + } + + return null; + } + } + + #endregion + + #region Internals + + /// + /// An object to be able maintain thread safety. + /// + internal object SyncRoot = new object(); + + /// + /// Unique ID for all message sent by the client. + /// + internal UInt64 ClientMessageCounter { get; set; } + + #endregion + + #region Privates + + /// + /// Supported client protocol versions. + /// + private readonly string[] ClientProtocols = new string[] { "1.3", "1.4", "1.5" }; + + /// + /// A timestamp that will be sent with all request for easier debugging. + /// + private UInt32 Timestamp { get { return (UInt32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).Ticks; } } + + /// + /// Request counter sent with all request for easier debugging. + /// + private UInt64 RequestCounter; + + /// + /// Instance of the last received message. Used for its MessageId. + /// + private MultiMessage LastReceivedMessage; + + /// + /// The GroupsToken sent by the server that stores what groups we are joined to. + /// We will send it with the reconnect request. + /// + private string GroupsToken; + + /// + /// Received messages before the Start request finishes. + /// + private List BufferedMessages; + + /// + /// When the last message received from the server. Used for reconnecting. + /// + private DateTime LastMessageReceivedAt; + + /// + /// When we started to reconnect. When too much time passes without a successful reconnect, we will close the connection. + /// + private DateTime ReconnectStartedAt; + + private DateTime ReconnectDelayStartedAt; + + /// + /// True, if the reconnect process started. + /// + private bool ReconnectStarted; + + /// + /// When the last ping request sent out. + /// + private DateTime LastPingSentAt; + + /// + /// Reference to the ping request. + /// + private HTTPRequest PingRequest; + + /// + /// When the transport started the connection process + /// + private DateTime? TransportConnectionStartedAt; + + /// + /// Cached StringBuilder instance used in BuildUri + /// + private StringBuilder queryBuilder = new StringBuilder(); + + /// + /// Builds and returns with the connection data made from the hub names. + /// + private string ConnectionData + { + get + { + if (!string.IsNullOrEmpty(BuiltConnectionData)) + return BuiltConnectionData; + + StringBuilder sb = new StringBuilder("[", Hubs.Length * 4); + + if (Hubs != null) + for (int i = 0; i < Hubs.Length; ++i) + { + sb.Append(@"{""Name"":"""); + sb.Append(Hubs[i].Name); + sb.Append(@"""}"); + + if (i < Hubs.Length - 1) + sb.Append(","); + } + + sb.Append("]"); + + return BuiltConnectionData = Uri.EscapeUriString(sb.ToString()); + } + } + + /// + /// The cached value of the result of the ConnectionData property call. + /// + private string BuiltConnectionData; + + /// + /// Builds the keys and values from the AdditionalQueryParams to an key=value form. If AdditionalQueryParams is null or empty, it will return an empty string. + /// + private string QueryParams + { + get + { + if (AdditionalQueryParams == null || AdditionalQueryParams.Count == 0) + return string.Empty; + + if (!string.IsNullOrEmpty(BuiltQueryParams)) + return BuiltQueryParams; + + StringBuilder sb = new StringBuilder(AdditionalQueryParams.Count * 4); + + foreach (var kvp in AdditionalQueryParams) + { + sb.Append("&"); + sb.Append(kvp.Key); + + if (!string.IsNullOrEmpty(kvp.Value)) + { + sb.Append("="); + sb.Append(Uri.EscapeDataString(kvp.Value)); + } + } + + return BuiltQueryParams = sb.ToString(); + } + } + + /// + /// The cached value of the result of the QueryParams property call. + /// + private string BuiltQueryParams; + + private SupportedProtocols NextProtocolToTry; + + #endregion + + #region Constructors + + public Connection(Uri uri, params string[] hubNames) + : this(uri) + { + if (hubNames != null && hubNames.Length > 0) + { + this.Hubs = new Hub[hubNames.Length]; + + for (int i = 0; i < hubNames.Length; ++i) + this.Hubs[i] = new Hub(hubNames[i], this); + } + } + + public Connection(Uri uri, params Hub[] hubs) + :this(uri) + { + this.Hubs = hubs; + if (hubs != null) + for (int i = 0; i < hubs.Length; ++i) + (hubs[i] as IHub).Connection = this; + } + + public Connection(Uri uri) + { + this.State = ConnectionStates.Initial; + this.Uri = uri; + + this.JsonEncoder = Connection.DefaultEncoder; + this.PingInterval = TimeSpan.FromMinutes(5); + + // Expected protocol + this.Protocol = ProtocolVersions.Protocol_2_2; + + this.ReconnectDelay = TimeSpan.FromSeconds(5); + } + + #endregion + + #region Starting the protocol + + /// + /// This function will start to authenticate if required, and the SignalR protocol negotiation. + /// + public void Open() + { + if (State != ConnectionStates.Initial && State != ConnectionStates.Closed) + return; + + if (AuthenticationProvider != null && AuthenticationProvider.IsPreAuthRequired) + { + this.State = ConnectionStates.Authenticating; + + AuthenticationProvider.OnAuthenticationSucceded += OnAuthenticationSucceded; + AuthenticationProvider.OnAuthenticationFailed += OnAuthenticationFailed; + + // Start the authentication process + AuthenticationProvider.StartAuthentication(); + } + else + StartImpl(); + } + + /// + /// Called when the authentication succeeded. + /// + /// + private void OnAuthenticationSucceded(IAuthenticationProvider provider) + { + provider.OnAuthenticationSucceded -= OnAuthenticationSucceded; + provider.OnAuthenticationFailed -= OnAuthenticationFailed; + + StartImpl(); + } + + /// + /// Called when the authentication failed. + /// + private void OnAuthenticationFailed(IAuthenticationProvider provider, string reason) + { + provider.OnAuthenticationSucceded -= OnAuthenticationSucceded; + provider.OnAuthenticationFailed -= OnAuthenticationFailed; + + (this as IConnection).Error(reason); + } + + /// + /// It's the real Start implementation. It will start the negotiation + /// + private void StartImpl() + { + this.State = ConnectionStates.Negotiating; + + NegotiationResult = new NegotiationData(this); + NegotiationResult.OnReceived = OnNegotiationDataReceived; + NegotiationResult.OnError = OnNegotiationError; + NegotiationResult.Start(); + } + + #region Negotiation Event Handlers + + /// + /// Protocol negotiation finished successfully. + /// + private void OnNegotiationDataReceived(NegotiationData data) + { + // Find out what supported protocol the server speak + int protocolIdx = -1; + for (int i = 0; i < ClientProtocols.Length && protocolIdx == -1; ++i) + if (data.ProtocolVersion == ClientProtocols[i]) + protocolIdx = i; + + // No supported protocol found? Try using the latest one. + if (protocolIdx == -1) + { + protocolIdx = (byte)ProtocolVersions.Protocol_2_2; + HTTPManager.Logger.Warning("SignalR Connection", "Unknown protocol version: " + data.ProtocolVersion); + } + + this.Protocol = (ProtocolVersions)protocolIdx; + + #if !BESTHTTP_DISABLE_WEBSOCKET + if (data.TryWebSockets) + { + Transport = new WebSocketTransport(this); + + #if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + NextProtocolToTry = SupportedProtocols.ServerSentEvents; + #else + NextProtocolToTry = SupportedProtocols.HTTP; + #endif + } + else + #endif + { + #if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + Transport = new ServerSentEventsTransport(this); + + // Long-Poll + NextProtocolToTry = SupportedProtocols.HTTP; + #else + + Transport = new PollingTransport(this); + + NextProtocolToTry = SupportedProtocols.Unknown; + #endif + } + + this.State = ConnectionStates.Connecting; + TransportConnectionStartedAt = DateTime.UtcNow; + + Transport.Connect(); + } + + /// + /// Protocol negotiation failed. + /// + private void OnNegotiationError(NegotiationData data, string error) + { + (this as IConnection).Error(error); + } + + #endregion + + #endregion + + #region Public Interface + + /// + /// Closes the connection and shuts down the transport. + /// + public void Close() + { + if (this.State == ConnectionStates.Closed) + return; + + this.State = ConnectionStates.Closed; + + //ReconnectStartedAt = null; + ReconnectStarted = false; + + TransportConnectionStartedAt = null; + + if (Transport != null) + { + Transport.Abort(); + Transport = null; + } + + NegotiationResult = null; + + HTTPManager.Heartbeats.Unsubscribe(this); + + LastReceivedMessage = null; + + if (Hubs != null) + for (int i = 0; i < Hubs.Length; ++i) + (Hubs[i] as IHub).Close(); + + if (BufferedMessages != null) + { + BufferedMessages.Clear(); + BufferedMessages = null; + } + + if (OnClosed != null) + { + try + { + OnClosed(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("SignalR Connection", "OnClosed", ex); + } + } + } + + /// + /// Initiates a reconnect to the SignalR server. + /// + public void Reconnect() + { + // Return if reconnect process already started. + if (ReconnectStarted) + return; + ReconnectStarted = true; + + // Set ReconnectStartedAt only when the previous State is not Reconnecting, + // so we keep the first date&time when we started reconnecting + if (this.State != ConnectionStates.Reconnecting) + ReconnectStartedAt = DateTime.UtcNow; + + this.State = ConnectionStates.Reconnecting; + + HTTPManager.Logger.Warning("SignalR Connection", "Reconnecting"); + + Transport.Reconnect(); + + if (PingRequest != null) + PingRequest.Abort(); + + if (OnReconnecting != null) + { + try + { + OnReconnecting(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("SignalR Connection", "OnReconnecting", ex); + } + } + } + + + /// + /// Will encode the argument to a Json string using the Connection's JsonEncoder, then will send it to the server. + /// + /// True if the plugin was able to send out the message + public bool Send(object arg) + { + if (arg == null) + throw new ArgumentNullException("arg"); + + lock(SyncRoot) + { + if (this.State != ConnectionStates.Connected) + return false; + + string json = JsonEncoder.Encode(arg); + + if (string.IsNullOrEmpty(json)) + HTTPManager.Logger.Error("SignalR Connection", "Failed to JSon encode the given argument. Please try to use an advanced JSon encoder(check the documentation how you can do it)."); + else + Transport.Send(json); + } + + return true; + } + + /// + /// Sends the given json string to the server. + /// + /// True if the plugin was able to send out the message + public bool SendJson(string json) + { + if (json == null) + throw new ArgumentNullException("json"); + + lock(SyncRoot) + { + if (this.State != ConnectionStates.Connected) + return false; + + Transport.Send(json); + } + + return true; + } + + #endregion + + #region IManager Functions + + /// + /// Called when we receive a message from the server + /// + void IConnection.OnMessage(IServerMessage msg) + { + if (this.State == ConnectionStates.Closed) + return; + + // Store messages that we receive while we are connecting + if (this.State == ConnectionStates.Connecting) + { + if (BufferedMessages == null) + BufferedMessages = new List(); + + BufferedMessages.Add(msg); + + return; + } + + LastMessageReceivedAt = DateTime.UtcNow; + + switch(msg.Type) + { + case MessageTypes.Multiple: + LastReceivedMessage = msg as MultiMessage; + + // Not received in the reconnect process, so we can't rely on it + if (LastReceivedMessage.IsInitialization) + HTTPManager.Logger.Information("SignalR Connection", "OnMessage - Init"); + + if (LastReceivedMessage.GroupsToken != null) + GroupsToken = LastReceivedMessage.GroupsToken; + + if (LastReceivedMessage.ShouldReconnect) + { + HTTPManager.Logger.Information("SignalR Connection", "OnMessage - Should Reconnect"); + + Reconnect(); + + // Should we return here not processing the messages that may come with it? + //return; + } + + if (LastReceivedMessage.Data != null) + for (int i = 0; i < LastReceivedMessage.Data.Count; ++i) + (this as IConnection).OnMessage(LastReceivedMessage.Data[i]); + + break; + + case MessageTypes.MethodCall: + MethodCallMessage methodCall = msg as MethodCallMessage; + + Hub hub = this[methodCall.Hub]; + + if (hub != null) + (hub as IHub).OnMethod(methodCall); + else + HTTPManager.Logger.Warning("SignalR Connection", string.Format("Hub \"{0}\" not found!", methodCall.Hub)); + + break; + + case MessageTypes.Result: + case MessageTypes.Failure: + case MessageTypes.Progress: + UInt64 id = (msg as IHubMessage).InvocationId; + hub = FindHub(id); + if (hub != null) + (hub as IHub).OnMessage(msg); + else + HTTPManager.Logger.Warning("SignalR Connection", string.Format("No Hub found for Progress message! Id: {0}", id.ToString())); + break; + + case MessageTypes.Data: + if (OnNonHubMessage != null) + OnNonHubMessage(this, (msg as DataMessage).Data); + break; + + case MessageTypes.KeepAlive: + break; + + default: + HTTPManager.Logger.Warning("SignalR Connection", "Unknown message type received: " + msg.Type.ToString()); + break; + } + } + + /// + /// Called from the transport implementations when the Start request finishes successfully. + /// + void IConnection.TransportStarted() + { + if (this.State != ConnectionStates.Connecting) + return; + + InitOnStart(); + + if (OnConnected != null) + { + try + { + OnConnected(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("SignalR Connection", "OnOpened", ex); + } + } + + // Deliver messages that we received before the /start request returned. + // This must be after the OnStarted call, to let the clients to subrscribe to these events. + if (BufferedMessages != null) + { + for (int i = 0; i < BufferedMessages.Count; ++i) + (this as IConnection).OnMessage(BufferedMessages[i]); + + BufferedMessages.Clear(); + BufferedMessages = null; + } + } + + /// + /// Called when the transport sucessfully reconnected to the server. + /// + void IConnection.TransportReconnected() + { + if (this.State != ConnectionStates.Reconnecting) + return; + + HTTPManager.Logger.Information("SignalR Connection", "Transport Reconnected"); + + InitOnStart(); + + if (OnReconnected != null) + { + try + { + OnReconnected(this); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("SignalR Connection", "OnReconnected", ex); + } + } + } + + /// + /// Called from the transport implementation when the Abort request finishes successfully. + /// + void IConnection.TransportAborted() + { + Close(); + } + + /// + /// Called when an error occures. If the connection is in the Connected state, it will start the reconnect process, otherwise it will close the connection. + /// + void IConnection.Error(string reason) + { + // Not interested about errors we received after we already closed + if (this.State == ConnectionStates.Closed) + return; + + // If we are just quitting, don't try to reconnect. + if (HTTPManager.IsQuitting) + { + Close(); + return; + } + + HTTPManager.Logger.Error("SignalR Connection", reason); + + ReconnectStarted = false; + + if (OnError != null) + OnError(this, reason); + + if (this.State == ConnectionStates.Connected || this.State == ConnectionStates.Reconnecting) + { + this.ReconnectDelayStartedAt = DateTime.UtcNow; + if (this.State != ConnectionStates.Reconnecting) + this.ReconnectStartedAt = DateTime.UtcNow; + + //Reconnect(); + } + else + { + // Fall back if possible + if (this.State != ConnectionStates.Connecting || !TryFallbackTransport()) + Close(); + } + } + + /// + /// Creates an Uri instance for the given request type. + /// + Uri IConnection.BuildUri(RequestTypes type) + { + return (this as IConnection).BuildUri(type, null); + } + + /// + /// Creates an Uri instance from the given parameters. + /// + Uri IConnection.BuildUri(RequestTypes type, TransportBase transport) + { + lock (SyncRoot) + { + // make sure that the queryBuilder is reseted + queryBuilder.Length = 0; + + UriBuilder uriBuilder = new UriBuilder(Uri); + + if (!uriBuilder.Path.EndsWith("/")) + uriBuilder.Path += "/"; + + this.RequestCounter %= UInt64.MaxValue; + + switch (type) + { + case RequestTypes.Negotiate: + uriBuilder.Path += "negotiate"; + goto default; + + case RequestTypes.Connect: +#if !BESTHTTP_DISABLE_WEBSOCKET + if (transport != null && transport.Type == TransportTypes.WebSocket) + uriBuilder.Scheme = HTTPProtocolFactory.IsSecureProtocol(Uri) ? "wss" : "ws"; +#endif + + uriBuilder.Path += "connect"; + goto default; + + case RequestTypes.Start: + uriBuilder.Path += "start"; + goto default; + + case RequestTypes.Poll: + uriBuilder.Path += "poll"; + + if (this.LastReceivedMessage != null) + { + queryBuilder.Append("messageId="); + queryBuilder.Append(this.LastReceivedMessage.MessageId); + } + + if (!string.IsNullOrEmpty(GroupsToken)) + { + if (queryBuilder.Length > 0) + queryBuilder.Append("&"); + + queryBuilder.Append("groupsToken="); + queryBuilder.Append(GroupsToken); + } + + goto default; + + case RequestTypes.Send: + uriBuilder.Path += "send"; + goto default; + + case RequestTypes.Reconnect: +#if !BESTHTTP_DISABLE_WEBSOCKET + if (transport != null && transport.Type == TransportTypes.WebSocket) + uriBuilder.Scheme = HTTPProtocolFactory.IsSecureProtocol(Uri) ? "wss" : "ws"; +#endif + + uriBuilder.Path += "reconnect"; + + if (this.LastReceivedMessage != null) + { + queryBuilder.Append("messageId="); + queryBuilder.Append(this.LastReceivedMessage.MessageId); + } + + if (!string.IsNullOrEmpty(GroupsToken)) + { + if (queryBuilder.Length > 0) + queryBuilder.Append("&"); + + queryBuilder.Append("groupsToken="); + queryBuilder.Append(GroupsToken); + } + + goto default; + + case RequestTypes.Abort: + uriBuilder.Path += "abort"; + goto default; + + case RequestTypes.Ping: + uriBuilder.Path += "ping"; + + queryBuilder.Append("&tid="); + queryBuilder.Append(this.RequestCounter++.ToString()); + + queryBuilder.Append("&_="); + queryBuilder.Append(Timestamp.ToString()); + + break; + + default: + if (queryBuilder.Length > 0) + queryBuilder.Append("&"); + + queryBuilder.Append("tid="); + queryBuilder.Append(this.RequestCounter++.ToString()); + + queryBuilder.Append("&_="); + queryBuilder.Append(Timestamp.ToString()); + + if (transport != null) + { + queryBuilder.Append("&transport="); + queryBuilder.Append(transport.Name); + } + + queryBuilder.Append("&clientProtocol="); + queryBuilder.Append(ClientProtocols[(byte)Protocol]); + + if (NegotiationResult != null && !string.IsNullOrEmpty(this.NegotiationResult.ConnectionToken)) + { + queryBuilder.Append("&connectionToken="); + queryBuilder.Append(this.NegotiationResult.ConnectionToken); + } + + if (this.Hubs != null && this.Hubs.Length > 0) + { + queryBuilder.Append("&connectionData="); + queryBuilder.Append(this.ConnectionData); + } + + break; + } + + // Query params are added to all uri + if (this.AdditionalQueryParams != null && this.AdditionalQueryParams.Count > 0) + queryBuilder.Append(this.QueryParams); + + uriBuilder.Query = queryBuilder.ToString(); + + // reset the string builder + queryBuilder.Length = 0; + + return uriBuilder.Uri; + } + } + + /// + /// It's called on every request before sending it out to the server. + /// + HTTPRequest IConnection.PrepareRequest(HTTPRequest req, RequestTypes type) + { + if (req != null && AuthenticationProvider != null) + AuthenticationProvider.PrepareRequest(req, type); + + if (RequestPreparator != null) + RequestPreparator(this, req, type); + + return req; + } + + /// + /// Will parse a "{ 'Response': 'xyz' }" object and returns with 'xyz'. If it fails to parse, or getting the 'Response' key, it will call the Error function. + /// + string IConnection.ParseResponse(string responseStr) + { + Dictionary dic = JSON.Json.Decode(responseStr) as Dictionary; + + if (dic == null) + { + (this as IConnection).Error("Failed to parse Start response: " + responseStr); + return string.Empty; + } + + object value; + if (!dic.TryGetValue("Response", out value) || value == null) + { + (this as IConnection).Error("No 'Response' key found in response: " + responseStr); + return string.Empty; + } + + return value.ToString(); + } + + #endregion + + #region IHeartbeat Implementation + + /// + /// IHeartbeat implementation to manage timeouts. + /// + void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif) + { + switch(this.State) + { + case ConnectionStates.Connected: + if (Transport.SupportsKeepAlive && NegotiationResult.KeepAliveTimeout != null && DateTime.UtcNow - LastMessageReceivedAt >= NegotiationResult.KeepAliveTimeout) + Reconnect(); + + if (PingRequest == null && DateTime.UtcNow - LastPingSentAt >= PingInterval) + Ping(); + + break; + + case ConnectionStates.Reconnecting: + if ( DateTime.UtcNow - ReconnectStartedAt >= NegotiationResult.DisconnectTimeout) + { + HTTPManager.Logger.Warning("SignalR Connection", "OnHeartbeatUpdate - Failed to reconnect in the given time!"); + + Close(); + } + else if (DateTime.UtcNow - ReconnectDelayStartedAt >= ReconnectDelay) + { + if (HTTPManager.Logger.Level <= Logger.Loglevels.Warning) + HTTPManager.Logger.Warning("SignalR Connection", this.ReconnectStarted.ToString() + " " + this.ReconnectStartedAt.ToString() + " " + NegotiationResult.DisconnectTimeout.ToString()); + Reconnect(); + } + break; + + default: + + if (TransportConnectionStartedAt != null && DateTime.UtcNow - TransportConnectionStartedAt >= NegotiationResult.TransportConnectTimeout) + { + HTTPManager.Logger.Warning("SignalR Connection", "OnHeartbeatUpdate - Transport failed to connect in the given time!"); + + // Using the Error function here instead of Close() will enable us to try to do a transport fallback. + (this as IConnection).Error("Transport failed to connect in the given time!"); + } + + break; + } + } + + #endregion + + #region Private Helper Functions + + /// + /// Init function to set the connected states and set up other variables. + /// + private void InitOnStart() + { + this.State = ConnectionStates.Connected; + + //ReconnectStartedAt = null; + ReconnectStarted = false; + TransportConnectionStartedAt = null; + + LastPingSentAt = DateTime.UtcNow; + LastMessageReceivedAt = DateTime.UtcNow; + + HTTPManager.Heartbeats.Subscribe(this); + } + + /// + /// Find and return with a Hub that has the message id. + /// + private Hub FindHub(UInt64 msgId) + { + if (Hubs != null) + for (int i = 0; i < Hubs.Length; ++i) + if ((Hubs[i] as IHub).HasSentMessageId(msgId)) + return Hubs[i]; + return null; + } + + /// + /// Try to fall back to next transport. If no more transport to try, it will return false. + /// + private bool TryFallbackTransport() + { + if (this.State == ConnectionStates.Connecting) + { + if (BufferedMessages != null) + BufferedMessages.Clear(); + + // stop the current transport + Transport.Stop(); + Transport = null; + + switch(NextProtocolToTry) + { +#if !BESTHTTP_DISABLE_WEBSOCKET + case SupportedProtocols.WebSocket: + Transport = new WebSocketTransport(this); + break; +#endif + +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + case SupportedProtocols.ServerSentEvents: + Transport = new ServerSentEventsTransport(this); + NextProtocolToTry = SupportedProtocols.HTTP; + break; +#endif + + case SupportedProtocols.HTTP: + Transport = new PollingTransport(this); + NextProtocolToTry = SupportedProtocols.Unknown; + break; + + case SupportedProtocols.Unknown: + return false; + } + + TransportConnectionStartedAt = DateTime.UtcNow; + + Transport.Connect(); + + if (PingRequest != null) + PingRequest.Abort(); + + return true; + } + + return false; + } + + /// + /// This event will be called when the AdditonalQueryPrams dictionary changed. We have to reset the cached values. + /// + private void AdditionalQueryParams_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + BuiltQueryParams = null; + } + + #endregion + + #region Ping Implementation + + /// + /// Sends a Ping request to the SignalR server. + /// + private void Ping() + { + HTTPManager.Logger.Information("SignalR Connection", "Sending Ping request."); + + PingRequest = new HTTPRequest((this as IConnection).BuildUri(RequestTypes.Ping), OnPingRequestFinished); + PingRequest.ConnectTimeout = PingInterval; + + (this as IConnection).PrepareRequest(PingRequest, RequestTypes.Ping); + + PingRequest.Send(); + + LastPingSentAt = DateTime.UtcNow; + } + + /// + /// Called when the Ping request finished. + /// + void OnPingRequestFinished(HTTPRequest req, HTTPResponse resp) + { + PingRequest = null; + + string reason = string.Empty; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + // Parse the response, and do nothing when we receive the "pong" response + string response = (this as IConnection).ParseResponse(resp.DataAsText); + + if (response != "pong") + reason = "Wrong answer for ping request: " + response; + else + HTTPManager.Logger.Information("SignalR Connection", "Pong received."); + } + else + reason = string.Format("Ping - Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + reason = "Ping - Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + reason = "Ping - Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + reason = "Ping - Processing the request Timed Out!"; + break; + } + + if (!string.IsNullOrEmpty(reason)) + (this as IConnection).Error(reason); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs.meta new file mode 100644 index 0000000..7d487ba --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Connection.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 878e20e1ec06ef542946893b5e37c3b6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs new file mode 100644 index 0000000..a1d7840 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs @@ -0,0 +1,196 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +namespace BestHTTP.SignalR +{ + /// + /// Possible transport types. + /// + public enum TransportTypes + { + /// + /// Transport using WebSockets. + /// + WebSocket, + + /// + /// Transport using ServerSentEvents protocol. + /// + ServerSentEvents, + + /// + /// Transport using long-polling requests. + /// + LongPoll + } + + /// + /// Server sent message types + /// + public enum MessageTypes + { + /// + /// An empty json object {} sent by the server to check keep alive. + /// + KeepAlive, + + /// + /// A no-hub message that contains data. + /// + Data, + + /// + /// A message that can hold multiple data message alongside with other information. + /// + Multiple, + + /// + /// A method call result. + /// + Result, + + /// + /// A message about a failed method call. + /// + Failure, + + /// + /// A message with all information to be able to call a method on the client. + /// + MethodCall, + + /// + /// A long running server-method's progress. + /// + Progress + } + + /// + /// Possible SignalR Connection states. + /// + public enum ConnectionStates + { + /// + /// The initial state of the connection. + /// + Initial, + + /// + /// The client authenticates itself with the server. This state is skipped if no AuthenticationProvider is present. + /// + Authenticating, + + /// + /// The client sent out the negotiation request to the server. + /// + Negotiating, + + /// + /// The client received the negotiation data, created the transport and wait's for the transport's connection. + /// + Connecting, + + /// + /// The transport connected and started successfully. + /// + Connected, + + /// + /// The client started the reconnect process. + /// + Reconnecting, + + /// + /// The connection is closed. + /// + Closed + } + + /// + /// Possible types of SignalR requests. + /// + public enum RequestTypes + { + /// + /// Request to the /negotiate path to negotiate protocol parameters. + /// + Negotiate, + + /// + /// Request to the /connect path to connect to the server. With long-polling, it's like a regular poll request. + /// + Connect, + + /// + /// Request to the /start path to start the protocol. + /// + Start, + + /// + /// Request to the /poll path to get new messages. Not used with the WebSocketTransport. + /// + Poll, + + /// + /// Request to the /send path to send a message to the server. Not used with the WebSocketTransport. + /// + Send, + + /// + /// Request to the /reconnect path to initiate a reconnection. It's used instead of the Connect type. + /// + Reconnect, + + /// + /// Request to the /abort path to close the connection. + /// + Abort, + + /// + /// Request to the /ping path to ping the server keeping the asp.net session alive. + /// + Ping + } + + /// + /// Possible states of a transport. + /// + public enum TransportStates + { + /// + /// Initial state + /// + Initial, + + /// + /// Connecting + /// + Connecting, + + /// + /// Reconnecting + /// + Reconnecting, + + /// + /// Sending Start request + /// + Starting, + + /// + /// Start request finished successfully + /// + Started, + + /// + /// Sending Abort request + /// + Closing, + + /// + /// The transport closed after Abort request sent + /// + Closed + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs.meta new file mode 100644 index 0000000..1ed5321 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Enums.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fafa6e4c8bf63324c82241199e91f437 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs.meta new file mode 100644 index 0000000..4060c0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7208796729371c74c9d7c3398b19f8f3 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs new file mode 100644 index 0000000..7dd1b9d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs @@ -0,0 +1,391 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; +using System.Collections.Generic; + +using BestHTTP.SignalR.Messages; +using System.Text; + +namespace BestHTTP.SignalR.Hubs +{ + public delegate void OnMethodCallDelegate(Hub hub, string method, params object[] args); + public delegate void OnMethodCallCallbackDelegate(Hub hub, MethodCallMessage methodCall); + + public delegate void OnMethodResultDelegate(Hub hub, ClientMessage originalMessage, ResultMessage result); + public delegate void OnMethodFailedDelegate(Hub hub, ClientMessage originalMessage, FailureMessage error); + public delegate void OnMethodProgressDelegate(Hub hub, ClientMessage originialMessage, ProgressMessage progress); + + /// + /// Represents a clientside Hub. This class can be used as a base class to encapsulate proxy functionalities. + /// + public class Hub : IHub + { + + #region Public Properties + + /// + /// Name of this hub. + /// + public string Name { get; private set; } + + /// + /// Server and user set state of the hub. + /// + public Dictionary State + { + // Create only when we need to. + get + { + if (state == null) + state = new Dictionary(); + return state; + } + } + private Dictionary state; + + /// + /// Event called every time when the server sends an order to call a method on the client. + /// + public event OnMethodCallDelegate OnMethodCall; + + #endregion + + #region Privates + + /// + /// Table of the sent messages. These messages will be removed from this table when a Result message is received from the server. + /// + private Dictionary SentMessages = new Dictionary(); + + /// + /// Methodname -> callback delegate mapping. This table stores the server callable functions. + /// + private Dictionary MethodTable = new Dictionary(); + + /// + /// A reusable StringBuilder to save some GC allocs + /// + private StringBuilder builder = new StringBuilder(); + + #endregion + + Connection IHub.Connection { get; set; } + + public Hub(string name) + :this(name, null) + { + + } + + public Hub(string name, Connection manager) + { + this.Name = name; + (this as IHub).Connection = manager; + } + + #region Public Hub Functions + + /// + /// Registers a callback function to the given method. + /// + public void On(string method, OnMethodCallCallbackDelegate callback) + { + MethodTable[method] = callback; + } + + /// + /// Removes callback from the given method. + /// + /// + public void Off(string method) + { + MethodTable[method] = null; + } + + /// + /// Orders the server to call a method with the given arguments. + /// + /// True if the plugin was able to send out the message + public bool Call(string method, params object[] args) + { + return Call(method, null, null, null, args); + } + + /// + /// Orders the server to call a method with the given arguments. + /// The onResult callback will be called when the server successfully called the function. + /// + /// True if the plugin was able to send out the message + public bool Call(string method, OnMethodResultDelegate onResult, params object[] args) + { + return Call(method, onResult, null, null, args); + } + + /// + /// Orders the server to call a method with the given arguments. + /// The onResult callback will be called when the server successfully called the function. + /// The onResultError will be called when the server can't call the function, or when the function throws an exception. + /// + /// True if the plugin was able to send out the message + public bool Call(string method, OnMethodResultDelegate onResult, OnMethodFailedDelegate onResultError, params object[] args) + { + return Call(method, onResult, onResultError, null, args); + } + + /// + /// Orders the server to call a method with the given arguments. + /// The onResult callback will be called when the server successfully called the function. + /// The onProgress callback called multiple times when the method is a long running function and reports back its progress. + /// + /// True if the plugin was able to send out the message + public bool Call(string method, OnMethodResultDelegate onResult, OnMethodProgressDelegate onProgress, params object[] args) + { + return Call(method, onResult, null, onProgress, args); + } + + /// + /// Orders the server to call a method with the given arguments. + /// The onResult callback will be called when the server successfully called the function. + /// The onResultError will be called when the server can't call the function, or when the function throws an exception. + /// The onProgress callback called multiple times when the method is a long running function and reports back its progress. + /// + /// True if the plugin was able to send out the message + public bool Call(string method, OnMethodResultDelegate onResult, OnMethodFailedDelegate onResultError, OnMethodProgressDelegate onProgress, params object[] args) + { + IHub thisHub = this as IHub; + + lock (thisHub.Connection.SyncRoot) + { + // Start over the counter if we are reached the max value if the UInt64 type. + // While we are using this property only here, we don't want to make it static to avoid another thread synchronization, neither we want to make it a Hub-instance field to achieve better deuggability. + thisHub.Connection.ClientMessageCounter %= UInt64.MaxValue; + + // Create and send the client message + return thisHub.Call(new ClientMessage(this, method, args, thisHub.Connection.ClientMessageCounter++, onResult, onResultError, onProgress)); + } + } + + #endregion + + #region IHub Implementation + + bool IHub.Call(ClientMessage msg) + { + IHub thisHub = this as IHub; + + lock (thisHub.Connection.SyncRoot) + { + if (!thisHub.Connection.SendJson(BuildMessage(msg))) + return false; + + SentMessages.Add(msg.CallIdx, msg); + } + + return true; + } + + /// + /// Return true if this hub sent the message with the given id. + /// + bool IHub.HasSentMessageId(UInt64 id) + { + return SentMessages.ContainsKey(id); + } + + /// + /// Called on the manager's close. + /// + void IHub.Close() + { + SentMessages.Clear(); + } + + /// + /// Called when the client receives an order to call a hub-function. + /// + void IHub.OnMethod(MethodCallMessage msg) + { + // Merge the newly received states with the old one + MergeState(msg.State); + + if (OnMethodCall != null) + { + try + { + OnMethodCall(this, msg.Method, msg.Arguments); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("Hub - " + this.Name, "IHub.OnMethod - OnMethodCall", ex); + } + } + + OnMethodCallCallbackDelegate callback; + if (MethodTable.TryGetValue(msg.Method, out callback) && callback != null) + { + try + { + callback(this, msg); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("Hub - " + this.Name, "IHub.OnMethod - callback", ex); + } + } + else + HTTPManager.Logger.Warning("Hub - " + this.Name, string.Format("[Client] {0}.{1} (args: {2})", this.Name, msg.Method, msg.Arguments.Length)); + } + + /// + /// Called when the client receives back messages as a result of a server method call. + /// + void IHub.OnMessage(IServerMessage msg) + { + ClientMessage originalMsg; + + UInt64 id = (msg as IHubMessage).InvocationId; + if (!SentMessages.TryGetValue(id, out originalMsg)) + { + // This can happen when a result message removes the ClientMessage from the SentMessages dictionary, + // then a late come progress message tries to access it + HTTPManager.Logger.Warning("Hub - " + this.Name, "OnMessage - Sent message not found with id: " + id.ToString()); + return; + } + + switch(msg.Type) + { + case MessageTypes.Result: + ResultMessage result = msg as ResultMessage; + + // Merge the incoming State before firing the events + MergeState(result.State); + + if (originalMsg.ResultCallback != null) + { + try + { + originalMsg.ResultCallback(this, originalMsg, result); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("Hub " + this.Name, "IHub.OnMessage - ResultCallback", ex); + } + } + + SentMessages.Remove(id); + + break; + + case MessageTypes.Failure: + FailureMessage error = msg as FailureMessage; + + // Merge the incoming State before firing the events + MergeState(error.State); + + if (originalMsg.ResultErrorCallback != null) + { + try + { + originalMsg.ResultErrorCallback(this, originalMsg, error); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("Hub " + this.Name, "IHub.OnMessage - ResultErrorCallback", ex); + } + } + + SentMessages.Remove(id); + break; + + case MessageTypes.Progress: + if (originalMsg.ProgressCallback != null) + { + try + { + originalMsg.ProgressCallback(this, originalMsg, msg as ProgressMessage); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("Hub " + this.Name, "IHub.OnMessage - ProgressCallback", ex); + } + } + break; + } + } + + #endregion + + #region Helper Functions + + /// + /// Merges the current and the new states. + /// +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + private void MergeState(IDictionary state) +#else + private void MergeState(IDictionary state) +#endif + { + if (state != null && state.Count > 0) + foreach (var kvp in state) + this.State[kvp.Key] = kvp.Value; + } + + /// + /// Builds a JSon string from the given message. + /// + private string BuildMessage(ClientMessage msg) + { + try + { + builder.Append("{\"H\":\""); + builder.Append(this.Name); + builder.Append("\",\"M\":\""); + builder.Append(msg.Method); + builder.Append("\",\"A\":"); + + string jsonEncoded = string.Empty; + + // Arguments + if (msg.Args != null && msg.Args.Length > 0) + jsonEncoded = (this as IHub).Connection.JsonEncoder.Encode(msg.Args); + else + jsonEncoded = "[]"; + + builder.Append(jsonEncoded); + + builder.Append(",\"I\":\""); + builder.Append(msg.CallIdx.ToString()); + builder.Append("\""); + + // State, if any + if (msg.Hub.state != null && msg.Hub.state.Count > 0) + { + builder.Append(",\"S\":"); + + jsonEncoded = (this as IHub).Connection.JsonEncoder.Encode(msg.Hub.state); + builder.Append(jsonEncoded); + } + + builder.Append("}"); + + return builder.ToString(); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("Hub - " + this.Name, "Send", ex); + + return null; + } + finally + { + // reset the StringBuilder instance, to reuse next time + builder.Length = 0; + } + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs.meta new file mode 100644 index 0000000..ee76d02 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/Hub.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 00b4b8fd0e14de941b796a56a1272233 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs new file mode 100644 index 0000000..5426c29 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; + +using BestHTTP.SignalR.Messages; + +namespace BestHTTP.SignalR.Hubs +{ + /// + /// Interface to be able to hide internally used functions and properties. + /// + public interface IHub + { + Connection Connection { get; set; } + + bool Call(ClientMessage msg); + bool HasSentMessageId(UInt64 id); + void Close(); + void OnMethod(MethodCallMessage msg); + void OnMessage(IServerMessage msg); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs.meta new file mode 100644 index 0000000..78982e7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Hubs/IHub.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1813781a232e6c74ba3e00896327ace6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders.meta new file mode 100644 index 0000000..794d22c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c593c51184e979a4d8e4bb2cc2a9b1d0 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs new file mode 100644 index 0000000..cc6c3c1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using BestHTTP.JSON; +using System.Collections.Generic; + +namespace BestHTTP.SignalR.JsonEncoders +{ + public sealed class DefaultJsonEncoder : IJsonEncoder + { + public string Encode(object obj) + { + return Json.Encode(obj); + } + + public IDictionary DecodeMessage(string json) + { + bool ok = false; + IDictionary result = Json.Decode(json, ref ok) as IDictionary; + return ok ? result : null; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs.meta new file mode 100644 index 0000000..d6d0d4e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/DefaultJsonEncoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1a4bf647dcdcdbf44ab1edc744192ca0 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs new file mode 100644 index 0000000..7304031 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System.Collections.Generic; + +namespace BestHTTP.SignalR.JsonEncoders +{ + /// + /// Interface to be able to write custom Json encoders/decoders. + /// + public interface IJsonEncoder + { + /// + /// This function must create a json formatted string from the given object. If the encoding fails, it should return null. + /// + string Encode(object obj); + + /// + /// This function must create a dictionary the Json formatted string parameter. If the decoding fails, it should return null. + /// + IDictionary DecodeMessage(string json); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs.meta new file mode 100644 index 0000000..ce9466d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/JsonEncoders/IJsonEncoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b494cd3e9ad9bd243bd68251a27c86b9 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages.meta new file mode 100644 index 0000000..ad77468 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3ea7772f76aa54748aa8b466ba3113a9 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs new file mode 100644 index 0000000..c1c4c86 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs @@ -0,0 +1,71 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; + +using BestHTTP.SignalR.Hubs; + +namespace BestHTTP.SignalR.Messages +{ + /// + /// This struct represents a message from the client. + /// It holds every data and reference needed to construct the string represented message that will be sent to the wire. + /// + public struct ClientMessage + { + /// + /// Reference to the source Hub. The Name and the State of the hub will be user. + /// + public readonly Hub Hub; + + /// + /// Name of the method on the server to be called. + /// + public readonly string Method; + + /// + /// Arguments of the method. + /// + public readonly object[] Args; + + /// + /// Unique id on the client of this message + /// + public readonly UInt64 CallIdx; + + /// + /// The delegate that will be called when the server will sends a result of this method call. + /// + public readonly OnMethodResultDelegate ResultCallback; + + /// + /// The delegate that will be called when the server sends an error-result to this method call. + /// + public readonly OnMethodFailedDelegate ResultErrorCallback; + + /// + /// The delegate that will be called when the server sends a progress message to this method call. + /// + public readonly OnMethodProgressDelegate ProgressCallback; + + public ClientMessage(Hub hub, + string method, + object[] args, + UInt64 callIdx, + OnMethodResultDelegate resultCallback, + OnMethodFailedDelegate resultErrorCallback, + OnMethodProgressDelegate progressCallback) + { + Hub = hub; + Method = method; + Args = args; + + CallIdx = callIdx; + + ResultCallback = resultCallback; + ResultErrorCallback = resultErrorCallback; + ProgressCallback = progressCallback; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs.meta new file mode 100644 index 0000000..658559c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ClientMessage.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: af18bb2021dd2f045b2d168d5769fab1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs new file mode 100644 index 0000000..c5ffb28 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs @@ -0,0 +1,19 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; + +namespace BestHTTP.SignalR.Messages +{ + public interface IServerMessage + { + MessageTypes Type { get; } + void Parse(object data); + } + + public interface IHubMessage + { + UInt64 InvocationId { get; } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs.meta new file mode 100644 index 0000000..278f678 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/IServerMessage.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 25c60db0524552144bf03b547ae8a585 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs new file mode 100644 index 0000000..8f82c5b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs @@ -0,0 +1,354 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET +using Newtonsoft.Json.Linq; +#endif +using System; +using System.Collections; +using System.Collections.Generic; + +namespace BestHTTP.SignalR.Messages +{ + /// + /// Keep-alive message sent by the server. No data sent with it. + /// + public sealed class KeepAliveMessage : IServerMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.KeepAlive; } } + void IServerMessage.Parse(object data) { } + } + + /// + /// A message that may contains multiple sub-messages and additional informations. + /// + public sealed class MultiMessage : IServerMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.Multiple; } } + + /// + /// Id of the sent message + /// + public string MessageId { get; private set; } + + /// + /// True if it's an initialization message, false otherwise. + /// + public bool IsInitialization { get; private set; } + + /// + /// Group token may be sent, if the group changed that the client belongs to. + /// + public string GroupsToken { get; private set; } + + /// + /// The server suggests that the client should do a reconnect turn. + /// + public bool ShouldReconnect { get; private set; } + + /// + /// Additional poll delay sent by the server. + /// + public TimeSpan? PollDelay { get; private set; } + + /// + /// List of server messages sent inside this message. + /// + public List Data { get; private set; } + + void IServerMessage.Parse(object data) + { + IDictionary dic = data as IDictionary; + object value; + + this.MessageId = dic["C"].ToString(); + + if (dic.TryGetValue("S", out value)) + IsInitialization = int.Parse(value.ToString()) == 1 ? true : false; + else + IsInitialization = false; + + if (dic.TryGetValue("G", out value)) + GroupsToken = value.ToString(); + + if (dic.TryGetValue("T", out value)) + ShouldReconnect = int.Parse(value.ToString()) == 1 ? true : false; + else + ShouldReconnect = false; + + if (dic.TryGetValue("L", out value)) + PollDelay = TimeSpan.FromMilliseconds(double.Parse(value.ToString())); + + IEnumerable enumerable = dic["M"] as IEnumerable; + + if (enumerable != null) + { + Data = new List(); + + foreach (object subData in enumerable) + { +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + IDictionary subObj = subData as IDictionary; +#else + IDictionary subObj = subData as IDictionary; +#endif + + IServerMessage subMsg = null; + + if (subObj != null) + { + if (subObj.ContainsKey("H")) + subMsg = new MethodCallMessage(); + else if (subObj.ContainsKey("I")) + subMsg = new ProgressMessage(); + else + subMsg = new DataMessage(); + } + else + subMsg = new DataMessage(); + + subMsg.Parse(subData); + + Data.Add(subMsg); + } + } + } + } + + /// + /// A simple non-hub data message. It holds only one Data property. + /// + public sealed class DataMessage : IServerMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.Data; } } + + public object Data { get; private set; } + + void IServerMessage.Parse(object data) + { + this.Data = data; + } + } + + /// + /// A Hub message that orders the client to call a method. + /// + public sealed class MethodCallMessage : IServerMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.MethodCall; } } + + /// + /// The name of the Hub that the method is called on. + /// + public string Hub { get; private set; } + + /// + /// Name of the Method. + /// + public string Method { get; private set; } + + /// + /// Arguments of the method call. + /// + public object[] Arguments { get; private set; } + + /// + /// State changes of the hub. It's handled automatically by the Hub. + /// +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + public IDictionary State { get; private set; } +#else + public IDictionary State { get; private set; } +#endif + + void IServerMessage.Parse(object data) + { + #if BESTHTTP_SIGNALR_WITH_JSONDOTNET + IDictionary dic = data as IDictionary; + #else + IDictionary dic = data as IDictionary; + #endif + + Hub = dic["H"].ToString(); + Method = dic["M"].ToString(); + + List args = new List(); + foreach (object arg in dic["A"] as IEnumerable) + args.Add(arg); + Arguments = args.ToArray(); + +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + JToken value; + if (dic.TryGetValue("S", out value)) + State = value as IDictionary; +#else + object value; + if (dic.TryGetValue("S", out value)) + State = value as IDictionary; +#endif + } + } + + /// + /// Message of a server side method invocation result. + /// + public sealed class ResultMessage : IServerMessage, IHubMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.Result; } } + + /// + /// The unique id that the client set when called the server side method. Used by the plugin to deliver this message to the good Hub. + /// + public UInt64 InvocationId { get; private set; } + + /// + /// The return value of the server side method call, or null if the method's return type is void. + /// + public object ReturnValue { get; private set; } + + /// + /// State changes of the hub. It's handled automatically by the Hub. + /// +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + public IDictionary State { get; private set; } +#else + public IDictionary State { get; private set; } +#endif + + void IServerMessage.Parse(object data) + { + IDictionary dic = data as IDictionary; + + InvocationId = UInt64.Parse(dic["I"].ToString()); + + object value; + if (dic.TryGetValue("R", out value)) + ReturnValue = value; + + if (dic.TryGetValue("S", out value)) + { +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + State = value as IDictionary; +#else + State = value as IDictionary; +#endif + } + } + } + + public sealed class FailureMessage : IServerMessage, IHubMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.Failure; } } + + /// + /// The unique id that the client set when called the server side method. Used by the plugin to deliver this message to the good Hub. + /// + public UInt64 InvocationId { get; private set; } + + /// + /// True if it's a hub error. + /// + public bool IsHubError { get; private set; } + + /// + /// If the method call failed, it contains the error message to detail what happened. + /// + public string ErrorMessage { get; private set; } + + /// + /// A dictionary that may contain additional error data (can only be present for hub errors). It can be null. + /// +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + public IDictionary AdditionalData { get; private set; } +#else + public IDictionary AdditionalData { get; private set; } +#endif + + /// + /// Stack trace of the error. It present only if detailed error reporting is turned on on the server (https://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.hubconfiguration.enabledetailederrors%28v=vs.118%29.aspx). + /// + public string StackTrace { get; private set; } + + /// + /// State changes of the hub. It's handled automatically by the Hub. + /// +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + public IDictionary State { get; private set; } +#else + public IDictionary State { get; private set; } +#endif + + void IServerMessage.Parse(object data) + { + IDictionary dic = data as IDictionary; + + InvocationId = UInt64.Parse(dic["I"].ToString()); + + object value; + + if (dic.TryGetValue("E", out value)) + ErrorMessage = value.ToString(); + + if (dic.TryGetValue("H", out value)) + IsHubError = int.Parse(value.ToString()) == 1 ? true : false; + + if (dic.TryGetValue("D", out value)) + { +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + AdditionalData = value as IDictionary; +#else + AdditionalData = value as IDictionary; +#endif + } + + if (dic.TryGetValue("T", out value)) + StackTrace = value.ToString(); + + if (dic.TryGetValue("S", out value)) + { +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + State = value as IDictionary; +#else + State = value as IDictionary; +#endif + } + } + } + + /// + /// When a server method is a long running method the server can send the information about the progress of execution of the method to the client. + /// + public sealed class ProgressMessage : IServerMessage, IHubMessage + { + MessageTypes IServerMessage.Type { get { return MessageTypes.Progress; } } + + /// + /// The unique id that the client set when called the server side method. Used by the plugin to deliver this message to the good Hub. + /// + public UInt64 InvocationId { get; private set; } + + /// + /// Current progress of the long running method. + /// + public double Progress { get; private set; } + + void IServerMessage.Parse(object data) + { +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + IDictionary dic = data as IDictionary; +#else + IDictionary dic = data as IDictionary; +#endif + +#if BESTHTTP_SIGNALR_WITH_JSONDOTNET + IDictionary P = dic["P"] as IDictionary; +#else + IDictionary P = dic["P"] as IDictionary; +#endif + + InvocationId = UInt64.Parse(P["I"].ToString()); + Progress = double.Parse(P["D"].ToString()); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs.meta new file mode 100644 index 0000000..eb21219 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Messages/ServerMessages.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a128625937e3c5b459b3aa221061a03f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs new file mode 100644 index 0000000..989f81f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs @@ -0,0 +1,276 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; +using System.Collections.Generic; + +using BestHTTP.JSON; + +namespace BestHTTP.SignalR +{ + public sealed class NegotiationData + { + #region Public Negotiate data + + /// + /// Path to the SignalR endpoint. Currently not used by the client. + /// + public string Url { get; private set; } + + /// + /// WebSocket endpoint. + /// + public string WebSocketServerUrl { get; private set; } + + /// + /// Connection token assigned by the server. See this article for more details: http://www.asp.net/signalr/overview/security/introduction-to-security#connectiontoken. + /// This value needs to be sent in each subsequent request as the value of the connectionToken parameter + /// + public string ConnectionToken { get; private set; } + + /// + /// The id of the connection. + /// + public string ConnectionId { get; private set; } + + /// + /// The amount of time in seconds the client should wait before attempting to reconnect if it has not received a keep alive message. + /// If the server is configured to not send keep alive messages this value is null. + /// + public TimeSpan? KeepAliveTimeout { get; private set; } + + /// + /// The amount of time within which the client should try to reconnect if the connection goes away. + /// + public TimeSpan DisconnectTimeout { get; private set; } + + /// + /// Timeout of poll requests. + /// + public TimeSpan ConnectionTimeout { get; private set; } + + /// + /// Whether the server supports websockets. + /// + public bool TryWebSockets { get; private set; } + + /// + /// The version of the protocol used for communication. + /// + public string ProtocolVersion { get; private set; } + + /// + /// The maximum amount of time the client should try to connect to the server using a given transport. + /// + public TimeSpan TransportConnectTimeout { get; private set; } + + /// + /// The wait time before restablishing a long poll connection after data is sent from the server. The default value is 0. + /// + public TimeSpan LongPollDelay { get; private set; } + + #endregion + + #region Event Handlers + + /// + /// Event handler that called when the negotiation data received and parsed successfully. + /// + public Action OnReceived; + + /// + /// Event handler that called when an error happens. + /// + public Action OnError; + + #endregion + + #region Private + + private HTTPRequest NegotiationRequest; + private IConnection Connection; + + #endregion + + public NegotiationData(Connection connection) + { + this.Connection = connection; + } + + /// + /// Start to get the negotiation data. + /// + public void Start() + { + NegotiationRequest = new HTTPRequest(Connection.BuildUri(RequestTypes.Negotiate), HTTPMethods.Get, true, true, OnNegotiationRequestFinished); + Connection.PrepareRequest(NegotiationRequest, RequestTypes.Negotiate); + NegotiationRequest.Send(); + + HTTPManager.Logger.Information("NegotiationData", "Negotiation request sent"); + } + + /// + /// Abort the negotiation request. + /// + public void Abort() + { + if (NegotiationRequest != null) + { + OnReceived = null; + OnError = null; + NegotiationRequest.Abort(); + } + } + + #region Request Event Handler + + private void OnNegotiationRequestFinished(HTTPRequest req, HTTPResponse resp) + { + NegotiationRequest = null; + + switch (req.State) + { + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("NegotiationData", "Negotiation data arrived: " + resp.DataAsText); + + int idx = resp.DataAsText.IndexOf("{"); + if (idx < 0) + { + RaiseOnError("Invalid negotiation text: " + resp.DataAsText); + return; + } + + var Negotiation = Parse(resp.DataAsText.Substring(idx)); + + if (Negotiation == null) + { + RaiseOnError("Parsing Negotiation data failed: " + resp.DataAsText); + return; + } + + if (OnReceived != null) + { + OnReceived(this); + OnReceived = null; + } + } + else + RaiseOnError(string.Format("Negotiation request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2} Uri: {3}", + resp.StatusCode, + resp.Message, + resp.DataAsText, + req.CurrentUri)); + break; + + case HTTPRequestStates.Error: + RaiseOnError(req.Exception != null ? (req.Exception.Message + " " + req.Exception.StackTrace) : string.Empty); + break; + + default: + RaiseOnError(req.State.ToString()); + break; + } + } + + #endregion + + #region Helper Methods + + private void RaiseOnError(string err) + { + HTTPManager.Logger.Error("NegotiationData", "Negotiation request failed with error: " + err); + + if (OnError != null) + { + OnError(this, err); + OnError = null; + } + } + + private NegotiationData Parse(string str) + { + bool success = false; + Dictionary dict = Json.Decode(str, ref success) as Dictionary; + if (!success) + return null; + + try + { + this.Url = GetString(dict, "Url"); + + if (dict.ContainsKey("webSocketServerUrl")) + this.WebSocketServerUrl = GetString(dict, "webSocketServerUrl"); + + this.ConnectionToken = Uri.EscapeDataString(GetString(dict, "ConnectionToken")); + this.ConnectionId = GetString(dict, "ConnectionId"); + + if (dict.ContainsKey("KeepAliveTimeout")) + this.KeepAliveTimeout = TimeSpan.FromSeconds(GetDouble(dict, "KeepAliveTimeout")); + + this.DisconnectTimeout = TimeSpan.FromSeconds(GetDouble(dict, "DisconnectTimeout")); + + if (dict.ContainsKey("ConnectionTimeout")) + this.ConnectionTimeout = TimeSpan.FromSeconds(GetDouble(dict, "ConnectionTimeout")); + else + this.ConnectionTimeout = TimeSpan.FromSeconds(120); + + this.TryWebSockets = (bool)Get(dict, "TryWebSockets"); + this.ProtocolVersion = GetString(dict, "ProtocolVersion"); + this.TransportConnectTimeout = TimeSpan.FromSeconds(GetDouble(dict, "TransportConnectTimeout")); + + if (dict.ContainsKey("LongPollDelay")) + this.LongPollDelay = TimeSpan.FromSeconds(GetDouble(dict, "LongPollDelay")); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("NegotiationData", "Parse", ex); + return null; + } + + return this; + } + + private static object Get(Dictionary from, string key) + { + object value; + if (!from.TryGetValue(key, out value)) + throw new System.Exception(string.Format("Can't get {0} from Negotiation data!", key)); + return value; + } + + private static string GetString(Dictionary from, string key) + { + return Get(from, key) as string; + } + + private static List GetStringList(Dictionary from, string key) + { + List value = Get(from, key) as List; + + List result = new List(value.Count); + for (int i = 0; i < value.Count; ++i) + { + string str = value[i] as string; + if (str != null) + result.Add(str); + } + + return result; + } + + private static int GetInt(Dictionary from, string key) + { + return (int)(double)Get(from, key); + } + + private static double GetDouble(Dictionary from, string key) + { + return (double)Get(from, key); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs.meta new file mode 100644 index 0000000..69855b5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/NegotiationData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c20f605e63af7ef4eb7782aa663f0196 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports.meta new file mode 100644 index 0000000..7a14d7a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c390001e221f7e1429a38eb6222413c5 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs new file mode 100644 index 0000000..799e301 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs @@ -0,0 +1,256 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; + +using BestHTTP.Extensions; +using BestHTTP.SignalR.Messages; + +namespace BestHTTP.SignalR.Transports +{ + public sealed class PollingTransport : PostSendTransportBase, IHeartbeat + { + #region Overridden Properties + + public override bool SupportsKeepAlive { get { return false; } } + public override TransportTypes Type { get { return TransportTypes.LongPoll; } } + + #endregion + + #region Privates + + /// + /// When we received the last poll. + /// + private DateTime LastPoll; + + /// + /// How much time we have to wait before we can send out a new poll request. This value sent by the server. + /// + private TimeSpan PollDelay; + + /// + /// How much time we wait to a poll request to finish. It's value is the server sent negotiation's ConnectionTimeout + 10sec. + /// + private TimeSpan PollTimeout; + + /// + /// Reference to the the current poll request. + /// + private HTTPRequest pollRequest; + + #endregion + + public PollingTransport(Connection connection) + : base("longPolling", connection) + { + this.LastPoll = DateTime.MinValue; + this.PollTimeout = connection.NegotiationResult.ConnectionTimeout + TimeSpan.FromSeconds(10); + } + + #region Overrides from TransportBase + + /// + /// Polling transport specific connection logic. It's a regular GET request to the /connect path. + /// + public override void Connect() + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Sending Open Request"); + + // Skip the Connecting state if we are reconnecting. If the connect succeeds, we will set the Started state directly + if (this.State != TransportStates.Reconnecting) + this.State = TransportStates.Connecting; + + RequestTypes requestType = this.State == TransportStates.Reconnecting ? RequestTypes.Reconnect : RequestTypes.Connect; + + var request = new HTTPRequest(Connection.BuildUri(requestType, this), HTTPMethods.Get, true, true, OnConnectRequestFinished); + + Connection.PrepareRequest(request, requestType); + + request.Send(); + } + + public override void Stop() + { + HTTPManager.Heartbeats.Unsubscribe(this); + + if (pollRequest != null) + { + pollRequest.Abort(); + pollRequest = null; + } + + // Should we abort the send requests in the sendRequestQueue? + } + + protected override void Started() + { + LastPoll = DateTime.UtcNow; + HTTPManager.Heartbeats.Subscribe(this); + } + + protected override void Aborted() + { + HTTPManager.Heartbeats.Unsubscribe(this); + } + + #endregion + + #region Request Handlers + + void OnConnectRequestFinished(HTTPRequest req, HTTPResponse resp) + { + // error reason if there is any. We will call the manager's Error function if it's not empty. + string reason = string.Empty; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Connect - Request Finished Successfully! " + resp.DataAsText); + + OnConnected(); + + IServerMessage msg = TransportBase.Parse(Connection.JsonEncoder, resp.DataAsText); + + if (msg != null) + { + Connection.OnMessage(msg); + + MultiMessage multiple = msg as MultiMessage; + if (multiple != null && multiple.PollDelay.HasValue) + PollDelay = multiple.PollDelay.Value; + } + } + else + reason = string.Format("Connect - Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + reason = "Connect - Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + reason = "Connect - Request Aborted!"; + break; + + // Ceonnecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + reason = "Connect - Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + reason = "Connect - Processing the request Timed Out!"; + break; + } + + if (!string.IsNullOrEmpty(reason)) + Connection.Error(reason); + } + + void OnPollRequestFinished(HTTPRequest req, HTTPResponse resp) + { + // When Stop() called on the transport. + // In Stop() we set the pollRequest to null, but a new poll request can be made after a quick reconnection, and there is a chanse that + // in this handler function we can null out the new request. So we return early here. + if (req.State == HTTPRequestStates.Aborted) + { + HTTPManager.Logger.Warning("Transport - " + this.Name, "Poll - Request Aborted!"); + return; + } + + // Set the pollRequest to null, now we can send out a new one + pollRequest = null; + + // error reason if there is any. We will call the manager's Error function if it's not empty. + string reason = string.Empty; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Poll - Request Finished Successfully! " + resp.DataAsText); + + IServerMessage msg = TransportBase.Parse(Connection.JsonEncoder, resp.DataAsText); + + if (msg != null) + { + Connection.OnMessage(msg); + + MultiMessage multiple = msg as MultiMessage; + if (multiple != null && multiple.PollDelay.HasValue) + PollDelay = multiple.PollDelay.Value; + + LastPoll = DateTime.UtcNow; + } + } + else + reason = string.Format("Poll - Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + reason = "Poll - Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // Ceonnecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + reason = "Poll - Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + reason = "Poll - Processing the request Timed Out!"; + break; + } + + if (!string.IsNullOrEmpty(reason)) + Connection.Error(reason); + } + + #endregion + + /// + /// Polling transport speficic function. Sends a GET request to the /poll path to receive messages. + /// + private void Poll() + { + pollRequest = new HTTPRequest(Connection.BuildUri(RequestTypes.Poll, this), HTTPMethods.Get, true, true, OnPollRequestFinished); + + Connection.PrepareRequest(pollRequest, RequestTypes.Poll); + + pollRequest.Timeout = this.PollTimeout; + + pollRequest.Send(); + } + + #region IHeartbeat Implementation + + void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif) + { + switch(State) + { + case TransportStates.Started: + if (pollRequest == null && DateTime.UtcNow >= (LastPoll + PollDelay + Connection.NegotiationResult.LongPollDelay)) + Poll(); + break; + } + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs.meta new file mode 100644 index 0000000..ec93c4d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PollingTransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 702a1cd6038bbc347a4b568983058f63 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs new file mode 100644 index 0000000..7ce7c89 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs @@ -0,0 +1,103 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System.Collections.Generic; + +using BestHTTP.SignalR.Messages; + +namespace BestHTTP.SignalR.Transports +{ + /// + /// A base class for implementations that must send the data in unique requests. These are currently the LongPolling and ServerSentEvents transports. + /// + public abstract class PostSendTransportBase : TransportBase + { + /// + /// Sent out send requests. Keeping a reference to them for future use. + /// + protected List sendRequestQueue = new List(); + + public PostSendTransportBase(string name, Connection con) + : base(name, con) + { + + } + + #region Send Implementation + + protected override void SendImpl(string json) + { + var request = new HTTPRequest(Connection.BuildUri(RequestTypes.Send, this), HTTPMethods.Post, true, true, OnSendRequestFinished); + + request.FormUsage = Forms.HTTPFormUsage.UrlEncoded; + request.AddField("data", json); + + Connection.PrepareRequest(request, RequestTypes.Send); + + // Set a lower priority then the default. This way requests that are sent out alongside with SignalR sent requests can be processed sooner. + request.Priority = -1; + + request.Send(); + + sendRequestQueue.Add(request); + } + + void OnSendRequestFinished(HTTPRequest req, HTTPResponse resp) + { + sendRequestQueue.Remove(req); + + // error reason if there is any. We will call the manager's Error function if it's not empty. + string reason = string.Empty; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Send - Request Finished Successfully! " + resp.DataAsText); + + if (!string.IsNullOrEmpty(resp.DataAsText)) + { + IServerMessage msg = TransportBase.Parse(Connection.JsonEncoder, resp.DataAsText); + + if (msg != null) + Connection.OnMessage(msg); + } + } + else + reason = string.Format("Send - Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + reason = "Send - Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + reason = "Send - Request Aborted!"; + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + reason = "Send - Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + reason = "Send - Processing the request Timed Out!"; + break; + } + + if (!string.IsNullOrEmpty(reason)) + Connection.Error(reason); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs.meta new file mode 100644 index 0000000..0d14532 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/PostSendTransportBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f47176f2538ccf54e855235ecb7647f3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs new file mode 100644 index 0000000..5a36384 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs @@ -0,0 +1,171 @@ +#if !BESTHTTP_DISABLE_SIGNALR +#if !BESTHTTP_DISABLE_SERVERSENT_EVENTS + +using System; + +using BestHTTP.ServerSentEvents; +using BestHTTP.SignalR.Messages; + +namespace BestHTTP.SignalR.Transports +{ + /// + /// A SignalR transport implementation that uses the Server-Sent Events protocol. + /// + public sealed class ServerSentEventsTransport : PostSendTransportBase + { + #region Overridden Properties + + /// + /// It's a persistent connection. We support the keep-alive mechanism. + /// + public override bool SupportsKeepAlive { get { return true; } } + + /// + /// Type of the transport. + /// + public override TransportTypes Type { get { return TransportTypes.ServerSentEvents; } } + + #endregion + + #region Privates + + /// + /// The EventSource object. + /// + private EventSource EventSource; + + #endregion + + public ServerSentEventsTransport(Connection con) + : base("serverSentEvents", con) + { + + } + + #region Overrides from TransportBase + + public override void Connect() + { + if (EventSource != null) + { + HTTPManager.Logger.Warning("ServerSentEventsTransport", "Start - EventSource already created!"); + return; + } + + // Skip the Connecting state if we are reconnecting. If the connect succeeds, we will set the Started state directly + if (this.State != TransportStates.Reconnecting) + this.State = TransportStates.Connecting; + + RequestTypes requestType = this.State == TransportStates.Reconnecting ? RequestTypes.Reconnect : RequestTypes.Connect; + + Uri uri = Connection.BuildUri(requestType, this); + + EventSource = new EventSource(uri); + + EventSource.OnOpen += OnEventSourceOpen; + EventSource.OnMessage += OnEventSourceMessage; + EventSource.OnError += OnEventSourceError; + EventSource.OnClosed += OnEventSourceClosed; + +#if !UNITY_WEBGL || UNITY_EDITOR + // Disable internal retry + EventSource.OnRetry += (es) => false; +#endif + + // Start connecting to the server. + EventSource.Open(); + } + + public override void Stop() + { + EventSource.OnOpen -= OnEventSourceOpen; + EventSource.OnMessage -= OnEventSourceMessage; + EventSource.OnError -= OnEventSourceError; + EventSource.OnClosed -= OnEventSourceClosed; + + EventSource.Close(); + + EventSource = null; + } + + protected override void Started() + { + // Nothing to do here for this transport + } + + /// + /// A custom Abort function where we will start to close the EventSource object. + /// + public override void Abort() + { + base.Abort(); + + EventSource.Close(); + } + + protected override void Aborted() + { + if (this.State == TransportStates.Closing) + this.State = TransportStates.Closed; + } + + #endregion + + #region EventSource Event Handlers + + private void OnEventSourceOpen(EventSource eventSource) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "OnEventSourceOpen"); + } + + private void OnEventSourceMessage(EventSource eventSource, BestHTTP.ServerSentEvents.Message message) + { + if (message.Data.Equals("initialized")) + { + base.OnConnected(); + + return; + } + + IServerMessage msg = TransportBase.Parse(Connection.JsonEncoder, message.Data); + + if (msg != null) + Connection.OnMessage(msg); + + } + + private void OnEventSourceError(EventSource eventSource, string error) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "OnEventSourceError"); + + // We are in a reconnecting phase, we have to connect now. + if (this.State == TransportStates.Reconnecting) + { + Connect(); + return; + } + + // Already closed? + if (this.State == TransportStates.Closed) + return; + + // Closing? Then we are closed now. + if (this.State == TransportStates.Closing) + this.State = TransportStates.Closed; + else // Errored when we didn't expected it. + Connection.Error(error); + } + + private void OnEventSourceClosed(ServerSentEvents.EventSource eventSource) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "OnEventSourceClosed"); + + OnEventSourceError(eventSource, "EventSource Closed!"); + } + + #endregion + } +} + +#endif +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs.meta new file mode 100644 index 0000000..218dab3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/ServerSentEventsTransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b8c1fc0aacfa94c4793a2e8958a34058 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs new file mode 100644 index 0000000..e2e92b1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs @@ -0,0 +1,386 @@ +#if !BESTHTTP_DISABLE_SIGNALR + +using System; +using System.Collections.Generic; + +using BestHTTP.SignalR.Messages; +using BestHTTP.SignalR.JsonEncoders; + +namespace BestHTTP.SignalR.Transports +{ + public delegate void OnTransportStateChangedDelegate(TransportBase transport, TransportStates oldState, TransportStates newState); + + public abstract class TransportBase + { + private const int MaxRetryCount = 5; + + #region Public Properties + + /// + /// Name of the transport. + /// + public string Name { get; protected set; } + + /// + /// True if the manager has to check the last message received time and reconnect if too much time passes. + /// + public abstract bool SupportsKeepAlive { get; } + + /// + /// Type of the transport. Used mainly by the manager in its BuildUri function. + /// + public abstract TransportTypes Type { get; } + + /// + /// Reference to the manager. + /// + public IConnection Connection { get; protected set; } + + /// + /// The current state of the transport. + /// + public TransportStates State + { + get { return _state; } + protected set + { + TransportStates old = _state; + _state = value; + + if (OnStateChanged != null) + OnStateChanged(this, old, _state); + } + } + public TransportStates _state; + + /// + /// Thi event called when the transport's State set to a new value. + /// + public event OnTransportStateChangedDelegate OnStateChanged; + + #endregion + + public TransportBase(string name, Connection connection) + { + this.Name = name; + this.Connection = connection; + this.State = TransportStates.Initial; + } + + #region Abstract functions + + /// + /// Start to connect to the server + /// + public abstract void Connect(); + + /// + /// Stop the connection + /// + public abstract void Stop(); + + /// + /// The transport specific implementation to send the given json string to the server. + /// + protected abstract void SendImpl(string json); + + /// + /// Called when the Start request finished successfully, or after a reconnect. + /// Manager.TransportOpened(); called from the TransportBase after this call + /// + protected abstract void Started(); + + /// + /// Called when the abort request finished successfully. + /// + protected abstract void Aborted(); + + #endregion + + /// + /// Called after a succesful connect/reconnect. The transport implementations have to call this function. + /// + protected void OnConnected() + { + if (this.State != TransportStates.Reconnecting) + { + // Send the Start request + Start(); + } + else + { + Connection.TransportReconnected(); + + Started(); + + this.State = TransportStates.Started; + } + } + + #region Start Request Sending + + /// + /// Sends out the /start request to the server. + /// + protected void Start() + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Sending Start Request"); + + this.State = TransportStates.Starting; + + if (this.Connection.Protocol > ProtocolVersions.Protocol_2_0) + { + var request = new HTTPRequest(Connection.BuildUri(RequestTypes.Start, this), HTTPMethods.Get, true, true, OnStartRequestFinished); + + request.Tag = 0; + request.DisableRetry = true; + + request.Timeout = Connection.NegotiationResult.ConnectionTimeout + TimeSpan.FromSeconds(10); + + Connection.PrepareRequest(request, RequestTypes.Start); + + request.Send(); + } + else + { + // The transport and the signalr protocol now started + this.State = TransportStates.Started; + + Started(); + + Connection.TransportStarted(); + } + } + + private void OnStartRequestFinished(HTTPRequest req, HTTPResponse resp) + { + switch (req.State) + { + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Start - Returned: " + resp.DataAsText); + + string response = Connection.ParseResponse(resp.DataAsText); + + if (response != "started") + { + Connection.Error(string.Format("Expected 'started' response, but '{0}' found!", response)); + return; + } + + // The transport and the signalr protocol now started + this.State = TransportStates.Started; + + Started(); + + Connection.TransportStarted(); + + return; + } + else + HTTPManager.Logger.Warning("Transport - " + this.Name, string.Format("Start - request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2} Uri: {3}", + resp.StatusCode, + resp.Message, + resp.DataAsText, + req.CurrentUri)); + goto default; + + default: + HTTPManager.Logger.Information("Transport - " + this.Name, "Start request state: " + req.State.ToString()); + + // The request may not reached the server. Try it again. + int retryCount = (int)req.Tag; + if (retryCount++ < MaxRetryCount) + { + req.Tag = retryCount; + req.Send(); + } + else + Connection.Error("Failed to send Start request."); + + break; + } + } + + #endregion + + #region Abort Implementation + + /// + /// Will abort the transport. In SignalR 'Abort'ing is a graceful process, while 'Close'ing is a hard-abortion... + /// + public virtual void Abort() + { + if (this.State != TransportStates.Started) + return; + + this.State = TransportStates.Closing; + + var request = new HTTPRequest(Connection.BuildUri(RequestTypes.Abort, this), HTTPMethods.Get, true, true, OnAbortRequestFinished); + + // Retry counter + request.Tag = 0; + request.DisableRetry = true; + + Connection.PrepareRequest(request, RequestTypes.Abort); + + request.Send(); + } + + protected void AbortFinished() + { + this.State = TransportStates.Closed; + + Connection.TransportAborted(); + + this.Aborted(); + } + + private void OnAbortRequestFinished(HTTPRequest req, HTTPResponse resp) + { + switch (req.State) + { + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Abort - Returned: " + resp.DataAsText); + + if (this.State == TransportStates.Closing) + AbortFinished(); + } + else + { + HTTPManager.Logger.Warning("Transport - " + this.Name, string.Format("Abort - Handshake request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2} Uri: {3}", + resp.StatusCode, + resp.Message, + resp.DataAsText, + req.CurrentUri)); + + // try again + goto default; + } + break; + default: + HTTPManager.Logger.Information("Transport - " + this.Name, "Abort request state: " + req.State.ToString()); + + // The request may not reached the server. Try it again. + int retryCount = (int)req.Tag; + if (retryCount++ < MaxRetryCount) + { + req.Tag = retryCount; + req.Send(); + } + else + Connection.Error("Failed to send Abort request!"); + + break; + } + } + + #endregion + + #region Send Implementation + + /// + /// Sends the given json string to the wire. + /// + /// + public void Send(string jsonStr) + { + try + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Sending: " + jsonStr); + + SendImpl(jsonStr); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("Transport - " + this.Name, "Send", ex); + } + } + + #endregion + + #region Helper Functions + + /// + /// Start the reconnect process + /// + public void Reconnect() + { + HTTPManager.Logger.Information("Transport - " + this.Name, "Reconnecting"); + + Stop(); + + this.State = TransportStates.Reconnecting; + + Connect(); + } + + /// + /// When the json string is successfully parsed will return with an IServerMessage implementation. + /// + public static IServerMessage Parse(IJsonEncoder encoder, string json) + { + // Nothing to parse? + if (string.IsNullOrEmpty(json)) + { + HTTPManager.Logger.Error("MessageFactory", "Parse - called with empty or null string!"); + return null; + } + + // We don't have to do further decoding, if it's an empty json object, then it's a KeepAlive message from the server + if (json.Length == 2 && json == "{}") + return new KeepAliveMessage(); + + IDictionary msg = null; + + try + { + // try to decode the json message with the encoder + msg = encoder.DecodeMessage(json); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("MessageFactory", "Parse - encoder.DecodeMessage", ex); + return null; + } + + if (msg == null) + { + HTTPManager.Logger.Error("MessageFactory", "Parse - Json Decode failed for json string: \"" + json + "\""); + return null; + } + + // "C" is for message id + IServerMessage result = null; + if (!msg.ContainsKey("C")) + { + // If there are no ErrorMessage in the object, then it was a success + if (!msg.ContainsKey("E")) + result = new ResultMessage(); + else + result = new FailureMessage(); + } + else + result = new MultiMessage(); + + try + { + result.Parse(msg); + } + catch + { + HTTPManager.Logger.Error("MessageFactory", "Can't parse msg: " + json); + throw; + } + + return result; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs.meta new file mode 100644 index 0000000..88831c2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/TransportBase.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 469a77c43ea68f14da659401301834f5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs new file mode 100644 index 0000000..cbdee97 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs @@ -0,0 +1,173 @@ +#if !BESTHTTP_DISABLE_SIGNALR +#if !BESTHTTP_DISABLE_WEBSOCKET + +using System; +using System.Text; + +using BestHTTP; +using BestHTTP.JSON; +using BestHTTP.SignalR.Hubs; +using BestHTTP.SignalR.Messages; +using BestHTTP.SignalR.JsonEncoders; + +namespace BestHTTP.SignalR.Transports +{ + public sealed class WebSocketTransport : TransportBase + { + #region Overridden Properties + + public override bool SupportsKeepAlive { get { return true; } } + public override TransportTypes Type { get { return TransportTypes.WebSocket; } } + + #endregion + + private WebSocket.WebSocket wSocket; + + public WebSocketTransport(Connection connection) + : base("webSockets", connection) + { + } + + #region Overrides from TransportBase + + /// + /// Websocket transport specific connection logic. It will create a WebSocket instance, and starts to connect to the server. + /// + public override void Connect() + { + if (wSocket != null) + { + HTTPManager.Logger.Warning("WebSocketTransport", "Start - WebSocket already created!"); + return; + } + + // Skip the Connecting state if we are reconnecting. If the connect succeeds, we will set the Started state directly + if (this.State != TransportStates.Reconnecting) + this.State = TransportStates.Connecting; + + RequestTypes requestType = this.State == TransportStates.Reconnecting ? RequestTypes.Reconnect : RequestTypes.Connect; + + Uri uri = Connection.BuildUri(requestType, this); + + // Create the WebSocket instance + wSocket = new WebSocket.WebSocket(uri); + + // Set up eventhandlers + wSocket.OnOpen += WSocket_OnOpen; + wSocket.OnMessage += WSocket_OnMessage; + wSocket.OnClosed += WSocket_OnClosed; + wSocket.OnErrorDesc += WSocket_OnError; + +#if !UNITY_WEBGL || UNITY_EDITOR + // prepare the internal http request + Connection.PrepareRequest(wSocket.InternalRequest, requestType); +#endif + + // start opening the websocket protocol + wSocket.Open(); + } + + protected override void SendImpl(string json) + { + if (wSocket != null && wSocket.IsOpen) + wSocket.Send(json); + } + + public override void Stop() + { + if (wSocket != null) + { + wSocket.OnOpen = null; + wSocket.OnMessage = null; + wSocket.OnClosed = null; + wSocket.OnErrorDesc = null; + wSocket.Close(); + wSocket = null; + } + } + + protected override void Started() + { + // Nothing to be done here for this transport + } + + /// + /// The /abort request successfully finished + /// + protected override void Aborted() + { + // if the websocket is still open, close it + if (wSocket != null && wSocket.IsOpen) + { + wSocket.Close(); + wSocket = null; + } + } + +#endregion + +#region WebSocket Events + + void WSocket_OnOpen(WebSocket.WebSocket webSocket) + { + if (webSocket != wSocket) + return; + + HTTPManager.Logger.Information("WebSocketTransport", "WSocket_OnOpen"); + + OnConnected(); + } + + void WSocket_OnMessage(WebSocket.WebSocket webSocket, string message) + { + if (webSocket != wSocket) + return; + + IServerMessage msg = TransportBase.Parse(Connection.JsonEncoder, message); + + if (msg != null) + Connection.OnMessage(msg); + } + + void WSocket_OnClosed(WebSocket.WebSocket webSocket, ushort code, string message) + { + if (webSocket != wSocket) + return; + + string reason = code.ToString() + " : " + message; + + HTTPManager.Logger.Information("WebSocketTransport", "WSocket_OnClosed " + reason); + + if (this.State == TransportStates.Closing) + this.State = TransportStates.Closed; + else + Connection.Error(reason); + } + + void WSocket_OnError(WebSocket.WebSocket webSocket, string reason) + { + if (webSocket != wSocket) + return; + + // On WP8.1, somehow we receive an exception that the remote server forcibly closed the connection instead of the + // WebSocket closed packet... Also, even the /abort request didn't finished. + if (this.State == TransportStates.Closing || + this.State == TransportStates.Closed) + { + base.AbortFinished(); + } + else + { + HTTPManager.Logger.Error("WebSocketTransport", "WSocket_OnError " + reason); + + this.State = TransportStates.Closed; + Connection.Error(reason); + } + } + +#endregion + } +} + +#endif +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs.meta new file mode 100644 index 0000000..e969abb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalR/Transports/WebSocketTransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5efa5f8b9a034084b87f47b2b74b8173 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore.meta new file mode 100644 index 0000000..eb99aa8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fe53b9220e298d844bd0d53106307094 +folderAsset: yes +timeCreated: 1515237542 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs new file mode 100644 index 0000000..bd00d35 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs @@ -0,0 +1,147 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET +using System; +using System.Collections.Generic; + +namespace BestHTTP.SignalRCore +{ + public enum TransportTypes + { + WebSocket + } + + public enum TransferModes + { + Binary, + Text + } + + public enum TransportStates + { + Initial, + Connecting, + Connected, + Closing, + Failed, + Closed + } + + /// + /// Possible states of a HubConnection + /// + public enum ConnectionStates + { + Initial, + Authenticating, + Negotiating, + Connected, + CloseInitiated, + Closed + } + + public interface ITransport + { + TransferModes TransferMode { get; } + TransportTypes TransportType { get; } + TransportStates State { get; } + + string ErrorReason { get; } + + event Action OnStateChanged; + + void StartConnect(); + void StartClose(); + + void Send(byte[] msg); + } + + public interface IEncoder + { + string Name { get; } + + string EncodeAsText(T value); + T DecodeAs(string text); + + byte[] EncodeAsBinary(T value); + T DecodeAs(byte[] data); + + object ConvertTo(Type toType, object obj); + } + + public class StreamItemContainer + { + public readonly long id; + + public List Items { get; private set; } + public T LastAdded { get; private set; } + + //public int newIdx; + //public int newCount; + + public bool IsCanceled; + + public StreamItemContainer(long _id) + { + this.id = _id; + this.Items = new List(); + } + + public void AddItem(T item) + { + if (this.Items == null) + this.Items = new List(); + + //this.newIdx = this.Items.Count; + //this.newCount = 1; + this.Items.Add(item); + this.LastAdded = item; + } + + //public void AddItems(T[] items) + //{ + // if (this.Items == null) + // this.Items = new List(); + // + // this.newIdx = this.Items.Count; + // this.newCount = items.Length; + // + // this.Items.AddRange(items); + //} + } + + struct CallbackDescriptor + { + public readonly Type[] ParamTypes; + public readonly Action Callback; + public CallbackDescriptor(Type[] paramTypes, Action callback) + { + this.ParamTypes = paramTypes; + this.Callback = callback; + } + } + + internal sealed class Subscription + { + public List callbacks = new List(1); + + public void Add(Type[] paramTypes, Action callback) + { + lock(callbacks) + this.callbacks.Add(new CallbackDescriptor(paramTypes, callback)); + } + + public void Remove(Action callback) + { + lock (callbacks) + { + int idx = -1; + for (int i = 0; i < this.callbacks.Count && idx == -1; ++i) + if (this.callbacks[i].Callback == callback) + idx = i; + + if (idx != -1) + this.callbacks.RemoveAt(idx); + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs.meta new file mode 100644 index 0000000..48b288e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HelperClasses.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6742bc413b5a23041b937fb3ee3b12d8 +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs new file mode 100644 index 0000000..c772cdc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs @@ -0,0 +1,653 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET +using BestHTTP.Futures; +using BestHTTP.SignalRCore.Messages; +using System; +using System.Collections.Generic; + +namespace BestHTTP.SignalRCore +{ + public sealed class HubOptions + { + /// + /// When this is set to true, the plugin will skip the negotiation request if the PreferedTransport is + /// WebSocket. + /// + public bool SkipNegotiation { get; set; } + + /// + /// The preferred transport to choose when more than one available. + /// + public TransportTypes PreferedTransport { get; set; } + } + + public sealed class HubConnection + { + public static readonly object[] EmptyArgs = new object[0]; + + /// + /// Uri of the Hub endpoint + /// + public Uri Uri { get; private set; } + + /// + /// Current state of this connection. + /// + public ConnectionStates State { get; private set; } + + /// + /// Current, active ITransport instance. + /// + public ITransport Transport { get; private set; } + + /// + /// The IProtocol implementation that will parse, encode and decode messages. + /// + public IProtocol Protocol { get; private set; } + + /// + /// This event is called when successfully connected to the hub. + /// + public event Action OnConnected; + + /// + /// This event is called when an unexpected error happen and the connection is closed. + /// + public event Action OnError; + + /// + /// This event is called when the connection is gracefully terminated. + /// + public event Action OnClosed; + + /// + /// This event is called for every server-sent message. When returns false, no further processing of the message is done + /// by the plugin. + /// + public event Func OnMessage; + + /// + /// An IAuthenticationProvider implementation that will be used to authenticate the connection. + /// + public IAuthenticationProvider AuthenticationProvider { get; set; } + + /// + /// Negotiation response sent by the server. + /// + public NegotiationResult NegotiationResult { get; private set; } + + /// + /// + /// + public HubOptions Options { get; private set; } + + /// + /// This will be increment to add a unique id to every message the plugin will send. + /// + private long lastInvocationId = 0; + + /// + /// Store the callback for all sent message that expect a return value from the server. All sent message has + /// a unique invocationId that will be sent back from the server. + /// + private Dictionary> invocations = new Dictionary>(); + + /// + /// This is where we store the methodname => callback mapping. + /// + private Dictionary subscriptions = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public HubConnection(Uri hubUri, IProtocol protocol) + : this(hubUri, protocol, new HubOptions()) + { + } + + public HubConnection(Uri hubUri, IProtocol protocol, HubOptions options) + { + this.Uri = hubUri; + this.State = ConnectionStates.Initial; + this.Options = options; + this.Protocol = protocol; + this.Protocol.Connection = this; + } + + public void StartConnect() + { + if (this.State != ConnectionStates.Initial) + return; + + HTTPManager.Logger.Verbose("HubConnection", "StartConnect"); + + if (this.AuthenticationProvider != null && this.AuthenticationProvider.IsPreAuthRequired) + { + HTTPManager.Logger.Information("HubConnection", "StartConnect - Authenticating"); + SetState(ConnectionStates.Authenticating); + + this.AuthenticationProvider.OnAuthenticationSucceded += OnAuthenticationSucceded; + this.AuthenticationProvider.OnAuthenticationFailed += OnAuthenticationFailed; + + // Start the authentication process + this.AuthenticationProvider.StartAuthentication(); + } + else + StartNegotiation(); + } + + private void OnAuthenticationSucceded(IAuthenticationProvider provider) + { + HTTPManager.Logger.Verbose("HubConnection", "OnAuthenticationSucceded"); + + this.AuthenticationProvider.OnAuthenticationSucceded -= OnAuthenticationSucceded; + this.AuthenticationProvider.OnAuthenticationFailed -= OnAuthenticationFailed; + + StartNegotiation(); + } + + private void OnAuthenticationFailed(IAuthenticationProvider provider, string reason) + { + HTTPManager.Logger.Error("HubConnection", "OnAuthenticationFailed: " + reason); + + this.AuthenticationProvider.OnAuthenticationSucceded -= OnAuthenticationSucceded; + this.AuthenticationProvider.OnAuthenticationFailed -= OnAuthenticationFailed; + + SetState(ConnectionStates.Closed, reason); + } + + private void StartNegotiation() + { + HTTPManager.Logger.Verbose("HubConnection", "StartNegotiation"); + + if (this.Options.SkipNegotiation) + { + HTTPManager.Logger.Verbose("HubConnection", "Skipping negotiation"); + ConnectImpl(); + + return; + } + + if (this.State == ConnectionStates.CloseInitiated) + { + SetState(ConnectionStates.Closed); + return; + } + + SetState(ConnectionStates.Negotiating); + + // https://github.com/aspnet/SignalR/blob/dev/specs/TransportProtocols.md#post-endpoint-basenegotiate-request + // Send out a negotiation request. While we could skip it and connect right with the websocket transport + // it might return with additional information that could be useful. + UriBuilder builder = new UriBuilder(this.Uri); + builder.Path += "/negotiate"; + + var request = new HTTPRequest(builder.Uri, HTTPMethods.Post, OnNegotiationRequestFinished); + if (this.AuthenticationProvider != null) + this.AuthenticationProvider.PrepareRequest(request); + request.Send(); + } + + private void ConnectImpl() + { + HTTPManager.Logger.Verbose("HubConnection", "ConnectImpl"); + + switch (this.Options.PreferedTransport) + { + case TransportTypes.WebSocket: + if (this.NegotiationResult != null && !IsTransportSupported("WebSockets")) + { + SetState(ConnectionStates.Closed, "The 'WebSockets' transport isn't supported by the server!"); + return; + } + + this.Transport = new Transports.WebSocketTransport(this); + this.Transport.OnStateChanged += Transport_OnStateChanged; + break; + + default: + SetState(ConnectionStates.Closed, "Unsupportted transport: " + this.Options.PreferedTransport); + break; + } + + this.Transport.StartConnect(); + } + + private bool IsTransportSupported(string transportName) + { + // https://github.com/aspnet/SignalR/blob/dev/specs/TransportProtocols.md#post-endpoint-basenegotiate-request + // If the negotiation response contains only the url and accessToken, no 'availableTransports' list is sent + if (this.NegotiationResult.SupportedTransports == null) + return true; + + for (int i = 0; i < this.NegotiationResult.SupportedTransports.Count; ++i) + if (this.NegotiationResult.SupportedTransports[i].Name == transportName) + return true; + + return false; + } + + private void OnNegotiationRequestFinished(HTTPRequest req, HTTPResponse resp) + { + if (this.State == ConnectionStates.CloseInitiated) + { + SetState(ConnectionStates.Closed); + return; + } + + string errorReason = null; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (resp.IsSuccess) + { + HTTPManager.Logger.Information("HubConnection", "Negotiation Request Finished Successfully! Response: " + resp.DataAsText); + + // Parse negotiation + this.NegotiationResult = NegotiationResult.Parse(resp.DataAsText, out errorReason); + + // TODO: check validity of the negotiation result: + // If url and accessToken is present, the other two must be null. + // https://github.com/aspnet/SignalR/blob/dev/specs/TransportProtocols.md#post-endpoint-basenegotiate-request + + if (string.IsNullOrEmpty(errorReason)) + ConnectImpl(); + } + else // Internal server error? + errorReason = string.Format("Negotiation Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + errorReason = "Negotiation Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + errorReason = "Negotiation Request Aborted!"; + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + errorReason = "Negotiation Request - Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + errorReason = "Negotiation Request - Processing the request Timed Out!"; + break; + } + + if (errorReason != null) + SetState(ConnectionStates.Closed, errorReason); + } + + public void StartClose() + { + HTTPManager.Logger.Verbose("HubConnection", "StartClose"); + + SetState(ConnectionStates.CloseInitiated); + + if (this.Transport != null) + this.Transport.StartClose(); + } + + public IFuture> Stream(string target, params object[] args) + { + var future = new Future>(); + + long id = InvokeImp(target, + args, + callback: (message) => + { + switch (message.type) + { + // StreamItem message contains only one item. + case MessageTypes.StreamItem: + { + var container = future.value; + + if (container.IsCanceled) + break; + + container.AddItem((TResult)this.Protocol.ConvertTo(typeof(TResult), message.item)); + + // (re)assign the container to raise OnItem event + future.AssignItem(container); + break; + } + + case MessageTypes.Completion: + { + bool isSuccess = string.IsNullOrEmpty(message.error); + if (isSuccess) + { + var container = future.value; + + // While completion message must not contain any result, this should be future-proof + //if (!container.IsCanceled && message.Result != null) + //{ + // TResult[] results = (TResult[])this.Protocol.ConvertTo(typeof(TResult[]), message.Result); + // + // container.AddItems(results); + //} + + future.Assign(container); + } + else + future.Fail(new Exception(message.error)); + break; + } + } + }, + isStreamingInvocation: true); + + future.BeginProcess(new StreamItemContainer(id)); + + return future; + } + + public void CancelStream(StreamItemContainer container) + { + Message message = new Message { + type = MessageTypes.CancelInvocation, + invocationId = container.id.ToString() + }; + + container.IsCanceled = true; + + SendMessage(message); + } + + public IFuture Invoke(string target, params object[] args) + { + Future future = new Future(); + + InvokeImp(target, + args, + (message) => + { + bool isSuccess = string.IsNullOrEmpty(message.error); + if (isSuccess) + future.Assign((TResult)this.Protocol.ConvertTo(typeof(TResult), message.result)); + else + future.Fail(new Exception(message.error)); + }); + + return future; + } + + public IFuture Send(string target, params object[] args) + { + Future future = new Future(); + + InvokeImp(target, + args, + (message) => + { + bool isSuccess = string.IsNullOrEmpty(message.error); + if (isSuccess) + future.Assign(true); + else + future.Fail(new Exception(message.error)); + }); + + return future; + } + + private long InvokeImp(string target, object[] args, Action callback, bool isStreamingInvocation = false) + { + if (this.State != ConnectionStates.Connected) + throw new Exception("Not connected yet!"); + + long invocationId = System.Threading.Interlocked.Increment(ref this.lastInvocationId); + var message = new Message + { + type = isStreamingInvocation ? MessageTypes.StreamInvocation : MessageTypes.Invocation, + invocationId = invocationId.ToString(), + target = target, + arguments = args, + nonblocking = callback == null, + }; + + SendMessage(message); + + if (callback != null) + this.invocations.Add(invocationId, callback); + + return invocationId; + } + + private void SendMessage(Message message) + { + byte[] encoded = this.Protocol.EncodeMessage(message); + this.Transport.Send(encoded); + } + + public void On(string methodName, Action callback) + { + On(methodName, null, (args) => callback()); + } + + public void On(string methodName, Action callback) + { + On(methodName, new Type[] { typeof(T1) }, (args) => callback((T1)args[0])); + } + + public void On(string methodName, Action callback) + { + On(methodName, + new Type[] { typeof(T1), typeof(T2) }, + (args) => callback((T1)args[0], (T2)args[1])); + } + + public void On(string methodName, Action callback) + { + On(methodName, + new Type[] { typeof(T1), typeof(T2), typeof(T3) }, + (args) => callback((T1)args[0], (T2)args[1], (T3)args[2])); + } + + public void On(string methodName, Action callback) + { + On(methodName, + new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) }, + (args) => callback((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3])); + } + + public void On(string methodName, Type[] paramTypes, Action callback) + { + Subscription subscription = null; + if (!this.subscriptions.TryGetValue(methodName, out subscription)) + this.subscriptions.Add(methodName, subscription = new Subscription()); + + subscription.Add(paramTypes, callback); + } + + internal void OnMessages(List messages) + { + for (int messageIdx = 0; messageIdx < messages.Count; ++messageIdx) + { + var message = messages[messageIdx]; + + try + { + if (this.OnMessage != null && !this.OnMessage(this, message)) + return; + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "Exception in OnMessage user code!", ex); + } + + switch (message.type) + { + case MessageTypes.Invocation: + { + Subscription subscribtion = null; + if (this.subscriptions.TryGetValue(message.target, out subscribtion)) + { + for (int i = 0; i < subscribtion.callbacks.Count; ++i) + { + var callbackDesc = subscribtion.callbacks[i]; + + object[] realArgs = null; + try + { + realArgs = this.Protocol.GetRealArguments(callbackDesc.ParamTypes, message.arguments); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "OnMessages - Invocation - GetRealArguments", ex); + } + + try + { + callbackDesc.Callback.Invoke(realArgs); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "OnMessages - Invocation - Invoke", ex); + } + } + } + + break; + } + + case MessageTypes.StreamItem: + { + long invocationId; + if (long.TryParse(message.invocationId, out invocationId)) + { + Action callback; + if (this.invocations.TryGetValue(invocationId, out callback) && callback != null) + { + try + { + callback(message); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "OnMessages - StreamItem - callback", ex); + } + } + } + break; + } + + case MessageTypes.Completion: + { + long invocationId; + if (long.TryParse(message.invocationId, out invocationId)) + { + Action callback; + if (this.invocations.TryGetValue(invocationId, out callback) && callback != null) + { + try + { + callback(message); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "OnMessages - Completion - callback", ex); + } + } + this.invocations.Remove(invocationId); + } + break; + } + + case MessageTypes.Close: + SetState(ConnectionStates.Closed, message.error); + break; + } + } + } + + private void Transport_OnStateChanged(TransportStates oldState, TransportStates newState) + { + HTTPManager.Logger.Verbose("HubConnection", string.Format("Transport_OnStateChanged - oldState: {0} newState: {1}", oldState.ToString(), newState.ToString())); + + switch (newState) + { + case TransportStates.Connected: + SetState(ConnectionStates.Connected); + break; + + case TransportStates.Failed: + SetState(ConnectionStates.Closed, this.Transport.ErrorReason); + break; + + case TransportStates.Closed: + SetState(ConnectionStates.Closed); + break; + } + } + + private void SetState(ConnectionStates state, string errorReason = null) + { + HTTPManager.Logger.Information("HubConnection", "SetState - from State: " + this.State.ToString() + " to State: " + state.ToString() + " errorReason: " + errorReason ?? string.Empty); + + if (this.State == state) + return; + + this.State = state; + + switch (state) + { + case ConnectionStates.Initial: + case ConnectionStates.Authenticating: + case ConnectionStates.Negotiating: + case ConnectionStates.CloseInitiated: + break; + + case ConnectionStates.Connected: + try + { + if (this.OnConnected != null) + this.OnConnected(this); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "Exception in OnConnected user code!", ex); + } + break; + + case ConnectionStates.Closed: + if (string.IsNullOrEmpty(errorReason)) + { + if (this.OnClosed != null) + { + try + { + this.OnClosed(this); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "Exception in OnClosed user code!", ex); + } + } + } + else + { + if (this.OnError != null) + { + try + { + this.OnError(this, errorReason); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("HubConnection", "Exception in OnError user code!", ex); + } + } + } + break; + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs.meta new file mode 100644 index 0000000..8058a0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/HubConnection.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e8abbf851f5c2224380d8755c487b006 +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs new file mode 100644 index 0000000..ce770d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs @@ -0,0 +1,44 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET + +using System; + +namespace BestHTTP.SignalRCore +{ + public delegate void OnAuthenticationSuccededDelegate(IAuthenticationProvider provider); + public delegate void OnAuthenticationFailedDelegate(IAuthenticationProvider provider, string reason); + + public interface IAuthenticationProvider + { + /// + /// The authentication must be run before any request made to build up the SignalR protocol + /// + bool IsPreAuthRequired { get; } + + /// + /// This event must be called when the pre-authentication succeded. When IsPreAuthRequired is false, no-one will subscribe to this event. + /// + event OnAuthenticationSuccededDelegate OnAuthenticationSucceded; + + /// + /// This event must be called when the pre-authentication failed. When IsPreAuthRequired is false, no-one will subscribe to this event. + /// + event OnAuthenticationFailedDelegate OnAuthenticationFailed; + + /// + /// This function called once, when the before the SignalR negotiation begins. If IsPreAuthRequired is false, then this step will be skipped. + /// + void StartAuthentication(); + + /// + /// This function will be called for every request before sending it. + /// + void PrepareRequest(HTTPRequest request); + + /// + /// This function can customize the given uri. If there's no intention to modify the uri, this function + /// should return with the parameter. + /// + Uri PrepareUri(Uri uri); + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs.meta new file mode 100644 index 0000000..2ed78d9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/IAuthenticationProvider.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d30367ca9f9cbda45ad05e42d66c93cd +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs new file mode 100644 index 0000000..a861674 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs @@ -0,0 +1,165 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET + +using BestHTTP.SignalRCore.Messages; +using System; +using System.Collections.Generic; + +#if NETFX_CORE || NET_4_6 +using System.Reflection; +#endif + +namespace BestHTTP.SignalRCore +{ + public interface IProtocol + { + TransferModes Type { get; } + IEncoder Encoder { get; } + HubConnection Connection { get; set; } + + /// + /// This function must parse textual representation of the messages into the list of Messages. + /// + void ParseMessages(string data, ref List messages); + + /// + /// This function must parse binary representation of the messages into the list of Messages. + /// + void ParseMessages(byte[] data, ref List messages); + + /// + /// This function must return the encoded representation of the given message. + /// + byte[] EncodeMessage(Message message); + + /// + /// This function must convert all element in the arguments array to the corresponding type from the argTypes array. + /// + object[] GetRealArguments(Type[] argTypes, object[] arguments); + + /// + /// Convert a value to the given type. + /// + object ConvertTo(Type toType, object obj); + } + + public sealed class JsonProtocol : IProtocol + { + public const char Separator = (char)0x1E; + + public TransferModes Type { get { return TransferModes.Text; } } + public IEncoder Encoder { get; private set; } + public HubConnection Connection { get; set; } + + public JsonProtocol(IEncoder encoder) + { + if (encoder == null) + throw new ArgumentNullException("encoder"); + if (encoder.Name != "json") + throw new ArgumentException("Encoder must be a json encoder!"); + + this.Encoder = encoder; + } + + public void ParseMessages(string data, ref List messages) + { + int from = 0; + int separatorIdx = data.IndexOf(JsonProtocol.Separator); + if (separatorIdx == -1) + throw new Exception("Missing separator!"); + + while (separatorIdx != -1) + { + string sub = data.Substring(from, separatorIdx - from); + + var message = this.Encoder.DecodeAs(sub); + + messages.Add(message); + + from = separatorIdx + 1; + separatorIdx = data.IndexOf(JsonProtocol.Separator, from); + } + } + + public void ParseMessages(byte[] data, ref List messages) { } + + public byte[] EncodeMessage(Message message) + { + string json = null; + switch (message.type) + { + case MessageTypes.Invocation: + case MessageTypes.StreamInvocation: + // While message contains all informations already, the spec states that no additional field are allowed in messages + // So we are creating 'specialized' messages here to send to the server. + json = this.Encoder.EncodeAsText(new InvocationMessage() + { + type = message.type, + invocationId = message.invocationId, + nonblocking = message.nonblocking, + target = message.target, + arguments = message.arguments + }); + break; + + case MessageTypes.CancelInvocation: + json = this.Encoder.EncodeAsText(new CancelInvocationMessage() + { + invocationId = message.invocationId + }); + break; + } + + return !string.IsNullOrEmpty(json) ? JsonProtocol.WithSeparator(json) : null; + } + + public object[] GetRealArguments(Type[] argTypes, object[] arguments) + { + if (arguments == null || arguments.Length == 0) + return null; + + if (argTypes.Length > arguments.Length) + throw new Exception(string.Format("argType.Length({0}) < arguments.length({1})", argTypes.Length, arguments.Length)); + + object[] realArgs = new object[arguments.Length]; + + for (int i = 0; i < arguments.Length; ++i) + realArgs[i] = ConvertTo(argTypes[i], arguments[i]); + + return realArgs; + } + + public object ConvertTo(Type toType, object obj) + { + if (obj == null) + return null; +#if NETFX_CORE //|| NET_4_6 + if (toType.GetTypeInfo().IsPrimitive || toType.GetTypeInfo().IsEnum) +#else + if (toType.IsPrimitive || toType.IsEnum) +#endif + return Convert.ChangeType(obj, toType); + + if (toType == typeof(string)) + return obj.ToString(); + + return this.Encoder.ConvertTo(toType, obj); + } + + /// + /// Returns the given string parameter's bytes with the added separator(0x1E). + /// + public static byte[] WithSeparator(string str) + { + int len = System.Text.Encoding.UTF8.GetByteCount(str); + + byte[] buffer = new byte[len + 1]; + + System.Text.Encoding.UTF8.GetBytes(str, 0, str.Length, buffer, 0); + + buffer[len] = 0x1e; + + return buffer; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs.meta new file mode 100644 index 0000000..312bd61 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/JsonProtocol.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b98779f03b6433e4387c86a676d50027 +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages.meta new file mode 100644 index 0000000..7c43f05 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 04849aa46f6e586469d9275d70387fb0 +folderAsset: yes +timeCreated: 1515237542 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs new file mode 100644 index 0000000..ca94889 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs @@ -0,0 +1,21 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET +using System; + +namespace BestHTTP.SignalRCore.Messages +{ + public struct InvocationMessage + { + public MessageTypes type; + public string invocationId; + public bool nonblocking; + public string target; + public object[] arguments; + } + + public struct CancelInvocationMessage + { + public MessageTypes type { get { return MessageTypes.CancelInvocation; } } + public string invocationId; + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs.meta new file mode 100644 index 0000000..585a5a4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Invocation.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 80d549225d0ced34c864973a497e97bc +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs new file mode 100644 index 0000000..2b0163a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs @@ -0,0 +1,84 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET +using System; + +namespace BestHTTP.SignalRCore.Messages +{ + public enum MessageTypes : int + { + /// + /// This is a made up message type, for easier handshake handling. + /// + Handshake = 0, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#invocation-message-encoding + /// + Invocation = 1, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#streamitem-message-encoding + /// + StreamItem = 2, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#completion-message-encoding + /// + Completion = 3, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#streaminvocation-message-encoding + /// + StreamInvocation = 4, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#cancelinvocation-message-encoding + /// + CancelInvocation = 5, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#ping-message-encoding + /// + Ping = 6, + + /// + /// https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#close-message-encoding + /// + Close = 7 + } + + public class Message + { + public MessageTypes type; + public string invocationId; + public bool nonblocking; + public string target; + public object[] arguments; + public object item; + public object result; + public string error; + + public override string ToString() + { + switch (this.type) + { + case MessageTypes.Invocation: + return string.Format("[Invocation Id: {0}, Target: '{1}', Argument count: {2}]", this.invocationId, this.target, this.arguments != null ? this.arguments.Length : 0); + case MessageTypes.StreamItem: + return string.Format("[StreamItem Id: {0}, Item: {1}]", this.invocationId, this.item.ToString()); + case MessageTypes.Completion: + return string.Format("[Completion Id: {0}, Result: {1}, Error: '{2}']", this.invocationId, this.result, this.error); + case MessageTypes.StreamInvocation: + return string.Format("[StreamInvocation Id: {0}, Target: '{1}', Argument count: {2}]", this.invocationId, this.target, this.arguments != null ? this.arguments.Length : 0); + case MessageTypes.CancelInvocation: + return string.Format("[CancelInvocation Id: {0}]", this.invocationId); + case MessageTypes.Ping: + return "[Ping]"; + case MessageTypes.Close: + return string.IsNullOrEmpty(this.error) ? "[Close]" : string.Format("[Close {0}]", this.error); + default: + return "Unknown message! Type: " + this.type; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs.meta new file mode 100644 index 0000000..7e70629 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/Message.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: f6a7c57303e62774fb902547acce515a +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs new file mode 100644 index 0000000..3eda319 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; + +namespace BestHTTP.SignalRCore.Messages +{ + public sealed class SupportedTransport + { + /// + /// Name of the transport. + /// + public string Name { get; private set; } + + /// + /// Supported transfer formats of the transport. + /// + public List SupportedFormats { get; private set; } + + internal SupportedTransport(string transportName, List transferFormats) + { + this.Name = transportName; + this.SupportedFormats = transferFormats; + } + } + + /// + /// Negotiation result of the /negotiation request. + /// + /// + public sealed class NegotiationResult + { + /// + /// The connectionId which is required by the Long Polling and Server-Sent Events transports (in order to correlate sends and receives). + /// + public string ConnectionId { get; private set; } + + /// + /// The availableTransports list which describes the transports the server supports. For each transport, the name of the transport (transport) is listed, as is a list of "transfer formats" supported by the transport (transferFormats) + /// + public List SupportedTransports { get; private set; } + + /// + /// The url which is the URL the client should connect to. + /// + public Uri Url { get; private set; } + + /// + /// The accessToken which is an optional bearer token for accessing the specified url. + /// + public string AccessToken { get; private set; } + + internal static NegotiationResult Parse(string json, out string error) + { + error = null; + + Dictionary response = BestHTTP.JSON.Json.Decode(json) as Dictionary; + if (response == null) + { + error = "Json decoding failed!"; + return null; + } + + try + { + NegotiationResult result = new NegotiationResult(); + object value; + if (response.TryGetValue("connectionId", out value)) + result.ConnectionId = value.ToString(); + + if (response.TryGetValue("availableTransports", out value)) + { + List transports = value as List; + if (transports != null) + { + List supportedTransports = new List(transports.Count); + + foreach (Dictionary transport in transports) + { + string transportName = string.Empty; + List transferModes = null; + + if (transport.TryGetValue("transport", out value)) + transportName = value.ToString(); + + if (transport.TryGetValue("transferFormats", out value)) + { + List transferFormats = value as List; + + if (transferFormats != null) + { + transferModes = new List(transferFormats.Count); + foreach (var mode in transferFormats) + transferModes.Add(mode.ToString()); + } + } + + supportedTransports.Add(new SupportedTransport(transportName, transferModes)); + } + + result.SupportedTransports = supportedTransports; + } + } + + if (response.TryGetValue("url", out value)) + result.Url = new Uri(value.ToString()); + + if (response.TryGetValue("accessToken", out value)) + result.AccessToken = value.ToString(); + + return result; + } + catch (Exception ex) + { + error = "Error while parsing result: " + ex.Message + " StackTrace: " + ex.StackTrace; + return null; + } + } + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs.meta new file mode 100644 index 0000000..de61e1a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Messages/NegotiationResult.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ff02294dfc0839f4b8cfa92dce810808 +timeCreated: 1528093299 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports.meta new file mode 100644 index 0000000..1c46ab7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 93299fbc9d294004caa37d06aea06bb5 +folderAsset: yes +timeCreated: 1515237543 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs new file mode 100644 index 0000000..e4ea7e2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs @@ -0,0 +1,253 @@ +#if !BESTHTTP_DISABLE_SIGNALR_CORE && !BESTHTTP_DISABLE_WEBSOCKET +using System; +using System.Collections.Generic; +using System.Text; + +using BestHTTP.SignalRCore.Messages; + +namespace BestHTTP.SignalRCore.Transports +{ + /// + /// WebSockets transport implementation. + /// https://github.com/aspnet/SignalR/blob/dev/specs/TransportProtocols.md#websockets-full-duplex + /// + internal sealed class WebSocketTransport : ITransport + { + public TransportTypes TransportType { get { return TransportTypes.WebSocket; } } + public TransferModes TransferMode { get { return TransferModes.Binary; } } + + /// + /// Current state of the transport. All changes will be propagated to the HubConnection through the onstateChanged event. + /// + public TransportStates State { + get { return this._state; } + private set + { + if (this._state != value) + { + TransportStates oldState = this._state; + this._state = value; + + if (this.OnStateChanged != null) + this.OnStateChanged(oldState, this._state); + } + } + } + private TransportStates _state; + + /// + /// This will store the reason of failures so HubConnection can include it in its OnError event. + /// + public string ErrorReason { get; private set; } + + /// + /// Called every time when the transport's changed. + /// + public event Action OnStateChanged; + + private WebSocket.WebSocket webSocket; + private HubConnection connection; + + /// + /// Cached list of parsed messages. + /// + private List messages = new List(); + + public WebSocketTransport(HubConnection con) + { + this.connection = con; + this.State = TransportStates.Initial; + } + + void ITransport.StartConnect() + { + HTTPManager.Logger.Verbose("WebSocketTransport", "StartConnect"); + + if (this.webSocket == null) + { + Uri baseUri = this.connection.Uri; + + // If we received an Url in the negotiation result, we have to connect to that endpoint. + if (this.connection.NegotiationResult != null && this.connection.NegotiationResult.Url != null) + baseUri = this.connection.NegotiationResult.Url; + + Uri uri = BuildUri(baseUri); + + // Also, if there's an authentication provider it can alter further our uri. + if (this.connection.AuthenticationProvider != null) + uri = this.connection.AuthenticationProvider.PrepareUri(uri) ?? uri; + + HTTPManager.Logger.Verbose("WebSocketTransport", "StartConnect connecting to Uri: " + uri.ToString()); + + this.webSocket = new WebSocket.WebSocket(uri); + } + +#if !UNITY_WEBGL || UNITY_EDITOR + // prepare the internal http request + if (this.connection.AuthenticationProvider != null) + this.connection.AuthenticationProvider.PrepareRequest(webSocket.InternalRequest); +#endif + this.webSocket.OnOpen += OnOpen; + this.webSocket.OnMessage += OnMessage; + this.webSocket.OnBinary += OnBinary; + this.webSocket.OnErrorDesc += OnError; + this.webSocket.OnClosed += OnClosed; + + this.webSocket.Open(); + + this.State = TransportStates.Connecting; + } + + void ITransport.Send(byte[] msg) + { + // To help debugging, in the editor when the plugin's loggging level is set to All, we will + // send all messages in textual form. This will help the readability when sent through a proxy. +#if UNITY_EDITOR + if (HTTPManager.Logger.Level == Logger.Loglevels.All) + this.webSocket.Send(System.Text.Encoding.UTF8.GetString(msg, 0, msg.Length)); + else +#endif + this.webSocket.Send(msg); + } + + // The websocket connection is open + private void OnOpen(WebSocket.WebSocket webSocket) + { + HTTPManager.Logger.Verbose("WebSocketTransport", "OnOpen"); + + // https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md#overview + // When our websocket connection is open, send the 'negotiation' message to the server. + + string json = string.Format("{{'protocol':'{0}', 'version': 1}}", this.connection.Protocol.Encoder.Name); + + byte[] buffer = JsonProtocol.WithSeparator(json); + + (this as ITransport).Send(buffer); + } + + private string ParseHandshakeResponse(string data) + { + // The handshake response is + // -an empty json object ('{}') if the handshake process is succesfull + // -otherwise it has one 'error' field + + Dictionary response = BestHTTP.JSON.Json.Decode(data) as Dictionary; + + if (response == null) + return "Couldn't parse json data: " + data; + + object error; + if (response.TryGetValue("error", out error)) + return error.ToString(); + + return null; + } + + private void HandleHandshakeResponse(string data) + { + this.ErrorReason = ParseHandshakeResponse(data); + + this.State = string.IsNullOrEmpty(this.ErrorReason) ? TransportStates.Connected : TransportStates.Failed; + } + + private void OnMessage(WebSocket.WebSocket webSocket, string data) + { + if (this.State == TransportStates.Connecting) + { + HandleHandshakeResponse(data); + + return; + } + + this.messages.Clear(); + try + { + this.connection.Protocol.ParseMessages(data, ref this.messages); + + this.connection.OnMessages(this.messages); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketTransport", "OnMessage(string)", ex); + } + finally + { + this.messages.Clear(); + } + } + + private void OnBinary(WebSocket.WebSocket webSocket, byte[] data) + { + if (this.State == TransportStates.Connecting) + { + HandleHandshakeResponse(System.Text.Encoding.UTF8.GetString(data, 0, data.Length)); + + return; + } + + this.messages.Clear(); + try + { + this.connection.Protocol.ParseMessages(data, ref this.messages); + + this.connection.OnMessages(this.messages); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketTransport", "OnMessage(byte[])", ex); + } + finally + { + this.messages.Clear(); + } + } + + private void OnError(WebSocket.WebSocket webSocket, string reason) + { + HTTPManager.Logger.Verbose("WebSocketTransport", "OnError: " + reason); + + this.ErrorReason = reason; + this.State = TransportStates.Failed; + } + + private void OnClosed(WebSocket.WebSocket webSocket, ushort code, string message) + { + HTTPManager.Logger.Verbose("WebSocketTransport", "OnClosed: " + code + " " + message); + + this.webSocket = null; + + this.State = TransportStates.Closed; + } + + void ITransport.StartClose() + { + HTTPManager.Logger.Verbose("WebSocketTransport", "StartClose"); + + if (this.webSocket != null) + { + this.State = TransportStates.Closing; + this.webSocket.Close(); + } + else + this.State = TransportStates.Closed; + } + + private Uri BuildUri(Uri baseUri) + { + if (this.connection.NegotiationResult == null) + return baseUri; + + UriBuilder builder = new UriBuilder(baseUri); + StringBuilder queryBuilder = new StringBuilder(); + + queryBuilder.Append(baseUri.Query); + if (!string.IsNullOrEmpty(this.connection.NegotiationResult.ConnectionId)) + queryBuilder.Append("&id=").Append(this.connection.NegotiationResult.ConnectionId); + + builder.Query = queryBuilder.ToString(); + + return builder.Uri; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs.meta new file mode 100644 index 0000000..4d953cb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SignalRCore/Transports/WebsocketTransport.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e89b403b974cebf40845e9ca6616a0e0 +timeCreated: 1515237548 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO.meta new file mode 100644 index 0000000..563bd54 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 70d2cd72d4442e349a1cfa407bbcfe8d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs new file mode 100644 index 0000000..dbc350f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs @@ -0,0 +1,105 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +namespace BestHTTP.SocketIO +{ + /// + /// Possible event types on the transport level. + /// + public enum TransportEventTypes : int + { + Unknown = -1, + Open = 0, + Close = 1, + Ping = 2, + Pong = 3, + Message = 4, + Upgrade = 5, + Noop = 6 + } + + /// + /// Event types of the SocketIO protocol. + /// + public enum SocketIOEventTypes : int + { + Unknown = -1, + + /// + /// Connect to a namespace, or we connected to a namespace + /// + Connect = 0, + + /// + /// Disconnect a namespace, or we disconnected from a namespace. + /// + Disconnect = 1, + + /// + /// A general event. The event's name is in the payload. + /// + Event = 2, + + /// + /// Acknowledgment of an event. + /// + Ack = 3, + + /// + /// Error sent by the server, or by the plugin + /// + Error = 4, + + /// + /// A general event with binary attached to the packet. The event's name is in the payload. + /// + BinaryEvent = 5, + + /// + /// Acknowledgment of a binary event. + /// + BinaryAck = 6 + } + + /// + /// Possible error codes that the SocketIO server can send. + /// + public enum SocketIOErrors + { + /// + /// Transport unknown + /// + UnknownTransport = 0, + + /// + /// Session ID unknown + /// + UnknownSid = 1, + + /// + /// Bad handshake method + /// + BadHandshakeMethod = 2, + + /// + /// Bad request + /// + BadRequest = 3, + + /// + /// Plugin internal error! + /// + Internal, + + /// + /// Exceptions that caught by the plugin but raised in a user code. + /// + User, + + /// + /// A custom, server sent error, most probably from a Socket.IO middleware. + /// + Custom, + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs.meta new file mode 100644 index 0000000..88ef434 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Enums.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 94f15ba2f99e9e148869183ae648e7e6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs new file mode 100644 index 0000000..6f4fc60 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs @@ -0,0 +1,23 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +namespace BestHTTP.SocketIO +{ + public sealed class Error + { + public SocketIOErrors Code { get; private set; } + public string Message { get; private set; } + + public Error(SocketIOErrors code, string msg) + { + this.Code = code; + this.Message = msg; + } + + public override string ToString() + { + return string.Format("Code: {0} Message: \"{1}\"", this.Code.ToString(), this.Message); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs.meta new file mode 100644 index 0000000..5656354 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Error.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bede350068da4b74b9cc566b9bff3bdd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events.meta new file mode 100644 index 0000000..125739a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 97e9578ca337d0f42a4145ade32a3a5c +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs new file mode 100644 index 0000000..9ab9a3e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs @@ -0,0 +1,93 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; +using System.Collections.Generic; + +namespace BestHTTP.SocketIO.Events +{ + public delegate void SocketIOCallback(Socket socket, Packet packet, params object[] args); + public delegate void SocketIOAckCallback(Socket socket, Packet packet, params object[] args); + + /// + /// A class to describe an event, and its metadatas. + /// + internal sealed class EventDescriptor + { + #region Public Properties + + /// + /// List of callback delegates. + /// + public List Callbacks { get; private set; } + + /// + /// If this property is true, callbacks are removed automatically after the event dispatch. + /// + public bool OnlyOnce { get; private set; } + + /// + /// If this property is true, the dispatching packet's Payload will be decoded using the Manager's Encoder. + /// + public bool AutoDecodePayload { get; private set; } + + #endregion + + /// + /// Cache an array on a hot-path. + /// + private SocketIOCallback[] CallbackArray; + + /// + /// Constructor to create an EventDescriptor instance and set the meta-datas. + /// + public EventDescriptor(bool onlyOnce, bool autoDecodePayload, SocketIOCallback callback) + { + this.OnlyOnce = onlyOnce; + this.AutoDecodePayload = autoDecodePayload; + this.Callbacks = new List(1); + + if (callback != null) + Callbacks.Add(callback); + } + + /// + /// Will call the callback delegates with the given parameters and remove the callbacks if this descriptor marked with a true OnlyOnce property. + /// + public void Call(Socket socket, Packet packet, params object[] args) + { + if (CallbackArray == null || CallbackArray.Length < Callbacks.Count) + Array.Resize(ref CallbackArray, Callbacks.Count); + + // Copy the callback delegates to an array, because in one of the callbacks we can modify the list(by calling On/Once/Off in an event handler) + // This way we can prevent some strange bug + Callbacks.CopyTo(CallbackArray); + + // Go through the delegates and call them + for (int i = 0; i < CallbackArray.Length; ++i) + { + try + { + // Call the delegate. + SocketIOCallback callback = CallbackArray[i]; + if (callback!= null) + callback(socket, packet, args); + } + catch (Exception ex) + { + (socket as ISocket).EmitError(SocketIOErrors.User, ex.Message + " " + ex.StackTrace); + + HTTPManager.Logger.Exception("EventDescriptor", "Call", ex); + } + + // If these callbacks has to be called only once, remove them from the main list + if (this.OnlyOnce) + Callbacks.Remove(CallbackArray[i]); + + // Don't keep any reference avoiding memory leaks + CallbackArray[i] = null; + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs.meta new file mode 100644 index 0000000..40d24c3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventDescriptor.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ab942858f5ff2a4458ec312bc2955779 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs new file mode 100644 index 0000000..7e42034 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; + +namespace BestHTTP.SocketIO.Events +{ + /// + /// Helper class to provide functions to an easy Enum->string conversation of the transport and SocketIO evenet types. + /// + public static class EventNames + { + public const string Connect = "connect"; + public const string Disconnect = "disconnect"; + public const string Event = "event"; + public const string Ack = "ack"; + public const string Error = "error"; + public const string BinaryEvent = "binaryevent"; + public const string BinaryAck = "binaryack"; + + private static string[] SocketIONames = new string[] { "unknown", "connect", "disconnect", "event", "ack", "error", "binaryevent", "binaryack" }; + private static string[] TransportNames = new string[] { "unknown", "open", "close", "ping", "pong", "message", "upgrade", "noop" }; + private static string[] BlacklistedEvents = new string[] { "connect", "connect_error", "connect_timeout", "disconnect", "error", "reconnect", + "reconnect_attempt", "reconnect_failed", "reconnect_error", "reconnecting" }; + + public static string GetNameFor(SocketIOEventTypes type) + { + return SocketIONames[(int)type + 1]; + } + + public static string GetNameFor(TransportEventTypes transEvent) + { + return TransportNames[(int)transEvent + 1]; + } + + /// + /// Checks an event name whether it's blacklisted or not. + /// + public static bool IsBlacklisted(string eventName) + { + for (int i = 0; i < BlacklistedEvents.Length; ++i) + if (string.Compare(BlacklistedEvents[i], eventName, StringComparison.OrdinalIgnoreCase) == 0) + return true; + return false; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs.meta new file mode 100644 index 0000000..68ed649 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventNames.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3ab78cfee54d71543bec1cdef098cd4b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs new file mode 100644 index 0000000..37f9432 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs @@ -0,0 +1,154 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System.Collections.Generic; + +namespace BestHTTP.SocketIO.Events +{ + /// + /// This class helps keep track and maintain EventDescriptor instances and dispatching packets to the right delegates. + /// + internal sealed class EventTable + { + #region Privates + + /// + /// The Socket that this EventTable is bound to. + /// + private Socket Socket { get; set; } + + /// + /// The 'EventName -> List of events' mapping. + /// + private Dictionary> Table = new Dictionary>(); + + #endregion + + /// + /// Constructor to create an instance and bind it to a socket. + /// + public EventTable(Socket socket) + { + this.Socket = socket; + } + + /// + /// Register a callback to a name with the given metadata. + /// + public void Register(string eventName, SocketIOCallback callback, bool onlyOnce, bool autoDecodePayload) + { + List events; + if (!Table.TryGetValue(eventName, out events)) + Table.Add(eventName, events = new List(1)); + + // Find a matching desriptor + var desc = events.Find((d) => d.OnlyOnce == onlyOnce && d.AutoDecodePayload == autoDecodePayload); + + // If not found, create one + if (desc == null) + events.Add(new EventDescriptor(onlyOnce, autoDecodePayload, callback)); + else // if found, add the new callback + desc.Callbacks.Add(callback); + } + + /// + /// Removes all events that registered for the given name. + /// + public void Unregister(string eventName) + { + Table.Remove(eventName); + } + + /// + /// + /// + public void Unregister(string eventName, SocketIOCallback callback) + { + List events; + if (Table.TryGetValue(eventName, out events)) + for (int i = 0; i < events.Count; ++i) + events[i].Callbacks.Remove(callback); + } + + /// + /// Will call the delegates that associated to the given eventName. + /// + public void Call(string eventName, Packet packet, params object[] args) + { + if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) + HTTPManager.Logger.Verbose("EventTable", "Call - " + eventName); + + List events; + + if (Table.TryGetValue(eventName, out events)) + for (int i = 0; i < events.Count; ++i) + events[i].Call(Socket, packet, args); + } + + /// + /// This function will get the eventName from the packet's Payload, and optionally will decode it from Json. + /// + public void Call(Packet packet) + { + string eventName = packet.DecodeEventName(); + string typeName = packet.SocketIOEvent != SocketIOEventTypes.Unknown ? EventNames.GetNameFor(packet.SocketIOEvent) : EventNames.GetNameFor(packet.TransportEvent); + object[] args = null; + + if (!HasSubsciber(eventName) && !HasSubsciber(typeName)) + return; + + // If this is an Event or BinaryEvent message, or we have a subscriber with AutoDecodePayload, then + // we have to decode the packet's Payload. + if (packet.TransportEvent == TransportEventTypes.Message && (packet.SocketIOEvent == SocketIOEventTypes.Event || packet.SocketIOEvent == SocketIOEventTypes.BinaryEvent) && ShouldDecodePayload(eventName)) + args = packet.Decode(Socket.Manager.Encoder); + + // call event callbacks registered for 'eventName' + if (!string.IsNullOrEmpty(eventName)) + Call(eventName, packet, args); + + if (!packet.IsDecoded && ShouldDecodePayload(typeName)) + args = packet.Decode(Socket.Manager.Encoder); + + // call event callbacks registered for 'typeName' + if (!string.IsNullOrEmpty(typeName)) + Call(typeName, packet, args); + } + + /// + /// Remove all event -> delegate association. + /// + public void Clear() + { + Table.Clear(); + } + + #region Private Helpers + + /// + /// Returns true, if for the given event name there are at least one event that needs a decoded + /// + /// + /// + private bool ShouldDecodePayload(string eventName) + { + List events; + + // If we find at least one EventDescriptor with AutoDecodePayload == true, we have to + // decode the whole payload + if (Table.TryGetValue(eventName, out events)) + for (int i = 0; i < events.Count; ++i) + if (events[i].AutoDecodePayload && events[i].Callbacks.Count > 0) + return true; + + return false; + } + + private bool HasSubsciber(string eventName) + { + return Table.ContainsKey(eventName); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs.meta new file mode 100644 index 0000000..6089fc3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Events/EventTable.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 62b1e6227e8b13446b06cf83b7ab23e2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs new file mode 100644 index 0000000..a05607b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs @@ -0,0 +1,101 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; +using System.Collections.Generic; + +namespace BestHTTP.SocketIO +{ + using BestHTTP.JSON; + + /// + /// Helper class to parse and hold handshake information. + /// + public sealed class HandshakeData + { + #region Public Handshake Data + + /// + /// Session ID of this connection. + /// + public string Sid { get; private set; } + + /// + /// List of possible upgrades. + /// + public List Upgrades { get; private set; } + + /// + /// What interval we have to set a ping message. + /// + public TimeSpan PingInterval { get; private set; } + + /// + /// What time have to pass without an answer to our ping request when we can consider the connection disconnected. + /// + public TimeSpan PingTimeout { get; private set; } + + #endregion + + #region Helper Methods + + public bool Parse(string str) + { + bool success = false; + Dictionary dict = Json.Decode(str, ref success) as Dictionary; + if (!success) + return false; + + try + { + this.Sid = GetString(dict, "sid"); + this.Upgrades = GetStringList(dict, "upgrades"); + this.PingInterval = TimeSpan.FromMilliseconds(GetInt(dict, "pingInterval")); + this.PingTimeout = TimeSpan.FromMilliseconds(GetInt(dict, "pingTimeout")); + } + catch (Exception ex) + { + BestHTTP.HTTPManager.Logger.Exception("HandshakeData", "Parse", ex); + return false; + } + + return true; + } + + private static object Get(Dictionary from, string key) + { + object value; + if (!from.TryGetValue(key, out value)) + throw new System.Exception(string.Format("Can't get {0} from Handshake data!", key)); + return value; + } + + private static string GetString(Dictionary from, string key) + { + return Get(from, key) as string; + } + + private static List GetStringList(Dictionary from, string key) + { + List value = Get(from, key) as List; + + List result = new List(value.Count); + for (int i = 0; i < value.Count; ++i) + { + string str = value[i] as string; + if (str != null) + result.Add(str); + } + + return result; + } + + private static int GetInt(Dictionary from, string key) + { + return (int)(double)Get(from, key); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs.meta new file mode 100644 index 0000000..9ad5b71 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/HandshakeData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 28457ee0deb7f0e4e8477f231304c601 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs new file mode 100644 index 0000000..7e5b171 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs @@ -0,0 +1,40 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +namespace BestHTTP.SocketIO +{ + using BestHTTP.SocketIO.Transports; + + /// + /// Interface to hide internal functions from the user by implementing it as an explicit interface. + /// + public interface IManager + { + void Remove(Socket socket); + void Close(bool removeSockets = true); + void TryToReconnect(); + bool OnTransportConnected(ITransport transport); + void OnTransportError(ITransport trans, string err); + void OnTransportProbed(ITransport trans); + void SendPacket(Packet packet); + void OnPacket(Packet packet); + void EmitEvent(string eventName, params object[] args); + void EmitEvent(SocketIOEventTypes type, params object[] args); + void EmitError(SocketIOErrors errCode, string msg); + void EmitAll(string eventName, params object[] args); + } + + /// + /// Interface to hide internal functions from the user by implementing it as an explicit interface. + /// + public interface ISocket + { + void Open(); + void Disconnect(bool remove); + void OnPacket(Packet packet); + void EmitEvent(SocketIOEventTypes type, params object[] args); + void EmitEvent(string eventName, params object[] args); + void EmitError(SocketIOErrors errCode, string msg); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs.meta new file mode 100644 index 0000000..d7d93f1 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Interfaces.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e37425596e0069c4b99fea0b55dcd4cc +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders.meta new file mode 100644 index 0000000..62ac15d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ed82682a337846d47b38e6ca7189a0c8 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs new file mode 100644 index 0000000..5dee8cf --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs @@ -0,0 +1,25 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System.Collections.Generic; +using BestHTTP.JSON; + +namespace BestHTTP.SocketIO.JsonEncoders +{ + /// + /// The default IJsonEncoder implementation. It's uses the Json class from the BestHTTP.JSON namespace to encode and decode. + /// + public sealed class DefaultJSonEncoder : IJsonEncoder + { + public List Decode(string json) + { + return Json.Decode(json) as List; + } + + public string Encode(List obj) + { + return Json.Encode(obj); + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs.meta new file mode 100644 index 0000000..d30ae65 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/DefaultJSonEncoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 692eedd1d08951b4fac2cd4447430cf7 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs new file mode 100644 index 0000000..5a8ecbc --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs @@ -0,0 +1,24 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System.Collections.Generic; + +namespace BestHTTP.SocketIO.JsonEncoders +{ + /// + /// Interface to be able to write custom Json encoders/decoders. + /// + public interface IJsonEncoder + { + /// + /// The Decode function must create a list of objects from the Json formatted string parameter. If the decoding fails, it should return null. + /// + List Decode(string json); + + /// + /// The Encode function must create a json formatted string from the parameter. If the encoding fails, it should return null. + /// + string Encode(List obj); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs.meta new file mode 100644 index 0000000..25f6b1f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/JsonEncoders/IJSonEncoder.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 68459b55b5787e04186d568f4ec8bbc3 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs new file mode 100644 index 0000000..ed1c9eb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs @@ -0,0 +1,611 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System.Text; + +namespace BestHTTP.SocketIO +{ + using System; + using System.Collections.Generic; + using BestHTTP.JSON; + + public sealed class Packet + { + private enum PayloadTypes : byte + { + Textual = 0, + Binary = 1 + } + + public const string Placeholder = "_placeholder"; + + #region Public properties + + /// + /// Event type of this packet on the transport layer. + /// + public TransportEventTypes TransportEvent { get; private set; } + + /// + /// The packet's type in the Socket.IO protocol. + /// + public SocketIOEventTypes SocketIOEvent { get; private set; } + + /// + /// How many attachment should have this packet. + /// + public int AttachmentCount { get; private set; } + + /// + /// The internal ack-id of this packet. + /// + public int Id { get; private set; } + + /// + /// The sender namespace's name. + /// + public string Namespace { get; private set; } + + /// + /// The payload as a Json string. + /// + public string Payload { get; private set; } + + /// + /// The decoded event name from the payload string. + /// + public string EventName { get; private set; } + + /// + /// All binary data attached to this event. + /// + public List Attachments { get { return attachments; } set { attachments = value; AttachmentCount = attachments != null ? attachments.Count : 0; } } + private List attachments; + + /// + /// Property to check whether all attachments are received to this packet. + /// + public bool HasAllAttachment { get { return Attachments != null && Attachments.Count == AttachmentCount; } } + + /// + /// True if it's already decoded. The DecodedArgs still can be null after the Decode call. + /// + public bool IsDecoded { get; private set; } + + /// + /// The decoded arguments from the result of a Json string -> c# object convert. + /// + public object[] DecodedArgs { get; private set; } + + #endregion + + #region Constructors + + /// + /// Internal constructor. Don't use it directly! + /// + internal Packet() + { + this.TransportEvent = TransportEventTypes.Unknown; + this.SocketIOEvent = SocketIOEventTypes.Unknown; + this.Payload = string.Empty; + } + + /// + /// Internal constructor. Don't use it directly! + /// + internal Packet(string from) + { + this.Parse(from); + } + + /// + /// Internal constructor. Don't use it directly! + /// + public Packet(TransportEventTypes transportEvent, SocketIOEventTypes packetType, string nsp, string payload, int attachment = 0, int id = 0) + { + this.TransportEvent = transportEvent; + this.SocketIOEvent = packetType; + this.Namespace = nsp; + this.Payload = payload; + this.AttachmentCount = attachment; + this.Id = id; + } + + #endregion + + #region Public Functions + + public object[] Decode(BestHTTP.SocketIO.JsonEncoders.IJsonEncoder encoder) + { + if (IsDecoded || encoder == null) + return DecodedArgs; + + IsDecoded = true; + + if (string.IsNullOrEmpty(Payload)) + return DecodedArgs; + + List decoded = encoder.Decode(Payload); + + if (decoded != null && decoded.Count > 0) + { + if (this.SocketIOEvent == SocketIOEventTypes.Ack || this.SocketIOEvent == SocketIOEventTypes.BinaryAck) + DecodedArgs = decoded.ToArray(); + else + { + decoded.RemoveAt(0); + + DecodedArgs = decoded.ToArray(); + } + } + + return DecodedArgs; + } + + /// + /// Will set and return with the EventName from the packet's Payload string. + /// + public string DecodeEventName() + { + // Already decoded + if (!string.IsNullOrEmpty(EventName)) + return EventName; + + // No Payload to decode + if (string.IsNullOrEmpty(Payload)) + return string.Empty; + + // Not array encoded, we can't decode + if (Payload[0] != '[') + return string.Empty; + + int idx = 1; + + // Search for the string-begin mark( ' or " chars) + while (Payload.Length > idx && Payload[idx] != '"' && Payload[idx] != '\'') + idx++; + + // Reached the end of the string + if (Payload.Length <= idx) + return string.Empty; + + int startIdx = ++idx; + + // Search for the trailing mark of the string + while (Payload.Length > idx && Payload[idx] != '"' && Payload[idx] != '\'') + idx++; + + // Reached the end of the string + if (Payload.Length <= idx) + return string.Empty; + + return EventName = Payload.Substring(startIdx, idx - startIdx); + } + + public string RemoveEventName(bool removeArrayMarks) + { + // No Payload to decode + if (string.IsNullOrEmpty(Payload)) + return string.Empty; + + // Not array encoded, we can't decode + if (Payload[0] != '[') + return string.Empty; + + int idx = 1; + + // Search for the string-begin mark( ' or " chars) + while (Payload.Length > idx && Payload[idx] != '"' && Payload[idx] != '\'') + idx++; + + // Reached the end of the string + if (Payload.Length <= idx) + return string.Empty; + + int startIdx = idx; + + // Search for end of first element, or end of the array marks + while (Payload.Length > idx && Payload[idx] != ',' && Payload[idx] != ']') + idx++; + + // Reached the end of the string + if (Payload.Length <= ++idx) + return string.Empty; + + string payload = Payload.Remove(startIdx, idx - startIdx); + + if (removeArrayMarks) + payload = payload.Substring(1, payload.Length - 2); + + return payload; + } + + /// + /// Will switch the "{'_placeholder':true,'num':X}" to a the index num X. + /// + /// True if successfully reconstructed, false otherwise. + public bool ReconstructAttachmentAsIndex() + { + //"452-["multiImage",{"image":true,"buffer1":{"_placeholder":true,"num":0},"buffer2":{"_placeholder":true,"num":1}}]" + + return PlaceholderReplacer((json, obj) => + { + int idx = Convert.ToInt32(obj["num"]); + this.Payload = this.Payload.Replace(json, idx.ToString()); + this.IsDecoded = false; + }); + } + + /// + /// Will switch the "{'_placeholder':true,'num':X}" to a the data as a base64 encoded string. + /// + /// True if successfully reconstructed, false otherwise. + public bool ReconstructAttachmentAsBase64() + { + //"452-["multiImage",{"image":true,"buffer1":{"_placeholder":true,"num":0},"buffer2":{"_placeholder":true,"num":1}}]" + + if (!HasAllAttachment) + return false; + + return PlaceholderReplacer((json, obj) => + { + int idx = Convert.ToInt32(obj["num"]); + this.Payload = this.Payload.Replace(json, string.Format("\"{0}\"", Convert.ToBase64String(this.Attachments[idx]))); + this.IsDecoded = false; + }); + } + + #endregion + + #region Internal Functions + + /// + /// Parse the packet from a server sent textual data. The Payload will be the raw json string. + /// + internal void Parse(string from) + { + int idx = 0; + this.TransportEvent = (TransportEventTypes)ToInt(from[idx++]); + + if (from.Length > idx && ToInt(from[idx]) >= 0) + this.SocketIOEvent = (SocketIOEventTypes)ToInt(from[idx++]); + else + this.SocketIOEvent = SocketIOEventTypes.Unknown; + + // Parse Attachment + if (this.SocketIOEvent == SocketIOEventTypes.BinaryEvent || this.SocketIOEvent == SocketIOEventTypes.BinaryAck) + { + int endIdx = from.IndexOf('-', idx); + if (endIdx == -1) + endIdx = from.Length; + + int attachment = 0; + int.TryParse(from.Substring(idx, endIdx - idx), out attachment); + this.AttachmentCount = attachment; + idx = endIdx + 1; + } + + // Parse Namespace + if (from.Length > idx && from[idx] == '/') + { + int endIdx = from.IndexOf(',', idx); + if (endIdx == -1) + endIdx = from.Length; + + this.Namespace = from.Substring(idx, endIdx - idx); + idx = endIdx + 1; + } + else + this.Namespace = "/"; + + // Parse Id + if (from.Length > idx && ToInt(from[idx]) >= 0) + { + int startIdx = idx++; + while (from.Length > idx && ToInt(from[idx]) >= 0) + idx++; + + int id = 0; + int.TryParse(from.Substring(startIdx, idx - startIdx), out id); + this.Id = id; + } + + // What left is the payload data + if (from.Length > idx) + this.Payload = from.Substring(idx); + else + this.Payload = string.Empty; + } + + /// + /// Custom function instead of char.GetNumericValue, as it throws an error under WebGL using the new 4.x runtime. + /// It will return the value of the char if it's a numeric one, otherwise -1. + /// + private int ToInt(char ch) + { + int charValue = Convert.ToInt32(ch); + int num = charValue - '0'; + if (num < 0 || num > 9) + return -1; + + return num; + } + + /// + /// Encodes this packet to a Socket.IO formatted string. + /// + internal string Encode() + { + StringBuilder builder = new StringBuilder(); + + // Set to Message if not set, and we are sending attachments + if (this.TransportEvent == TransportEventTypes.Unknown && this.AttachmentCount > 0) + this.TransportEvent = TransportEventTypes.Message; + + if (this.TransportEvent != TransportEventTypes.Unknown) + builder.Append(((int)this.TransportEvent).ToString()); + + // Set to BinaryEvent if not set, and we are sending attachments + if (this.SocketIOEvent == SocketIOEventTypes.Unknown && this.AttachmentCount > 0) + this.SocketIOEvent = SocketIOEventTypes.BinaryEvent; + + if (this.SocketIOEvent != SocketIOEventTypes.Unknown) + builder.Append(((int)this.SocketIOEvent).ToString()); + + if (this.SocketIOEvent == SocketIOEventTypes.BinaryEvent || this.SocketIOEvent == SocketIOEventTypes.BinaryAck) + { + builder.Append(this.AttachmentCount.ToString()); + builder.Append("-"); + } + + // Add the namespace. If there is any other then the root nsp ("/") + // then we have to add a trailing "," if we have more data. + bool nspAdded = false; + if (this.Namespace != "/") + { + builder.Append(this.Namespace); + nspAdded = true; + } + + // ack id, if any + if (this.Id != 0) + { + if (nspAdded) + { + builder.Append(","); + nspAdded = false; + } + + builder.Append(this.Id.ToString()); + } + + // payload + if (!string.IsNullOrEmpty(this.Payload)) + { + if (nspAdded) + { + builder.Append(","); + nspAdded = false; + } + + builder.Append(this.Payload); + } + + return builder.ToString(); + } + + /// + /// Encodes this packet to a Socket.IO formatted byte array. + /// + internal byte[] EncodeBinary() + { + if (AttachmentCount != 0 || (Attachments != null && Attachments.Count != 0)) + { + if (Attachments == null) + throw new ArgumentException("packet.Attachments are null!"); + + if (AttachmentCount != Attachments.Count) + throw new ArgumentException("packet.AttachmentCount != packet.Attachments.Count. Use the packet.AddAttachment function to add data to a packet!"); + } + + // Encode it as usual + string encoded = Encode(); + + // Convert it to a byte[] + byte[] payload = Encoding.UTF8.GetBytes(encoded); + + // Encode it to a message + byte[] buffer = EncodeData(payload, PayloadTypes.Textual, null); + + // If there is any attachment, convert them too, and append them after each other + if (AttachmentCount != 0) + { + int idx = buffer.Length; + + // List to temporarily hold the converted attachments + List attachmentDatas = new List(AttachmentCount); + + // The sum size of the converted attachments to be able to resize our buffer only once. This way we can avoid some GC garbage + int attachmentDataSize = 0; + + // Encode our attachments, and store them in our list + for (int i = 0; i < AttachmentCount; i++) + { + byte[] tmpBuff = EncodeData(Attachments[i], PayloadTypes.Binary, new byte[] { 4 }); + attachmentDatas.Add(tmpBuff); + + attachmentDataSize += tmpBuff.Length; + } + + // Resize our buffer once + Array.Resize(ref buffer, buffer.Length + attachmentDataSize); + + // And copy all data into it + for (int i = 0; i < AttachmentCount; ++i) + { + byte[] data = attachmentDatas[i]; + Array.Copy(data, 0, buffer, idx, data.Length); + + idx += data.Length; + } + } + + // Return the buffer + return buffer; + } + + /// + /// Will add the byte[] that the server sent to the attachments list. + /// + internal void AddAttachmentFromServer(byte[] data, bool copyFull) + { + if (data == null || data.Length == 0) + return; + + if (this.attachments == null) + this.attachments = new List(this.AttachmentCount); + + if (copyFull) + this.Attachments.Add(data); + else + { + byte[] buff = new byte[data.Length - 1]; + Array.Copy(data, 1, buff, 0, data.Length - 1); + + this.Attachments.Add(buff); + } + } + + #endregion + + #region Private Helper Functions + + /// + /// Encodes a byte array to a Socket.IO binary encoded message + /// + private byte[] EncodeData(byte[] data, PayloadTypes type, byte[] afterHeaderData) + { + // Packet binary encoding: + // [ 0|1 ][ length of data ][ FF ][data] + // <1 = binary, 0 = string>[...] + + // Get the length of the payload. Socket.IO uses a wasteful encoding to send the length of the data. + // If the data is 16 bytes we have to send the length as two bytes: byte value of the character '1' and byte value of the character '6'. + // Instead of just one byte: 0xF. If the payload is 123 bytes, we can't send as 0x7B... + int afterHeaderLength = (afterHeaderData != null ? afterHeaderData.Length : 0); + string lenStr = (data.Length + afterHeaderLength).ToString(); + byte[] len = new byte[lenStr.Length]; + for (int cv = 0; cv < lenStr.Length; ++cv) + len[cv] = (byte)char.GetNumericValue(lenStr[cv]); + + // We need another buffer to store the final data + byte[] buffer = new byte[data.Length + len.Length + 2 + afterHeaderLength]; + + // The payload is textual -> 0 + buffer[0] = (byte)type; + + // Copy the length of the data + for (int cv = 0; cv < len.Length; ++cv) + buffer[1 + cv] = len[cv]; + + int idx = 1 + len.Length; + + // End of the header data + buffer[idx++] = 0xFF; + + if (afterHeaderData != null && afterHeaderData.Length > 0) + { + Array.Copy(afterHeaderData, 0, buffer, idx, afterHeaderData.Length); + idx += afterHeaderData.Length; + } + + // Copy our payload data to the buffer + Array.Copy(data, 0, buffer, idx, data.Length); + + return buffer; + } + + /// + /// Searches for the "{'_placeholder':true,'num':X}" string, and will call the given action to modify the PayLoad + /// + private bool PlaceholderReplacer(Action> onFound) + { + if (string.IsNullOrEmpty(this.Payload)) + return false; + + // Find the first index of the "_placeholder" str + int placeholderIdx = this.Payload.IndexOf(Placeholder); + + while (placeholderIdx >= 0) + { + // Find the object-start token + int startIdx = placeholderIdx; + while (this.Payload[startIdx] != '{') + startIdx--; + + // Find the object-end token + int endIdx = placeholderIdx; + while (this.Payload.Length > endIdx && this.Payload[endIdx] != '}') + endIdx++; + + // We reached the end + if (this.Payload.Length <= endIdx) + return false; + + // Get the object, and decode it + string placeholderJson = this.Payload.Substring(startIdx, endIdx - startIdx + 1); + bool success = false; + Dictionary obj = Json.Decode(placeholderJson, ref success) as Dictionary; + if (!success) + return false; + + // Check for presence and value of _placeholder + object value; + if (!obj.TryGetValue(Placeholder, out value) || + !(bool)value) + return false; + + // Check for presence of num + if (!obj.TryGetValue("num", out value)) + return false; + + // Let do, what we have to do + onFound(placeholderJson, obj); + + // Find the next attachment if there is any + placeholderIdx = this.Payload.IndexOf(Placeholder); + } + + return true; + } + + #endregion + + #region Overrides and Interface Implementations + + /// + /// Returns with the Payload of this packet. + /// + public override string ToString() + { + return this.Payload; + } + + /// + /// Will clone this packet to an identical packet instance. + /// + internal Packet Clone() + { + Packet packet = new Packet(this.TransportEvent, this.SocketIOEvent, this.Namespace, this.Payload, 0, this.Id); + packet.EventName = this.EventName; + packet.AttachmentCount = this.AttachmentCount; + packet.attachments = this.attachments; + + return packet; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs.meta new file mode 100644 index 0000000..f553883 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Packet.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 907cf4e3f52e02c409084c624e734c7c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs new file mode 100644 index 0000000..c484918 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs @@ -0,0 +1,475 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; +using System.Collections.Generic; + +namespace BestHTTP.SocketIO +{ + using BestHTTP; + using BestHTTP.SocketIO.Events; + + /// + /// This class represents a Socket.IO namespace. + /// + public sealed class Socket : ISocket + { + #region Public Properties + + /// + /// The SocketManager instance that created this socket. + /// + public SocketManager Manager { get; private set; } + + /// + /// The namespace that this socket is bound to. + /// + public string Namespace { get; private set; } + + /// + /// Unique Id of the socket. + /// + public string Id { get; private set; } + + /// + /// True if the socket is connected and open to the server. False otherwise. + /// + public bool IsOpen { get; private set; } + + /// + /// While this property is True, the socket will decode the Packet's Payload data using the parent SocketManager's Encoder. You must set this property before any event subscription! Its default value is True; + /// + public bool AutoDecodePayload { get; set; } + + #endregion + + #region Privates + + /// + /// A table to store acknowledgment callbacks associated to the given ids. + /// + private Dictionary AckCallbacks; + + /// + /// Tha callback table that helps this class to manage event subscription and dispatching events. + /// + private EventTable EventCallbacks; + + /// + /// Cached list to spare some GC alloc. + /// + private List arguments = new List(); + + #endregion + + /// + /// Internal constructor. + /// + internal Socket(string nsp, SocketManager manager) + { + this.Namespace = nsp; + this.Manager = manager; + this.IsOpen = false; + this.AutoDecodePayload = true; + this.EventCallbacks = new EventTable(this); + } + + #region Socket Handling + + /// + /// Internal function to start opening the socket. + /// + void ISocket.Open() + { + // The transport already established the connection + if (Manager.State == SocketManager.States.Open) + OnTransportOpen(Manager.Socket, null); + else + { + // We want to receive a message when we are connected. + Manager.Socket.Off(EventNames.Connect, OnTransportOpen); + Manager.Socket.On(EventNames.Connect, OnTransportOpen); + + if (Manager.Options.AutoConnect && Manager.State == SocketManager.States.Initial) + Manager.Open(); + } + } + + /// + /// Disconnects this socket/namespace. + /// + public void Disconnect() + { + (this as ISocket).Disconnect(true); + } + + /// + /// Disconnects this socket/namespace. + /// + void ISocket.Disconnect(bool remove) + { + // Send a disconnect packet to the server + if (IsOpen) + { + Packet packet = new Packet(TransportEventTypes.Message, SocketIOEventTypes.Disconnect, this.Namespace, string.Empty); + (Manager as IManager).SendPacket(packet); + + // IsOpen must be false, because in the OnPacket preprocessing the packet would call this function again + IsOpen = false; + (this as ISocket).OnPacket(packet); + } + + if (AckCallbacks != null) + AckCallbacks.Clear(); + + if (remove) + { + EventCallbacks.Clear(); + + (Manager as IManager).Remove(this); + } + } + + #endregion + + #region Emit Implementations + + public Socket Emit(string eventName, params object[] args) + { + return Emit(eventName, null, args); + } + + public Socket Emit(string eventName, SocketIOAckCallback callback, params object[] args) + { + bool blackListed = EventNames.IsBlacklisted(eventName); + if (blackListed) + throw new ArgumentException("Blacklisted event: " + eventName); + + arguments.Clear(); + arguments.Add(eventName); + + // Find and swap any binary data(byte[]) to a placeholder string. + // Server side these will be swapped back. + List attachments = null; + if (args != null && args.Length > 0) + { + int idx = 0; + for (int i = 0; i < args.Length; ++i) + { + byte[] binData = args[i] as byte[]; + if (binData != null) + { + if (attachments == null) + attachments = new List(); + + Dictionary placeholderObj = new Dictionary(2); + placeholderObj.Add(Packet.Placeholder, true); + placeholderObj.Add("num", idx++); + + arguments.Add(placeholderObj); + + attachments.Add(binData); + } + else + arguments.Add(args[i]); + } + } + + string payload = null; + + try + { + payload = Manager.Encoder.Encode(arguments); + } + catch(Exception ex) + { + (this as ISocket).EmitError(SocketIOErrors.Internal, "Error while encoding payload: " + ex.Message + " " + ex.StackTrace); + + return this; + } + + // We don't use it further in this function, so we can clear it to not hold any unwanted reference. + arguments.Clear(); + + if (payload == null) + throw new ArgumentException("Encoding the arguments to JSON failed!"); + + int id = 0; + + if (callback != null) + { + id = Manager.NextAckId; + + if (AckCallbacks == null) + AckCallbacks = new Dictionary(); + + AckCallbacks[id] = callback; + } + + Packet packet = new Packet(TransportEventTypes.Message, + attachments == null ? SocketIOEventTypes.Event : SocketIOEventTypes.BinaryEvent, + this.Namespace, + payload, + 0, + id); + + if (attachments != null) + packet.Attachments = attachments; // This will set the AttachmentCount property too. + + (Manager as IManager).SendPacket(packet); + + return this; + } + + public Socket EmitAck(Packet originalPacket, params object[] args) + { + if (originalPacket == null) + throw new ArgumentNullException("originalPacket == null!"); + + if (/*originalPacket.Id == 0 ||*/ + (originalPacket.SocketIOEvent != SocketIOEventTypes.Event && originalPacket.SocketIOEvent != SocketIOEventTypes.BinaryEvent)) + throw new ArgumentException("Wrong packet - you can't send an Ack for a packet with id == 0 and SocketIOEvent != Event or SocketIOEvent != BinaryEvent!"); + + arguments.Clear(); + if (args != null && args.Length > 0) + arguments.AddRange(args); + + string payload = null; + try + { + payload = Manager.Encoder.Encode(arguments); + } + catch (Exception ex) + { + (this as ISocket).EmitError(SocketIOErrors.Internal, "Error while encoding payload: " + ex.Message + " " + ex.StackTrace); + + return this; + } + + if (payload == null) + throw new ArgumentException("Encoding the arguments to JSON failed!"); + + Packet packet = new Packet(TransportEventTypes.Message, + originalPacket.SocketIOEvent == SocketIOEventTypes.Event ? SocketIOEventTypes.Ack : SocketIOEventTypes.BinaryAck, + this.Namespace, + payload, + 0, + originalPacket.Id); + + (Manager as IManager).SendPacket(packet); + + return this; + } + + #endregion + + #region On Implementations + + /// + /// Register a callback for a given name + /// + public void On(string eventName, SocketIOCallback callback) + { + EventCallbacks.Register(eventName, callback, false, this.AutoDecodePayload); + } + + public void On(SocketIOEventTypes type, SocketIOCallback callback) + { + string eventName = EventNames.GetNameFor(type); + + EventCallbacks.Register(eventName, callback, false, this.AutoDecodePayload); + } + + public void On(string eventName, SocketIOCallback callback, bool autoDecodePayload) + { + EventCallbacks.Register(eventName, callback, false, autoDecodePayload); + } + + public void On(SocketIOEventTypes type, SocketIOCallback callback, bool autoDecodePayload) + { + string eventName = EventNames.GetNameFor(type); + + EventCallbacks.Register(eventName, callback, false, autoDecodePayload); + } + + #endregion + + #region Once Implementations + + public void Once(string eventName, SocketIOCallback callback) + { + EventCallbacks.Register(eventName, callback, true, this.AutoDecodePayload); + } + + public void Once(SocketIOEventTypes type, SocketIOCallback callback) + { + EventCallbacks.Register(EventNames.GetNameFor(type), callback, true, this.AutoDecodePayload); + } + + public void Once(string eventName, SocketIOCallback callback, bool autoDecodePayload) + { + EventCallbacks.Register(eventName, callback, true, autoDecodePayload); + } + + public void Once(SocketIOEventTypes type, SocketIOCallback callback, bool autoDecodePayload) + { + EventCallbacks.Register(EventNames.GetNameFor(type), callback, true, autoDecodePayload); + } + + #endregion + + #region Off Implementations + + /// + /// Remove all callbacks for all events. + /// + public void Off() + { + EventCallbacks.Clear(); + } + + /// + /// Removes all callbacks to the given event. + /// + public void Off(string eventName) + { + EventCallbacks.Unregister(eventName); + } + + /// + /// Removes all callbacks to the given event. + /// + public void Off(SocketIOEventTypes type) + { + Off(EventNames.GetNameFor(type)); + } + + /// + /// Remove the specified callback. + /// + public void Off(string eventName, SocketIOCallback callback) + { + EventCallbacks.Unregister(eventName, callback); + } + + /// + /// Remove the specified callback. + /// + public void Off(SocketIOEventTypes type, SocketIOCallback callback) + { + EventCallbacks.Unregister(EventNames.GetNameFor(type), callback); + } + + #endregion + + #region Packet Handling + + /// + /// Last call of the OnPacket chain(Transport -> Manager -> Socket), we will dispatch the event if there is any callback + /// + void ISocket.OnPacket(Packet packet) + { + // Some preprocessing of the packet + switch(packet.SocketIOEvent) + { + case SocketIOEventTypes.Connect: + this.Id = this.Namespace != "/" ? this.Namespace + "#" + this.Manager.Handshake.Sid : this.Manager.Handshake.Sid; + break; + + case SocketIOEventTypes.Disconnect: + if (IsOpen) + { + IsOpen = false; + EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Disconnect), packet); + Disconnect(); + } + break; + + // Create an Error object from the server-sent json string + case SocketIOEventTypes.Error: + bool success = false; + object result = JSON.Json.Decode(packet.Payload, ref success); + if (success) + { + var errDict = result as Dictionary; + Error err; + + if (errDict != null && errDict.ContainsKey("code")) + err = new Error((SocketIOErrors)Convert.ToInt32(errDict["code"]), errDict["message"] as string); + else + err = new Error(SocketIOErrors.Custom, packet.Payload); + + EventCallbacks.Call(EventNames.GetNameFor(SocketIOEventTypes.Error), packet, err); + + return; + } + break; + } + + // Dispatch the event to all subscriber + EventCallbacks.Call(packet); + + // call Ack callbacks + if ((packet.SocketIOEvent == SocketIOEventTypes.Ack || packet.SocketIOEvent == SocketIOEventTypes.BinaryAck) && AckCallbacks != null) + { + SocketIOAckCallback ackCallback = null; + if (AckCallbacks.TryGetValue(packet.Id, out ackCallback) && + ackCallback != null) + { + try + { + ackCallback(this, packet, this.AutoDecodePayload ? packet.Decode(Manager.Encoder) : null); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("Socket", "ackCallback", ex); + } + } + + AckCallbacks.Remove(packet.Id); + } + } + + #endregion + + /// + /// Emits an internal packet-less event to the user level. + /// + void ISocket.EmitEvent(SocketIOEventTypes type, params object[] args) + { + (this as ISocket).EmitEvent(EventNames.GetNameFor(type), args); + } + + /// + /// Emits an internal packet-less event to the user level. + /// + void ISocket.EmitEvent(string eventName, params object[] args) + { + if (!string.IsNullOrEmpty(eventName)) + EventCallbacks.Call(eventName, null, args); + } + + void ISocket.EmitError(SocketIOErrors errCode, string msg) + { + (this as ISocket).EmitEvent(SocketIOEventTypes.Error, new Error(errCode, msg)); + } + + #region Private Helper Functions + + /// + /// Called when a "connect" event received to the root namespace + /// + private void OnTransportOpen(Socket socket, Packet packet, params object[] args) + { + // If this is not the root namespace, then we send a connect message to the server + if (this.Namespace != "/") + (Manager as IManager).SendPacket(new Packet(TransportEventTypes.Message, SocketIOEventTypes.Connect, this.Namespace, string.Empty)); + + // and we are now open + IsOpen = true; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs.meta new file mode 100644 index 0000000..3929554 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Socket.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2087171a4dffa4f49a83c2c61d3debba +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs new file mode 100644 index 0000000..f17d1f9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs @@ -0,0 +1,684 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; +using System.Collections.Generic; + +using BestHTTP.SocketIO.Transports; +using BestHTTP.Extensions; +using BestHTTP.SocketIO.JsonEncoders; +using BestHTTP.SocketIO.Events; + +namespace BestHTTP.SocketIO +{ + public sealed class SocketManager : IHeartbeat, IManager + { + /// + /// Possible states of a SocketManager instance. + /// + public enum States + { + /// + /// Initial state of the SocketManager + /// + Initial, + + /// + /// The SocketManager is closed, initiated by the user or by the server + /// + Closed, + + /// + /// The SocketManager is currently opening. + /// + Opening, + + /// + /// The SocketManager is open, events can be sent to the server. + /// + Open, + + /// + /// Paused for transport upgrade + /// + Paused, + + /// + /// An error occurred, the SocketManager now trying to connect again to the server. + /// + Reconnecting + } + + /// + /// The default Json encode/decoder that will be used to encode/decode the event arguments. + /// + public static IJsonEncoder DefaultEncoder = new DefaultJSonEncoder(); + + /// + /// Supported Socket.IO protocol version + /// + public const int MinProtocolVersion = 4; + + #region Public Properties + + /// + /// The current state of this Socket.IO manager. + /// + public States State { get { return state; } private set { PreviousState = state; state = value; } } + private States state; + + /// + /// The SocketOptions instance that this manager will use. + /// + public SocketOptions Options { get; private set; } + + /// + /// The Uri to the Socket.IO endpoint. + /// + public Uri Uri { get; private set; } + + /// + /// The server sent and parsed Handshake data. + /// + public HandshakeData Handshake { get; private set; } + + /// + /// The currently used main transport instance. + /// + public ITransport Transport { get; private set; } + + /// + /// The Request counter for request-based transports. + /// + public ulong RequestCounter { get; internal set; } + + /// + /// The root("/") Socket. + /// + public Socket Socket { get { return GetSocket(); } } + + /// + /// Indexer to access socket associated to the given namespace. + /// + public Socket this[string nsp] { get { return GetSocket(nsp); } } + + /// + /// How many reconnect attempts made. + /// + public int ReconnectAttempts { get; private set; } + + /// + /// The JSon encoder that will be used to encode the sent data to json and decode the received json to an object list. + /// + public IJsonEncoder Encoder { get; set; } + + #endregion + + #region Internal Properties + + /// + /// Timestamp support to the request based transports. + /// + internal UInt32 Timestamp { get { return (UInt32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds; } } + + /// + /// Auto-incrementing property to return Ack ids. + /// + internal int NextAckId { get { return System.Threading.Interlocked.Increment(ref nextAckId); } } + private int nextAckId; + + /// + /// Internal property to store the previous state of the manager. + /// + internal States PreviousState { get; private set; } + + /// + /// Transport currently upgrading. + /// + internal ITransport UpgradingTransport { get; set; } + + #endregion + + #region Privates + + /// + /// Namespace name -> Socket mapping + /// + private Dictionary Namespaces = new Dictionary(); + + /// + /// List of the sockets to able to iterate over them easily. + /// + private List Sockets = new List(); + + /// + /// List of unsent packets. Only instantiated when we have to use it. + /// + private List OfflinePackets; + + /// + /// When we sent out the last heartbeat(Ping) message. + /// + private DateTime LastHeartbeat = DateTime.MinValue; + + /// + /// When we have to try to do a reconnect attempt + /// + private DateTime ReconnectAt; + + /// + /// When we started to connect to the server. + /// + private DateTime ConnectionStarted; + + /// + /// Private flag to avoid multiple Close call + /// + private bool closing; + + /// + /// Whether the connection is waiting for a ping response. + /// + private bool IsWaitingPong; + + #endregion + + #region Constructors + + /// + /// Constructor to create a SocketManager instance that will connect to the given uri. + /// + public SocketManager(Uri uri) + :this(uri, new SocketOptions()) + { + + } + + /// + /// Constructor to create a SocketManager instance. + /// + public SocketManager(Uri uri, SocketOptions options) + { + Uri = uri; + Options = options; + State = States.Initial; + PreviousState = States.Initial; + Encoder = SocketManager.DefaultEncoder; + } + + #endregion + + /// + /// Returns with the "/" namespace, the same as the Socket property. + /// + public Socket GetSocket() + { + return GetSocket("/"); + } + + /// + /// Returns with the specified namespace + /// + public Socket GetSocket(string nsp) + { + if (string.IsNullOrEmpty(nsp)) + throw new ArgumentNullException("Namespace parameter is null or empty!"); + + /*if (nsp[0] != '/') + nsp = "/" + nsp;*/ + + Socket socket = null; + if (!Namespaces.TryGetValue(nsp, out socket)) + { + // No socket found, create one + socket = new Socket(nsp, this); + + Namespaces.Add(nsp, socket); + Sockets.Add(socket); + + (socket as ISocket).Open(); + } + + return socket; + } + + /// + /// Internal function to remove a Socket instance from this manager. + /// + /// + void IManager.Remove(Socket socket) + { + Namespaces.Remove(socket.Namespace); + Sockets.Remove(socket); + + if (Sockets.Count == 0) + Close(); + } + + #region Connection to the server, and upgrading + + /// + /// This function will begin to open the Socket.IO connection by sending out the handshake request. + /// If the Options' AutoConnect is true, it will be called automatically. + /// + public void Open() + { + if (State != States.Initial && + State != States.Closed && + State != States.Reconnecting) + return; + + HTTPManager.Logger.Information("SocketManager", "Opening"); + + ReconnectAt = DateTime.MinValue; + + switch (Options.ConnectWith) + { + case TransportTypes.Polling: Transport = new PollingTransport(this); break; +#if !BESTHTTP_DISABLE_WEBSOCKET + case TransportTypes.WebSocket: Transport = new WebSocketTransport(this); break; +#endif + } + Transport.Open(); + + + (this as IManager).EmitEvent("connecting"); + + State = States.Opening; + + ConnectionStarted = DateTime.UtcNow; + + HTTPManager.Heartbeats.Subscribe(this); + + // The root namespace will be opened by default + GetSocket("/"); + } + + /// + /// Closes this Socket.IO connection. + /// + public void Close() + { + (this as IManager).Close(true); + } + + /// + /// Closes this Socket.IO connection. + /// + void IManager.Close(bool removeSockets) + { + if (State == States.Closed || closing) + return; + closing = true; + + HTTPManager.Logger.Information("SocketManager", "Closing"); + + HTTPManager.Heartbeats.Unsubscribe(this); + + // Disconnect the sockets. The Disconnect function will call the Remove function to remove it from the Sockets list. + if (removeSockets) + while (Sockets.Count > 0) + (Sockets[Sockets.Count - 1] as ISocket).Disconnect(removeSockets); + else + for (int i = 0; i < Sockets.Count; ++i) + (Sockets[i] as ISocket).Disconnect(removeSockets); + + // Set to Closed after Socket's Disconnect. This way we can send the disconnect events to the server. + State = States.Closed; + + LastHeartbeat = DateTime.MinValue; + + if (OfflinePackets != null) + OfflinePackets.Clear(); + + // Remove the references from the dictionary too. + if (removeSockets) + Namespaces.Clear(); + + Handshake = null; + + if (Transport != null) + Transport.Close(); + Transport = null; + + closing = false; + } + + /// + /// Called from a ITransport implementation when an error occurs and we may have to try to reconnect. + /// + void IManager.TryToReconnect() + { + if (State == States.Reconnecting || + State == States.Closed) + return; + + if (!Options.Reconnection || HTTPManager.IsQuitting) + { + Close(); + + return; + } + + if (++ReconnectAttempts >= Options.ReconnectionAttempts) + { + (this as IManager).EmitEvent("reconnect_failed"); + Close(); + + return; + } + + Random rand = new Random(); + + int delay = (int)Options.ReconnectionDelay.TotalMilliseconds * ReconnectAttempts; + + ReconnectAt = DateTime.UtcNow + + TimeSpan.FromMilliseconds(Math.Min(rand.Next(/*rand min:*/(int)(delay - (delay * Options.RandomizationFactor)), + /*rand max:*/(int)(delay + (delay * Options.RandomizationFactor))), + (int)Options.ReconnectionDelayMax.TotalMilliseconds)); + + (this as IManager).Close(false); + + State = States.Reconnecting; + + for (int i = 0; i < Sockets.Count; ++i) + (Sockets[i] as ISocket).Open(); + + // In the Close() function we unregistered + HTTPManager.Heartbeats.Subscribe(this); + + HTTPManager.Logger.Information("SocketManager", "Reconnecting"); + } + + /// + /// Called by transports when they are connected to the server. + /// + bool IManager.OnTransportConnected(ITransport trans) + { + if (State != States.Opening) + return false; + + if (PreviousState == States.Reconnecting) + (this as IManager).EmitEvent("reconnect"); + + State = States.Open; + + ReconnectAttempts = 0; + + // Send out packets that we collected while there were no available transport. + SendOfflinePackets(); + + HTTPManager.Logger.Information("SocketManager", "Open"); + +#if !BESTHTTP_DISABLE_WEBSOCKET + // Can we upgrade to WebSocket transport? + if (Transport.Type != TransportTypes.WebSocket && + Handshake.Upgrades.Contains("websocket")) + { + UpgradingTransport = new WebSocketTransport(this); + UpgradingTransport.Open(); + } +#endif + + return true; + } + + void IManager.OnTransportError(ITransport trans, string err) + { + (this as IManager).EmitError(SocketIOErrors.Internal, err); + + trans.Close(); + (this as IManager).TryToReconnect(); + } + + void IManager.OnTransportProbed(ITransport trans) + { + HTTPManager.Logger.Information("SocketManager", "\"probe\" packet received"); + + // If we have to reconnect, we will go straight with the transport we were able to upgrade + Options.ConnectWith = trans.Type; + + // Pause ourself to wait for any send and receive turn to finish. + State = States.Paused; + } + + #endregion + + #region Packet Handling + + /// + /// Select the best transport to send out packets. + /// + private ITransport SelectTransport() + { + if (State != States.Open || Transport == null) + return null; + + return Transport.IsRequestInProgress ? null : Transport; + } + + /// + /// Will select the best transport and sends out all packets that are in the OfflinePackets list. + /// + private void SendOfflinePackets() + { + ITransport trans = SelectTransport(); + + // Send out packets that we not sent while no transport was available. + // This function is called before the event handlers get the 'connected' event, so + // theoretically the packet orders are remains. + if (OfflinePackets != null && OfflinePackets.Count > 0 && trans != null) + { + trans.Send(OfflinePackets); + OfflinePackets.Clear(); + } + } + + /// + /// Internal function that called from the Socket class. It will send out the packet instantly, or if no transport is available it will store + /// the packet in the OfflinePackets list. + /// + void IManager.SendPacket(Packet packet) + { + ITransport trans = SelectTransport(); + + if (trans != null) + { + try + { + trans.Send(packet); + } + catch(Exception ex) + { + (this as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); + } + } + else + { + if (OfflinePackets == null) + OfflinePackets = new List(); + + // The same packet can be sent through multiple Sockets. + OfflinePackets.Add(packet.Clone()); + } + } + + /// + /// Called from the currently operating Transport. Will pass forward to the Socket that has to call the callbacks. + /// + void IManager.OnPacket(Packet packet) + { + if (State == States.Closed) + return; + + switch(packet.TransportEvent) + { + case TransportEventTypes.Open: + if (Handshake == null) + { + Handshake = new HandshakeData(); + if (!Handshake.Parse(packet.Payload)) + HTTPManager.Logger.Warning("SocketManager", "Expected handshake data, but wasn't able to pars. Payload: " + packet.Payload); + + (this as IManager).OnTransportConnected(Transport); + + return; + } + break; + + case TransportEventTypes.Ping: + (this as IManager).SendPacket(new Packet(TransportEventTypes.Pong, SocketIOEventTypes.Unknown, "/", string.Empty)); + break; + + case TransportEventTypes.Pong: + IsWaitingPong = false; + break; + } + + Socket socket = null; + if (Namespaces.TryGetValue(packet.Namespace, out socket)) + (socket as ISocket).OnPacket(packet); + else + HTTPManager.Logger.Warning("SocketManager", "Namespace \"" + packet.Namespace + "\" not found!"); + } + + #endregion + + /// + /// Sends an event to all available namespaces. + /// + public void EmitAll(string eventName, params object[] args) + { + for (int i = 0; i < Sockets.Count; ++i) + Sockets[i].Emit(eventName, args); + } + + /// + /// Emits an internal packet-less event to the root namespace without creating it if it isn't exists yet. + /// + void IManager.EmitEvent(string eventName, params object[] args) + { + Socket socket = null; + if (Namespaces.TryGetValue("/", out socket)) + (socket as ISocket).EmitEvent(eventName, args); + } + + /// + /// Emits an internal packet-less event to the root namespace without creating it if it isn't exists yet. + /// + void IManager.EmitEvent(SocketIOEventTypes type, params object[] args) + { + (this as IManager).EmitEvent(EventNames.GetNameFor(type), args); + } + + void IManager.EmitError(SocketIOErrors errCode, string msg) + { + (this as IManager).EmitEvent(SocketIOEventTypes.Error, new Error(errCode, msg)); + } + + void IManager.EmitAll(string eventName, params object[] args) + { + for (int i = 0; i < Sockets.Count; ++i) + (Sockets[i] as ISocket).EmitEvent(eventName, args); + } + + #region IHeartbeat Implementation + + /// + /// Called from the HTTPManager's OnUpdate function every frame. It's main function is to send out heartbeat messages. + /// + void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif) + { + switch (State) + { + case States.Paused: + // To ensure no messages are lost, the upgrade packet will only be sent once all the buffers of the existing transport are flushed and the transport is considered paused. + if (!Transport.IsRequestInProgress && + !Transport.IsPollingInProgress) + { + State = States.Open; + + // Close the current transport + Transport.Close(); + + // and switch to the newly upgraded one + Transport = UpgradingTransport; + UpgradingTransport = null; + + // We will send an Upgrade("5") packet. + Transport.Send(new Packet(TransportEventTypes.Upgrade, SocketIOEventTypes.Unknown, "/", string.Empty)); + + goto case States.Open; + } + break; + + case States.Opening: + if (DateTime.UtcNow - ConnectionStarted >= Options.Timeout) + { + (this as IManager).EmitError(SocketIOErrors.Internal, "Connection timed out!"); + (this as IManager).EmitEvent("connect_error"); + (this as IManager).EmitEvent("connect_timeout"); + (this as IManager).TryToReconnect(); + } + + break; + + case States.Reconnecting: + if (ReconnectAt != DateTime.MinValue && DateTime.UtcNow >= ReconnectAt) + { + (this as IManager).EmitEvent("reconnect_attempt"); + (this as IManager).EmitEvent("reconnecting"); + + Open(); + } + break; + + case States.Open: + ITransport trans = null; + + // Select transport to use + if (Transport != null && Transport.State == TransportStates.Open) + trans = Transport; + + // not yet open? + if (trans == null || trans.State != TransportStates.Open) + return; + + // Start to poll the server for events + trans.Poll(); + + // Start to send out unsent packets + SendOfflinePackets(); + + // First time we reached this point. Set the LastHeartbeat to the current time, 'cause we are just opened. + if (LastHeartbeat == DateTime.MinValue) + { + LastHeartbeat = DateTime.UtcNow; + return; + } + + // It's time to send out a ping event to the server + if (!IsWaitingPong && DateTime.UtcNow - LastHeartbeat > Handshake.PingInterval) + { + (this as IManager).SendPacket(new Packet(TransportEventTypes.Ping, SocketIOEventTypes.Unknown, "/", string.Empty)); + + LastHeartbeat = DateTime.UtcNow; + IsWaitingPong = true; + } + + // No pong event received in the given time, we are disconnected. + if (IsWaitingPong && DateTime.UtcNow - LastHeartbeat > Handshake.PingTimeout) + { + IsWaitingPong = false; + (this as IManager).TryToReconnect(); + } + + break; // case States.Open: + } + } + + #endregion + + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs.meta new file mode 100644 index 0000000..6c5a75c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketManager.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 71662b80689f3cc479fbd747b6b05ed4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs new file mode 100644 index 0000000..62596f5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs @@ -0,0 +1,158 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; +using System.Text; + +using PlatformSupport.Collections.ObjectModel; + +#if !NETFX_CORE + using PlatformSupport.Collections.Specialized; +#else + using System.Collections.Specialized; +#endif + +namespace BestHTTP.SocketIO +{ + public sealed class SocketOptions + { + #region Properties + + /// + /// The SocketManager will try to connect with this transport. + /// + public Transports.TransportTypes ConnectWith { get; set; } + + /// + /// Whether to reconnect automatically after a disconnect (default true) + /// + public bool Reconnection { get; set; } + + /// + /// Number of attempts before giving up (default Int.MaxValue) + /// + public int ReconnectionAttempts { get; set; } + + /// + /// How long to initially wait before attempting a new reconnection (default 1000ms). + /// Affected by +/- RandomizationFactor, for example the default initial delay will be between 500ms to 1500ms. + /// + public TimeSpan ReconnectionDelay { get; set; } + + /// + /// Maximum amount of time to wait between reconnections (default 5000ms). + /// Each attempt increases the reconnection delay along with a randomization as above. + /// + public TimeSpan ReconnectionDelayMax { get; set; } + + /// + /// (default 0.5`), [0..1] + /// + public float RandomizationFactor { get { return randomizationFactor; } set { randomizationFactor = Math.Min(1.0f, Math.Max(0.0f, value)); } } + private float randomizationFactor; + + /// + /// Connection timeout before a connect_error and connect_timeout events are emitted (default 20000ms) + /// + public TimeSpan Timeout { get; set; } + + /// + /// By setting this false, you have to call SocketManager's Open() whenever you decide it's appropriate. + /// + public bool AutoConnect { get; set; } + + /// + /// Additional query parameters that will be passed for the handshake uri. If the value is null, or an empty string it will be not appended to the query only the key. + /// The keys and values must be escaped properly, as the plugin will not escape these. + /// + public ObservableDictionary AdditionalQueryParams + { + get { return additionalQueryParams; } + set + { + // Unsubscribe from previous dictionary's events + if (additionalQueryParams != null) + additionalQueryParams.CollectionChanged -= AdditionalQueryParams_CollectionChanged; + + additionalQueryParams = value; + + // Clear out the cached value + BuiltQueryParams = null; + + // Subscribe to the collection changed event + if (value != null) + value.CollectionChanged += AdditionalQueryParams_CollectionChanged; + } + } + private ObservableDictionary additionalQueryParams; + + /// + /// If it's false, the parameters in the AdditionalQueryParams will be passed for all HTTP requests. Its default value is true. + /// + public bool QueryParamsOnlyForHandshake { get; set; } + + #endregion + + /// + /// The cached value of the result of the BuildQueryParams() call. + /// + private string BuiltQueryParams; + + /// + /// Constructor, setting the default option values. + /// + public SocketOptions() + { + ConnectWith = Transports.TransportTypes.Polling; + Reconnection = true; + ReconnectionAttempts = int.MaxValue; + ReconnectionDelay = TimeSpan.FromMilliseconds(1000); + ReconnectionDelayMax = TimeSpan.FromMilliseconds(5000); + RandomizationFactor = 0.5f; + Timeout = TimeSpan.FromMilliseconds(20000); + AutoConnect = true; + QueryParamsOnlyForHandshake = true; + } + + #region Helper Functions + + /// + /// Builds the keys and values from the AdditionalQueryParams to an key=value form. If AdditionalQueryParams is null or empty, it will return an empty string. + /// + internal string BuildQueryParams() + { + if (AdditionalQueryParams == null || AdditionalQueryParams.Count == 0) + return string.Empty; + + if (!string.IsNullOrEmpty(BuiltQueryParams)) + return BuiltQueryParams; + + StringBuilder sb = new StringBuilder(AdditionalQueryParams.Count * 4); + + foreach(var kvp in AdditionalQueryParams) + { + sb.Append("&"); + sb.Append(kvp.Key); + + if (!string.IsNullOrEmpty(kvp.Value)) + { + sb.Append("="); + sb.Append(kvp.Value); + } + } + + return BuiltQueryParams = sb.ToString(); + } + + /// + /// This event will be called when the AdditonalQueryPrams dictionary changed. We have to reset the cached values. + /// + private void AdditionalQueryParams_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + BuiltQueryParams = null; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs.meta new file mode 100644 index 0000000..6554f97 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/SocketOptions.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f6da26edefd917f4c9d36cc053c80415 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports.meta new file mode 100644 index 0000000..5358aa9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: eaefe2a013280de43aa61175fa8c119a +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs new file mode 100644 index 0000000..abc8483 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs @@ -0,0 +1,104 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System.Collections.Generic; + +namespace BestHTTP.SocketIO.Transports +{ + public enum TransportTypes + { + Polling, + +#if !BESTHTTP_DISABLE_WEBSOCKET + WebSocket +#endif + } + + /// + /// Possible states of an ITransport implementation. + /// + public enum TransportStates : int + { + /// + /// The transport is connecting to the server. + /// + Connecting = 0, + + /// + /// The transport is connected, and started the opening process. + /// + Opening = 1, + + /// + /// The transport is open, can send and receive packets. + /// + Open = 2, + + /// + /// The transport is closed. + /// + Closed = 3, + + /// + /// The transport is paused. + /// + Paused = 4 + } + + /// + /// An interface that a Socket.IO transport must implement. + /// + public interface ITransport + { + /// + /// Type of this transport. + /// + TransportTypes Type { get; } + + /// + /// Current state of the transport + /// + TransportStates State { get; } + + /// + /// SocketManager instance that this transport is bound to. + /// + SocketManager Manager { get; } + + /// + /// True if the transport is busy with sending messages. + /// + bool IsRequestInProgress { get; } + + /// + /// True if the transport is busy with a poll request. + /// + bool IsPollingInProgress { get; } + + /// + /// Start open/upgrade the transport. + /// + void Open(); + + /// + /// Do a poll for available messages on the server. + /// + void Poll(); + + /// + /// Send a single packet to the server. + /// + void Send(Packet packet); + + /// + /// Send a list of packets to the server. + /// + void Send(List packets); + + /// + /// Close this transport. + /// + void Close(); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs.meta new file mode 100644 index 0000000..4b63c0c --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/ITransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c13819a2cd1052c4b8fd103084362fed +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs new file mode 100644 index 0000000..a341cb5 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs @@ -0,0 +1,449 @@ +#if !BESTHTTP_DISABLE_SOCKETIO + +using System; +using System.Text; + +namespace BestHTTP.SocketIO.Transports +{ + internal sealed class PollingTransport : ITransport + { + #region Public (ITransport) Properties + + public TransportTypes Type { get { return TransportTypes.Polling; } } + public TransportStates State { get; private set; } + public SocketManager Manager { get; private set; } + public bool IsRequestInProgress { get { return LastRequest != null; } } + public bool IsPollingInProgress { get { return PollRequest != null; } } + + #endregion + + #region Private Fields + + /// + /// The last POST request we sent to the server. + /// + private HTTPRequest LastRequest; + + /// + /// Last GET request we sent to the server. + /// + private HTTPRequest PollRequest; + + /// + /// The last packet with expected binary attachments + /// + private Packet PacketWithAttachment; + + #endregion + + private enum PayloadTypes : byte + { + Text, + Binary + } + + public PollingTransport(SocketManager manager) + { + Manager = manager; + } + + public void Open() + { + string format = "{0}?EIO={1}&transport=polling&t={2}-{3}{5}"; + if (Manager.Handshake != null) + format += "&sid={4}"; + + bool sendAdditionalQueryParams = !Manager.Options.QueryParamsOnlyForHandshake || (Manager.Options.QueryParamsOnlyForHandshake && Manager.Handshake == null); + + HTTPRequest request = new HTTPRequest(new Uri(string.Format(format, + Manager.Uri.ToString(), + SocketManager.MinProtocolVersion, + Manager.Timestamp.ToString(), + Manager.RequestCounter++.ToString(), + Manager.Handshake != null ? Manager.Handshake.Sid : string.Empty, + sendAdditionalQueryParams ? Manager.Options.BuildQueryParams() : string.Empty)), + OnRequestFinished); + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + // Don't even try to cache it + request.DisableCache = true; +#endif + + request.DisableRetry = true; + + request.Send(); + + State = TransportStates.Opening; + } + + /// + /// Closes the transport and cleans up resources. + /// + public void Close() + { + if (State == TransportStates.Closed) + return; + + State = TransportStates.Closed; + + /* + if (LastRequest != null) + LastRequest.Abort(); + + if (PollRequest != null) + PollRequest.Abort();*/ + } + + #region Packet Sending Implementation + + private System.Collections.Generic.List lonelyPacketList = new System.Collections.Generic.List(1); + public void Send(Packet packet) + { + try + { + lonelyPacketList.Add(packet); + Send(lonelyPacketList); + } + finally + { + lonelyPacketList.Clear(); + } + } + + public void Send(System.Collections.Generic.List packets) + { + if (State != TransportStates.Opening && State != TransportStates.Open) + return; + + if (IsRequestInProgress) + throw new Exception("Sending packets are still in progress!"); + + byte[] buffer = null; + + try + { + buffer = packets[0].EncodeBinary(); + + for (int i = 1; i < packets.Count; ++i) + { + byte[] tmpBuffer = packets[i].EncodeBinary(); + + Array.Resize(ref buffer, buffer.Length + tmpBuffer.Length); + + Array.Copy(tmpBuffer, 0, buffer, buffer.Length - tmpBuffer.Length, tmpBuffer.Length); + } + + packets.Clear(); + } + catch (Exception ex) + { + (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); + return; + } + + LastRequest = new HTTPRequest(new Uri(string.Format("{0}?EIO={1}&transport=polling&t={2}-{3}&sid={4}{5}", + Manager.Uri.ToString(), + SocketManager.MinProtocolVersion, + Manager.Timestamp.ToString(), + Manager.RequestCounter++.ToString(), + Manager.Handshake.Sid, + !Manager.Options.QueryParamsOnlyForHandshake ? Manager.Options.BuildQueryParams() : string.Empty)), + HTTPMethods.Post, + OnRequestFinished); + + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + // Don't even try to cache it + LastRequest.DisableCache = true; +#endif + + LastRequest.SetHeader("Content-Type", "application/octet-stream"); + LastRequest.RawData = buffer; + + LastRequest.Send(); + } + + private void OnRequestFinished(HTTPRequest req, HTTPResponse resp) + { + // Clear out the LastRequest variable, so we can start sending out new packets + LastRequest = null; + + if (State == TransportStates.Closed) + return; + + string errorString = null; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) + HTTPManager.Logger.Verbose("PollingTransport", "OnRequestFinished: " + resp.DataAsText); + + if (resp.IsSuccess) + { + // When we are sending data, the response is an 'ok' string + if (req.MethodType != HTTPMethods.Post) + ParseResponse(resp); + } + else + errorString = string.Format("Polling - Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2} Uri: {3}", + resp.StatusCode, + resp.Message, + resp.DataAsText, + req.CurrentUri); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + errorString = (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"); + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + errorString = string.Format("Polling - Request({0}) Aborted!", req.CurrentUri); + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + errorString = string.Format("Polling - Connection Timed Out! Uri: {0}", req.CurrentUri); + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + errorString = string.Format("Polling - Processing the request({0}) Timed Out!", req.CurrentUri); + break; + } + + if (!string.IsNullOrEmpty(errorString)) + (Manager as IManager).OnTransportError(this, errorString); + } + + #endregion + + #region Polling Implementation + + public void Poll() + { + if (PollRequest != null || State == TransportStates.Paused) + return; + + PollRequest = new HTTPRequest(new Uri(string.Format("{0}?EIO={1}&transport=polling&t={2}-{3}&sid={4}{5}", + Manager.Uri.ToString(), + SocketManager.MinProtocolVersion, + Manager.Timestamp.ToString(), + Manager.RequestCounter++.ToString(), + Manager.Handshake.Sid, + !Manager.Options.QueryParamsOnlyForHandshake ? Manager.Options.BuildQueryParams() : string.Empty)), + HTTPMethods.Get, + OnPollRequestFinished); + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + // Don't even try to cache it + PollRequest.DisableCache = true; +#endif + + PollRequest.DisableRetry = true; + + PollRequest.Send(); + } + + private void OnPollRequestFinished(HTTPRequest req, HTTPResponse resp) + { + // Clear the PollRequest variable, so we can start a new poll. + PollRequest = null; + + if (State == TransportStates.Closed) + return; + + string errorString = null; + + switch (req.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + + if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) + HTTPManager.Logger.Verbose("PollingTransport", "OnPollRequestFinished: " + resp.DataAsText); + + if (resp.IsSuccess) + ParseResponse(resp); + else + errorString = string.Format("Polling - Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2} Uri: {3}", + resp.StatusCode, + resp.Message, + resp.DataAsText, + req.CurrentUri); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + errorString = req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"; + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + errorString = string.Format("Polling - Request({0}) Aborted!", req.CurrentUri); + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + errorString = string.Format("Polling - Connection Timed Out! Uri: {0}", req.CurrentUri); + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + errorString = string.Format("Polling - Processing the request({0}) Timed Out!", req.CurrentUri); + break; + } + + if (!string.IsNullOrEmpty(errorString)) + (Manager as IManager).OnTransportError(this, errorString); + } + + #endregion + + #region Packet Parsing and Handling + + /// + /// Preprocessing and sending out packets to the manager. + /// + private void OnPacket(Packet packet) + { + if (packet.AttachmentCount != 0 && !packet.HasAllAttachment) + { + PacketWithAttachment = packet; + return; + } + + switch (packet.TransportEvent) + { + case TransportEventTypes.Open: + if (this.State != TransportStates.Opening) + HTTPManager.Logger.Warning("PollingTransport", "Received 'Open' packet while state is '" + State.ToString() + "'"); + else + State = TransportStates.Open; + goto default; + + case TransportEventTypes.Message: + if (packet.SocketIOEvent == SocketIOEventTypes.Connect) //2:40 + this.State = TransportStates.Open; + goto default; + + default: + (Manager as IManager).OnPacket(packet); + break; + } + } + + /// + /// Will parse the response, and send out the parsed packets. + /// + private void ParseResponse(HTTPResponse resp) + { + try + { + if (resp != null && resp.Data != null && resp.Data.Length >= 1) + { + +// 1.x +//00000000 00 09 07 ff 30 7b 22 73 69 64 22 3a 22 6f 69 48 0{"sid":"oiH +//00000010 34 31 33 73 61 49 4e 52 53 67 37 41 4b 41 41 41 413saINRSg7AKAAA +//00000020 41 22 2c 22 75 70 67 72 61 64 65 73 22 3a 5b 22 A","upgrades":[" +//00000030 77 65 62 73 6f 63 6b 65 74 22 5d 2c 22 70 69 6e websocket"],"pin +//00000040 67 49 6e 74 65 72 76 61 6c 22 3a 32 35 30 30 30 gInterval":25000 +//00000050 2c 22 70 69 6e 67 54 69 6d 65 6f 75 74 22 3a 36 ,"pingTimeout":6 +//00000060 30 30 30 30 7d 0000} + +// 2.x +//00000000 39 37 3a 30 7b 22 73 69 64 22 3a 22 73 36 62 5a 97:0{"sid":"s6bZ +//00000010 6c 43 37 66 51 59 6b 4f 46 4f 62 35 41 41 41 41 lC7fQYkOFOb5AAAA +//00000020 22 2c 22 75 70 67 72 61 64 65 73 22 3a 5b 22 77 ","upgrades":["w +//00000030 65 62 73 6f 63 6b 65 74 22 5d 2c 22 70 69 6e 67 ebsocket"],"ping +//00000040 49 6e 74 65 72 76 61 6c 22 3a 32 35 30 30 30 2c Interval":25000, +//00000050 22 70 69 6e 67 54 69 6d 65 6f 75 74 22 3a 36 30 "pingTimeout":60 +//00000060 30 30 30 7d 32 3a 34 30 000}2:40 + + int idx = 0; + + while (idx < resp.Data.Length) + { + PayloadTypes type = PayloadTypes.Text; + int length = 0; + + if (resp.Data[idx] < '0') { + type = (PayloadTypes)resp.Data[idx++]; + + byte num = resp.Data[idx++]; + while (num != 0xFF) { + length = (length * 10) + num; + num = resp.Data[idx++]; + } + } + else { + byte next = resp.Data[idx++]; + while (next != ':') { + length = (length * 10) + (next - '0'); + next = resp.Data[idx++]; + } + } + + Packet packet = null; + switch(type) + { + case PayloadTypes.Text: + packet = new Packet(Encoding.UTF8.GetString(resp.Data, idx, length)); + break; + case PayloadTypes.Binary: + if (PacketWithAttachment != null) + { + // First byte is the packet type. We can skip it, so we advance our idx and we also have + // to decrease length + idx++; + length--; + + byte[] buffer = new byte[length]; + Array.Copy(resp.Data, idx, buffer, 0, length); + + PacketWithAttachment.AddAttachmentFromServer(buffer, true); + + if (PacketWithAttachment.HasAllAttachment) + { + packet = PacketWithAttachment; + PacketWithAttachment = null; + } + } + break; + } // switch + + if (packet != null) + { + try + { + OnPacket(packet); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); + (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); + } + } + + idx += length; + + }// while + } + } + catch (Exception ex) + { + (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); + + HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex); + } + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs.meta new file mode 100644 index 0000000..70a0afb --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/PollingTransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d38d2293870da854287018c9eb086861 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs new file mode 100644 index 0000000..56168e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs @@ -0,0 +1,369 @@ +#if !BESTHTTP_DISABLE_SOCKETIO +#if !BESTHTTP_DISABLE_WEBSOCKET + +using System; +using System.Collections.Generic; + +namespace BestHTTP.SocketIO.Transports +{ + using BestHTTP.WebSocket; + using Extensions; + + /// + /// A transport implementation that can communicate with a SocketIO server. + /// + internal sealed class WebSocketTransport : ITransport + { + public TransportTypes Type { get { return TransportTypes.WebSocket; } } + public TransportStates State { get; private set; } + public SocketManager Manager { get; private set; } + public bool IsRequestInProgress { get { return false; } } + public bool IsPollingInProgress { get { return false; } } + public WebSocket Implementation { get; private set; } + + private Packet PacketWithAttachment; + private byte[] Buffer; + + public WebSocketTransport(SocketManager manager) + { + State = TransportStates.Closed; + Manager = manager; + } + + #region Some ITransport Implementation + + public void Open() + { + if (State != TransportStates.Closed) + return; + + Uri uri = null; + string baseUrl = new UriBuilder(HTTPProtocolFactory.IsSecureProtocol(Manager.Uri) ? "wss" : "ws", + Manager.Uri.Host, + Manager.Uri.Port, + Manager.Uri.GetRequestPathAndQueryURL()).Uri.ToString(); + string format = "{0}?EIO={1}&transport=websocket{3}"; + if (Manager.Handshake != null) + format += "&sid={2}"; + + bool sendAdditionalQueryParams = !Manager.Options.QueryParamsOnlyForHandshake || (Manager.Options.QueryParamsOnlyForHandshake && Manager.Handshake == null); + + uri = new Uri(string.Format(format, + baseUrl, + SocketManager.MinProtocolVersion, + Manager.Handshake != null ? Manager.Handshake.Sid : string.Empty, + sendAdditionalQueryParams ? Manager.Options.BuildQueryParams() : string.Empty)); + + Implementation = new WebSocket(uri); + + Implementation.OnOpen = OnOpen; + Implementation.OnMessage = OnMessage; + Implementation.OnBinary = OnBinary; + Implementation.OnError = OnError; + Implementation.OnClosed = OnClosed; + + Implementation.Open(); + + State = TransportStates.Connecting; + } + + /// + /// Closes the transport and cleans up resources. + /// + public void Close() + { + if (State == TransportStates.Closed) + return; + + State = TransportStates.Closed; + + if (Implementation != null) + Implementation.Close(); + else + HTTPManager.Logger.Warning("WebSocketTransport", "Close - WebSocket Implementation already null!"); + Implementation = null; + } + + /// + /// Polling implementation. With WebSocket it's just a skeleton. + /// + public void Poll() + { + } + + #endregion + + #region WebSocket Events + + /// + /// WebSocket implementation OnOpen event handler. + /// + private void OnOpen(WebSocket ws) + { + if (ws != Implementation) + return; + + HTTPManager.Logger.Information("WebSocketTransport", "OnOpen"); + + State = TransportStates.Opening; + + // Send a Probe packet to test the transport. If we receive back a pong with the same payload we can upgrade + if (Manager.UpgradingTransport == this) + Send(new Packet(TransportEventTypes.Ping, SocketIOEventTypes.Unknown, "/", "probe")); + } + + /// + /// WebSocket implementation OnMessage event handler. + /// + private void OnMessage(WebSocket ws, string message) + { + if (ws != Implementation) + return; + + if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) + HTTPManager.Logger.Verbose("WebSocketTransport", "OnMessage: " + message); + + Packet packet = null; + try + { + packet = new Packet(message); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketTransport", "OnMessage Packet parsing", ex); + } + + if (packet == null) + { + HTTPManager.Logger.Error("WebSocketTransport", "Message parsing failed. Message: " + message); + return; + } + + try + { + + if (packet.AttachmentCount == 0) + OnPacket(packet); + else + PacketWithAttachment = packet; + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketTransport", "OnMessage OnPacket", ex); + } + } + + /// + /// WebSocket implementation OnBinary event handler. + /// + private void OnBinary(WebSocket ws, byte[] data) + { + if (ws != Implementation) + return; + + if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) + HTTPManager.Logger.Verbose("WebSocketTransport", "OnBinary"); + + if (PacketWithAttachment != null) + { + PacketWithAttachment.AddAttachmentFromServer(data, false); + + if (PacketWithAttachment.HasAllAttachment) + { + try + { + OnPacket(PacketWithAttachment); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketTransport", "OnBinary", ex); + } + finally + { + PacketWithAttachment = null; + } + } + } + else + { + // TODO: we received an unwanted binary message? + } + } + + /// + /// WebSocket implementation OnError event handler. + /// + private void OnError(WebSocket ws, Exception ex) + { + if (ws != Implementation) + return; + + string errorStr = string.Empty; + + if (ex != null) + errorStr = (ex.Message + " " + ex.StackTrace); + else + { +#if !UNITY_WEBGL || UNITY_EDITOR + switch (ws.InternalRequest.State) + { + // The request finished without any problem. + case HTTPRequestStates.Finished: + if (ws.InternalRequest.Response.IsSuccess || ws.InternalRequest.Response.StatusCode == 101) + errorStr = string.Format("Request finished. Status Code: {0} Message: {1}", ws.InternalRequest.Response.StatusCode.ToString(), ws.InternalRequest.Response.Message); + else + errorStr = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + ws.InternalRequest.Response.StatusCode, + ws.InternalRequest.Response.Message, + ws.InternalRequest.Response.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + errorStr = "Request Finished with Error! : " + ws.InternalRequest.Exception != null ? (ws.InternalRequest.Exception.Message + " " + ws.InternalRequest.Exception.StackTrace) : string.Empty; + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + errorStr = "Request Aborted!"; + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + errorStr = "Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + errorStr = "Processing the request Timed Out!"; + break; + } +#endif + } + + if (Manager.UpgradingTransport != this) + (Manager as IManager).OnTransportError(this, errorStr); + else + Manager.UpgradingTransport = null; + } + + /// + /// WebSocket implementation OnClosed event handler. + /// + private void OnClosed(WebSocket ws, ushort code, string message) + { + if (ws != Implementation) + return; + + HTTPManager.Logger.Information("WebSocketTransport", "OnClosed"); + + Close(); + + if (Manager.UpgradingTransport != this) + (Manager as IManager).TryToReconnect(); + else + Manager.UpgradingTransport = null; + } + +#endregion + +#region Packet Sending Implementation + + /// + /// A WebSocket implementation of the packet sending. + /// + public void Send(Packet packet) + { + if (State == TransportStates.Closed || + State == TransportStates.Paused) + return; + + string encoded = packet.Encode(); + + if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) + HTTPManager.Logger.Verbose("WebSocketTransport", "Send: " + encoded); + + if (packet.AttachmentCount != 0 || (packet.Attachments != null && packet.Attachments.Count != 0)) + { + if (packet.Attachments == null) + throw new ArgumentException("packet.Attachments are null!"); + + if (packet.AttachmentCount != packet.Attachments.Count) + throw new ArgumentException("packet.AttachmentCount != packet.Attachments.Count. Use the packet.AddAttachment function to add data to a packet!"); + } + + Implementation.Send(encoded); + + if (packet.AttachmentCount != 0) + { + int maxLength = packet.Attachments[0].Length + 1; + for (int cv = 1; cv < packet.Attachments.Count; ++cv) + if ((packet.Attachments[cv].Length + 1) > maxLength) + maxLength = packet.Attachments[cv].Length + 1; + + if (Buffer == null || Buffer.Length < maxLength) + Array.Resize(ref Buffer, maxLength); + + for (int i = 0; i < packet.AttachmentCount; i++) + { + Buffer[0] = (byte)TransportEventTypes.Message; + + Array.Copy(packet.Attachments[i], 0, Buffer, 1, packet.Attachments[i].Length); + + Implementation.Send(Buffer, 0, (ulong)packet.Attachments[i].Length + 1UL); + } + } + } + + /// + /// A WebSocket implementation of the packet sending. + /// + public void Send(List packets) + { + for (int i = 0; i < packets.Count; ++i) + Send(packets[i]); + + packets.Clear(); + } + +#endregion + +#region Packet Handling + + /// + /// Will only process packets that need to upgrade. All other packets are passed to the Manager. + /// + private void OnPacket(Packet packet) + { + switch (packet.TransportEvent) + { + case TransportEventTypes.Open: + if (this.State != TransportStates.Opening) + HTTPManager.Logger.Warning("WebSocketTransport", "Received 'Open' packet while state is '" + State.ToString() + "'"); + else + State = TransportStates.Open; + goto default; + + case TransportEventTypes.Pong: + // Answer for a Ping Probe. + if (packet.Payload == "probe") + { + State = TransportStates.Open; + (Manager as IManager).OnTransportProbed(this); + } + + goto default; + + default: + if (Manager.UpgradingTransport != this) + (Manager as IManager).OnPacket(packet); + break; + } + } + +#endregion + } +} + +#endif +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs.meta new file mode 100644 index 0000000..cdaa9aa --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/SocketIO/Transports/WebSocketTransport.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 28075d7868e0f0845ab98be53d258c85 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Statistics.meta b/Assets/Best HTTP (Pro)/BestHTTP/Statistics.meta new file mode 100644 index 0000000..c4e7719 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Statistics.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c93e4b20636a0bc4085d9712e1ca585d +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs b/Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs new file mode 100644 index 0000000..8d57738 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs @@ -0,0 +1,90 @@ +using System; + +namespace BestHTTP.Statistics +{ + [Flags] + public enum StatisticsQueryFlags : byte + { + /// + /// Connection based statistics will be returned as the result of the query. + /// + Connections = 0x01, + + /// + /// Caching based statistics will be returned as the result of the query. + /// + Cache = 0x02, + + /// + /// Cookie based statistics will be returned as the result of the query. + /// + Cookies = 0x04, + + /// + /// All statistics will be returned as the result of the query. + /// + All = 0xFF, + } + + public struct GeneralStatistics + { + public StatisticsQueryFlags QueryFlags; + + #region Connection Statistics + + /// + /// Number of HTTPConnection instances + /// + public int Connections; + + /// + /// Number of active connections. These connections are currently processing a request. + /// + public int ActiveConnections; + + /// + /// Number of free connections. These connections are finished with there requests and waiting for another request or to recycle. + /// + public int FreeConnections; + + /// + /// Number of recycled connections. These connections will be removed as soon as possible. + /// + public int RecycledConnections; + + /// + /// Number of requests that are waiting in the queue for a free connection. + /// + public int RequestsInQueue; + + #endregion + + #region Cache Statistics + + /// + /// Number of cached responses. + /// + public int CacheEntityCount; + + /// + /// Sum size of the cached responses in bytes. + /// + public ulong CacheSize; + + #endregion + + #region Cookie Statistics + + /// + /// Number of cookies in the Cookie Jar. + /// + public int CookieCount; + + /// + /// Sum size of the stored cookies in bytes. + /// + public uint CookieJarSize; + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs.meta new file mode 100644 index 0000000..fe4e276 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/Statistics/Statistics.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 5f393cb0ae396954a8658922a9824064 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket.meta new file mode 100644 index 0000000..6d10d98 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7b831e0970fca74409c9458a8a6774de +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions.meta new file mode 100644 index 0000000..53aae1e --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5e44072d24b360245b3b38f37c984cee +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs new file mode 100644 index 0000000..cbd807b --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs @@ -0,0 +1,41 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + +using BestHTTP.WebSocket.Frames; + +namespace BestHTTP.WebSocket.Extensions +{ + public interface IExtension + { + /// + /// This is the first pass: here we can add headers to the request to initiate an extension negotiation. + /// + /// + void AddNegotiation(HTTPRequest request); + + /// + /// If the websocket upgrade succeded it will call this function to be able to parse the server's negotiation + /// response. Inside this function the IsEnabled should be set. + /// + bool ParseNegotiation(WebSocketResponse resp); + + /// + /// This function should return a new header flag based on the inFlag parameter. The extension should set only the + /// Rsv1-3 bits in the header. + /// + byte GetFrameHeader(WebSocketFrame writer, byte inFlag); + + /// + /// This function will be called to be able to transform the data that will be sent to the server. + /// + /// + /// + byte[] Encode(WebSocketFrame writer); + + /// + /// This function can be used the decode the server-sent data. + /// + byte[] Decode(byte header, byte[] data); + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs.meta new file mode 100644 index 0000000..9d0c5e9 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/IExtension.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0ef9ac8246255ea449a40171fb654053 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs new file mode 100644 index 0000000..e43ce2d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs @@ -0,0 +1,334 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using BestHTTP.Extensions; +using BestHTTP.WebSocket.Frames; +using BestHTTP.Decompression.Zlib; + +namespace BestHTTP.WebSocket.Extensions +{ + /// + /// Compression Extensions for WebSocket implementation. + /// http://tools.ietf.org/html/rfc7692 + /// + public sealed class PerMessageCompression : IExtension + { + private static readonly byte[] Trailer = new byte[] { 0x00, 0x00, 0xFF, 0xFF }; + + #region Public Properties + + /// + /// By including this extension parameter in an extension negotiation offer, a client informs the peer server + /// of a hint that even if the server doesn't include the "client_no_context_takeover" extension parameter in + /// the corresponding extension negotiation response to the offer, the client is not going to use context takeover. + /// + public bool ClientNoContextTakeover { get; private set; } + + /// + /// By including this extension parameter in an extension negotiation offer, a client prevents the peer server from using context takeover. + /// + public bool ServerNoContextTakeover { get; private set; } + + /// + /// This parameter indicates the base-2 logarithm of the LZ77 sliding window size of the client context. + /// + public int ClientMaxWindowBits { get; private set; } + + /// + /// This parameter indicates the base-2 logarithm of the LZ77 sliding window size of the server context. + /// + public int ServerMaxWindowBits { get; private set; } + + /// + /// The compression level that the client will use to compress the frames. + /// + public CompressionLevel Level { get; private set; } + + /// + /// What minimum data length will trigger the compression. + /// + public int MinimumDataLegthToCompress { get; set; } + + #endregion + + #region Private fields + + /// + /// Cached object to support context takeover. + /// + private System.IO.MemoryStream compressorOutputStream; + private DeflateStream compressorDeflateStream; + + /// + /// Cached object to support context takeover. + /// + private System.IO.MemoryStream decompressorInputStream; + private System.IO.MemoryStream decompressorOutputStream; + private DeflateStream decompressorDeflateStream; + + private byte[] copyBuffer = new byte[1024]; + #endregion + + public PerMessageCompression() + :this(CompressionLevel.Default, false, false, ZlibConstants.WindowBitsMax, ZlibConstants.WindowBitsMax, 10) + { } + + public PerMessageCompression(CompressionLevel level, + bool clientNoContextTakeover, + bool serverNoContextTakeover, + int desiredClientMaxWindowBits, + int desiredServerMaxWindowBits, + int minDatalengthToCompress) + { + this.Level = level; + this.ClientNoContextTakeover = clientNoContextTakeover; + this.ServerNoContextTakeover = ServerNoContextTakeover; + this.ClientMaxWindowBits = desiredClientMaxWindowBits; + this.ServerMaxWindowBits = desiredServerMaxWindowBits; + this.MinimumDataLegthToCompress = minDatalengthToCompress; + } + + #region IExtension Implementation + + /// + /// This will start the permessage-deflate negotiation process. + /// + /// + public void AddNegotiation(HTTPRequest request) + { + // The default header value that we will send out minimum. + string headerValue = "permessage-deflate"; + + + // http://tools.ietf.org/html/rfc7692#section-7.1.1.1 + // A client MAY include the "server_no_context_takeover" extension parameter in an extension negotiation offer. This extension parameter has no value. + // By including this extension parameter in an extension negotiation offer, a client prevents the peer server from using context takeover. + // If the peer server doesn't use context takeover, the client doesn't need to reserve memory to retain the LZ77 sliding window between messages. + if (this.ServerNoContextTakeover) + headerValue += "; server_no_context_takeover"; + + + // http://tools.ietf.org/html/rfc7692#section-7.1.1.2 + // A client MAY include the "client_no_context_takeover" extension parameter in an extension negotiation offer. + // This extension parameter has no value. By including this extension parameter in an extension negotiation offer, + // a client informs the peer server of a hint that even if the server doesn't include the "client_no_context_takeover" + // extension parameter in the corresponding extension negotiation response to the offer, the client is not going to use context takeover. + if (this.ClientNoContextTakeover) + headerValue += "; client_no_context_takeover"; + + // http://tools.ietf.org/html/rfc7692#section-7.1.2.1 + // By including this parameter in an extension negotiation offer, a client limits the LZ77 sliding window size that the server + // will use to compress messages.If the peer server uses a small LZ77 sliding window to compress messages, the client can reduce the memory needed for the LZ77 sliding window. + if (this.ServerMaxWindowBits != ZlibConstants.WindowBitsMax) + headerValue += "; server_max_window_bits=" + this.ServerMaxWindowBits.ToString(); + else + // Absence of this parameter in an extension negotiation offer indicates that the client can receive messages compressed using an LZ77 sliding window of up to 32,768 bytes. + this.ServerMaxWindowBits = ZlibConstants.WindowBitsMax; + + // http://tools.ietf.org/html/rfc7692#section-7.1.2.2 + // By including this parameter in an offer, a client informs the peer server that the client supports the "client_max_window_bits" + // extension parameter in an extension negotiation response and, optionally, a hint by attaching a value to the parameter. + if (this.ClientMaxWindowBits != ZlibConstants.WindowBitsMax) + headerValue += "; client_max_window_bits=" + this.ClientMaxWindowBits.ToString(); + else + { + headerValue += "; client_max_window_bits"; + + // If the "client_max_window_bits" extension parameter in an extension negotiation offer has a value, the parameter also informs the + // peer server of a hint that even if the server doesn't include the "client_max_window_bits" extension parameter in the corresponding + // extension negotiation response with a value greater than the one in the extension negotiation offer or if the server doesn't include + // the extension parameter at all, the client is not going to use an LZ77 sliding window size greater than the size specified + // by the value in the extension negotiation offer to compress messages. + this.ClientMaxWindowBits = ZlibConstants.WindowBitsMax; + } + + // Add the new header to the request. + request.AddHeader("Sec-WebSocket-Extensions", headerValue); + } + + public bool ParseNegotiation(WebSocketResponse resp) + { + // Search for any returned neogitation offer + var headerValues = resp.GetHeaderValues("Sec-WebSocket-Extensions"); + if (headerValues == null) + return false; + + for (int i = 0; i < headerValues.Count; ++i) + { + // If found, tokenize it + HeaderParser parser = new HeaderParser(headerValues[i]); + + for (int cv = 0; cv < parser.Values.Count; ++cv) + { + HeaderValue value = parser.Values[i]; + + if (!string.IsNullOrEmpty(value.Key) && value.Key.StartsWith("permessage-deflate", StringComparison.OrdinalIgnoreCase)) + { + HTTPManager.Logger.Information("PerMessageCompression", "Enabled with header: " + headerValues[i]); + + HeaderValue option; + if (value.TryGetOption("client_no_context_takeover", out option)) + this.ClientNoContextTakeover = true; + + if (value.TryGetOption("server_no_context_takeover", out option)) + this.ServerNoContextTakeover = true; + + if (value.TryGetOption("client_max_window_bits", out option)) + if (option.HasValue) + { + int windowBits; + if (int.TryParse(option.Value, out windowBits)) + this.ClientMaxWindowBits = windowBits; + } + + if (value.TryGetOption("server_max_window_bits", out option)) + if (option.HasValue) + { + int windowBits; + if (int.TryParse(option.Value, out windowBits)) + this.ServerMaxWindowBits = windowBits; + } + + return true; + } + } + } + + return false; + } + + /// + /// IExtension implementation to set the Rsv1 flag in the header if we are we will want to compress the data + /// in the writer. + /// + public byte GetFrameHeader(WebSocketFrame writer, byte inFlag) + { + // http://tools.ietf.org/html/rfc7692#section-7.2.3.1 + // the RSV1 bit is set only on the first frame. + if ((writer.Type == WebSocketFrameTypes.Binary || writer.Type == WebSocketFrameTypes.Text) && + writer.Data != null && writer.Data.Length >= this.MinimumDataLegthToCompress) + return (byte)(inFlag | 0x40); + else + return inFlag; + } + + /// + /// IExtension implementation to be able to compress the data hold in the writer. + /// + public byte[] Encode(WebSocketFrame writer) + { + if (writer.Data == null) + return WebSocketFrame.NoData; + + // Is compressing enabled for this frame? If so, compress it. + if ((writer.Header & 0x40) != 0) + return Compress(writer.Data); + else + return writer.Data; + } + + /// + /// IExtension implementation to possible decompress the data. + /// + public byte[] Decode(byte header, byte[] data) + { + // Is the server compressed the data? If so, decompress it. + if ((header & 0x40) != 0) + return Decompress(data); + else + return data; + } + + #endregion + + #region Private Helper Functions + + /// + /// A function to compress and return the data parameter with possible context takeover support (reusing the DeflateStream). + /// + private byte[] Compress(byte[] data) + { + if (compressorOutputStream == null) + compressorOutputStream = new System.IO.MemoryStream(); + compressorOutputStream.SetLength(0); + + if (compressorDeflateStream == null) + { + compressorDeflateStream = new DeflateStream(compressorOutputStream, CompressionMode.Compress, this.Level, true, this.ClientMaxWindowBits); + compressorDeflateStream.FlushMode = FlushType.Sync; + } + + byte[] result = null; + try + { + compressorDeflateStream.Write(data, 0, data.Length); + compressorDeflateStream.Flush(); + + compressorOutputStream.Position = 0; + + // http://tools.ietf.org/html/rfc7692#section-7.2.1 + // Remove 4 octets (that are 0x00 0x00 0xff 0xff) from the tail end. After this step, the last octet of the compressed data contains (possibly part of) the DEFLATE header bits with the "BTYPE" bits set to 00. + compressorOutputStream.SetLength(compressorOutputStream.Length - 4); + + result = compressorOutputStream.ToArray(); + } + finally + { + if (this.ClientNoContextTakeover) + { + compressorDeflateStream.Dispose(); + compressorDeflateStream = null; + } + } + + return result; + } + + /// + /// A function to decompress and return the data parameter with possible context takeover support (reusing the DeflateStream). + /// + private byte[] Decompress(byte[] data) + { + if (decompressorInputStream == null) + decompressorInputStream = new System.IO.MemoryStream(data.Length + 4); + + decompressorInputStream.Write(data, 0, data.Length); + + // http://tools.ietf.org/html/rfc7692#section-7.2.2 + // Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the payload of the message. + decompressorInputStream.Write(PerMessageCompression.Trailer, 0, PerMessageCompression.Trailer.Length); + + decompressorInputStream.Position = 0; + + if (decompressorDeflateStream == null) + { + decompressorDeflateStream = new DeflateStream(decompressorInputStream, CompressionMode.Decompress, CompressionLevel.Default, true, this.ServerMaxWindowBits); + decompressorDeflateStream.FlushMode = FlushType.Sync; + } + + if (decompressorOutputStream == null) + decompressorOutputStream = new System.IO.MemoryStream(); + decompressorOutputStream.SetLength(0); + + int readCount; + while ((readCount = decompressorDeflateStream.Read(copyBuffer, 0, copyBuffer.Length)) != 0) + decompressorOutputStream.Write(copyBuffer, 0, readCount); + + decompressorDeflateStream.SetLength(0); + + byte[] result = decompressorOutputStream.ToArray(); + + if (this.ServerNoContextTakeover) + { + decompressorDeflateStream.Dispose(); + decompressorDeflateStream = null; + } + + return result; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs.meta new file mode 100644 index 0000000..0acf916 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Extensions/PerMessageCompression.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4c6122052eb4822438f8d080c0f8574f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames.meta new file mode 100644 index 0000000..9bff9d6 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d07681f5c8c854d42b668e7c6f0a8764 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs new file mode 100644 index 0000000..e39d4b8 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs @@ -0,0 +1,170 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; + +namespace BestHTTP.WebSocket.Frames +{ + /// + /// Denotes a binary frame. The "Payload data" is arbitrary binary data whose interpretation is solely up to the application layer. + /// This is the base class of all other frame writers, as all frame can be represented as a byte array. + /// + public sealed class WebSocketFrame + { + public static readonly byte[] NoData = new byte[0]; + + public WebSocketFrameTypes Type { get; private set; } + public bool IsFinal { get; private set; } + public byte Header { get; private set; } + + public byte[] Data { get; private set; } + public bool UseExtensions { get; private set; } + + #region Constructors + + public WebSocketFrame(WebSocket webSocket, WebSocketFrameTypes type, byte[] data) + :this(webSocket, type, data, true) + { } + + public WebSocketFrame(WebSocket webSocket, WebSocketFrameTypes type, byte[] data, bool useExtensions) + : this(webSocket, type, data, 0, data != null ? (UInt64)data.Length : 0, true, useExtensions) + { + } + + public WebSocketFrame(WebSocket webSocket, WebSocketFrameTypes type, byte[] data, bool isFinal, bool useExtensions) + : this(webSocket, type, data, 0, data != null ? (UInt64)data.Length : 0, isFinal, useExtensions) + { + } + + public WebSocketFrame(WebSocket webSocket, WebSocketFrameTypes type, byte[] data, UInt64 pos, UInt64 length, bool isFinal, bool useExtensions) + { + this.Type = type; + this.IsFinal = isFinal; + this.UseExtensions = useExtensions; + + if (data != null) + { + this.Data = new byte[length]; + Array.Copy(data, (int)pos, this.Data, 0, (int)length); + } + else + data = NoData; + + // First byte: Final Bit + Rsv flags + OpCode + byte finalBit = (byte)(IsFinal ? 0x80 : 0x0); + this.Header = (byte)(finalBit | (byte)Type); + + if (this.UseExtensions && webSocket != null && webSocket.Extensions != null) + { + for (int i = 0; i < webSocket.Extensions.Length; ++i) + { + var ext = webSocket.Extensions[i]; + if (ext != null) + { + this.Header |= ext.GetFrameHeader(this, this.Header); + this.Data = ext.Encode(this); + } + } + } + } + + #endregion + + #region Public Functions + + public byte[] Get() + { + if (Data == null) + Data = NoData; + + using (var ms = new MemoryStream(this.Data.Length + 9)) + { + // For the complete documentation for this section see: + // http://tools.ietf.org/html/rfc6455#section-5.2 + + // Write the header + ms.WriteByte(this.Header); + + // The length of the "Payload data", in bytes: if 0-125, that is the payload length. If 126, the following 2 bytes interpreted as a + // 16-bit unsigned integer are the payload length. If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the + // most significant bit MUST be 0) are the payload length. Multibyte length quantities are expressed in network byte order. + if (this.Data.Length < 126) + ms.WriteByte((byte)(0x80 | (byte)this.Data.Length)); + else if (this.Data.Length < UInt16.MaxValue) + { + ms.WriteByte((byte)(0x80 | 126)); + byte[] len = BitConverter.GetBytes((UInt16)this.Data.Length); + if (BitConverter.IsLittleEndian) + Array.Reverse(len, 0, len.Length); + + ms.Write(len, 0, len.Length); + } + else + { + ms.WriteByte((byte)(0x80 | 127)); + byte[] len = BitConverter.GetBytes((UInt64)this.Data.Length); + if (BitConverter.IsLittleEndian) + Array.Reverse(len, 0, len.Length); + + ms.Write(len, 0, len.Length); + } + + // All frames sent from the client to the server are masked by a 32-bit value that is contained within the frame. This field is + // present if the mask bit is set to 1 and is absent if the mask bit is set to 0. + // If the data is being sent by the client, the frame(s) MUST be masked. + byte[] mask = BitConverter.GetBytes((Int32)this.GetHashCode()); + ms.Write(mask, 0, mask.Length); + + // Do the masking. + for (int i = 0; i < this.Data.Length; ++i) + ms.WriteByte((byte)(Data[i] ^ mask[i % 4])); + + return ms.ToArray(); + } + } + + public WebSocketFrame[] Fragment(ushort maxFragmentSize) + { + if (this.Data == null) + return null; + + // All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented. + if (this.Type != WebSocketFrameTypes.Binary && this.Type != WebSocketFrameTypes.Text) + return null; + + if (this.Data.Length <= maxFragmentSize) + return null; + + this.IsFinal = false; + + // Clear final bit from the header flags + this.Header &= 0x7F; + + // One chunk will remain in this fragment, so we have to allocate one less + int count = (this.Data.Length / maxFragmentSize) + (this.Data.Length % maxFragmentSize == 0 ? -1 : 0); + + WebSocketFrame[] fragments = new WebSocketFrame[count]; + + // Skip one chunk, for the current one + UInt64 pos = maxFragmentSize; + while (pos < (UInt64)this.Data.Length) + { + UInt64 chunkLength = Math.Min(maxFragmentSize, (UInt64)this.Data.Length - pos); + + fragments[fragments.Length - count--] = new WebSocketFrame(null, WebSocketFrameTypes.Continuation, this.Data, pos, chunkLength, pos + chunkLength >= (UInt64)this.Data.Length, false); + + pos += chunkLength; + } + + byte[] newData = new byte[maxFragmentSize]; + Array.Copy(this.Data, 0, newData, 0, maxFragmentSize); + this.Data = newData; + + return fragments; + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs.meta new file mode 100644 index 0000000..dcaea16 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrame.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2f674a60005f409438aa505311bf2e7a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs new file mode 100644 index 0000000..475ae0a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs @@ -0,0 +1,201 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.Collections.Generic; +using System.IO; + +using BestHTTP.Extensions; +using BestHTTP.WebSocket.Extensions; + +namespace BestHTTP.WebSocket.Frames +{ + /// + /// Represents an incoming WebSocket Frame. + /// + public sealed class WebSocketFrameReader + { +#region Properties + + public byte Header { get; private set; } + + /// + /// True if it's a final Frame in a sequence, or the only one. + /// + public bool IsFinal { get; private set; } + + /// + /// The type of the Frame. + /// + public WebSocketFrameTypes Type { get; private set; } + + /// + /// Indicates if there are any mask sent to decode the data. + /// + public bool HasMask { get; private set; } + + /// + /// The length of the Data. + /// + public UInt64 Length { get; private set; } + + /// + /// The sent byte array as a mask to decode the data. + /// + public byte[] Mask { get; private set; } + + /// + /// The decoded array of bytes. + /// + public byte[] Data { get; private set; } + + /// + /// Textual representation of the received Data. + /// + public string DataAsText { get; private set; } + + #endregion + + #region Internal & Private Functions + + internal void Read(Stream stream) + { + // For the complete documentation for this section see: + // http://tools.ietf.org/html/rfc6455#section-5.2 + + this.Header = ReadByte(stream); + + // The first byte is the Final Bit and the type of the frame + IsFinal = (this.Header & 0x80) != 0; + Type = (WebSocketFrameTypes)(this.Header & 0xF); + + byte maskAndLength = ReadByte(stream); + + // The second byte is the Mask Bit and the length of the payload data + HasMask = (maskAndLength & 0x80) != 0; + + // if 0-125, that is the payload length. + Length = (UInt64)(maskAndLength & 127); + + // If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length. + if (Length == 126) + { + byte[] rawLen = new byte[2]; + stream.ReadBuffer(rawLen); + + if (BitConverter.IsLittleEndian) + Array.Reverse(rawLen, 0, rawLen.Length); + + Length = (UInt64)BitConverter.ToUInt16(rawLen, 0); + } + else if (Length == 127) + { + // If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the + // most significant bit MUST be 0) are the payload length. + + byte[] rawLen = new byte[8]; + stream.ReadBuffer(rawLen); + + if (BitConverter.IsLittleEndian) + Array.Reverse(rawLen, 0, rawLen.Length); + + Length = (UInt64)BitConverter.ToUInt64(rawLen, 0); + } + + // Read the Mask, if has any + if (HasMask) + { + Mask = new byte[4]; + if (stream.Read(Mask, 0, 4) < Mask.Length) + throw ExceptionHelper.ServerClosedTCPStream(); + } + + Data = new byte[Length]; + + if (Length == 0L) + return; + + int readLength = 0; + + do + { + int read = stream.Read(Data, readLength, Data.Length - readLength); + + if (read <= 0) + throw ExceptionHelper.ServerClosedTCPStream(); + + readLength += read; + } while (readLength < Data.Length); + + // It would be great to speed this up with SSE + if (HasMask) + for (int i = 0; i < Data.Length; ++i) + Data[i] = (byte)(Data[i] ^ Mask[i % 4]); + } + + private byte ReadByte(Stream stream) + { + int read = stream.ReadByte(); + + if (read < 0) + throw ExceptionHelper.ServerClosedTCPStream(); + + return (byte)read; + } + + #endregion + + #region Public Functions + + /// + /// Assembles all fragments into a final frame. Call this on the last fragment of a frame. + /// + /// The list of previously downloaded and parsed fragments of the frame + public void Assemble(List fragments) + { + // this way the following algorithms will handle this fragment's data too + fragments.Add(this); + + UInt64 finalLength = 0; + for (int i = 0; i < fragments.Count; ++i) + finalLength += fragments[i].Length; + + byte[] buffer = new byte[finalLength]; + UInt64 pos = 0; + for (int i = 0; i < fragments.Count; ++i) + { + Array.Copy(fragments[i].Data, 0, buffer, (int)pos, (int)fragments[i].Length); + pos += fragments[i].Length; + } + + // All fragments of a message are of the same type, as set by the first fragment's opcode. + this.Type = fragments[0].Type; + + // Reserver flags may be contained only in the first fragment + + this.Header = fragments[0].Header; + this.Length = finalLength; + this.Data = buffer; + } + + /// + /// This function will decode the received data incrementally with the associated websocket's extensions. + /// + public void DecodeWithExtensions(WebSocket webSocket) + { + if (webSocket.Extensions != null) + for (int i = 0; i < webSocket.Extensions.Length; ++i) + { + var ext = webSocket.Extensions[i]; + if (ext != null) + this.Data = ext.Decode(this.Header, this.Data); + } + + if (this.Type == WebSocketFrameTypes.Text && this.Data != null) + this.DataAsText = System.Text.Encoding.UTF8.GetString(this.Data, 0, this.Data.Length); + } + + #endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs.meta new file mode 100644 index 0000000..652a61d --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameReader.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 551161b05e7dd8c4d85aadf44c841056 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs new file mode 100644 index 0000000..168d1f4 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs @@ -0,0 +1,48 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + +namespace BestHTTP.WebSocket.Frames +{ + public enum WebSocketFrameTypes : byte + { + /// + /// A fragmented message's first frame's contain the type of the message(binary or text), all consecutive frame of that message must be a Continuation frame. + /// Last of these frame's Fin bit must be 1. + /// + /// For a text message sent as three fragments, the first fragment would have an opcode of 0x1 (text) and a FIN bit clear, + /// the second fragment would have an opcode of 0x0 (Continuation) and a FIN bit clear, + /// and the third fragment would have an opcode of 0x0 (Continuation) and a FIN bit that is set. + Continuation = 0x0, + Text = 0x1, + Binary = 0x2, + //Reserved1 = 0x3, + //Reserved2 = 0x4, + //Reserved3 = 0x5, + //Reserved4 = 0x6, + //Reserved5 = 0x7, + + /// + /// The Close frame MAY contain a body (the "Application data" portion of the frame) that indicates a reason for closing, + /// such as an endpoint shutting down, an endpoint having received a frame too large, or an endpoint having received a frame that + /// does not conform to the format expected by the endpoint. + /// As the data is not guaranteed to be human readable, clients MUST NOT show it to end users. + /// + ConnectionClose = 0x8, + + /// + /// The Ping frame contains an opcode of 0x9. A Ping frame MAY include "Application data". + /// + Ping = 0x9, + + /// + /// A Pong frame sent in response to a Ping frame must have identical "Application data" as found in the message body of the Ping frame being replied to. + /// + Pong = 0xA, + //Reserved6 = 0xB, + //Reserved7 = 0xC, + //Reserved8 = 0xD, + //Reserved9 = 0xE, + //Reserved10 = 0xF, + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs.meta new file mode 100644 index 0000000..b274244 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/Frames/WebSocketFrameTypes.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 111b231c861908546b2c5acfa6d69bae +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs new file mode 100644 index 0000000..b76d1cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs @@ -0,0 +1,827 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET + +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using BestHTTP.Extensions; + +#if UNITY_WEBGL && !UNITY_EDITOR + using System.Runtime.InteropServices; +#else + using BestHTTP.WebSocket.Frames; + using BestHTTP.WebSocket.Extensions; +#endif + +namespace BestHTTP.WebSocket +{ + /// + /// States of the underlying browser's WebSocket implementation's state. + /// + public enum WebSocketStates : byte + { + Connecting = 0, + Open = 1, + Closing = 2, + Closed = 3, + Unknown + }; + + public delegate void OnWebSocketOpenDelegate(WebSocket webSocket); + public delegate void OnWebSocketMessageDelegate(WebSocket webSocket, string message); + public delegate void OnWebSocketBinaryDelegate(WebSocket webSocket, byte[] data); + public delegate void OnWebSocketClosedDelegate(WebSocket webSocket, UInt16 code, string message); + public delegate void OnWebSocketErrorDelegate(WebSocket webSocket, Exception ex); + public delegate void OnWebSocketErrorDescriptionDelegate(WebSocket webSocket, string reason); + +#if (!UNITY_WEBGL || UNITY_EDITOR) + public delegate void OnWebSocketIncompleteFrameDelegate(WebSocket webSocket, WebSocketFrameReader frame); +#else + delegate void OnWebGLWebSocketOpenDelegate(uint id); + delegate void OnWebGLWebSocketTextDelegate(uint id, string text); + delegate void OnWebGLWebSocketBinaryDelegate(uint id, IntPtr pBuffer, int length); + delegate void OnWebGLWebSocketErrorDelegate(uint id, string error); + delegate void OnWebGLWebSocketCloseDelegate(uint id, int code, string reason); +#endif + + public sealed class WebSocket + { +#region Properties + +#if !UNITY_WEBGL || UNITY_EDITOR + public WebSocketStates State { get; private set; } +#else + public WebSocketStates State { get { return ImplementationId != 0 ? WS_GetState(ImplementationId) : WebSocketStates.Unknown; } } +#endif + + /// + /// The connection to the WebSocket server is open. + /// + public bool IsOpen + { + get + { +#if (!UNITY_WEBGL || UNITY_EDITOR) + return webSocket != null && !webSocket.IsClosed; +#else + return ImplementationId != 0 && WS_GetState(ImplementationId) == WebSocketStates.Open; +#endif + } + } + + public int BufferedAmount + { + get + { +#if (!UNITY_WEBGL || UNITY_EDITOR) + return webSocket.BufferedAmount; +#else + return WS_GetBufferedAmount(ImplementationId); +#endif + } + } + +#if (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Set to true to start a new thread to send Pings to the WebSocket server + /// + public bool StartPingThread { get; set; } + + /// + /// The delay between two Pings in millisecs. Minimum value is 100, default is 1000. + /// + public int PingFrequency { get; set; } + + /// + /// If StartPingThread set to true, the plugin will close the connection and emit an OnError/OnErrorDesc event if no + /// message is received from the server in the given time. Its default value is 10 sec. + /// + public TimeSpan CloseAfterNoMesssage { get; set; } + + /// + /// The internal HTTPRequest object. + /// + public HTTPRequest InternalRequest { get; private set; } + + /// + /// IExtension implementations the plugin will negotiate with the server to use. + /// + public IExtension[] Extensions { get; private set; } + + /// + /// Latency calculated from the ping-pong message round-trip times. + /// + public int Latency { get { return webSocket.Latency; } } + +#endif + + /// + /// Called when the connection to the WebSocket server is established. + /// + public OnWebSocketOpenDelegate OnOpen; + + /// + /// Called when a new textual message is received from the server. + /// + public OnWebSocketMessageDelegate OnMessage; + + /// + /// Called when a new binary message is received from the server. + /// + public OnWebSocketBinaryDelegate OnBinary; + + /// + /// Called when the WebSocket connection is closed. + /// + public OnWebSocketClosedDelegate OnClosed; + + /// + /// Called when an error is encountered. The Exception parameter may be null. + /// + public OnWebSocketErrorDelegate OnError; + + /// + /// Called when an error is encountered. The parameter will be the description of the error. + /// + public OnWebSocketErrorDescriptionDelegate OnErrorDesc; + +#if (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Called when an incomplete frame received. No attempt will be made to reassemble these fragments internally, and no reference are stored after this event to this frame. + /// + public OnWebSocketIncompleteFrameDelegate OnIncompleteFrame; +#endif + + #endregion + + #region Private Fields + +#if (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// Indicates wheter we sent out the connection request to the server. + /// + private bool requestSent; + + /// + /// The internal WebSocketResponse object + /// + private WebSocketResponse webSocket; +#else + internal static Dictionary WebSockets = new Dictionary(); + + private uint ImplementationId; + private Uri Uri; + private string Protocol; + +#endif + + #endregion + + #region Constructors + + /// + /// Creates a WebSocket instance from the given uri. + /// + /// The uri of the WebSocket server + public WebSocket(Uri uri) + :this(uri, string.Empty, string.Empty) + { +#if (!UNITY_WEBGL || UNITY_EDITOR) && !BESTHTTP_DISABLE_GZIP + this.Extensions = new IExtension[] { new PerMessageCompression(/*compression level: */ Decompression.Zlib.CompressionLevel.Default, + /*clientNoContextTakeover: */ false, + /*serverNoContextTakeover: */ false, + /*clientMaxWindowBits: */ Decompression.Zlib.ZlibConstants.WindowBitsMax, + /*desiredServerMaxWindowBits: */ Decompression.Zlib.ZlibConstants.WindowBitsMax, + /*minDatalengthToCompress: */ 5) }; +#endif + } + + /// + /// Creates a WebSocket instance from the given uri, protocol and origin. + /// + /// The uri of the WebSocket server + /// Servers that are not intended to process input from any web page but only for certain sites SHOULD verify the |Origin| field is an origin they expect. + /// If the origin indicated is unacceptable to the server, then it SHOULD respond to the WebSocket handshake with a reply containing HTTP 403 Forbidden status code. + /// The application-level protocol that the client want to use(eg. "chat", "leaderboard", etc.). Can be null or empty string if not used. + /// Optional IExtensions implementations + public WebSocket(Uri uri, string origin, string protocol +#if !UNITY_WEBGL || UNITY_EDITOR + , params IExtension[] extensions +#endif + ) + + { + string scheme = HTTPProtocolFactory.IsSecureProtocol(uri) ? "wss" : "ws"; + int port = uri.Port != -1 ? uri.Port : (scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) ? 443 : 80); + + // Somehow if i use the UriBuilder it's not the same as if the uri is constructed from a string... + //uri = new UriBuilder(uri.Scheme, uri.Host, uri.Scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) ? 443 : 80, uri.PathAndQuery).Uri; + uri = new Uri(scheme + "://" + uri.Host + ":" + port + uri.GetRequestPathAndQueryURL()); + +#if !UNITY_WEBGL || UNITY_EDITOR + // Set up some default values. + this.PingFrequency = 1000; + this.CloseAfterNoMesssage = TimeSpan.FromSeconds(10); + + InternalRequest = new HTTPRequest(uri, OnInternalRequestCallback); + + // Called when the regular GET request is successfully upgraded to WebSocket + InternalRequest.OnUpgraded = OnInternalRequestUpgraded; + + //http://tools.ietf.org/html/rfc6455#section-4 + + //The request MUST contain a |Host| header field whose value contains /host/ plus optionally ":" followed by /port/ (when not using the default port). + if (uri.Port != 80) + InternalRequest.SetHeader("Host", uri.Host + ":" + uri.Port); + else + InternalRequest.SetHeader("Host", uri.Host); + + // The request MUST contain an |Upgrade| header field whose value MUST include the "websocket" keyword. + InternalRequest.SetHeader("Upgrade", "websocket"); + + // The request MUST contain a |Connection| header field whose value MUST include the "Upgrade" token. + InternalRequest.SetHeader("Connection", "keep-alive, Upgrade"); + + // The request MUST include a header field with the name |Sec-WebSocket-Key|. The value of this header field MUST be a nonce consisting of a + // randomly selected 16-byte value that has been base64-encoded (see Section 4 of [RFC4648]). The nonce MUST be selected randomly for each connection. + InternalRequest.SetHeader("Sec-WebSocket-Key", GetSecKey(new object[] { this, InternalRequest, uri, new object() })); + + // The request MUST include a header field with the name |Origin| [RFC6454] if the request is coming from a browser client. + // If the connection is from a non-browser client, the request MAY include this header field if the semantics of that client match the use-case described here for browser clients. + // More on Origin Considerations: http://tools.ietf.org/html/rfc6455#section-10.2 + if (!string.IsNullOrEmpty(origin)) + InternalRequest.SetHeader("Origin", origin); + + // The request MUST include a header field with the name |Sec-WebSocket-Version|. The value of this header field MUST be 13. + InternalRequest.SetHeader("Sec-WebSocket-Version", "13"); + + if (!string.IsNullOrEmpty(protocol)) + InternalRequest.SetHeader("Sec-WebSocket-Protocol", protocol); + + // Disable caching + InternalRequest.SetHeader("Cache-Control", "no-cache"); + InternalRequest.SetHeader("Pragma", "no-cache"); + + this.Extensions = extensions; + +#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR) + InternalRequest.DisableCache = true; + InternalRequest.DisableRetry = true; +#endif + + InternalRequest.TryToMinimizeTCPLatency = true; + +#if !BESTHTTP_DISABLE_PROXY + // WebSocket is not a request-response based protocol, so we need a 'tunnel' through the proxy + if (HTTPManager.Proxy != null) + InternalRequest.Proxy = new HTTPProxy(HTTPManager.Proxy.Address, + HTTPManager.Proxy.Credentials, + false, /*turn on 'tunneling'*/ + false, /*sendWholeUri*/ + HTTPManager.Proxy.NonTransparentForHTTPS); +#endif +#else + this.Uri = uri; + this.Protocol = protocol; +#endif + + HTTPManager.Setup(); + } + +#endregion + +#region Request Callbacks + +#if (!UNITY_WEBGL || UNITY_EDITOR) + private void OnInternalRequestCallback(HTTPRequest req, HTTPResponse resp) + { + string reason = string.Empty; + + switch (req.State) + { + case HTTPRequestStates.Finished: + if (resp.IsSuccess || resp.StatusCode == 101) + { + // The request finished without any problem. + HTTPManager.Logger.Information("WebSocket", string.Format("Request finished. Status Code: {0} Message: {1}", resp.StatusCode.ToString(), resp.Message)); + + return; + } + else + reason = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", + resp.StatusCode, + resp.Message, + resp.DataAsText); + break; + + // The request finished with an unexpected error. The request's Exception property may contain more info about the error. + case HTTPRequestStates.Error: + reason = "Request Finished with Error! " + (req.Exception != null ? ("Exception: " + req.Exception.Message + req.Exception.StackTrace) : string.Empty); + break; + + // The request aborted, initiated by the user. + case HTTPRequestStates.Aborted: + reason = "Request Aborted!"; + break; + + // Connecting to the server is timed out. + case HTTPRequestStates.ConnectionTimedOut: + reason = "Connection Timed Out!"; + break; + + // The request didn't finished in the given time. + case HTTPRequestStates.TimedOut: + reason = "Processing the request Timed Out!"; + break; + + default: + return; + } + + if (this.State != WebSocketStates.Connecting || !string.IsNullOrEmpty(reason)) + { + if (OnError != null) + OnError(this, req.Exception); + + if (OnErrorDesc != null) + OnErrorDesc(this, reason); + + if (OnError == null && OnErrorDesc == null) + HTTPManager.Logger.Error("WebSocket", reason); + } + else if (OnClosed != null) + OnClosed(this, (ushort)WebSocketStausCodes.NormalClosure, "Closed while opening"); + + if (!req.IsKeepAlive && resp != null && resp is WebSocketResponse) + (resp as WebSocketResponse).CloseStream(); + } + + private void OnInternalRequestUpgraded(HTTPRequest req, HTTPResponse resp) + { + webSocket = resp as WebSocketResponse; + + if (webSocket == null) + { + if (OnError != null) + OnError(this, req.Exception); + + if (OnErrorDesc != null) + { + string reason = string.Empty; + if (req.Exception != null) + reason = req.Exception.Message + " " + req.Exception.StackTrace; + + OnErrorDesc(this, reason); + } + + this.State = WebSocketStates.Closed; + return; + } + + // If Close called while we connected + if (this.State == WebSocketStates.Closed) + { + webSocket.CloseStream(); + return; + } + + webSocket.WebSocket = this; + + if (this.Extensions != null) + { + for (int i = 0; i < this.Extensions.Length; ++i) + { + var ext = this.Extensions[i]; + + try + { + if (ext != null && !ext.ParseNegotiation(webSocket)) + this.Extensions[i] = null; // Keep extensions only that successfully negotiated + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "ParseNegotiation", ex); + + // Do not try to use a defective extension in the future + this.Extensions[i] = null; + } + } + } + + this.State = WebSocketStates.Open; + if (OnOpen != null) + { + try + { + OnOpen(this); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnOpen", ex); + } + } + + webSocket.OnText = (ws, msg) => + { + if (OnMessage != null) + OnMessage(this, msg); + }; + + webSocket.OnBinary = (ws, bin) => + { + if (OnBinary != null) + OnBinary(this, bin); + }; + + webSocket.OnClosed = (ws, code, msg) => + { + this.State = WebSocketStates.Closed; + + if (OnClosed != null) + OnClosed(this, code, msg); + }; + + if (OnIncompleteFrame != null) + webSocket.OnIncompleteFrame = (ws, frame) => + { + if (OnIncompleteFrame != null) + OnIncompleteFrame(this, frame); + }; + + if (StartPingThread) + webSocket.StartPinging(Math.Max(PingFrequency, 100)); + + webSocket.StartReceive(); + } +#endif + +#endregion + +#region Public Interface + + /// + /// Start the opening process. + /// + public void Open() + { +#if (!UNITY_WEBGL || UNITY_EDITOR) + if (requestSent) + throw new InvalidOperationException("Open already called! You can't reuse this WebSocket instance!"); + + if (this.Extensions != null) + { + try + { + for (int i = 0; i < this.Extensions.Length; ++i) + { + var ext = this.Extensions[i]; + if (ext != null) + ext.AddNegotiation(InternalRequest); + } + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "Open", ex); + } + } + + InternalRequest.Send(); + requestSent = true; + this.State = WebSocketStates.Connecting; +#else + try + { + ImplementationId = WS_Create(this.Uri.OriginalString, this.Protocol, OnOpenCallback, OnTextCallback, OnBinaryCallback, OnErrorCallback, OnCloseCallback); + WebSockets.Add(ImplementationId, this); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "Open", ex); + } +#endif + } + + /// + /// It will send the given message to the server in one frame. + /// + public void Send(string message) + { + if (!IsOpen) + return; + +#if (!UNITY_WEBGL || UNITY_EDITOR) + webSocket.Send(message); +#else + WS_Send_String(this.ImplementationId, message); +#endif + } + + /// + /// It will send the given data to the server in one frame. + /// + public void Send(byte[] buffer) + { + if (!IsOpen) + return; +#if (!UNITY_WEBGL || UNITY_EDITOR) + webSocket.Send(buffer); +#else + WS_Send_Binary(this.ImplementationId, buffer, 0, buffer.Length); +#endif + } + + /// + /// Will send count bytes from a byte array, starting from offset. + /// + public void Send(byte[] buffer, ulong offset, ulong count) + { + if (!IsOpen) + return; +#if (!UNITY_WEBGL || UNITY_EDITOR) + webSocket.Send(buffer, offset, count); +#else + WS_Send_Binary(this.ImplementationId, buffer, (int)offset, (int)count); +#endif + } + +#if (!UNITY_WEBGL || UNITY_EDITOR) + /// + /// It will send the given frame to the server. + /// + public void Send(WebSocketFrame frame) + { + if (IsOpen) + webSocket.Send(frame); + } +#endif + + /// + /// It will initiate the closing of the connection to the server. + /// + public void Close() + { + if (State >= WebSocketStates.Closing) + return; + +#if !UNITY_WEBGL || UNITY_EDITOR + if (this.State == WebSocketStates.Connecting) + { + this.State = WebSocketStates.Closed; + if (OnClosed != null) + OnClosed(this, (ushort)WebSocketStausCodes.NoStatusCode, string.Empty); + } + else + { + this.State = WebSocketStates.Closing; + webSocket.Close(); + } +#else + WS_Close(this.ImplementationId, 1000, "Bye!"); +#endif + } + + /// + /// It will initiate the closing of the connection to the server sending the given code and message. + /// + public void Close(UInt16 code, string message) + { + if (!IsOpen) + return; +#if (!UNITY_WEBGL || UNITY_EDITOR) + webSocket.Close(code, message); +#else + WS_Close(this.ImplementationId, code, message); +#endif + } + + public static byte[] EncodeCloseData(UInt16 code, string message) + { + //If there is a body, the first two bytes of the body MUST be a 2-byte unsigned integer + // (in network byte order) representing a status code with value /code/ defined in Section 7.4 (http://tools.ietf.org/html/rfc6455#section-7.4). Following the 2-byte integer, + // the body MAY contain UTF-8-encoded data with value /reason/, the interpretation of which is not defined by this specification. + // This data is not necessarily human readable but may be useful for debugging or passing information relevant to the script that opened the connection. + int msgLen = Encoding.UTF8.GetByteCount(message); + using (MemoryStream ms = new MemoryStream(2 + msgLen)) + { + byte[] buff = BitConverter.GetBytes(code); + if (BitConverter.IsLittleEndian) + Array.Reverse(buff, 0, buff.Length); + + ms.Write(buff, 0, buff.Length); + + buff = Encoding.UTF8.GetBytes(message); + ms.Write(buff, 0, buff.Length); + + return ms.ToArray(); + } + } + +#endregion + +#region Private Helpers + +#if !UNITY_WEBGL || UNITY_EDITOR + private string GetSecKey(object[] from) + { + byte[] keys = new byte[16]; + int pos = 0; + + for (int i = 0; i < from.Length; ++i) + { + byte[] hash = BitConverter.GetBytes((Int32)from[i].GetHashCode()); + + for (int cv = 0; cv < hash.Length && pos < keys.Length; ++cv) + keys[pos++] = hash[cv]; + } + + return Convert.ToBase64String(keys); + } +#endif + +#endregion + +#region WebGL Static Callbacks +#if UNITY_WEBGL && !UNITY_EDITOR + + [AOT.MonoPInvokeCallback(typeof(OnWebGLWebSocketOpenDelegate))] + static void OnOpenCallback(uint id) + { + WebSocket ws; + if (WebSockets.TryGetValue(id, out ws)) + { + if (ws.OnOpen != null) + { + try + { + ws.OnOpen(ws); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnOpen", ex); + } + } + } + else + HTTPManager.Logger.Warning("WebSocket", "OnOpenCallback - No WebSocket found for id: " + id.ToString()); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLWebSocketTextDelegate))] + static void OnTextCallback(uint id, string text) + { + WebSocket ws; + if (WebSockets.TryGetValue(id, out ws)) + { + if (ws.OnMessage != null) + { + try + { + ws.OnMessage(ws, text); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnMessage", ex); + } + } + } + else + HTTPManager.Logger.Warning("WebSocket", "OnTextCallback - No WebSocket found for id: " + id.ToString()); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLWebSocketBinaryDelegate))] + static void OnBinaryCallback(uint id, IntPtr pBuffer, int length) + { + WebSocket ws; + if (WebSockets.TryGetValue(id, out ws)) + { + if (ws.OnBinary != null) + { + try + { + byte[] buffer = new byte[length]; + + // Copy data from the 'unmanaged' memory to managed memory. Buffer will be reclaimed by the GC. + Marshal.Copy(pBuffer, buffer, 0, length); + + ws.OnBinary(ws, buffer); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnBinary", ex); + } + } + } + else + HTTPManager.Logger.Warning("WebSocket", "OnBinaryCallback - No WebSocket found for id: " + id.ToString()); + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLWebSocketErrorDelegate))] + static void OnErrorCallback(uint id, string error) + { + WebSocket ws; + if (WebSockets.TryGetValue(id, out ws)) + { + WebSockets.Remove(id); + + if (ws.OnError != null) + { + try + { + ws.OnError(ws, new Exception(error)); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnError", ex); + } + } + + if (ws.OnErrorDesc != null) + { + try + { + ws.OnErrorDesc(ws, error); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnErrorDesc", ex); + } + } + } + else + HTTPManager.Logger.Warning("WebSocket", "OnErrorCallback - No WebSocket found for id: " + id.ToString()); + + try + { + WS_Release(id); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "WS_Release", ex); + } + } + + [AOT.MonoPInvokeCallback(typeof(OnWebGLWebSocketCloseDelegate))] + static void OnCloseCallback(uint id, int code, string reason) + { + WebSocket ws; + if (WebSockets.TryGetValue(id, out ws)) + { + WebSockets.Remove(id); + + if (ws.OnClosed != null) + { + try + { + ws.OnClosed(ws, (ushort)code, reason); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "OnClosed", ex); + } + } + } + else + HTTPManager.Logger.Warning("WebSocket", "OnCloseCallback - No WebSocket found for id: " + id.ToString()); + + try + { + WS_Release(id); + } + catch(Exception ex) + { + HTTPManager.Logger.Exception("WebSocket", "WS_Release", ex); + } + } + +#endif +#endregion + +#region WebGL Interface +#if UNITY_WEBGL && !UNITY_EDITOR + + [DllImport("__Internal")] + static extern uint WS_Create(string url, string protocol, OnWebGLWebSocketOpenDelegate onOpen, OnWebGLWebSocketTextDelegate onText, OnWebGLWebSocketBinaryDelegate onBinary, OnWebGLWebSocketErrorDelegate onError, OnWebGLWebSocketCloseDelegate onClose); + + [DllImport("__Internal")] + static extern WebSocketStates WS_GetState(uint id); + + [DllImport("__Internal")] + static extern int WS_GetBufferedAmount(uint id); + + [DllImport("__Internal")] + static extern int WS_Send_String(uint id, string strData); + + [DllImport("__Internal")] + static extern int WS_Send_Binary(uint id, byte[] buffer, int pos, int length); + + [DllImport("__Internal")] + static extern void WS_Close(uint id, ushort code, string reason); + + [DllImport("__Internal")] + static extern void WS_Release(uint id); + +#endif +#endregion + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs.meta new file mode 100644 index 0000000..be2a0c3 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocket.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 32e0cd2913acd794aa3fc7d414fe78e4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs new file mode 100644 index 0000000..2b7302f --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs @@ -0,0 +1,705 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET && (!UNITY_WEBGL || UNITY_EDITOR) + +using System; +using System.IO; +using System.Threading; +using System.Collections.Generic; +using System.Text; + +using BestHTTP.Extensions; +using BestHTTP.WebSocket.Frames; + +namespace BestHTTP.WebSocket +{ + public sealed class WebSocketResponse : HTTPResponse, IHeartbeat, IProtocol + { + /// + /// Capacity of the RTT buffer where the latencies are kept. + /// + public static int RTTBufferCapacity = 5; + + #region Public Interface + + /// + /// A reference to the original WebSocket instance. Used for accessing extensions. + /// + public WebSocket WebSocket { get; internal set; } + + /// + /// Called when a Text message received + /// + public Action OnText; + + /// + /// Called when a Binary message received + /// + public Action OnBinary; + + /// + /// Called when an incomplete frame received. No attempt will be made to reassemble these fragments. + /// + public Action OnIncompleteFrame; + + /// + /// Called when the connection closed. + /// + public Action OnClosed; + + /// + /// Indicates whether the connection to the server is closed or not. + /// + public bool IsClosed { get { return closed; } } + + /// + /// On what frequency we have to send a ping to the server. + /// + public TimeSpan PingFrequnecy { get; private set; } + + /// + /// Maximum size of a fragment's payload data. Its default value is 32767. + /// + public UInt16 MaxFragmentSize { get; private set; } + + /// + /// Length of unsent, buffered up data in bytes. + /// + public int BufferedAmount { get { return this._bufferedAmount; } } + private int _bufferedAmount; + + /// + /// Calculated latency from the Round-Trip Times we store in the rtts field. + /// + public int Latency { get; private set; } + + #endregion + + #region Private Fields + + private List IncompleteFrames = new List(); + private List CompletedFrames = new List(); + private List frameCache = new List(); + private WebSocketFrameReader CloseFrame; + + private object FrameLock = new object(); + private object SendLock = new object(); + + private List unsentFrames = new List(); + private AutoResetEvent newFrameSignal = new AutoResetEvent(false); + private volatile bool sendThreadCreated = false; + + /// + /// True if we sent out a Close message to the server + /// + private volatile bool closeSent; + + /// + /// True if this WebSocket connection is closed + /// + private volatile bool closed; + + /// + /// When we sent out the last ping. + /// + private DateTime lastPing = DateTime.MinValue; + + /// + /// When we received the last pong. + /// + private DateTime lastMessage = DateTime.MinValue; + + /// + /// A circular buffer to store the last N rtt times calculated by the pong messages. + /// + private CircularBuffer rtts = new CircularBuffer(WebSocketResponse.RTTBufferCapacity); + + #endregion + + internal WebSocketResponse(HTTPRequest request, Stream stream, bool isStreamed, bool isFromCache) + : base(request, stream, isStreamed, isFromCache) + { + base.IsClosedManually = true; + + closed = false; + MaxFragmentSize = UInt16.MaxValue / 2; + } + + internal void StartReceive() + { + if (IsUpgraded) + { +#if NETFX_CORE + #pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(ReceiveThreadFunc); + #pragma warning restore 4014 +#else + ThreadPool.QueueUserWorkItem(ReceiveThreadFunc); +#endif + } + } + + internal void CloseStream() + { + var conn = HTTPManager.GetConnectionWith(this.baseRequest); + if (conn != null) + conn.Abort(HTTPConnectionStates.Closed); + } + + #region Public interface for interacting with the server + + /// + /// It will send the given message to the server in one frame. + /// + public void Send(string message) + { + if (message == null) + throw new ArgumentNullException("message must not be null!"); + + byte[] data = System.Text.Encoding.UTF8.GetBytes(message); + + Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Text, data)); + } + + /// + /// It will send the given data to the server in one frame. + /// + public void Send(byte[] data) + { + if (data == null) + throw new ArgumentNullException("data must not be null!"); + + WebSocketFrame frame = new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Binary, data); + + if (frame.Data != null && frame.Data.Length > this.MaxFragmentSize) + { + WebSocketFrame[] additionalFrames = frame.Fragment(this.MaxFragmentSize); + + lock(SendLock) + { + Send(frame); + if (additionalFrames != null) + for (int i = 0; i < additionalFrames.Length; ++i) + Send(additionalFrames[i]); + } + } + else + Send(frame); + } + + /// + /// Will send count bytes from a byte array, starting from offset. + /// + public void Send(byte[] data, ulong offset, ulong count) + { + if (data == null) + throw new ArgumentNullException("data must not be null!"); + if (offset + count > (ulong)data.Length) + throw new ArgumentOutOfRangeException("offset + count >= data.Length"); + + WebSocketFrame frame = new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Binary, data, offset, count, true, true); + + if (frame.Data != null && frame.Data.Length > this.MaxFragmentSize) + { + WebSocketFrame[] additionalFrames = frame.Fragment(this.MaxFragmentSize); + + lock (SendLock) + { + Send(frame); + + if (additionalFrames != null) + for (int i = 0; i < additionalFrames.Length; ++i) + Send(additionalFrames[i]); + } + } + else + Send(frame); + } + + /// + /// It will send the given frame to the server. + /// + public void Send(WebSocketFrame frame) + { + if (frame == null) + throw new ArgumentNullException("frame is null!"); + + if (closed || closeSent) + return; + + lock (SendLock) + { + this.unsentFrames.Add(frame); + + if (!sendThreadCreated) + { + HTTPManager.Logger.Information("WebSocketResponse", "Send - Creating thread"); +#if NETFX_CORE +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(SendThreadFunc); +#pragma warning restore 4014 +#else + ThreadPool.QueueUserWorkItem(SendThreadFunc); +#endif + sendThreadCreated = true; + } + } + + Interlocked.Add(ref this._bufferedAmount, frame.Data != null ? frame.Data.Length : 0); + + //if (HTTPManager.Logger.Level <= Logger.Loglevels.All) + // HTTPManager.Logger.Information("WebSocketResponse", "Signaling SendThread!"); + + newFrameSignal.Set(); + } + + /// + /// It will send the given frame to the server by inserting the frame into the queue as the first element. + /// + public void Insert(WebSocketFrame frame) + { + if (frame == null) + throw new ArgumentNullException("frame is null!"); + + if (closed || closeSent) + return; + + lock (SendLock) + { + this.unsentFrames.Insert(0, frame); + + if (!sendThreadCreated) + { + HTTPManager.Logger.Information("WebSocketResponse", "Insert - Creating thread"); +#if NETFX_CORE +#pragma warning disable 4014 + Windows.System.Threading.ThreadPool.RunAsync(SendThreadFunc); +#pragma warning restore 4014 +#else + ThreadPool.QueueUserWorkItem(SendThreadFunc); +#endif + sendThreadCreated = true; + } + } + + Interlocked.Add(ref this._bufferedAmount, frame.Data != null ? frame.Data.Length : 0); + + newFrameSignal.Set(); + } + + public void SendNow(WebSocketFrame frame) + { + if (frame == null) + throw new ArgumentNullException("frame is null!"); + + if (closed || closeSent) + return; + + byte[] rawData = frame.Get(); + Stream.Write(rawData, 0, rawData.Length); + Stream.Flush(); + } + + /// + /// It will initiate the closing of the connection to the server. + /// + public void Close() + { + Close(1000, "Bye!"); + } + + /// + /// It will initiate the closing of the connection to the server. + /// + public void Close(UInt16 code, string msg) + { + if (closed) + return; + + lock (SendLock) + this.unsentFrames.Clear(); + + Interlocked.Exchange(ref this._bufferedAmount, 0); + + Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.ConnectionClose, WebSocket.EncodeCloseData(code, msg))); + } + + public void StartPinging(int frequency) + { + if (frequency < 100) + throw new ArgumentException("frequency must be at least 100 milliseconds!"); + + PingFrequnecy = TimeSpan.FromMilliseconds(frequency); + lastMessage = DateTime.UtcNow; + + SendPing(); + + HTTPManager.Heartbeats.Subscribe(this); + HTTPUpdateDelegator.OnApplicationForegroundStateChanged += OnApplicationForegroundStateChanged; + } + + #endregion + + #region Private Threading Functions + + private void SendThreadFunc(object param) + { + List localFrames = new List(); + try + { + while (!closed && !closeSent) + { + //if (HTTPManager.Logger.Level <= Logger.Loglevels.All) + // HTTPManager.Logger.Information("WebSocketResponse", "SendThread - Waiting..."); + newFrameSignal.WaitOne(); + + try + { + lock (SendLock) + { + // add frames int reversed order + for (int i = this.unsentFrames.Count - 1; i >= 0; --i) + localFrames.Add(this.unsentFrames[i]); + + this.unsentFrames.Clear(); + } + + //if (HTTPManager.Logger.Level <= Logger.Loglevels.All) + // HTTPManager.Logger.Information("WebSocketResponse", "SendThread - Wait is over, " + localFrames.Count.ToString() + " new frames!"); + + while (localFrames.Count > 0) + { + WebSocketFrame frame = localFrames[localFrames.Count - 1]; + localFrames.RemoveAt(localFrames.Count - 1); + + if (!closeSent) + { + byte[] rawData = frame.Get(); + Stream.Write(rawData, 0, rawData.Length); + + if (frame.Type == WebSocketFrameTypes.ConnectionClose) + closeSent = true; + } + + Interlocked.Add(ref this._bufferedAmount, -frame.Data.Length); + } + + Stream.Flush(); + } + catch(Exception ex) + { + if (HTTPUpdateDelegator.IsCreated) + { + this.baseRequest.Exception = ex; + this.baseRequest.State = HTTPRequestStates.Error; + } + else + this.baseRequest.State = HTTPRequestStates.Aborted; + + closed = true; + } + } + } + finally + { + sendThreadCreated = false; + + HTTPManager.Logger.Information("WebSocketResponse", "SendThread - Closed!"); + } + } + + private void ReceiveThreadFunc(object param) + { + try + { + while (!closed) + { + try + { + WebSocketFrameReader frame = new WebSocketFrameReader(); + frame.Read(Stream); + + lastMessage = DateTime.UtcNow; + + // A server MUST NOT mask any frames that it sends to the client. A client MUST close a connection if it detects a masked frame. + // In this case, it MAY use the status code 1002 (protocol error) + // (These rules might be relaxed in a future specification.) + if (frame.HasMask) + { + Close(1002, "Protocol Error: masked frame received from server!"); + continue; + } + + if (!frame.IsFinal) + { + if (OnIncompleteFrame == null) + IncompleteFrames.Add(frame); + else + lock (FrameLock) CompletedFrames.Add(frame); + continue; + } + + switch (frame.Type) + { + // For a complete documentation and rules on fragmentation see http://tools.ietf.org/html/rfc6455#section-5.4 + // A fragmented Frame's last fragment's opcode is 0 (Continuation) and the FIN bit is set to 1. + case WebSocketFrameTypes.Continuation: + // Do an assemble pass only if OnFragment is not set. Otherwise put it in the CompletedFrames, we will handle it in the HandleEvent phase. + if (OnIncompleteFrame == null) + { + frame.Assemble(IncompleteFrames); + + // Remove all incomplete frames + IncompleteFrames.Clear(); + + // Control frames themselves MUST NOT be fragmented. So, its a normal text or binary frame. Go, handle it as usual. + goto case WebSocketFrameTypes.Binary; + } + else + lock (FrameLock) CompletedFrames.Add(frame); + break; + + case WebSocketFrameTypes.Text: + case WebSocketFrameTypes.Binary: + frame.DecodeWithExtensions(WebSocket); + lock (FrameLock) CompletedFrames.Add(frame); + break; + + // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in response, unless it already received a Close frame. + case WebSocketFrameTypes.Ping: + if (!closeSent && !closed) + Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Pong, frame.Data)); + break; + + case WebSocketFrameTypes.Pong: + try + { + // Get the ticks from the frame's payload + long ticksSent = BitConverter.ToInt64(frame.Data, 0); + + // the difference between the current time and the time when the ping message is sent + TimeSpan diff = TimeSpan.FromTicks(lastMessage.Ticks - ticksSent); + + // add it to the buffer + this.rtts.Add((int)diff.TotalMilliseconds); + + // and calculate the new latency + this.Latency = CalculateLatency(); + } + catch + { + // https://tools.ietf.org/html/rfc6455#section-5.5 + // A Pong frame MAY be sent unsolicited. This serves as a + // unidirectional heartbeat. A response to an unsolicited Pong frame is + // not expected. + } + + break; + + // If an endpoint receives a Close frame and did not previously send a Close frame, the endpoint MUST send a Close frame in response. + case WebSocketFrameTypes.ConnectionClose: + CloseFrame = frame; + if (!closeSent) + Send(new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.ConnectionClose, null)); + closed = true; + break; + } + } +#if !NETFX_CORE + catch (ThreadAbortException) + { + IncompleteFrames.Clear(); + this.baseRequest.State = HTTPRequestStates.Aborted; + + closed = true; + + newFrameSignal.Set(); + } +#endif + catch (Exception e) + { + if (HTTPUpdateDelegator.IsCreated) + { + this.baseRequest.Exception = e; + this.baseRequest.State = HTTPRequestStates.Error; + } + else + this.baseRequest.State = HTTPRequestStates.Aborted; + + closed = true; + newFrameSignal.Set(); + } + } + } + finally + { + HTTPManager.Heartbeats.Unsubscribe(this); + HTTPUpdateDelegator.OnApplicationForegroundStateChanged -= OnApplicationForegroundStateChanged; + + HTTPManager.Logger.Information("WebSocketResponse", "ReceiveThread - Closed!"); + } + } + + #endregion + + #region Sending Out Events + + /// + /// Internal function to send out received messages. + /// + void IProtocol.HandleEvents() + { + frameCache.Clear(); + lock (FrameLock) + { + frameCache.AddRange(CompletedFrames); + CompletedFrames.Clear(); + } + + for (int i = 0; i < frameCache.Count; ++i) + { + WebSocketFrameReader frame = frameCache[i]; + + // Bugs in the clients shouldn't interrupt the code, so we need to try-catch and ignore any exception occurring here + try + { + switch (frame.Type) + { + case WebSocketFrameTypes.Continuation: + if (OnIncompleteFrame != null) + OnIncompleteFrame(this, frame); + break; + + case WebSocketFrameTypes.Text: + // Any not Final frame is handled as a fragment + if (!frame.IsFinal) + goto case WebSocketFrameTypes.Continuation; + + if (OnText != null) + OnText(this, frame.DataAsText); + break; + + case WebSocketFrameTypes.Binary: + // Any not Final frame is handled as a fragment + if (!frame.IsFinal) + goto case WebSocketFrameTypes.Continuation; + + if (OnBinary != null) + OnBinary(this, frame.Data); + break; + } + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketResponse", "HandleEvents", ex); + } + } + + frameCache.Clear(); + + // 2015.05.09 + // State checking added because if there is an error the OnClose called first, and then the OnError. + // Now, when there is an error only the OnError event will be called! + if (IsClosed && OnClosed != null && baseRequest.State == HTTPRequestStates.Processing) + { + try + { + UInt16 statusCode = 0; + string msg = string.Empty; + + // If we received any data, we will get the status code and the message from it + if (CloseFrame != null && CloseFrame.Data != null && CloseFrame.Data.Length >= 2) + { + if (BitConverter.IsLittleEndian) + Array.Reverse(CloseFrame.Data, 0, 2); + statusCode = BitConverter.ToUInt16(CloseFrame.Data, 0); + + if (CloseFrame.Data.Length > 2) + msg = Encoding.UTF8.GetString(CloseFrame.Data, 2, CloseFrame.Data.Length - 2); + } + + OnClosed(this, statusCode, msg); + } + catch (Exception ex) + { + HTTPManager.Logger.Exception("WebSocketResponse", "HandleEvents - OnClosed", ex); + } + } + } + + #endregion + + #region IHeartbeat Implementation + + void IHeartbeat.OnHeartbeatUpdate(TimeSpan dif) + { + DateTime now = DateTime.UtcNow; + + if (now - lastPing >= PingFrequnecy) + SendPing(); + + if (now - (lastMessage + this.PingFrequnecy) > this.WebSocket.CloseAfterNoMesssage) + { + HTTPManager.Logger.Warning("WebSocketResponse", + string.Format("No message received in the given time! Closing WebSocket. LastMessage: {0}, PingFrequency: {1}, Close After: {2}, Now: {3}", + this.lastMessage, this.PingFrequnecy, this.WebSocket.CloseAfterNoMesssage, now)); + + CloseWithError("No message received in the given time!"); + } + } + + #endregion + + private void OnApplicationForegroundStateChanged(bool isPaused) + { + if (!isPaused) + lastMessage = DateTime.UtcNow; + } + + private void SendPing() + { + lastPing = DateTime.UtcNow; + + try + { + long ticks = DateTime.UtcNow.Ticks; + var ticksBytes = BitConverter.GetBytes(ticks); + + var pingFrame = new WebSocketFrame(this.WebSocket, WebSocketFrameTypes.Ping, ticksBytes); + + Insert(pingFrame); + } + catch + { + HTTPManager.Logger.Information("WebSocketResponse", "Error while sending PING message! Closing WebSocket."); + CloseWithError("Error while sending PING message!"); + } + } + + private void CloseWithError(string message) + { + this.baseRequest.Exception = new Exception(message); + this.baseRequest.State = HTTPRequestStates.Error; + + this.closed = true; + + HTTPManager.Heartbeats.Unsubscribe(this); + HTTPUpdateDelegator.OnApplicationForegroundStateChanged -= OnApplicationForegroundStateChanged; + + newFrameSignal.Set(); + CloseStream(); + } + + private int CalculateLatency() + { + if (this.rtts.Count == 0) + return 0; + + int sumLatency = 0; + for (int i = 0; i < this.rtts.Count; ++i) + sumLatency += this.rtts[i]; + + return sumLatency / this.rtts.Count; + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs.meta new file mode 100644 index 0000000..72de547 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketResponse.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 46daae4eb8da43145b58819255462ded +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs new file mode 100644 index 0000000..97b457a --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs @@ -0,0 +1,83 @@ +#if !BESTHTTP_DISABLE_WEBSOCKET + +namespace BestHTTP.WebSocket +{ + /// + /// http://tools.ietf.org/html/rfc6455#section-7.4.1 + /// + public enum WebSocketStausCodes : ushort + { + /// + /// Indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled. + /// + NormalClosure = 1000, + + /// + /// Indicates that an endpoint is "going away", such as a server going down or a browser having navigated away from a page. + /// + GoingAway = 1001, + + /// + /// Indicates that an endpoint is terminating the connection due to a protocol error. + /// + ProtocolError = 1002, + + /// + /// Indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept + /// (e.g., an endpoint that understands only text data MAY send this if it receives a binary message). + /// + WrongDataType = 1003, + + /// + /// Reserved. The specific meaning might be defined in the future. + /// + Reserved = 1004, + + /// + /// A reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. + /// It is designated for use in applications expecting a status code to indicate that no status code was actually present. + /// + NoStatusCode = 1005, + + /// + /// A reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. + /// It is designated for use in applications expecting a status code to indicate that the connection was closed abnormally, e.g., without sending or receiving a Close control frame. + /// + ClosedAbnormally = 1006, + + /// + /// Indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message (e.g., non-UTF-8 [RFC3629] data within a text message). + /// + DataError = 1007, + + /// + /// Indicates that an endpoint is terminating the connection because it has received a message that violates its policy. + /// This is a generic status code that can be returned when there is no other more suitable status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the policy. + /// + PolicyError = 1008, + + /// + /// Indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process. + /// + TooBigMessage = 1009, + + /// + /// Indicates that an endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, + /// but the server didn't return them in the response message of the WebSocket handshake. + /// The list of extensions that are needed SHOULD appear in the /reason/ part of the Close frame. Note that this status code is not used by the server, because it can fail the WebSocket handshake instead. + /// + ExtensionExpected = 1010, + + /// + /// Indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. + /// + WrongRequest = 1011, + + /// + /// A reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting a status code to indicate that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified). + /// + TLSHandshakeError = 1015 + } +} + +#endif \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs.meta b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs.meta new file mode 100644 index 0000000..8030e65 --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTP/WebSocket/WebSocketStatusCodes.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b782b81b6b7755d478dc07521f33f09c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf b/Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d98b11800d81581e6ce7492c207f391b6eb1ef23 GIT binary patch literal 444035 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%0DKMF;mGrH9Q93U^{=eQP9btU*s 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

    !}i+-ZE^U)Vm3axnIJxy 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 Se-Ecpml!(;TKY@$w7szj7des|o% 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

    tBIXa9R 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 literal 0 HcmV?d00001 diff --git a/Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf.meta b/Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf.meta new file mode 100644 index 0000000..a72cabe --- /dev/null +++ b/Assets/Best HTTP (Pro)/BestHTTPDocumentationEN.pdf.meta @@ -0,0 +1,38 @@ +fileFormatVersion: 2 +guid: 2613ad626d854294e8beb55d7c422bf3 +labels: +- http +- www +- web +- cache +- stream +- wp8 +- wsa +- metro +- rest +- api +- socket +- socket.io +- websocket +- websockets +- cookie +- proxy +- il2cpp +- android +- tcp +- https +- ios +- webrequest +- signalr +- eventsource +- server-sent +- events +- server-sentevents +- authentication +- samsung +- smart +- tv +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Plugins.meta b/Assets/Best HTTP (Pro)/Plugins.meta new file mode 100644 index 0000000..261cd79 --- /dev/null +++ b/Assets/Best HTTP (Pro)/Plugins.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f2acd3f924ae69c44b7aadb54e686d44 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Plugins/WebGL.meta b/Assets/Best HTTP (Pro)/Plugins/WebGL.meta new file mode 100644 index 0000000..aebd4cd --- /dev/null +++ b/Assets/Best HTTP (Pro)/Plugins/WebGL.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b48528ef6a3e52f4ba5e4335dff83841 +folderAsset: yes +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib new file mode 100644 index 0000000..8cd8693 --- /dev/null +++ b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib @@ -0,0 +1,154 @@ +var Lib_BEST_HTTP_WebGL_ES_Bridge = +{ + $es: { + eventSourceInstances: {}, + nextInstanceId : 1, + + Set : function(event) { + es.eventSourceInstances[es.nextInstanceId] = event; + return es.nextInstanceId++; + }, + + Get : function(id) { + return es.eventSourceInstances[id]; + }, + + Remove: function(id) { + delete es.eventSourceInstances[id]; + }, + + _callOnError: function(errCallback, id, reason) + { + if (reason) + { + var length = lengthBytesUTF8(reason) + 1; + var buffer = _malloc(length); + + stringToUTF8Array(reason, HEAPU8, buffer, length); + + Runtime.dynCall('vii', errCallback, [id, buffer]); + + _free(buffer); + } + else + Runtime.dynCall('vii', errCallback, [id, 0]); + }, + + _GenericEventHandler: function(id, eventName, e, onMessage) { + function AllocString(str) { + if (str != undefined) + { + var length = lengthBytesUTF8(str) + 1; + var buff = _malloc(length); + + stringToUTF8Array(str, HEAPU8, buff, length); + + return buff; + } + + return 0; + } + + var eventBuffer = AllocString(eventName); + var dataBuffer = AllocString(e.data); + var idBuffer = AllocString(e.id); + + Runtime.dynCall('viiiii', onMessage, [id, eventBuffer, dataBuffer, idBuffer, e.retry]); + + if (eventBuffer != 0) + _free(eventBuffer); + + if (dataBuffer != 0) + _free(dataBuffer); + + if (idBuffer != 0) + _free(idBuffer); + } + }, + + ES_IsSupported: function() { + return typeof(EventSource) !== "undefined"; + }, + + ES_Create: function(urlPtr, withCredentials, onOpen, onMessage, onError) + { + var url = /*encodeURI*/(Pointer_stringify(urlPtr)) + .replace(/\+/g, '%2B') + .replace(/%252[fF]/ig, '%2F'); + + var event = { + onError: onError + }; + + var id = es.nextInstanceId; + + console.log(id + ' ES_Create(' + url + ', ' + withCredentials + ')'); + + event.eventImpl = new EventSource(url, { withCredentials: withCredentials != 0 ? true : false } ); + event.onMessage = onMessage; + + event.eventImpl.onopen = function() { + console.log(id + ' ES_Create - onOpen'); + + Runtime.dynCall('vi', onOpen, [id]); + }; + + event.eventImpl.onmessage = function(e) { + console.log(id + ' on Generic Message'); + es._GenericEventHandler(id, undefined, e, onMessage); + }; + + event.eventImpl.onerror = function(e) { + console.log(id + ' ES_Create - onError'); + + es._callOnError(onError, id, "Unknown Error!"); + }; + + return es.Set(event); + }, + + ES_AddEventHandler: function(id, eventNamePtr) { + var eventName = Pointer_stringify(eventNamePtr); + + console.log(id + ' ES_AddEventHandler(' + eventName + ')'); + + var event = es.Get(id); + + try + { + event.eventImpl.addEventListener(eventName, function(e) { + console.log(id + ' onEvent('+ eventName + ')'); + + es._GenericEventHandler(id, eventName, e, event.onMessage); + }); + } + catch(e) { + es._callOnError(event.eventImpl.onError, id, ' ' + e.name + ': ' + e.message); + } + }, + + ES_Close: function(id) + { + console.log(id + ' ES_Close'); + + var event = es.Get(id); + + try + { + event.eventImpl.close(); + } + catch(e) { + es._callOnError(event.eventImpl.onError, id, ' ' + e.name + ': ' + e.message); + } + }, + + ES_Release: function(id) + { + console.log(id + ' ES_Release'); + + es.Remove(id); + } +}; + +autoAddDeps(Lib_BEST_HTTP_WebGL_ES_Bridge, '$es'); +mergeInto(LibraryManager.library, Lib_BEST_HTTP_WebGL_ES_Bridge); diff --git a/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib.meta b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib.meta new file mode 100644 index 0000000..8f5b990 --- /dev/null +++ b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_EventSource.jslib.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: ac23b06f7735b8e478ce14b0d4ac2a68 +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + WebGL: + enabled: 1 + settings: {} + data: + enabled: 0 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebRequest.jslib b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebRequest.jslib new file mode 100644 index 0000000..9feb77b --- /dev/null +++ b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebRequest.jslib @@ -0,0 +1,241 @@ +var Lib_BEST_HTTP_WebGL_HTTP_Bridge = +{ + /*LogLevels: { + All: 0, + Information: 1, + Warning: 2, + Error: 3, + Exception: 4, + None: 5 + }*/ + + $wr: { + requestInstances: {}, + nextRequestId: 1, + loglevel: 2 + }, + + XHR_Create: function(method, url, user, passwd) + { + var _url = /*encodeURI*/(Pointer_stringify(url)) + .replace(/\+/g, '%2B') + .replace(/%252[fF]/ig, '%2F'); + var _method = Pointer_stringify(method); + + if (wr.loglevel <= 1) /*information*/ + console.log(wr.nextRequestId + ' XHR_Create ' + _method + ' ' + _url); + + var http = new XMLHttpRequest(); + + if (user && passwd) + { + var u = Pointer_stringify(user); + var p = Pointer_stringify(passwd); + + http.withCredentials = true; + http.open(_method, _url, /*async:*/ true , u, p); + } + else + http.open(_method, _url, /*async:*/ true); + + http.responseType = 'arraybuffer'; + + wr.requestInstances[wr.nextRequestId] = http; + return wr.nextRequestId++; + }, + + XHR_SetTimeout: function (request, timeout) + { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_SetTimeout ' + timeout); + + wr.requestInstances[request].timeout = timeout; + }, + + XHR_SetRequestHeader: function (request, header, value) + { + var _header = Pointer_stringify(header); + var _value = Pointer_stringify(value); + + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_SetRequestHeader ' + _header + ' ' + _value); + + wr.requestInstances[request].setRequestHeader(_header, _value); + }, + + XHR_SetResponseHandler: function (request, onresponse, onerror, ontimeout, onaborted) + { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_SetResponseHandler'); + + var http = wr.requestInstances[request]; + // LOAD + http.onload = function http_onload(e) { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' - onload ' + http.status + ' ' + http.statusText); + + if (onresponse) + { + var response = 0; + if (!!http.response) + response = http.response; + + var byteArray = new Uint8Array(response); + var buffer = _malloc(byteArray.length); + HEAPU8.set(byteArray, buffer); + + Runtime.dynCall('viiiii', onresponse, [request, http.status, buffer, byteArray.length, 0]); + + _free(buffer); + } + }; + + if (onerror) + { + http.onerror = function http_onerror(e) { + function HandleError(err) + { + var length = lengthBytesUTF8(err) + 1; + var buffer = _malloc(length); + + stringToUTF8Array(err, HEAPU8, buffer, length); + + Runtime.dynCall('vii', onerror, [request, buffer]); + + _free(buffer); + } + + if (e.error) + HandleError(e.error); + else + HandleError("Unknown Error! Maybe a CORS porblem?"); + }; + } + + if (ontimeout) + http.ontimeout = function http_onerror(e) { + Runtime.dynCall('vi', ontimeout, [request]); + }; + + if (onaborted) + http.onabort = function http_onerror(e) { + Runtime.dynCall('vi', onaborted, [request]); + }; + }, + + XHR_SetProgressHandler: function (request, onprogress, onuploadprogress) + { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_SetProgressHandler'); + + var http = wr.requestInstances[request]; + if (http) + { + if (onprogress) + http.onprogress = function http_onprogress(e) { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_SetProgressHandler - onProgress ' + e.loaded + ' ' + e.total); + + if (e.lengthComputable) + Runtime.dynCall('viii', onprogress, [request, e.loaded, e.total]); + }; + + if (onuploadprogress) + http.upload.addEventListener("progress", function http_onprogress(e) { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_SetProgressHandler - onUploadProgress ' + e.loaded + ' ' + e.total); + + if (e.lengthComputable) + Runtime.dynCall('viii', onuploadprogress, [request, e.loaded, e.total]); + }, true); + } + }, + + XHR_Send: function (request, ptr, length) + { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_Send ' + ptr + ' ' + length); + + var http = wr.requestInstances[request]; + + try { + if (length > 0) + http.send(HEAPU8.subarray(ptr, ptr+length)); + else + http.send(); + } + catch(e) { + if (wr.loglevel <= 4) /*exception*/ + console.error(request + ' ' + e.name + ": " + e.message); + } + }, + + XHR_GetResponseHeaders: function(request, callback) + { + if (wr.loglevel <= 1) /*information*/ + console.log(request + ' XHR_GetResponseHeaders'); + + var headers = wr.requestInstances[request].getAllResponseHeaders().trim() + "\r\n"; + + if (wr.loglevel <= 1) /*information*/ + console.log(' "' + headers + '"'); + + var byteArray = new Uint8Array(headers.length); + for(var i=0,j=headers.length;i 0) + // ws._callOnError(onError, id, e.reason); + // else + // { + // switch (e.code) + // { + // case 1001: ws._callOnError(onError, id, "Endpoint going away."); + // break; + // case 1002: ws._callOnError(onError, id, "Protocol error."); + // break; + // case 1003: ws._callOnError(onError, id, "Unsupported message."); + // break; + // case 1005: ws._callOnError(onError, id, "No status."); + // break; + // case 1006: ws._callOnError(onError, id, "Abnormal disconnection."); + // break; + // case 1009: ws._callOnError(onError, id, "Data frame too large."); + // break; + // default: ws._callOnError(onError, id, "Error " + e.code); + // } + // } + //} + //else + ws._callOnClose(onClose, id, e.code, e.reason); + }; + + return ws.Set(socket); + }, + + WS_GetState: function (id) + { + var socket = ws.Get(id); + + if (typeof socket === 'undefined' || + socket == null || + typeof socket.socketImpl === 'undefined' || + socket.socketImpl == null) + return 3; // closed + + return socket.socketImpl.readyState; + }, + + WS_GetBufferedAmount: function (id) + { + var socket = ws.Get(id); + return socket.socketImpl.bufferedAmount; + }, + + WS_Send_String: function (id, str) + { + var socket = ws.Get(id); + var str = Pointer_stringify(str); + + try + { + socket.socketImpl.send(str); + } + catch(e) { + ws._callOnError(socket.onError, id, ' ' + e.name + ': ' + e.message); + } + + return socket.socketImpl.bufferedAmount; + }, + + WS_Send_Binary: function(id, ptr, pos, length) + { + var socket = ws.Get(id); + + try + { + var buff = HEAPU8.subarray(ptr + pos, ptr + pos + length); + socket.socketImpl.send(buff /*HEAPU8.buffer.slice(ptr + pos, ptr + pos + length)*/); + } + catch(e) { + ws._callOnError(socket.onError, id, ' ' + e.name + ': ' + e.message); + } + + return socket.socketImpl.bufferedAmount; + }, + + WS_Close: function (id, code, reason) + { + var socket = ws.Get(id); + var reasonStr = Pointer_stringify(reason); + + console.log(id + ' WS_Close(' + code + ', ' + reasonStr + ')'); + + socket.socketImpl.close(/*ulong*/code, reasonStr); + }, + + WS_Release: function(id) + { + console.log(id + ' WS_Release'); + + ws.Remove(id); + } +}; + +autoAddDeps(Lib_BEST_HTTP_WebGL_WS_Bridge, '$ws'); +mergeInto(LibraryManager.library, Lib_BEST_HTTP_WebGL_WS_Bridge); diff --git a/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebSocket.jslib.meta b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebSocket.jslib.meta new file mode 100644 index 0000000..3ddde4a --- /dev/null +++ b/Assets/Best HTTP (Pro)/Plugins/WebGL/BestHTTP_WebSocket.jslib.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: 8efe6cedf2832a647a33465b85e4f311 +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + platformData: + Any: + enabled: 0 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + WebGL: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/ReleaseNotes.txt b/Assets/Best HTTP (Pro)/ReleaseNotes.txt new file mode 100644 index 0000000..44435b2 --- /dev/null +++ b/Assets/Best HTTP (Pro)/ReleaseNotes.txt @@ -0,0 +1,584 @@ +1.10.8 (2018.07.02) +General +-[Improvement] Greatly reduced the TCP packets that sent out for a HTTP request +WebSocket +-[Improvement] Frame downloading now isn't blocked while user code is executing on current completed frames +SocketIO +-[Bugfix] Implemented a new ToInt function instead of char.GetNumericValue as this later one throws an exception under WebGL using the new 4.x runtime +SignalR Core +-[Improvement] Fixed compile errors for WSA +-[Improvement] Added HubOptions to be able to set more options +-[Improvement] Now it's possible to skip the negotiation process and connect straigth with the (only) WebSocket protocol +-[Bugfix] Authentication provider's PrepareRequest wasn't called on the negotiation request. + +1.10.7 (2018.06.05) +General +-[Improvement] Logger will log out time infromation too +-[Improvement] HTTPRequest will send a Content-Length header with zero value when there's no data to send +WebSocket +-[Bugfix] Fixed a case where the connection reported closed unintentionally +SignalR Core +-[Improvement] Added PrepareUri function to the IAuthenticationProvider interface +-[Improvement] Added negotiation request. Negotiation result now stored in the NegotiationResult property. +-[Improvement] Added support for 'Close' server messages +-[Improvement] More documentation and code comments +-[Improvement] Code cleanup + +1.10.6 (2018.05.20) +General +-[Bugfix] Fixed a case where aborting a request throw and exception +SocketIO +-[Bugfix] Will not send a ping packet while waiting for a pong +WebSocket +-[Bugfix] OnError OnErrorDesc events not called when the websocket's State > Connecting +SignalRCore +-[Improvement] New BESTHTTP_DISABLE_SIGNALR_CORE symbol to disable SignalR Core +-[Bugfix] The SignalR Core implementation has no dependency on SignalR classes now + +1.10.5 (2018.04.17) +General +-[Improvement] HTTPRequest will send Content-Length header with zero value if there's no data +-[Improvement] Added timing info to logging +WebSocket +-[Improvement] Improved error handling +SignalR Core +-[Improvement] Added /negotiation request and NegotiationResult property to the HubConnection +-[Improvement] More code comments and logging +-[Improvement] Added support for Close server messages +-[Bugfix] Removed compile warnings + +1.10.4 (2018.04.15) +General +-[Improvement] csproj files added to the package to genereate dlls +-[Improvement] Improved compatibilty with other packages that are have theirs own Utility class in the root namespace. +-[Improvement] Improved compatibility with the Experimental (.NET 4.6) runtime +-[Improvement] Using the HTTPRequest's CustomTLSServerNameList property now it's possible to add custom SNIs +-[Bugfix] Decompressor used during streaming will buffer up data if necessary to avoid a GZip exception. +-[Bugfix] Removed unnecessary logging in the HTTPUpdateDelegator +-[Bugfix] TLS SNIs will not be sent if the host is an IPv4 or IPv6 address +-[Bugfix] Digest authentication failed with the proxy +WebSocket +-[Improvement] Now it's possible to close the websocket before it connects +-[Improvement] New State property to access the websocket's state +-[Bugfix] [WebGL] HTTPManager.Setup() isn't called when only the WebSocket protocol is used +SocketIO +-[Bugfix] proper pingTimeout implementation (thanks @carsanlop for the code!) +SignalR +-[Bugfix] It will not try to reconnect after leaving Unity's play mode. +SignalR Core +-[New Feature] New SignalR Core implementation for SignalRCore 1.0.0-alpha2 + +1.10.3 (2017.11.11) +General +-[Improvement] Added OPTIONS verb +-[Improvement] Better compatibility with Unity 2017.2 +-[Bugfix] Boundary generated for multipart/form-data will be a truely unique value that shouldn't be found in the payload +WebSocket +-[New Feature] Added new CloseAfterNoMesssage TimeSpan property to the WebSocket class. When StartPingThread is true, the plugin will check for messages and will close the connection and emit an OnError/OnErrorDesc event after the specified time. It's not available on WebGL platform! +-[New Feature] Added Latency property. When StartPingThread is true, it will calculate the latency from the Ping-Pong message round-trip times. It's not available on WebGL platform! +SignalR +-[Bugfix] Group token not sent with polling requests + +1.10.2 (2017.07.29) +General +-[Bugfix] Fixed an exception when redirected + +1.10.1 (2017.07.26) +General +-[New Feature] Added BESTHTTP_DISABLE_GZIP to be able to disable gzip Accept-Encoding requests +-[Improvement] Improved compatibility when run in an Editor window +-[Improvement] DNS query is done async with timeout (Thanks goes to chriser on the forums for the code) +-[Bugfix] The HTTPConnection object will not close the TCP stream when the "Connection: Close" header present and the http response handler's IsClosedManually set to true. +-[Bugfix] Fixed a compilation issue in RawJsonForm.cs when both BESTHTTP_DISABLE_SOCKETIO and BESTHTTP_DISABLE_SIGNALR are defined +-[Bugfix] When a request's DisableChace is set to true, it will not produce a warning if caching headers added manually +-[Bugfix] When there's no connection the CookieJar will not override saved cookies with an empty one +Websocket +-[Bugfix] Fixed an issue where receive threads are not shut down resulting in an exception +Socket.IO +-[Improvement] Compatibility with Socket.IO 2.0.0 +Server-Sent Events +-[Improvement] Added WithCredentials property to the EventSource class under WebGL +-[Improvement] EventSource constructor will thrown a NotSupportedException under WebGL when the underlying browser isn't supports the EventSource protocol +-[Bugfix] Subscibing to a named event (On(...)) isn't worked under WebGL + +1.10.0 (2017.05.05) +General +-Removed support for Windows Phone 8 +-[New Feature] HTTPManager and HTTPRequest has a new property 'TryToMinimizeTCPLatency' to turn on/off TCP NoDelay +-[New Feature] A new Form type 'RawJson' to send the fields added with AddField jon encoded +-[Improvement] Added DefaultCertificationValidator to the HTTPManger +-[Improvement] Improved compatibility with Unity 2017.1 +-[Improvement] Now the plugin capable to download files larger than 2 GB (Thanks goes to Daniel @ present4D) +-[Bugfix] Accessing streaming assets now possible under WebGL builds +-[Bugfix] Fixed a sneaky bug where the HTTPUpdateDelegator unloaded in builds +Socket.IO +-[Improvement] Sockets now have an Id property generated the same as in the JS Socket.IO lib. + +1.9.17 (2017.01.29) +General +-[New Feature] GZip content encoding is now supported when UseStreaming is on. The plugin now will automatically decompress downloaded chunks. +-[Improvement] Removed .Bind() calls from the TcpClient class to remove the need of the com.apple.security.network.server permission. +-[Improvement] Added support for PATCH requests +-[Improvement] Improved the Clear() function of the HTTPRequest to reset more properties +-[Bugfix] Sending text fields will not include additional quotes around the charset value +-[Bugfix][WebGL] Fixed multiple bugs where WebGL requests are failed early +WebSocket +-[New Feature] Send became non-blocking, buffered up data will be sent on a thread +-[New Feature] WebSocket has a new property: BufferedAmount to get the length of the unsent, buffered up data in bytes +-[Improvement] Improved compatibility with Citrix + +1.9.16 (2016.10.24) +General +-[Improvement] Using the HTTPRequest's CacheOnly property now it's possible to download a resource into the cache only. The response object's Data will not be populated in this case! (Thanks goes to Sakari for the complete patch!) +-[Bugfix] Made a workaround for a mono bug where on macOS Uri created a file:// uri from a relative path instead throwing an exception. +WebSocket +-[Bugfix] The client sent wrong number of frames for a large frame +-[Bugfix] Fixed a bug to be able to connect to Asp .NET Core hosted WebSocket servers +SignalR +-[Bugfix] The plugin will wait a little now before a new reconnect attempt + +1.9.15 (2016.09.22) +General +-[Improvement] When ConnectTimeout of the HTTPManager or HTTPRequest is set to TimeSpan.Zero, no timeout logic is executed. +-[Bugfix] Removed read&write timeouts as it caused issues in some cases +-[Bugfix] Fixed a compile error when BESTHTTP_DISABLE_CACHING was defined + +1.9.14 (2016.09.13) +General +-[Improvement] Added Read and Write timeouts +-[Improvement] Added diagnostic logging. They will be logged when LogLevels.All is used +-[Improvement] Removed a frightening warning about lock acquisition +-[Improvement] Removed an additonal BinaryWriter instantiation when sending out a request +-[Bugfix] Fixed a case where uris without a leading ‘/’ would fail +-[Bugfix] [WebGL] Fixed url lowercase converting +-[Bugfix] No exceptions should be thrown now when quitting +-[Bugfix] Fixed a case where a cache entity deleted unintentionally on startup +Server-Sent Event +-[Bugfix] Content-Type header check was too strict + +1.9.13 (2016.07.20) +General +-[Improvement] Default Connection idle time lowered to 20 seconds +-[Bugfix] Made workaround for mono bugs around Uri encodings +-[Bugfix] Cached content wasn’t refreshed (thanks goes to Jeff Mrochuk) +Server-Sent Events +-[Bugfix] Fixed a case where it would produce an exception when no On function is used to subscribe to an event + +1.9.12 (2016.06.21) +General +-[Improvement] Reading a file with the file:// protocol will not result in an “Access Denied” exception on PS4 (Thanks goes to Dong-Geun Oh for reporting and sending a patch) +-[Improvement] ThreadPools are used again instead of raw Threads +-[Improvement] Content-Length header’s value will be used even with chunked encoding for download progress report +-[Improvement] Improved thread locking +-[Bugfix] Automatic retry will be done only for GET request on erro +-[Bugfix] TCP connection will be closed when the request’s IsKeepAlive set to false +-[Bugfix] [WebGL] OnBeforeHeaderSend will be called now properly +-[Bugfix] [WebGL] Callbacks will be called now when an error occur in the XHR_Send function +-[Bugfix] HTTPRequest.AddField with null encoding will work now +-[Bugfix] Callback called with request’s State Processing on application quit +WebSocket +-[Improvement] Documentation and code changes to emphasize that WebSocket instance can’t be reused +-[Improvement] Text frames will be decoded on the read thread to further minimize cpu burden on the main Unity thread +SignalR +-[Improvement] New BESTHTTP_SIGNALR_WITH_JSONDOTNET compile-time directive to use Newtonsoft’s JSon.NET. Using this the plugin will default to the JsonDotnetEncoder. +SocketIO +-[Bugfix] Fixed a case where calling Off on an event caused an exception when the server sent that event again + +1.9.11 (2016.04.04) +General +-[Bugfix][WebGL] Fixed a case where http requests truncated under Microsoft Edge +-[Bugfix] The plugin will work again in editor windows +-[Bugfix] Multiple fixes around request abortion +Server-Sent Events +-[Bugfix] [WebGL] Newly created event sources will not use the same id(1) over and over +Socket.IO +-[Improvement] Rewrote handshake processing to be able to skip the polling transport +-[Improvement] Now it’s possible to inform the plugin what transport it should use to connect with through the SocketOptions’ ConnectWith property +-[Improvement][PollingTransport] Will not force the server to send textual packets +-[Improvement][PollingTransport] Greatly improved packet parsing speed +-[Bugfix] The plugin will process messages sent with the handshake data + +1.9.10 (2016.03.14) +General +-[New Feature] Apple TvOS support added. +-[New Feature] Keep-Alive header support added +-[New Feature] New OnBeforeHeaderSend event added to the HTTPRequest class to be able to access and modify headers just before they are sent out. +-[Improvement] Decreased memory allocations when no encoding is used in the response +-[Improvement] Updated link.xml +-[Improvement] The default value for UserAlternateSSL is changed to true +-[Improvement] [WebGL] The WebGL connection will use the logger’s level +-[Improvement] [WebGL] The plugin will handle correctly UTF16 strings (Thanks goes to Eugen and Zorrendor) +-[Bugfix] [UWP] Because of a missing Flush() call, body-less requests are not sent out +SignalR +-[Improvement] Connection’s PingInterval is now set to public +-[Bugfix] PrepareRequest doesn’t called for Ping requests +WebSocket +-[Bugfix] [WebGL] Fixed a bug where checking the websocket’s IsOpen status caused an error +-[Bugfix] Fixed a case where assembled frames decoded with extensions twice + +1.9.9 (2016.02.16) +General +-[Bugfix] On redirection the plugin tried to load from the cache for the wrong uri +-[Bugfix] On application exit HTTPUpdateDelegator will now shut down the update thread if it’s used +-[Bugfix] Cookies will be sent for protocols other than http too +-[Bugfix] Empty headers will no longer sent out +-[Bugfix] Null values in headers will no longer cause an exception +-[Improvement] Added some missing documentation. +-[Improvement] Exception logging now will include inner exceptions too +WebSockets +-[New Feature] Support for extensions added +-[New Feature] Per-Message Deflate compression extension added +Socket.IO +-[Improvement] Custom errors by middlewares are now supported +-[Improvement] Socket.Options’ AdditionalQueryParams changed from Dictionary to ObservableDictionary to automatically delete the cached value when it’s changed +-[Bugfix] The plugin will not decode the payload for Emit callbacks +SignalR +-[Improvement] AdditionalQueryParams changed from Dictionary to ObservableDictionary to automatically delete the cached value when it’s changed + +1.9.8 (2016.01.04) +General +-[Improvement] Download progress report will be more frequent now with Chunked encoding +WebSockets +-[Bugfix] Sending pings will not be capped on 100ms now +-[Bugfix] [WebGL] Binary data sending and receiving will be handled correctly now + +1.9.7 (2015.12.13) +General +-[Bugfix] Improved compatibility with 5.3 coroutine changes +-[Improvement] Example scripts are in a namespace too + +1.9.6 (2015.12.08) +General +-[Improvement] Changes made to greatly improve compatibility for Windows Store builds targeting IL2CPP scripting backend +Socket.IO +-[Improvement] The WebSocketTransport will send and Update packet to the server without any other payload to improve compatibility + +1.9.5 (2015.11.30) +General +-[Fix] The plugin will choose the Content-Length header when Content-Range present too +-[Improvement] Improved threading of HTTPUpdateDelegator +WebGL +-[Fix] The plugin will not try to decode the content as chunked, as the browser done it already +Socket.IO +-[Fix] Fixed a rare bug where WebSocket transport tried to access a null object +-[Improvement] An error event will be emitted on timeout too +SignalR +-[Improvement] Call functions now will return true if the plugin was able to send the message to the server + +1.9.4 (2015.10.16) +General +-[Bugfix] Fixed a possible connection error on editors running on non-windows +-[Improvement] Added two more constructors to the Cookie class + +1.9.3 (2015.10.10) +-WebGL support added! Check out the documentation about the limitations. +General +-[Improvement] Improved shutdown handling in the editor +-[Improvement] Cache will work on redirect uris as expected +-[Bugfix] Tcp channel disconnection is now detected much quicker +SignalR +-[Improvement] Added support for SignalR 2.0.x +-[Improvement] Improved logging in some cases +WebSocket +-[Bugfix] The plugin will detect a lost connection sooner + +1.9.2 (2015.09.03) +General +-[Improvement] WP8 support is back! +-[Improvement] Improved compatibility with Windows 10 Universal App build for Unity 5.2 +-[Improvement] Improved shutdown handling in the editor + +1.9.1 (2015.08.26) +General +-[Improvement] Improved error reporting on WSA platforms for TcpClient +-[New feature] Initial and experimental file:// protocol support +Socket.IO +-[Bugfix] Emitting binary data wrongly converted +SignalR +-[Improvement] Improved logging +ServerSentEvents +-[Bugfix] Improved compatibility + +1.9.0 (2015.07.29) +Windows Phone 8 silverlight based build support removed! +General +-[New Feature] Various features can be disabled now with the following defines: +--+BESTHTTP_DISABLE_COOKIES +--+BESTHTTP_DISABLE_CACHING +--+BESTHTTP_DISABLE_SERVERSENT_EVENTS +--+BESTHTTP_DISABLE_WEBSOCKET +--+BESTHTTP_DISABLE_SIGNALR +--+BESTHTTP_DISABLE_SOCKETIO +--+BESTHTTP_DISABLE_ALTERNATE_SSL +--+BESTHTTP_DISABLE_UNITY_FORM +--+Check the manual on how you can set these in Unity: http://docs.unity3d.com/Manual/PlatformDependentCompilation.html +-[Improvement] Removed DLL depenencies +-[Improvement] Improved HTTPConnection teardown on quitting +-[Improvement] Improved compatibility when used in an editor window +-[Bugfix] Cookies are stored from redirections +Socket.IO +-[Bugfix] WebSocketTransport not switched to secure protocol when the Uri of the socket.io endpoint is HTTPS +-[BugFix] Disconnect event not fired when the server initiated the disconnect (Thx go to Takayasu Oyama) +SignalR +-[Bugfix] WebSocketTransport not reconnected properly (Thx go to Jaakko Jumisko) + +1.8.2 (2015.06.26) +General +-[Improvement] HTTPResponse’s DataAsTexture2D will use the full constructor now +-[Bugfix] CookieJar’s SetupFolder will check for save support now +-[Bugfix] Cache service deleted all files on maitenance +SignalR +-[Improvement] Better compatibility with JSon .NET encoder +Socket.IO +-[Bugfix] Fixed a case where Disconnect event fired twice +-[Bugfix] First argument on Ack callbacks are removed unintentionally +-[Bugfix] Fixed a case where the ‘disconnect’ event fired twice +Server-Sent Events +-[Improvement] Message class qualified by its namespace everywhere to prevent compile errors + +1.8.1 (2015.05.26) +General +-[New Feature] Server-Sent Events protocol added! +-[Improvement] Updated documentation +-[Improvement] Changed ICertificateVerifyer interface to receive the target server’s uri for validation +-[Bugfix] Fixed a case where HTTPConnections are stuck in the Initial state blocking requests in the queue +Socket.IO +-[Bugfix] Much simpler protocol upgrade/downgrade code to avoid a case when a poll request received by the server after a websocket upgrade +SignalR +-[Improvement] Can fall back to ServerSentEvents protocol + +1.8.0 (2015.05.19) +General +-[New Feature] SignalR protocol added! +-[New Feature] Samsung Smart TV support added! +-[Improvement] HTTPManager has a new UseAlternateSSLDefaultValue property to change the default UseAlternateSSL value +-[Improvement] Custom Cookies added to the request now will overwrite cookies that are stored in the CookieJar, instead of merging and sending both +-[Improvement] Custom Cookies can be added now to the CookieJar +-[Bugfix] In some case, the HTTPManager created new connections that not used after but blocked new requests +-[Bugfix] Fixes a case where a HTTRequest’s State set to Finished instead of Error +-[Bugfix] Fixed a case where custom cookies are not sent +-[Bugfix] Aborting a finished request will not create a stuck connection +WebSocket +-[Improvement] Reading speed of payload data from the wire greatly improved +-[Improvement] New OnErrorDesc event added. This will receive a string errorDesc param. It has a higher chance that it’s stores a meaningfull error description then the previos OnError +-[Bugfix] Fixed a case when the OnError didn’t called + +1.7.11 (2015.04.27) +General +-[Improvement] Greatly improved chache filename generation. New filenames are much-much shorter, therefore (very) long urls can be saved now too +-[Bugfix] Removed unnecessary entry in the link.xml. With this change, full stripping is supported in IL2CPP builds with the .NET 2.0 Subset Api Compatibility Level (Thanks goes to Andrew Wu from Scientific Games for catching/reporting it!) +-[Bugfix] Authentication headers are transformed to lowercase +WebSocket +-[Bugfix] Fixed a case where server sent messages get lost when received before the OnOpen event + +1.7.10(2015.04.17) +General +-[Improvement] The plugin will choose the best supported algorithm if multiple “Proxy-Authenticate” headers are present +-[Improvement] Proxy authentication is now handled for explicit https too +-[Improvement] Saved some cpu cycles and GC allocs while sending a request +-[Improvement] New NonTransparentForHTTPS property in the HTTPProxy class to be able to automotacally switch proxy mode for secure protocols(https://, wss://) +-[Improvement] More, and more accurate logging +-[Improvement] Added some missing documentation to the HTTPProxy class +-[Bugfix] Proxy authentication tried to send the wrong credentials +-[Bugfix] Waiting for the request to finish with a StartCoroutine is exited sooner in some cases +-[Bugfix] One of the HTTPProxy constructor doesn’t set the SendWholeUri to its default value +-[Bugfix] AuthenticateAsClient called with the wrong host parameter when used with a proxy +-[Bugfix] HTTPConnection class now will use the request DisableRetry property, and will not retry a post request by default +-[Bugfix] Fixed a case where an Error state surfaced as Finished +Socket.IO: +-[Improvement] More improvements around transport fallback +-[Improvement] Better error logging in WebSocketTransport +WebSocket: +-[Improvement] If global proxy is set (HTTPManager.Proxy) it will use it as a tunnel automatically +-[Improvement] Better error logging + +1.7.9 (2015.04.01) +[New Feature] OnBeforeRedirection callback added to HTTPRequest. It’s called before a new request is made to the new url. In this callback the redirection can be disabled, or the request can be changed. +[Improvement] Updated BouncyCastle to the latest git version +[Improvement] When UseAlternateSSL is true, the client will send the hostname with the TLS handshake request to greatly improve HTTPS compatibility +[Improvement] More logging +[Bugfix] Fixed a case, when Socket.IO does not fall back to polling when the WebSocket transport fails to connect +[Bugfix] A possible NullRef exception when the request Timed Out + +1.7.8 (2015.03.25) +[Bugfix] Fixed compile error in UploadStream.cs +[Bugfix] Fixed compile errors on WP/WSA builds when used with JSON .NET For Unity (http://u3d.as/5q2) + +1.7.7 (2015.03.17) +[New Feature] Socket.IO’s SocketOptions has two new property to control additional query parameters of the requests +[Improvement] New UploadStream.cs in the Examples folder to help and demonstrate uploading streams +[Bugfix] UploadStream upload not worked + +1.7.6 (2015.03.07) +[New Feature] New CustomCertificateVerifyer property to the HTTPRequest class to be able to set custom validator for the AlternateSSL handler too +[Improvement] Improved Unity5 compatibility + +1.7.5 (2015.03.02) +[New Feature] New Priority property in the HTTPRequest class to be able prioritize queued requests +[Improvement] Additional GC alloc improvements +[Bugfix] Fixed a possible crash in the plugin under iOS + +1.7.4 (2015.02.25) +[New Feature] New UploadStream property in the HTTPRequest class +[New Feature] New OnUploadProgress callback in the HTTPRequest class +[Improvement] Switched from System.Action usage to properly named delegates +[Improvement] Removed some GC allocs +[Bugfix] Fixed an example that tried to access an internal constant + +1.7.3 (2015.02.10) +[Improvement] Timeout improvement +[Improvement] Unity 5 compatibility fixes + +1.7.2 (2015.02.09) +[Improvement] Custom cookies can be added to a HTTPRequest. More on this in the documentation +[Improvement] Queued requests can be aborted too +[Improvement] GetGeneralStatistics function added to the HTTPManager. This function will return a GeneralStatistics struct that contains infromations about connections, cache and cookies. +[Improvement] HTTPRequest’s Callback can be set to a new value after the request’s State is changed +[Improvement] New code samples with a demo-browser! Check it out live here: http://bit.ly/1AkM6gi +-Texture Download Sample +-Asset Bundle Download Sample +-Large File Download Sample +-WebSocket - Echo Sample +-Socket.IO - Chat Sample +-Socket.IO - WePlay Sample +-Cache Maintenance Sample + +1.7.1 (2015.02.03) +[Improvement] Greater compatibility with IL2CPP + +1.7.0 (2015.01.27) +General: +-[Improvement] Improved cache compatibility +-[Improvement] Improved proxy compatibility +-[Improvement] HTTPRequest’s Send function will return the request to be able to chain some functions +-[Improvement] Logger Added to the HTTPManager. Initially the Socket.IO implementation will use it. +-[Improvement] HTTPManager’s MaxConnectionIdleTime lowered to 30 secs +-[Improvement] HTTPRange’s ToString is overridden for quicker debugging +-[Improvement] HTTPRequest’s GetRange function will no longer throw a null exception when there is no “content-range” header. It will return with null. +-[Improvement] Removed uncessary exception logging in Directory platformsupport code +-[Improvement] Renamed Tree class to remove Unity warning +-[Bugfix] Internal buffer size for streaming set to the wrong value +WebSocket changes: +-[Improvement] Added some missing documentation +-[Improvement] Removed the need of a new thread to send automatic pings +-[Improvement] New Send function to send a portion of a byte array +Socket.IO +-[New Feature] Initial Socket.IO release compatible with the latest official Socket.IO implementation + +1.6.4 (2015.01.13) +[Bugfix] POSTs with no data now will set the correct Content-Length header +[Bugfix] Parallel POSTs to the same uri will no longer block each other + +1.6.3 (2014.12.22) +[Improvement] A global default proxy can be set through HTTPManager.Proxy instead of setting it per-request +[Improvement] Added new callback-less constructor to the HTTPRequest (thx to eedok) +[Improvement] Added some documentation +[Bugfix] The proper “host:port” value will be set to the “Host” header (thx to Matthew Boehlig) +[Bugfix] Removed accidentally added WP8.1 dependency + +1.6.2 (2014.11.19) +[Improvement] Native HTTPS support in WP8 and WinRT builds +[Improvement] Removed some compiler warnings in WP8/WinRT builds +[Improvement] Improved proxy compatibility +[Improvement] Non-transparent proxy connection response(status code, message and headers) can be accessed through the request’s ProxyResponse property +[Improvements] Added “Known Bugs/Limitations” to the documentation +[Bugfix] HTTPManager.MaxConnectionPerServer will be handled correctly with proxies +[Bugfix] Idle free connection will be removed correctly + +1.6.1 (2014.11.09) +[Bugfix] WebPlayer build failed to connect to the server +[Bugfix] Two HTTPRequest states(Aborted and Error) unintentionally swapped, now they are back as supposed +[Bugfix] Proxy header handling improvement +[Improvement] More documentation + +1.6.0 (2014.11.01) +[New Feature] Windows Store Apps support added +[Bugfix] Minor bugfixes + +1.5.1 (2014.10.21) +[Improvement] Added global ConnectTimeout and RequestTimeout properties to the HTTPManager +[Improvement] Added documentation about the new features +[Bugfix] multipart/form-data now sends the corrent line endings + +1.5.0 (2014.10.18) +[Improvement] ConnectionTimeout added to the HTTPRequest class to maximize the wait time to connect to the server. +[Improvement] TimeOut added to the HTTPRequest class to maximize the wait time to finish a request. +[Improvement] Updated BouncyCastle. +[Improvement] Rewrote the WP8 TcpClient implementation +[Improvement] Custom certification validation can be added to a HTTPRequest on iOS, Android and Desktop builds by setting the CustomCertificationValidator event. +[BugFix] Fixed handling of an empty form data. + +1.4.3 (2014.09.01) +[Bug Fix] Various bug fixes around redirection + +1.4.2 (2014.09.01) +[Bug Fix] Fixed a bug that intruduced in 1.4.0 that prevented a WebSocket connection to connect to the host in a WebPlayer build +[Improvement] Host header can be set now without overridden by the plugin +[Improvement] Improved thread safety. Now sending requests on multiple threads are safe too. + +1.4.0 (2014.08.19) +[BugFix] Form sending doesn’t handled correctly in some cases +[Improvement] Rewrote form sending. Now correctly supports Url-Encoded and Multipart forms +[New Feature] Download aborting. An ongoing download can be aborted now through a HTTPRequest object’s Abort() function +[New Feature] New HTTPRequestStates enum and State property in the HTTPRequest class to be able to check the current state of the request + +1.3.7 (2014.08.03) +[BugFix] In some situations a WebSocket length read incorrectly +[New Feature] HTTPRequest can be used with yield return +[New Feature] Install script to circumvent manual folder moving +[Improvement] Improved link.xml + +1.3.6 (2014.06.20) +[Imp] Added some more inline ducumentation +[Imp] Cookie parsing improvement if Path missing +[Bugfix] Digest authentication missing "opaque=" + +1.3.5 (2014.06.15) +[Improvement] Unknown Content-Encoding will be treated as “identity” +[Improvement] Better WebSocket error handling +[Improvement] Actualized examples +[Improvement] link.xml in the package in case of stripping error +[BugFix] Fixed WebSocket big frame reading error + +1.3.x (2014.05.04) +[New Feature] New OnProgress event in the HTTPRequest class to be able to track the download progress. + +1.3.1 (2014.04.02) +[Improvement] Improved compatibility with Good ol' Sockets + +1.3.0 (2014.03.30) +[New Feature] Transparent and Tunnel Proxy support with untested proxy authentication +[New Feature] Cookie support! It will automatically handles all cookie sending and receiving, no additional code required! +[Improvement] Handling a rare case when the server doesn’t sent Content-Length header in a regular non-chunked response +[Improvement] Default User-Agent added +[Bugfix] WP8 - fixed a case where reading back a response failed + +1.2.3 (2014.01.06) +[Improvement] WebSocket - Improvements around sending large text messages + +1.2.2 (2014.01.05) +[Improvement] WebSocket - Fragmented messages compatibility improvement +[Improvement] WebSocket - New property in the WebSocketResponse class to control the maximum size of a fragment’s payload data (MaxFragmentSize). + +1.2.1: (pro only) +[Improvement] Ability to handle DHE_RSA_WITH_AES_256 certificates if UseAlternateSSL is set to true on a HTTPRequest object. + +1.2.0 (2013.11.05) +[New Feature] WebSockets + +1.1.5 (2013.10.02) +[New Feature] Basic and Digest authentication support through a new Credentials property in the HTTPRequest class +[Improvement] More then one redirection supported for a single request +[Improvement] New MaxRedirects property in the HTTPRequest class +[Improvement] New GetFirstHeaderValue(string headerName) function in the HTTPRequest class +[Improvement] New optimized parsers, for now only used for parsing the authentication header +[Improvement] Some code cleanup +[Bugfix] In some cases after sending the request and not receiving any data caused a new reconnect +[Bugfix] Some caching proxies return with float values in Max-Age header + +1.1.4 (2013.09.15) +[New Feature] Unity 3.5 support added. +[New Feature] WebPlayer support added. +[Improvement] POST request doesn't retry the request when downloading/parsing the response fails. If something goes bad, the request object's Exception property will hold the exception (as always). +[Improvement] There is a new property called DisableRetry to disable resending the request if downloading/parsing the response fails. The default value is true if the request's MethodType is POST, otherwise false. +[Improvement] There is new property called RawData to send data in a POST request without setting any fields. If RawData is set any field that added through AddField, AddBinaryData, SetFields to the request will be ignored. \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/ReleaseNotes.txt.meta b/Assets/Best HTTP (Pro)/ReleaseNotes.txt.meta new file mode 100644 index 0000000..bf5e342 --- /dev/null +++ b/Assets/Best HTTP (Pro)/ReleaseNotes.txt.meta @@ -0,0 +1,38 @@ +fileFormatVersion: 2 +guid: fe366785ac6802f418654b21d3d4e972 +labels: +- http +- www +- web +- cache +- stream +- wp8 +- wsa +- metro +- rest +- api +- socket +- socket.io +- websocket +- websockets +- cookie +- proxy +- il2cpp +- android +- tcp +- https +- ios +- webrequest +- signalr +- eventsource +- server-sent +- events +- server-sentevents +- authentication +- samsung +- smart +- tv +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Unity 2017.2 and up - Editor.csproj.meta b/Assets/Best HTTP (Pro)/Unity 2017.2 and up - Editor.csproj.meta new file mode 100644 index 0000000..de7b430 --- /dev/null +++ b/Assets/Best HTTP (Pro)/Unity 2017.2 and up - Editor.csproj.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3dff95aad8aa1714f9a63beb65eecdd1 +timeCreated: 1523773778 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Unity 2017.2 and up - UWP.csproj.meta b/Assets/Best HTTP (Pro)/Unity 2017.2 and up - UWP.csproj.meta new file mode 100644 index 0000000..af6e72f --- /dev/null +++ b/Assets/Best HTTP (Pro)/Unity 2017.2 and up - UWP.csproj.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 02196b990df06b642926439dc75d6e54 +timeCreated: 1523771701 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Unity 5.x and up - Editor.csproj.meta b/Assets/Best HTTP (Pro)/Unity 5.x and up - Editor.csproj.meta new file mode 100644 index 0000000..fe8b692 --- /dev/null +++ b/Assets/Best HTTP (Pro)/Unity 5.x and up - Editor.csproj.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 11c82f406762a3842b5edee2b83f1916 +timeCreated: 1523773778 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Unity 5.x and up - General.csproj.meta b/Assets/Best HTTP (Pro)/Unity 5.x and up - General.csproj.meta new file mode 100644 index 0000000..7717d7d --- /dev/null +++ b/Assets/Best HTTP (Pro)/Unity 5.x and up - General.csproj.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1e0079ac594f4ff419a323c142b3bea9 +timeCreated: 1523773778 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Unity 5.x and up - UWP.csproj.meta b/Assets/Best HTTP (Pro)/Unity 5.x and up - UWP.csproj.meta new file mode 100644 index 0000000..039cea7 --- /dev/null +++ b/Assets/Best HTTP (Pro)/Unity 5.x and up - UWP.csproj.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ce8ec2ceeba19f7488c66865724f75a4 +timeCreated: 1523773778 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/Unity 5.x and up - WebGL.csproj.meta b/Assets/Best HTTP (Pro)/Unity 5.x and up - WebGL.csproj.meta new file mode 100644 index 0000000..539bdbf --- /dev/null +++ b/Assets/Best HTTP (Pro)/Unity 5.x and up - WebGL.csproj.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b6778a8babcdfad48a043ac6fdb2800f +timeCreated: 1523773778 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/license.txt b/Assets/Best HTTP (Pro)/license.txt new file mode 100644 index 0000000..f07dcff --- /dev/null +++ b/Assets/Best HTTP (Pro)/license.txt @@ -0,0 +1,171 @@ +Asset STORE End User License Agreement +1. Parties to the Agreement/The Subject Matter of the Agreement: +1.1 + +This Unity Asset Store End User License Agreement (hereinafter referred to as “EULAâ€) is a non-exclusive, legally binding end user license agreement between any individual or a single entity (“END-USERâ€) that acquires an Asset from the Unity Asset Store and either (i) Unity Technologies ApS (company no. 30 71 99 13), Lovstraede 5, DK-1152 Copenhagen K, Denmark (“Licensor†or "Unity"), or as the case may be (ii) any third party (“Providerâ€) that distributes its Assets from the Unity Asset Store. Consequently, this EULA shall apply regardless of whether a purchased Asset is produced by Unity or by a Provider ("Licensor"). This EULA is therefore a non-exclusive, legally binding end user license agreement as the case may be between either (i) Unity and END-User (in which case the term "Licensor" shall refer to Unity), or (ii) Provider and End User (in which case the term "Licensor" shall refer to Provider). + +1.2 + +By installing, copying, accessing, downloading or otherwise using the Assets, End User agrees to be bound the provisions of this EULA. All definitions of the Terms shall also apply in this EULA unless the context clearly provides for a different understanding. + +1.3 + +The subject matter of this EULA is the licensing to END-USER of any Asset acquired by End User from the Unity Asset Store. The Assets are licensed, not sold. + +1.4 + +END USER hereby acknowledges that in the event it acquires an ASSET which in the Unity Asset Store is marked as an Asset which is distributed by Provider (as opposed to Unity), then Provider shall be considered as Licensor of such Asset and, consequently, only Provider (as opposed to Unity) shall be responsible for any liability whatsoever under, any EULA or any breach by Provider, including (without limitation) liability for infringement of any intellectual property rights, irrespective of the fact that payment takes place to Unity. + +2. END-USER's Rights and Obligations +2.1 + +END-USER may use the licensed Assets only for their intended purpose. + +2.2 + +2.2.1 Non-Restricted Assets. The following concerns only Assets that are not Restricted Assets: + +Licensor grants to the END-USER a non-exclusive, worldwide, and perpetual license to the Asset to integrate Assets only as incorporated and embedded components of electronic games and interactive media and distribute such electronic game and interactive media. Except for game services software development kits (“Services SDKsâ€), END-USERS may modify Assets. END-USER may otherwise not reproduce, distribute, sublicense, rent, lease or lend the Assets. It is emphasized that the END-USERS shall not be entitled to distribute or transfer in any way (including, without, limitation by way of sublicense) the Assets in any other way than as integrated components of electronic games and interactive media. Without limitation of the foregoing it is emphasized that END-USER shall not be entitled to share the costs related to purchasing an Asset and then let any third party that has contributed to such purchase use such Asset (forum pooling). + +2.2.2 Restricted Assets. The following concerns only Restricted Assets: + +Restricted Assets have license terms different from other Assets. Those license terms are found in the materials accompanying Restricted Assets ("Restricted Asset Terms"). For clarity, to the extent Restricted Asset Terms are different from this EULA, the Restricted Asset Terms will control; otherwise, this EULA will continue to apply. No other use is licensed or permitted and END-USER may otherwise not use, reproduce, distribute, sublicense, rent, lease or lend Restricted Assets. Without limitation of the foregoing it is emphasized that END-USER shall not be entitled to share the costs related to purchasing a Restricted Asset and then let any third party that has contributed to such purchase use such Restricted Asset (forum pooling). + +2.3 + +EXCEPT FOR EDITOR EXTENSION ASSETS, END-USER is granted a license to install and use Assets on an unlimited number of computers provided that these computers are either all (i) physically located at a single physical location ("Site") belonging to END-USER, or (ii) laptops belonging to END-USER which have been made available by END-USER to its employees that are employed at the same Site provided all such computers have appropriately licensed Unity software installed. Consequently, any Asset may only be used at particular Site or on computers assigned to END-USER's employees employed at the same Site and may only be moved to another Site subject to prior written approval from Licensor. THIS CLAUSE 2.3 DOES NOT APPLY TO ASSETS THAT IN THE UNITY ASSET STORE ARE CATEGORIZED UNDER THE HEADING "EDITOR EXTENSIONS." + +2.4 + +Editor Extensions: END-USER is granted a license to install and use any Assets which are categorized in the Asset Store as "Editor Extensions" only on one (1) computer. For the avoidance of doubt, Editor Extension Assets are licensed on a per computer basis may not be shared or used concurrently on different computers. + +2.5 + +Game Services SDKs: If END-USER downloads and integrates Services SDKs, END-USER may be required to accept a Licensor end user agreement and/or additional Licensor terms and conditions to use such services. + +2.6 + +END-USER shall pay for the license to the Assets in accordance with the payment process provided in the Asset Store. END USER shall provide customary billing and tax information such as name, billing address, credit card information and VAT number (for EU residents). END USER agrees to pay for all purchases hereby authorizes the collection of such amounts including applicable taxes by charging the credit card provided, either directly by Unity or indirectly, via a third party online payment processor. VAT numbers cannot be added or changed after the purchase is completed. If you are directed to a third party payment processor, you may be subject to terms and conditions governing use of that third party’s service and that third party’s Privacy Policy. Please review such third party’s terms and conditions and privacy policy before using the services. All sales are final and there shall be no refunds except as required by law. + +2.7 + +Some components of Assets (whether developed by Unity or third parties) may also be governed by applicable open source software licenses. In the event of a conflict between the applicable EULA and any such open source licenses, the open source software licenses shall prevail with respect to those components. + +2.8 + +With respect to any Unity licensed Assets, no modification or use of those Assets shall: (i) infringe, misappropriate, or violate a third party’s patent, copyright, trademark, trade secret, moral rights, or other intellectual property rights, or rights of publicity or privacy; (ii) violate, or encourage any conduct that would violate, any applicable law or regulation or would give rise to liability of any kind; (iii) be fraudulent, false, misleading, or deceptive; (iv) be defamatory, obscene, pornographic, vulgar, or offensive; (v) promote discrimination, bigotry, racism, hatred, harassment, or harm against any individual or group; (vi) promote violence or actions that are threatening to any other person; or (vii) promote illegal or harmful activities or substances. + +2.9 + +In this EULA, “Restricted Asset†means any Asset licensed hereunder that is designated (on prior written approval from Unity) as a “Restricted Asset†in any materials accompanying the Asset. + +3. Licensor’s Rights and Obligations +3.1 + +Licensor shall render support services to END-USER only in the event a special agreement to this effect has been entered into. + +4. Termination +4.1 + +Without prejudice to any other rights, Licensor may terminate this EULA if END-USER fails to comply with the terms and conditions of this EULA and the Terms. + +4.2 + +END-USER may terminate END-USER’s license at any time. + +4.3 + +In the event that Unity at its discretion or as a result of a decision made by any competent court or authority makes a refund to END-USER of the fees paid for any Asset, then this EULA shall terminate for such Asset. + +4.4 + +In the event of termination of this EULA, all license rights granted herein terminate and END-USER shall immediately destroy any and all copies of the Assets contained on any type of media under the control of END-USER and confirm such destruction in writing to LICENSOR. + +5. Duplication Rights/Back Up Copy +5.1 + +END-USER may not make copies of the Assets, except and only to the extent that such activity is expressly permitted under mandatory statutory applicable law. In addition Licensor acknowledges that copies of the Assets may be made when the Assets have been integrated as parts of electronic games and interactive media, cf. Section 2.3 above. + +5.2 + +After installation of one copy of the Asset pursuant to this EULA, END USER may keep the original copy of the Asset solely for back up or archival purposes. + +6. Reverse Engineering, Decompilation, and Disassembly +6.1 + +Except for Services SDKs, END USER may modify Assets. END USER shall not reverse engineer, decompile, or disassemble Services SDKs, except and only to the extent that such activity is expressly permitted under mandatory statutory applicable law. + +7. Trademarks +7.1 + +This EULA does not grant END-USER any rights in connection with any trademarks or service marks of Licensor, Provider or Licensor's other suppliers. + +8. Upgrades and Support +8.1 + +Assets identified as upgrades replace and/or supplement the licensed Assets. + +8.2 + +Licensor may at its own discretion from time to time provide upgrades of the Assets to END USER without requesting further payment. Irrespective hereof END-USER is only entitled to licenses to upgrades if END-USER has entered into an Upgrade Agreement with Licensor. END-USER may use the upgraded Assets only in accordance with the terms of this EULA. + +8.3 + +END-USER is only entitled to support if END-USER has entered into a Support Agreement with Licensor. + +9. Copyright +9.1 + +The Assets are protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. + +9.2 + +All title and intellectual property rights in and to the Assets (including but not limited to any software, images, photographs, animations, graphics, 3D graphics, video, audio, music, text, tutorials, and “applets†incorporated into the Assets), the accompanying printed materials, and any copies of the Assets are owned by Licensor. All rights not expressly granted are reserved by Licensor. For greater certainty and without limitation of the foregoing, use of Assets, whether modified as permitted hereunder or unmodified, is limited to use as expressly provided in this EULA. + +10. Disclaimer of Warranties +10.1 + +END-USER UNDERSTANDS AND ACCEPTS THAT PRIOR TO PLACING ANY ASSET ON THE UNITY ASSET STORE, UNITY DOES NOT UNDERTAKE ANY LEGAL OBLIGATION TO MONITOR, PRE-SCREEN, REVIEW, FLAG, FILTER, MODIFY, REFUSE OR REMOVE ANY ASSET OR THEIR CONTENT FROM THE UNITY ASSET STORE. CONSEQUENTLY, END-USER EXPRESSLY UNDERSTANDS AND AGREES THAT ITS USE OF THE ASSETS IS AT END-USER'S SOLE RISK AND THAT THE ASSETS ARE PROVIDED “AS IS†AND “AS AVAILABLE†WITHOUT WARRANTY OF ANY KIND, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW. IN PARTICULAR, LICENSOR, ITS SUBSIDIARIES, HOLDING COMPANIES AND AFFILIATES, AND ITS LICENSORS DO NOT REPRESENT OR WARRANT TO END-USER THAT: + +(A) END-USER'S USE OF THE ASSETS WILL MEET END-USER'S REQUIREMENTS, +(B) END-USER'S USE OF THE ASSETS WILL BE UNINTERRUPTED, TIMELY, SECURE OR FREE FROM ERROR, +(C) ANY INFORMATION OBTAINED BY END-USER AS A RESULT OF END-USER'S USE OF THE ASSETS WILL BE ACCURATE OR RELIABLE, AND +(D) THAT DEFECTS IN THE OPERATION OR FUNCTIONALITY OF ANY SOFTWARE PROVIDED TO END-USER AS PART OF THE ASSETS WILL BE CORRECTED. +10.2 + +END-USER'S USE OF ANY ASSETS IS AT END-USER'S OWN DISCRETION AND RISK AND END-USER IS SOLELY RESPONSIBLE FOR ANY DAMAGE TO END-USER'S COMPUTER SYSTEM, OR OTHER DEVICE, OR LOSS OF DATA THAT RESULTS FROM SUCH USE. + +10.3 + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES TERMS OR CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY IMPLIED WARRANTIES TERMS AND CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT, WITH RESPECT TO ANY ASSETS. + +10.4 + +NONE OF THE ASSETS ARE INTENDED FOR USE IN THE OPERATION OF NUCLEAR FACILITIES, LIFE SUPPORT SYSTEMS, EMERGENCY COMMUNICATIONS, AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL SYSTEMS, OR ANY OTHER SUCH ACTIVITIES IN WHICH CASE THE FAILURE OF THE ASSETS COULD LEAD TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE. + +11. Limitation of Liability +11.1 + +LICENSOR AND ITS SUBSIDIARIES, HOLDING COMPANIES AND OTHER AFFILIATES TOTAL LIABILITY TO END-USER FROM ALL CAUSES OF ACTION AND UNDER ALL THEORIES OF LIABILITY UNDER THESE TERMS WILL BE LIMITED TO THE AMOUNTS PAID TO END-USER BY END-USER IN THE PAST SIX MONTHS FOR THE ASSETS RELATING TO THE DISPUTE. IN NO EVENT WILL LICENSOR OR ITS SUBSIDIARIES, HOLDING COMPANIES AND OTHER AFFILIATES SHALL BE LIABLE TO END-USER FOR ANY SPECIAL, INCIDENTAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING LOSS OF DATA, BUSINESS, PROFITS OR ABILITY TO EXECUTE) OR FOR the cost of procuring substitute products ARISING OUT OF OR IN CONNECTION WITH THESE TERMS OR YOUR USE OF THE ASSET STORE OR ANY ASSETS DOWNLOADED OR OTHERWISE OBTAINED FROM THE UNITY ASSET STORE, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, AND WHETHER OR NOT LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. THE FOREGOING LIMITATIONS WILL SURVIVE AND APPLY EVEN IF ANY LIMITED REMEDY SPECIFIED IN THIS AGREEMENT IS FOUND TO HAVE FAILED OF ITS ESSENTIAL PURPOSE. + +11.2 + +END-USER EXPRESSLY UNDERSTAND AND AGREE THAT LICENSOR, ITS SUBSIDIARIES, HOLDING COMPANIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO END-USER FOR ANY LOSS OR DAMAGE WHICH MAY BE INCURRED BY END-USER, INCLUDING BUT NOT LIMITED TO LOSS OR DAMAGE AS A RESULT OF: + +(I) ANY RELIANCE PLACED BY END-USER ON THE COMPLETENESS, ACCURACY OR EXISTENCE OF ANY ADVERTISING, OR AS A RESULT OF ANY RELATIONSHIP OR TRANSACTION BETWEEN END-USER AND LICENSOR OR ANY, DEVELOPER, ADVERTISER OR SPONSOR WHOSE ADVERTISING APPEARS IN THE ASSETS OR ON THE UNITY ASSET STORE; +(II) ANY CHANGES WHICH LICENSOR MAY MAKE TO THE ASSETS OR ON THE UNITY ASSET STORE, OR FOR ANY PERMANENT OR TEMPORARY CESSATION IN THE PROVISION OF THE UNITY ASSET STORE OR THE ASSETS (OR ANY FEATURES WITHIN THE ASSETS); +(III) THE DELETION OF, CORRUPTION OF, OR FAILURE TO STORE, ANY CONTENT AND OTHER COMMUNICATIONS DATA MAINTAINED OR TRANSMITTED BY OR THROUGH END-USER'S USE OF THE ASSETS; +(IV) END-USER'S FAILURE TO PROVIDE UNITY WITH ACCURATE ACCOUNT INFORMATION; +11.3 + +NOTHING IN THE TERMS EXCLUDES THE LIABILITY FOR LICENSOR, ITS SUBSIDIARIES OR AFFILIATES FOR: (I) DEATH AND PERSONAL INJURY CAUSED BY NEGLIGENCE; (II) FRAUDULENT MISREPRESENTATION; OR (III) ANY OTHER LIABILITY WHICH CANNOT BE LIMITED BY APPLICABLE LAW. + +12. Export Restrictions +12.1 + +Assets available on the Unity Asset Store may be subject to laws, administrative regulations and executive orders of those authorities responsible according to any applicable laws relating to the control of imports and exports of the Assets (“Export Lawsâ€). You agree to comply with all applicable Export Laws and you shall not export or re-export directly or indirectly (including via remote access) any part of the Assets to any country to which a license is required under the Export Laws without first obtaining a license. + +13. Venue and Applicable Law +13.1 + +This EULA and END-USER's relationship with Licensor under this EULA, shall be governed by the laws of Denmark without regard to its conflict of laws provisions. Any dispute arising out of or in connection with this Agreement, including any disputes regarding the existence, validity or termination thereof, shall be settled by simplified arbitration arranged by The Danish Institute of Arbitration in accordance with the rules of simplified arbitration procedure adopted by The Danish Institute of Arbitration and in force at the time when such proceedings are commenced. Notwithstanding this, Provider agrees that Licensor shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction. \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/license.txt.meta b/Assets/Best HTTP (Pro)/license.txt.meta new file mode 100644 index 0000000..01aa041 --- /dev/null +++ b/Assets/Best HTTP (Pro)/license.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d3b503aff0a21bf4db6cd58a4538485a +timeCreated: 1518595425 +licenseType: Free +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/link.xml b/Assets/Best HTTP (Pro)/link.xml new file mode 100644 index 0000000..18b0f09 --- /dev/null +++ b/Assets/Best HTTP (Pro)/link.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/link.xml.meta b/Assets/Best HTTP (Pro)/link.xml.meta new file mode 100644 index 0000000..52243c0 --- /dev/null +++ b/Assets/Best HTTP (Pro)/link.xml.meta @@ -0,0 +1,38 @@ +fileFormatVersion: 2 +guid: ddecb9df09ed71446ba7ca31ced7e9a5 +labels: +- http +- www +- web +- cache +- stream +- wp8 +- wsa +- metro +- rest +- api +- socket +- socket.io +- websocket +- websockets +- cookie +- proxy +- il2cpp +- android +- tcp +- https +- ios +- webrequest +- signalr +- eventsource +- server-sent +- events +- server-sentevents +- authentication +- samsung +- smart +- tv +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Best HTTP (Pro)/link_android_subset.xml b/Assets/Best HTTP (Pro)/link_android_subset.xml new file mode 100644 index 0000000..78abf27 --- /dev/null +++ b/Assets/Best HTTP (Pro)/link_android_subset.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/Best HTTP (Pro)/link_android_subset.xml.meta b/Assets/Best HTTP (Pro)/link_android_subset.xml.meta new file mode 100644 index 0000000..281b761 --- /dev/null +++ b/Assets/Best HTTP (Pro)/link_android_subset.xml.meta @@ -0,0 +1,6 @@ +fileFormatVersion: 2 +guid: e735d6733fbcd8f46a2dbc2de051f0ce +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ConcurrentDownloadManager_Test1.cs b/Assets/ConcurrentDownloadManager_Test1.cs new file mode 100644 index 0000000..41f063b --- /dev/null +++ b/Assets/ConcurrentDownloadManager_Test1.cs @@ -0,0 +1,388 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using BestHTTP; +using UnityEngine; +using System.Diagnostics; // for testing the time/performance +using Debug = UnityEngine.Debug; +using System.Threading; + +[Serializable] +public class ConcurrentDownloadManager_Test1 { + + [Serializable] + internal class ContentRange { + public readonly int start; + public readonly int end; + + public ContentRange(int rangeStart, int rangeEnd) { + start = rangeStart; + end = rangeEnd; + } + + public override string ToString() { return "" + start + " - " + end; } + } + + #region Member Variables + + // State + private long mContentSize = 0; + private int mDownloadedContentSize = 0; + private int mCompletedDownloadsCount = 0; + private int mConnectionCount = 1; + private List mRequests = new List(); + private bool mDownloadComplete = false; + private List mUnfinishedRequests + = new List(); // for a back-up check if requests finished + + private List mCompletedRanges = new List(); + + // When mFragmentSize or mConnectionCount is small and streaming is on, + // it will take multiple fragments to fill up one connection + // This variable helps us keep track of how many + // bytes have been downloaded so that we know where the offset in memory + // is for fragments past the first one + private Dictionary mRequestToBytesDownloaded = + new Dictionary(); + + // Data + private byte[] mDownloadedData = null; + private int mConsecutiveBytesCount = 0; + private int mCurrentThreadCount = 0; + + // Constants + private const int mFragmentSize = 128 * 1024; + + // Other + private Stopwatch mStopwatch = new Stopwatch(); + private int mRequestsSent = 0; + private int mCurrentRequestIndex = -1; + private object mAddRangeLock = new object(); + private object mConsecutiveBytesLock = new object(); + + #endregion + + #region Public Interface + + public ConcurrentDownloadManager_Test1() { + HTTPManager.MaxConnectionPerServer = 255; + ResetCompletedDownloadsCount(); + } + + public void Download(HTTPRequest request, int connectionCount) { + Reset(); + mStopwatch.Start(); + SetConnectionCount(connectionCount); + DoHeadRequest(request); + } + + ///

    + /// Returns a buffer of the consecutive downloaded bytes + /// This is a direct reference and can modify the original data; this is fastest + /// + /// A direct reference to the consecutive downloaded bytes + public ArraySegment GetConsecutiveBytes() { + lock (mDownloadedData) { + if (mDownloadedData == null) { return new ArraySegment(); } + + ArraySegment segment = + new ArraySegment(mDownloadedData, 0, GetConsecutiveBytesCount()); + return segment; + } + } + + /// + /// Copies the consecutive bytes into a new buffer and returns it. + /// The original data is immutable, so this is safer, but slower. + /// + /// A copy of the consecutive downloaded bytes + public byte[] GetConsecutiveBytesCopy() { + lock (mDownloadedData) { + if (mDownloadedData == null) { return null; } + + byte[] copyOfData = new byte[GetConsecutiveBytesCount()]; + Buffer.BlockCopy(mDownloadedData, 0, copyOfData, 0, + GetConsecutiveBytesCount()); + return copyOfData; + } + } + + public bool IsDownloadComplete() { + //Debug.Log("Content size: " + mContentSize + "; ConsecutiveByteCnt: " + GetConsecutiveBytesCount()); + return GetCompletedDownloadsCount() >= mConnectionCount && + GetConsecutiveBytesCount() >= mContentSize && + mContentSize > 0 /*to ensure this only returns true AFTER a download begins*/ + ; + } + + public float GetPercentDone() { + if (mContentSize <= 0) { return 0; } + float value = ((float) mDownloadedContentSize / mContentSize); + return Mathf.Clamp01(value); + } + + public void CancelRequests() { + HTTPManager.OnQuit(); + } + + #endregion + + #region Head Request + + private void DoHeadRequest(HTTPRequest request) { + Uri requestUri = new Uri(request.Uri.AbsoluteUri); + Debug.Log("Sending HEAD request to " + requestUri.AbsoluteUri); + HTTPRequest headReq = new HTTPRequest(requestUri, HTTPMethods.Head, OnHeadRequestComplete); + headReq.Send(); + } + + private void OnHeadRequestComplete(HTTPRequest request, HTTPResponse response) { + if (response == null || + request.State == HTTPRequestStates.Error) { + OnHeadRequestError(request); + return; + } + + long contentSize = Convert.ToInt64(response.GetFirstHeaderValue("content-length")); + mContentSize = contentSize; + + Debug.Log("Head request is complete. Status code: " + response.StatusCode); + ExecuteVideoDownload(request, mContentSize, mConnectionCount); + } + + private void OnHeadRequestError(HTTPRequest request) { + Debug.LogError("Error making HEAD request: " + request.Exception.Message); + } + + #endregion + + #region Video Download + + private void ExecuteVideoDownload(HTTPRequest request, long contentSize, int connections) { + AllocateMemory(); + + //Debug.Log("Downloading content at " + request.Uri.AbsoluteUri); + mConnectionCount = connections; + Uri requestUri = new Uri(request.Uri.AbsoluteUri); + + for (int i = 0; i < connections; i++) { + ContentRange range = GetContentRange(i, connections, contentSize); + //Debug.Log("Content range request: " + range.start + "-" + range.end); + HTTPRequest finalizedPartialRequest = PreparePartialDownloadRequest(requestUri, range); + AddRequest(finalizedPartialRequest); + } + + for (int i = 0; i < mRequests.Count; i++) { OnRequestInitialize(mRequests[i]); } + } + + // Send the request + private void OnRequestInitialize(HTTPRequest request) { + //Debug.Log("Sending HTTP Request to " + request.Uri.AbsoluteUri); + //Interlocked.Increment(ref mRequestsSent); + request.Send(); + } + + private void OnDownloadFinish(HTTPRequest request, HTTPResponse response) { + if (request.State == HTTPRequestStates.Error) { + OnRequestError(request); + } else if (request.State == HTTPRequestStates.TimedOut) { + OnRequestTimeout(request); + } else if (request.State == HTTPRequestStates.ConnectionTimedOut) { + OnRequestConnectionTimeout(request); + } else { + ProcessDownloadedData(request, + response); + if (request.State == HTTPRequestStates.Finished) + OnRequestFinish(request); + } + } + + private void OnRequestError(HTTPRequest request) { + Debug.LogError("Error with request: " + + "\n" + request.Exception.ToString() + + "\n" + request.Exception.StackTrace); + OnRequestInitialize(request); + } + + private void OnRequestTimeout(HTTPRequest request) { + Debug.LogError("Request timed out: "); + OnRequestInitialize(request); + } + + private void OnRequestConnectionTimeout(HTTPRequest request) { + Debug.LogError("Request connection timed out"); + OnRequestInitialize(request); + } + + private void OnRequestFinish(HTTPRequest request) { + //Debug.Log("On request finish"); + lock (mUnfinishedRequests) { mUnfinishedRequests.Remove(request); } + + if (request == null) { return; } + OnDownloadComplete(); + + if (AreDownloadsFinished()) { + mStopwatch.Stop(); + this.elapsed = mStopwatch.Elapsed; + Debug.Log("Time elapsed (ms): " + mStopwatch.Elapsed); + Debug.Log("Consecutive bytes: " + GetConsecutiveBytesCount()); + //mDownloadComplete = true; + } + } + + private TimeSpan elapsed; + public TimeSpan GetDownloadTime() { return this.elapsed; } + + private void OnDownloadComplete() { Interlocked.Increment(ref mCompletedDownloadsCount); } + + #endregion + + #region Memory & State + + private void AllocateMemory() { + Debug.Assert(mContentSize > 1024); // just a sanity check for the content size; 1KB is arbitrary + mDownloadedData = new byte[mContentSize]; // Allocate memory + mConsecutiveBytesCount = 0; + } + + private void ProcessDownloadedData(HTTPRequest request, HTTPResponse response) { + //Debug.Log("Processing downloaded data"); + if (request == null || response == null) { return; } + + if (!mRequestToBytesDownloaded.ContainsKey(request)) { + mRequestToBytesDownloaded[request] = 0; + } + + if (!response.IsStreamed) { + byte[] data = response.Data; + + // Copy data into memory + int offset = response.GetRange().FirstBytePos + mRequestToBytesDownloaded[request]; + int length = data.Length; + CopyDownloadedFragment(offset, length, ref data); + + // Keep track of how many bytes this connection downloaded & consecutive bytes + Interlocked.Add(ref mDownloadedContentSize, length); + Interlocked.Add(ref mConsecutiveBytesCount, length); + mDownloadComplete = mConsecutiveBytesCount >= mContentSize + && mContentSize > 0; + } else { + List fragments = response.GetStreamedFragments(); + if (fragments == null) + return; + + for (int i = 0; i < fragments.Count; i++) { + byte[] fragment = fragments[i]; + + // Copy data into memory + int offset = response.GetRange().FirstBytePos + mRequestToBytesDownloaded[request]; + int length = fragment.Length; + CopyDownloadedFragment(offset, length, ref fragment); + + // Keep track of how many bytes this connection downloaded & consecutive bytes + Interlocked.Add(ref mDownloadedContentSize, length); + mRequestToBytesDownloaded[request] += length; + Interlocked.Add(ref mConsecutiveBytesCount, length); + mDownloadComplete = mConsecutiveBytesCount >= mContentSize + && mContentSize > 0; + } + } + } + + private void CopyDownloadedFragment(int offset, int length, ref byte[] data) { + Buffer.BlockCopy(data, 0, mDownloadedData, offset, length); + } + + #endregion + + #region Helpers + + private void Reset() { + mContentSize = 0; + mDownloadedContentSize = 0; + mCompletedDownloadsCount = 0; + mConnectionCount = 1; + mRequests = new List(); + mDownloadComplete = false; + + mCompletedRanges = new List(); + + // Data + mDownloadedData = null; + mConsecutiveBytesCount = 0; + + // Other + mStopwatch = new Stopwatch(); + elapsed = TimeSpan.Zero; + mRequestsSent = 0; + mCurrentRequestIndex = -1; + } + + // division is 0-indexed + private ContentRange GetContentRange(int division, int totalDivisions, long contentLength) { + long divisionSize = contentLength / totalDivisions; + long offset = divisionSize * (division); + + long remainingBytes = contentLength % totalDivisions; + if (remainingBytes > 0 && division == totalDivisions-1) { // last division + divisionSize += remainingBytes; // get the last bytes (but sub 1 because index starts at 0) + } + + ContentRange range = new ContentRange((int) offset, (int) (offset+divisionSize-1)); + return range; + } + + private HTTPRequest PreparePartialDownloadRequest(Uri requestUri, ContentRange range) { + HTTPRequest partialRequest = new HTTPRequest(requestUri, OnDownloadFinish); + partialRequest.UseStreaming = true; + partialRequest.DisableCache = true; + partialRequest.SetRangeHeader(range.start, range.end); + partialRequest.MaxFragmentQueueLength = 1000; + + return partialRequest; + } + + #endregion + + #region Getters/Setters + + private void SetConnectionCount(int newConnectionCount) { + Debug.Assert(newConnectionCount > 0); + if (newConnectionCount <= 0) { return; } + mConnectionCount = newConnectionCount; + } + + private int GetConnectionCount() { + Debug.Assert(mConnectionCount > 0); + if (mConnectionCount <= 0) { SetConnectionCount(1); } // ensure valid output + return mConnectionCount; + } + + public int GetConsecutiveBytesCount() { + return mConsecutiveBytesCount; + } + + public byte[] GetDownloadedData() { + return mDownloadedData; + } + + private bool AreDownloadsFinished() { + bool downloadsComplete = GetCompletedDownloadsCount() >= GetConnectionCount(); + return downloadsComplete; + } + + private int GetFragmentSize() { return mFragmentSize; } + + private int GetCompletedDownloadsCount() { return mCompletedDownloadsCount; } + private void ResetCompletedDownloadsCount() { mCompletedDownloadsCount = 0; } + + private List GetRequests() { return mRequests; } + + private void AddRequest(HTTPRequest request) { + GetRequests().Add(request); + mUnfinishedRequests.Add(request); + } + private void RemoveRequest(HTTPRequest request) { GetRequests().Remove(request); } + + #endregion +} \ No newline at end of file diff --git a/Assets/ConcurrentDownloadManager_Test1.cs.meta b/Assets/ConcurrentDownloadManager_Test1.cs.meta new file mode 100644 index 0000000..cf2a439 --- /dev/null +++ b/Assets/ConcurrentDownloadManager_Test1.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 120a3574f3a7ce64c91a4160e68a115d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ConcurrentDownloadManager_Test2.cs b/Assets/ConcurrentDownloadManager_Test2.cs new file mode 100644 index 0000000..724d710 --- /dev/null +++ b/Assets/ConcurrentDownloadManager_Test2.cs @@ -0,0 +1,384 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using BestHTTP; +using UnityEngine; +using System.Diagnostics; // for testing the time/performance +using Debug = UnityEngine.Debug; +using System.Threading; + +[Serializable] +public class ConcurrentDownloadManager_Test2 { + + [Serializable] + internal class ContentRange { + public readonly int start; + public readonly int end; + + public ContentRange(int rangeStart, int rangeEnd) { + start = rangeStart; + end = rangeEnd; + } + + public override string ToString() { return "" + start + " - " + end; } + } + + #region Member Variables + + // State + private long mContentSize = 0; + private int mDownloadedContentSize = 0; + private int mCompletedDownloadsCount = 0; + private int mConnectionCount = 1; + private List mRequests = new List(); + private bool mDownloadComplete = false; + private List mUnfinishedRequests + = new List(); // for a back-up check if requests finished + + private List mCompletedRanges = new List(); + + // When mFragmentSize or mConnectionCount is small and streaming is on, + // it will take multiple fragments to fill up one connection + // This variable helps us keep track of how many + // bytes have been downloaded so that we know where the offset in memory + // is for fragments past the first one + private Dictionary mRequestToBytesDownloaded = + new Dictionary(); + + // Data + private byte[] mDownloadedData = null; + private int mConsecutiveBytesCount = 0; + private int mCurrentThreadCount = 0; + + // Constants + private const int mFragmentSize = 128 * 1024; + + // Other + private Stopwatch mStopwatch = new Stopwatch(); + private int mRequestsSent = 0; + private int mCurrentRequestIndex = -1; + private object mAddRangeLock = new object(); + private object mConsecutiveBytesLock = new object(); + + #endregion + + #region Public Interface + + public ConcurrentDownloadManager_Test2() { + HTTPManager.MaxConnectionPerServer = 255; + ResetCompletedDownloadsCount(); + } + + public void Download(HTTPRequest request, int connectionCount) { + Reset(); + mStopwatch.Start(); + SetConnectionCount(connectionCount); + DoHeadRequest(request); + } + + /// + /// Returns a buffer of the consecutive downloaded bytes + /// This is a direct reference and can modify the original data; this is fastest + /// + /// A direct reference to the consecutive downloaded bytes + public ArraySegment GetConsecutiveBytes() { + lock (mDownloadedData) { + if (mDownloadedData == null) { return new ArraySegment(); } + + ArraySegment segment = + new ArraySegment(mDownloadedData, 0, GetConsecutiveBytesCount()); + return segment; + } + } + + /// + /// Copies the consecutive bytes into a new buffer and returns it. + /// The original data is immutable, so this is safer, but slower. + /// + /// A copy of the consecutive downloaded bytes + public byte[] GetConsecutiveBytesCopy() { + lock (mDownloadedData) { + if (mDownloadedData == null) { return null; } + + byte[] copyOfData = new byte[GetConsecutiveBytesCount()]; + Buffer.BlockCopy(mDownloadedData, 0, copyOfData, 0, + GetConsecutiveBytesCount()); + return copyOfData; + } + } + + public bool IsDownloadComplete() { + //Debug.Log("Content size: " + mContentSize + "; ConsecutiveByteCnt: " + GetConsecutiveBytesCount()); + return GetCompletedDownloadsCount() >= mConnectionCount && + GetConsecutiveBytesCount() >= mContentSize && + mContentSize > 0 /*to ensure this only returns true AFTER a download begins*/ + ; + } + + public float GetPercentDone() { + if (mContentSize <= 0) { return 0; } + float value = ((float) mDownloadedContentSize / mContentSize); + return Mathf.Clamp01(value); + } + + public void CancelRequests() { + HTTPManager.OnQuit(); + } + + #endregion + + #region Head Request + + private void DoHeadRequest(HTTPRequest request) { + Uri requestUri = new Uri(request.Uri.AbsoluteUri); + Debug.Log("Sending HEAD request to " + requestUri.AbsoluteUri); + HTTPRequest headReq = new HTTPRequest(requestUri, HTTPMethods.Head, OnHeadRequestComplete); + headReq.Send(); + } + + private void OnHeadRequestComplete(HTTPRequest request, HTTPResponse response) { + if (response == null || + request.State == HTTPRequestStates.Error) { + OnHeadRequestError(request); + return; + } + + long contentSize = Convert.ToInt64(response.GetFirstHeaderValue("content-length")); + mContentSize = contentSize; + + Debug.Log("Head request is complete. Status code: " + response.StatusCode); + ExecuteVideoDownload(request, mContentSize, mConnectionCount); + } + + private void OnHeadRequestError(HTTPRequest request) { + Debug.LogError("Error making HEAD request: " + request.Exception.Message); + } + + #endregion + + #region Video Download + + private void ExecuteVideoDownload(HTTPRequest request, long contentSize, int connections) { + AllocateMemory(); + + //Debug.Log("Downloading content at " + request.Uri.AbsoluteUri); + mConnectionCount = connections; + Uri requestUri = new Uri(request.Uri.AbsoluteUri); + + for (int i = 0; i < connections; i++) { + ContentRange range = GetContentRange(i, connections, contentSize); + //Debug.Log("Content range request: " + range.start + "-" + range.end); + HTTPRequest finalizedPartialRequest = PreparePartialDownloadRequest(requestUri, range); + AddRequest(finalizedPartialRequest); + } + + for (int i = 0; i < mRequests.Count; i++) { OnRequestInitialize(mRequests[i]); } + } + + // Send the request + private void OnRequestInitialize(HTTPRequest request) { + Debug.Log("Sending HTTP Request to " + request.Uri.AbsoluteUri); + //Interlocked.Increment(ref mRequestsSent); + request.Send(); + } + + private void OnDownloadFinish(HTTPRequest request, HTTPResponse response) { + if (request.State == HTTPRequestStates.Error) { + OnRequestError(request); + } else if (request.State == HTTPRequestStates.TimedOut) { + OnRequestTimeout(request); + } else if (request.State == HTTPRequestStates.ConnectionTimedOut) { + OnRequestConnectionTimeout(request); + } else { + ProcessDownloadedData(request, + response); + if (request.State == HTTPRequestStates.Finished) + OnRequestFinish(request); + } + } + + private void OnRequestError(HTTPRequest request) { + Debug.LogError("Error with request: " + + "\n" + request.Exception.ToString() + + "\n" + request.Exception.StackTrace); + OnRequestInitialize(request); + } + + private void OnRequestTimeout(HTTPRequest request) { + Debug.LogError("Request timed out: "); + OnRequestInitialize(request); + } + + private void OnRequestConnectionTimeout(HTTPRequest request) { + Debug.LogError("Request connection timed out"); + OnRequestInitialize(request); + } + + private void OnRequestFinish(HTTPRequest request) { + //Debug.Log("On request finish"); + lock (mUnfinishedRequests) { mUnfinishedRequests.Remove(request); } + + if (request == null) { return; } + OnDownloadComplete(); + + if (AreDownloadsFinished()) { + mStopwatch.Stop(); + this.elapsed = mStopwatch.Elapsed; + Debug.Log("Time elapsed (ms): " + mStopwatch.Elapsed); + Debug.Log("Consecutive bytes: " + GetConsecutiveBytesCount()); + //mDownloadComplete = true; + } + } + + private TimeSpan elapsed; + public TimeSpan GetDownloadTime() { return this.elapsed; } + + private void OnDownloadComplete() { Interlocked.Increment(ref mCompletedDownloadsCount); } + + #endregion + + #region Memory & State + + private void AllocateMemory() { + Debug.Assert(mContentSize > 1024); // just a sanity check for the content size; 1KB is arbitrary + mDownloadedData = new byte[mContentSize]; // Allocate memory + mConsecutiveBytesCount = 0; + } + + private void ProcessDownloadedData(HTTPRequest request, HTTPResponse response) { + //Debug.Log("Processing downloaded data"); + if (request == null || response == null) { return; } + + if (!mRequestToBytesDownloaded.ContainsKey(request)) { + mRequestToBytesDownloaded[request] = 0; + } + + if (!response.IsStreamed) { + byte[] data = response.Data; + + // Copy data into memory + int offset = response.GetRange().FirstBytePos + mRequestToBytesDownloaded[request]; + int length = data.Length; + CopyDownloadedFragment(offset, length, ref data); + + // Keep track of how many bytes this connection downloaded & consecutive bytes + Interlocked.Add(ref mDownloadedContentSize, length); + Interlocked.Add(ref mConsecutiveBytesCount, length); + mDownloadComplete = mConsecutiveBytesCount >= mContentSize + && mContentSize > 0; + } else { + List fragments = response.GetStreamedFragments(); + if (fragments != null) + for (int i = 0; i < fragments.Count; i++) { + byte[] fragment = fragments[i]; + + // Copy data into memory + int offset = response.GetRange().FirstBytePos + mRequestToBytesDownloaded[request]; + int length = fragment.Length; + CopyDownloadedFragment(offset, length, ref fragment); + + // Keep track of how many bytes this connection downloaded & consecutive bytes + Interlocked.Add(ref mDownloadedContentSize, length); + mRequestToBytesDownloaded[request] += length; + Interlocked.Add(ref mConsecutiveBytesCount, length); + mDownloadComplete = mConsecutiveBytesCount >= mContentSize + && mContentSize > 0; + } + } + } + + private void CopyDownloadedFragment(int offset, int length, ref byte[] data) { + Buffer.BlockCopy(data, 0, mDownloadedData, offset, length); + } + + #endregion + + #region Helpers + + private void Reset() { + mContentSize = 0; + mDownloadedContentSize = 0; + mCompletedDownloadsCount = 0; + mConnectionCount = 1; + mRequests = new List(); + mDownloadComplete = false; + + mCompletedRanges = new List(); + + // Data + mDownloadedData = null; + mConsecutiveBytesCount = 0; + + // Other + mStopwatch = new Stopwatch(); + mRequestsSent = 0; + mCurrentRequestIndex = -1; + } + + // division is 0-indexed + private ContentRange GetContentRange(int division, int totalDivisions, long contentLength) { + long divisionSize = contentLength / totalDivisions; + long offset = divisionSize * (division); + + long remainingBytes = contentLength % totalDivisions; + if (remainingBytes > 0 && division == totalDivisions-1) { // last division + divisionSize += remainingBytes; // get the last bytes (but sub 1 because index starts at 0) + } + + ContentRange range = new ContentRange((int) offset, (int) (offset+divisionSize-1)); + return range; + } + + private HTTPRequest PreparePartialDownloadRequest(Uri requestUri, ContentRange range) { + HTTPRequest partialRequest = new HTTPRequest(requestUri, OnDownloadFinish); + partialRequest.UseStreaming = true; + partialRequest.DisableCache = true; + partialRequest.SetRangeHeader(range.start, range.end); + + return partialRequest; + } + + #endregion + + #region Getters/Setters + + private void SetConnectionCount(int newConnectionCount) { + Debug.Assert(newConnectionCount > 0); + if (newConnectionCount <= 0) { return; } + mConnectionCount = newConnectionCount; + } + + private int GetConnectionCount() { + Debug.Assert(mConnectionCount > 0); + if (mConnectionCount <= 0) { SetConnectionCount(1); } // ensure valid output + return mConnectionCount; + } + + public int GetConsecutiveBytesCount() { + return mConsecutiveBytesCount; + } + + public byte[] GetDownloadedData() { + return mDownloadedData; + } + + private bool AreDownloadsFinished() { + bool downloadsComplete = GetCompletedDownloadsCount() >= GetConnectionCount(); + return downloadsComplete; + } + + private int GetFragmentSize() { return mFragmentSize; } + + private int GetCompletedDownloadsCount() { return mCompletedDownloadsCount; } + private void ResetCompletedDownloadsCount() { mCompletedDownloadsCount = 0; } + + private List GetRequests() { return mRequests; } + + private void AddRequest(HTTPRequest request) { + GetRequests().Add(request); + mUnfinishedRequests.Add(request); + } + private void RemoveRequest(HTTPRequest request) { GetRequests().Remove(request); } + + #endregion +} \ No newline at end of file diff --git a/Assets/ConcurrentDownloadManager_Test2.cs.meta b/Assets/ConcurrentDownloadManager_Test2.cs.meta new file mode 100644 index 0000000..303b13b --- /dev/null +++ b/Assets/ConcurrentDownloadManager_Test2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 890e9575f1a4bc941aab89b70e93888d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ConcurrentQueue.cs b/Assets/ConcurrentQueue.cs new file mode 100644 index 0000000..cbfa37d --- /dev/null +++ b/Assets/ConcurrentQueue.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using UnityEngine; + +public class ConcurrentQueue +{ + private List queue; + private object syncLock = new object(); + + public ConcurrentQueue() + { + this.queue = new List(); + } + + public ConcurrentQueue(int capacity) + { + this.queue = new List(capacity); + } + + public int Count + { + get + { + //lock (syncLock) + { + return queue.Count; + } + } + } + + public void Clear() + { + lock (syncLock) + { + queue.Clear(); + } + } + + public void Enqueue(T obj) + { + lock (syncLock) + { + queue.Add(obj); + } + } + + public void EnqueueRange(IEnumerable objs) + { + lock (syncLock) + { + queue.AddRange(objs); + } + } + + public bool TryEnqueue(T obj) + { + if (Monitor.TryEnter(syncLock, 0)) + { + try + { + queue.Add(obj); + return true; + } + finally + { + Monitor.Exit(syncLock); + } + } + else + { + return false; + } + } + + public bool TryEnqueueRange(IEnumerable objs) + { + if (Monitor.TryEnter(syncLock, 0)) + { + try + { + queue.AddRange(objs); + return true; + } + finally + { + Monitor.Exit(syncLock); + } + } + else + { + return false; + } + } + + public bool Dequeue(out T target) + { + target = default(T); + + if (queue.Count == 0) + return false; + + lock (syncLock) + { + if (queue.Count == 0) + return false; + + target = queue[0]; + queue.RemoveAt(0); + + return true; + } + } + + public bool DequeueAll(List targetList) + { + if (queue.Count == 0) + return false; + + lock (syncLock) + { + if (queue.Count == 0) + return false; + + targetList.AddRange(queue); + queue.Clear(); + + return true; + } + } + + public bool TryDequeue(out T target) + { + target = default(T); + + if (queue.Count == 0) + return false; + + if (Monitor.TryEnter(syncLock, 0)) + { + try + { + if (queue.Count == 0) + return false; + + target = queue[0]; + queue.RemoveAt(0); + + return true; + } + finally + { + Monitor.Exit(syncLock); + } + } + else + { + return false; + } + } + + public bool TryDequeueAll(List targetList) + { + if (queue.Count == 0) + return false; + + if (Monitor.TryEnter(syncLock, 0)) + { + try + { + if (queue.Count == 0) + return false; + + targetList.AddRange(queue); + queue.Clear(); + + return true; + } + finally + { + Monitor.Exit(syncLock); + } + } + else + { + return false; + } + } +} diff --git a/Assets/ConcurrentQueue.cs.meta b/Assets/ConcurrentQueue.cs.meta new file mode 100644 index 0000000..bbf1626 --- /dev/null +++ b/Assets/ConcurrentQueue.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 0c26f3e50287f3548ba95a0beb970a35 +timeCreated: 1537278287 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DistributedDownloadManager.cs b/Assets/DistributedDownloadManager.cs new file mode 100644 index 0000000..f0ed489 --- /dev/null +++ b/Assets/DistributedDownloadManager.cs @@ -0,0 +1,567 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using BestHTTP; +using UnityEngine; +using System.Diagnostics; +using System.Linq; +// for testing the time/performance +using Debug = UnityEngine.Debug; +using System.Threading; + + +/// +/// Each video file will be fragmented into multiple sections at different URIs. These fragments +/// have to each be downloaded and subsequently reassembled +/// 1. For each URI, do a head request to determine the fragment's content length +/// Otherwise, we wouldn't know where each fragment gets placed in memory, +/// and there would be extra memory usage which we want to avoid +/// 2. After all the content lengths are determined, GET requests should be sent to download the fragments +/// 3. As each fragment is being downloaded, each chunk needs to be copied into memory +/// TODO: update consecutive bytes state + count +/// 4. When all fragments are done, the download is done +/// +public class DistributedDownloadManager { + + #region Member Variables + + // State + private long mContentSize = 0; + private int mDownloadedContentSize = 0; + private int mCompletedDownloadsCount = 0; + private int mConnectionCount = 1; + private int mThreadCount = 1; + private bool mDownloadComplete = false; + + // When mFragmentSize or mConnectionCount is small and streaming is on, + // it will take multiple fragments to fill up one connection + // This variable helps us keep track of how many + // bytes have been downloaded so that we know where the offset in memory + // is for fragments past the first one + private Dictionary mRequestToBytesDownloaded = + new Dictionary(); + + // Data + private byte[] mDownloadedData = null; + private int mConsecutiveBytesCount = 0; + private List mThreads = new List(); + private int mCurrentThreadCount = 0; + private RemoteFileMetadata m_RemoteFileMetadata; + + // Constants + private const int mFragmentSize = 8 * 1024 * 1024; + + // Other + public Stopwatch mStopwatch = new Stopwatch(); + private string lastDownloadedURI = ""; // for error checking + + #endregion + + #region Public Interface + + public DistributedDownloadManager() { + HTTPManager.MaxConnectionPerServer = 8; + ResetCompletedDownloadsCount(); + } + + /// + /// Downloads a file that is fragmented into different URIs + /// + /// + /// + public void Download(RemoteFileMetadata fileMetadata, int threadCount) { + Reset(); + if (!fileMetadata.IsValid()) { return; } + + m_RemoteFileMetadata = fileMetadata; + SetConnectionCount(fileMetadata.GetFileFragments().Count); + SetThreadCount(threadCount); + + for (int i = 0; i < mThreadCount; ++i) { + Thread t = new Thread(WorkerThread); + mThreads.Add(t); + t.Start(); + } + + mStopwatch.Start(); + } + + + /// + /// Returns a buffer of the consecutive downloaded bytes + /// This is a direct reference and can modify the original data; this is fastest + /// + /// A direct reference to the consecutive downloaded bytes + public ArraySegment GetConsecutiveBytes() { + lock (mDownloadedData) { + if (mDownloadedData == null) { return new ArraySegment(); } + + ArraySegment segment = + new ArraySegment(mDownloadedData, 0, GetConsecutiveBytesCount()); + return segment; + } + } + + /// + /// Copies the consecutive bytes into a new buffer and returns it. + /// The original data is immutable, so this is safer, but slower. + /// + /// A copy of the consecutive downloaded bytes + public byte[] GetConsecutiveBytesCopy() { + if (mDownloadedData == null) { return null; } + + lock (mDownloadedData) { + + byte[] copyOfData = new byte[GetConsecutiveBytesCount()]; + Buffer.BlockCopy(mDownloadedData, 0, copyOfData, 0, + GetConsecutiveBytesCount()); + return copyOfData; + } + } + + public bool IsDownloadComplete() { + //Debug.Log("Content size: " + mContentSize + "; ConsecutiveByteCnt: " + GetConsecutiveBytesCount()); + //return GetCompletedDownloadsCount() >= mConnectionCount && + // GetConsecutiveBytesCount() >= mContentSize && + // mContentSize > 0 /*to ensure this only returns true AFTER a download begins*/ + // ; + return mDownloadComplete && + mDownloadedContentSize >= mContentSize && + mContentSize > 0; + } + + public byte[] GetDownloadedData() { return mDownloadedData; } + + public float GetPercentDone() { + if (mContentSize <= 0) { return 0; } + float value = ((float) mDownloadedContentSize / mContentSize); + return Mathf.Clamp01(value); + } + + public void StopThreads() { mDownloadComplete = true; } + + #endregion + + #region Controller + + private void WorkerThread() { + ConcurrentQueue fragmentQueue = + m_RemoteFileMetadata.GetFileFragmentDataQueue(); + + while (!mDownloadComplete) { + RemoteFileFragmentMetadata fragmentMetadata; + bool hasData = fragmentQueue.Dequeue(out fragmentMetadata); + + if (!hasData || fragmentMetadata == null) { + fragmentQueue.Enqueue(fragmentMetadata); + Thread.Sleep(16); + continue; + } + + if (fragmentMetadata.IsReadyForHeadRequest()) { + BeginHeadRequest(fragmentMetadata); + fragmentQueue.Enqueue(fragmentMetadata); + } + else if (m_RemoteFileMetadata.AreHeadRequestsCompleted() && + fragmentMetadata.IsReadyForDownload()) { + BeginDownloadRequest(fragmentMetadata); + fragmentQueue.Enqueue(fragmentMetadata); + } + else if (fragmentMetadata.IsFinishedDownloading()) { + OnDownloadFinish(fragmentMetadata); + } else { + fragmentQueue.Enqueue(fragmentMetadata); + } + + Thread.Sleep(24); + } + Debug.Log("Worker thread completed"); + } + + #endregion + + #region Head Request + + private void BeginHeadRequest(RemoteFileFragmentMetadata fragmentMetadata) { + HTTPRequest headRequest = new HTTPRequest(fragmentMetadata.uri, + HTTPMethods.Head, + OnHeadRequestComplete); + fragmentMetadata.BeginHeadRequest(); + DoHeadRequest(headRequest); + } + + private void DoHeadRequest(HTTPRequest request) { + Debug.Log("Sending HEAD request to " + request.Uri.AbsoluteUri); + request.Send(); + } + + private void OnHeadRequestComplete(HTTPRequest request, HTTPResponse response) { + if (response == null) { + OnHeadRequestError(request); + return; + } + + RemoteFileFragmentMetadata fragment = + m_RemoteFileMetadata.GetFileFragmentDataFromUri(request.Uri.AbsoluteUri); + fragment.ProcessHeadResponse(response); + + Debug.Log("Head request is complete. Status code: " + response.StatusCode); + + if (m_RemoteFileMetadata.AreHeadRequestsCompleted()) { OnAllHeadRequestsComplete(); } + } + + private void OnAllHeadRequestsComplete() { + // Memory + mContentSize = m_RemoteFileMetadata.GetMemorySize(); + AllocateMemory(); + } + + private void OnHeadRequestError(HTTPRequest request) { + Debug.LogError("Error making HEAD request: " + request.Exception.Message); + BeginHeadRequest(m_RemoteFileMetadata.GetFileFragmentDataFromUri(request.Uri.AbsoluteUri)); + } + + #endregion + + #region Video Download + + private void BeginDownloadRequest(RemoteFileFragmentMetadata fragmentMetadata) { + // Request + HTTPRequest request = + PreparePartialDownloadRequest(fragmentMetadata.uri.AbsoluteUri); + fragmentMetadata.BeginDownload(); + SendDownloadRequest(request); + } + + // Send the request + private void SendDownloadRequest(HTTPRequest request) { + Debug.Log("Sending HTTP Request to " + request.Uri.AbsoluteUri); + request.Send(); + } + + private void OnDownloadProcessing(HTTPRequest request, HTTPResponse response) { + Debug.Assert(response != null); + Debug.Log("Processing request from " + request.Uri.AbsoluteUri); + RemoteFileFragmentMetadata fragmentMetadata = + m_RemoteFileMetadata.GetFileFragmentDataFromUri(request.Uri.AbsoluteUri); + Debug.Log("Fragment index: " + fragmentMetadata.index); + + lock (fragmentMetadata) { + if (!response.HasStreamedFragments()) { return; } + List fragmentBytesList = response.GetStreamedFragments(); + + //if (lastDownloadedURI == request.Uri.AbsoluteUri) { + // Debug.LogWarning("Download callback called twice in a row -- ignoring the second one"); + // return; + //} + if (fragmentBytesList == null) { return; } + + for (int i = 0; i < fragmentBytesList.Count; ++i) { + byte[] fragmentBytes = fragmentBytesList[i]; + int offset = + m_RemoteFileMetadata.GetFileFragmentMemoryOffset(fragmentMetadata) + + (int) fragmentMetadata.GetDownloadedBytes(); + int length = fragmentBytes.Length; + + Debug.Log("Copying " + length + " bytes at offset " + offset); + CopyDownloadedFragment(offset, length, ref fragmentBytes); + fragmentMetadata.AddDownloadedBytes(length); + Interlocked.Add(ref mDownloadedContentSize, length); + Debug.Log("Downloaded content size: " + mDownloadedContentSize + " / " + mContentSize); + } + + fragmentMetadata.ProcessGetResponse(response); + } + lastDownloadedURI = request.Uri.AbsoluteUri; // for error checking + } + + private void OnDownloadFinish(RemoteFileFragmentMetadata fragment) { + Debug.Log("On request finish"); + + OnDownloadComplete(); + + if (AreDownloadsFinished()) { + //mDownloadComplete = true; + OnAllDownloadsFinished(); + } + } + + // copy stuff into memory + private void OnAllDownloadsFinished() { + Debug.Log("Time elapsed (ms): " + mStopwatch.Elapsed); + Debug.Log("Consecutive bytes: " + GetConsecutiveBytesCount()); + mDownloadComplete = true; + } + + private void OnDownloadComplete() { Interlocked.Increment(ref mCompletedDownloadsCount); } + + #endregion + + #region Memory & State + + private void AllocateMemory() { + Debug.Assert(mContentSize > 1024); // just a sanity check for the content size; 1KB is arbitrary + mDownloadedData = new byte[mContentSize]; // Allocate memory + mConsecutiveBytesCount = 0; + } + + private void CopyDownloadedFragment(int offset, int length, ref byte[] data) { + lock (mDownloadedData) { + Buffer.BlockCopy(data, 0, mDownloadedData, offset, length); + } + } + + #endregion + + #region Helpers + + private void Reset() { + mContentSize = 0; + mDownloadedContentSize = 0; + mCompletedDownloadsCount = 0; + mConnectionCount = 1; + mThreadCount = 1; + mDownloadComplete = false; + + // Data + mDownloadedData = null; + m_RemoteFileMetadata = null; + mConsecutiveBytesCount = 0; + + // Other + mStopwatch = new Stopwatch(); + } + + private HTTPRequest PreparePartialDownloadRequest(string requestUriString) { + Uri requestUri = new Uri(requestUriString); + HTTPRequest partialRequest = new HTTPRequest(requestUri) { + UseStreaming = true, + StreamFragmentSize = GetFragmentSize(), + DisableCache = true, + Callback = OnDownloadProcessing + }; + + return partialRequest; + } + + #endregion + + #region Getters/Setters + + private void SetConnectionCount(int newConnectionCount) { + Debug.Assert(newConnectionCount > 0); + if (newConnectionCount <= 0) { return; } + mConnectionCount = newConnectionCount; + } + + private int GetConnectionCount() { + Debug.Assert(mConnectionCount > 0); + if (mConnectionCount <= 0) { SetConnectionCount(1); } // ensure valid output + return mConnectionCount; + } + + private void SetThreadCount(int newThreadCount) { + Debug.Assert(newThreadCount > 0); + if (newThreadCount <= 0) { return; } + mThreadCount = newThreadCount; + } + + private int GetThreadCount() { + Debug.Assert(mThreadCount > 0); + if (mThreadCount <= 0) { SetThreadCount(1); } // ensure valid output + return mThreadCount; + } + + public int GetConsecutiveBytesCount() { + return mConsecutiveBytesCount; + } + + + private bool AreDownloadsFinished() { + bool downloadsComplete = GetCompletedDownloadsCount() >= + m_RemoteFileMetadata.GetFileFragments().Count; + return downloadsComplete; + } + + private int GetFragmentSize() { return mFragmentSize; } + + private int GetCompletedDownloadsCount() { return mCompletedDownloadsCount; } + private void ResetCompletedDownloadsCount() { mCompletedDownloadsCount = 0; } + + #endregion +} + +public class RemoteFileMetadata { + private List m_FileData = + new List(); + + private ConcurrentQueue m_FileDataQueue; + + public RemoteFileMetadata AddFileFragmentData(RemoteFileFragmentMetadata metadata) { + m_FileData.Add(metadata); + Sort(); + return this; + } + + public RemoteFileMetadata AddFileFragmentData(Uri uri, uint index) { + RemoteFileFragmentMetadata metadata = new RemoteFileFragmentMetadata(uri, index); + m_FileData.Add(metadata); + Sort(); + return this; + } + + public bool IsValid() { + for (int i = 0; i < GetFileFragments().Count; i++) { + RemoteFileFragmentMetadata fragment = GetFileFragments()[i]; + if (fragment == null) { + Debug.LogWarning("FileFragmentData is NULL"); + return false; + } + + if (fragment.index != i) { + Debug.LogWarning("FileFragmentData index is " + fragment.index + + " but should be " + i); + return false; + } + } + + return true; + } + + public bool IsFinishedDownloading() { + for (int i = 0; i < GetFileFragments().Count; ++i) { + RemoteFileFragmentMetadata fragment = GetFileFragments()[i]; + if (!fragment.IsFinishedDownloading()) { return false; } + } + + return true; + } + + public bool AreHeadRequestsCompleted() { + for (int i = 0; i < GetFileFragments().Count; ++i) { + RemoteFileFragmentMetadata fragment = GetFileFragments()[i]; + if (!(fragment.IsReadyForDownload() || + fragment.IsDownloading() || + fragment.IsFinishedDownloading())) { return false; } + } + + return true; + } + + public RemoteFileFragmentMetadata GetFileFragmentDataFromUri(string absoluteUri) { + for (int i = 0; i < GetFileFragments().Count; ++i) { + RemoteFileFragmentMetadata fragment = GetFileFragments()[i]; + if (fragment.uri.AbsoluteUri == absoluteUri) { return fragment; } + } + + return null; + } + + /// + /// Get this fragment's offset in the buffer. Previous fragments must finish downloading though to make their + /// content length known (in chunked encoding) though + /// + /// + /// The offset in memory to which this fragment should be copied to + public int GetFileFragmentMemoryOffset(RemoteFileFragmentMetadata fragment) { + int offset = 0; + for (int i = 0; i < GetFileFragments().Count; i++) { + RemoteFileFragmentMetadata currentFragment = GetFileFragments()[i]; + + if (currentFragment != fragment) { + offset += (int) currentFragment.GetSize(); + } else { break; } + } + + return offset; + } + + public int GetMemorySize() { + int bytes = 0; + for (int i = 0; i < GetFileFragments().Count; ++i) { + bytes += (int) GetFileFragments()[i].GetSize(); + } + + return bytes; + } + + /// + /// Creates a concurrent queue from the list of fragments. + /// Only call this after all the fragments have been added to the list + /// + /// + public ConcurrentQueue GetFileFragmentDataQueue() { + if (m_FileDataQueue == null) { + m_FileDataQueue = new ConcurrentQueue(); + + for (int i = 0; i < GetFileFragments().Count; ++i) { + m_FileDataQueue.Enqueue(GetFileFragments()[i]); + } + } + + return m_FileDataQueue; + } + + private void Sort() { + GetFileFragments().Sort((x, y) => (x.index.CompareTo(y.index))); + } + + public List GetFileFragments() { return m_FileData; } +} + +public class RemoteFileFragmentMetadata { + private enum FileFragmentDataState { + ReadyForHeadRequest, + HeadRequest, + ReadyForDownload, + Downloading, + Finished + }; + + public Uri uri; + public uint index; + private uint size = 0; // in bytes + private uint downloadedBytes = 0; + private FileFragmentDataState state = FileFragmentDataState.ReadyForHeadRequest; + + + public RemoteFileFragmentMetadata(Uri _uri, uint _index) { + uri = _uri; + index = _index; + } + + public void ProcessHeadResponse(HTTPResponse response) { + Debug.Assert(response != null, this); + size = Convert.ToUInt32(response.GetFirstHeaderValue("content-length")); + state = FileFragmentDataState.ReadyForDownload; + } + + public void ProcessGetResponse(HTTPResponse response) { + if (response.IsStreamingFinished) { state = FileFragmentDataState.Finished; } + } + + public void AddDownloadedBytes(int size) { downloadedBytes += (uint) size; } + + public uint GetDownloadedBytes() { return downloadedBytes; } + + public uint GetSize() { return size; } + + public void BeginHeadRequest() { state = FileFragmentDataState.HeadRequest; } + + public void BeginDownload() { state = FileFragmentDataState.Downloading; } + + public bool IsReadyForHeadRequest() { + return state == FileFragmentDataState.ReadyForHeadRequest; + } + + public bool IsReadyForDownload() { + return state == FileFragmentDataState.ReadyForDownload; + } + + public bool IsDownloading() { return state == FileFragmentDataState.Downloading; } + + public bool IsFinishedDownloading() { + return state == FileFragmentDataState.Finished; + } + +} diff --git a/Assets/DistributedDownloadManager.cs.meta b/Assets/DistributedDownloadManager.cs.meta new file mode 100644 index 0000000..d769c0e --- /dev/null +++ b/Assets/DistributedDownloadManager.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 85d282bd495b9384287c9b136f663d54 +timeCreated: 1537277823 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DownloadSpeedTest_Test1.cs b/Assets/DownloadSpeedTest_Test1.cs new file mode 100644 index 0000000..f11a1b1 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test1.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public sealed class DownloadSpeedTest_Test1 : MonoBehaviour +{ + public UnityEngine.UI.Text statusText; + + [NonSerialized] + ConcurrentDownloadManager_Test1 manager; + + private void Start() + { + Application.runInBackground = true; + + int workerThreads, completionThreads; + //System.Threading.ThreadPool.GetAvailableThreads(out workerThreads, out completionThreads); + //Debug.Log("Available worker threads: " + workerThreads); + + System.Threading.ThreadPool.GetMinThreads(out workerThreads, out completionThreads); + Debug.Log("Min worker threads: " + workerThreads); + + System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out completionThreads); + Debug.Log("Max worker threads: " + workerThreads); + } + + public void On_StartTestButtonClicked() + { + manager = new ConcurrentDownloadManager_Test1(); + manager.Download(new BestHTTP.HTTPRequest(new Uri("https://data.panomoments.com/processed/58a7514e550d37000bfd46d2/5a90ce21d3df99000e981d11/uhd_dashinit.mp4")), 128); + } + + private void Update() + { + if (this.manager != null) + { + if (!this.manager.IsDownloadComplete()) + this.statusText.text = this.manager.GetPercentDone().ToString("F2"); + else + this.statusText.text = "Finished in " + this.manager.GetDownloadTime().TotalMilliseconds.ToString("N0") + "ms"; + } + } +} \ No newline at end of file diff --git a/Assets/DownloadSpeedTest_Test1.cs.meta b/Assets/DownloadSpeedTest_Test1.cs.meta new file mode 100644 index 0000000..adeaf30 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test1.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a9c85a1b212aba4881711d8dbf04bf9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DownloadSpeedTest_Test1.unity b/Assets/DownloadSpeedTest_Test1.unity new file mode 100644 index 0000000..ba04992 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test1.unity @@ -0,0 +1,865 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 8 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311918, g: 0.3807398, b: 0.35872716, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 9 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &296382935 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 296382936} + - component: {fileID: 296382938} + - component: {fileID: 296382937} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &296382936 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 296382935} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2064235129} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &296382937 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 296382935} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Home +--- !u!222 &296382938 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 296382935} +--- !u!1 &451395639 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 451395642} + - component: {fileID: 451395641} + - component: {fileID: 451395640} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &451395640 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_Enabled: 1 +--- !u!20 &451395641 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &451395642 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &581481930 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 581481931} + - component: {fileID: 581481934} + - component: {fileID: 581481933} + - component: {fileID: 581481932} + - component: {fileID: 581481935} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &581481931 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 710223368} + - {fileID: 1622957196} + - {fileID: 2064235129} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &581481932 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &581481933 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &581481934 +Canvas: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 1 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &581481935 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2d01d5a9483e5ad469c85f2a244a0ef3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &710223367 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 710223368} + - component: {fileID: 710223371} + - component: {fileID: 710223370} + - component: {fileID: 710223369} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &710223368 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2032664814} + m_Father: {fileID: 581481931} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &710223369 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 710223370} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 864711696} + m_MethodName: On_StartTestButtonClicked + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &710223370 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &710223371 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} +--- !u!1 &864711695 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 864711697} + - component: {fileID: 864711696} + m_Layer: 0 + m_Name: DownloadSpeedTest + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &864711696 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864711695} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3a9c85a1b212aba4881711d8dbf04bf9, type: 3} + m_Name: + m_EditorClassIdentifier: + statusText: {fileID: 1622957197} +--- !u!4 &864711697 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864711695} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1622957195 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1622957196} + - component: {fileID: 1622957198} + - component: {fileID: 1622957197} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1622957196 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 581481931} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: -70} + m_SizeDelta: {x: 0, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1622957197 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 0 +--- !u!222 &1622957198 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} +--- !u!1 &1664915794 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1664915797} + - component: {fileID: 1664915796} + - component: {fileID: 1664915795} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1664915795 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1664915796 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1664915797 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2032664813 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2032664814} + - component: {fileID: 2032664816} + - component: {fileID: 2032664815} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2032664814 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 710223368} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2032664815 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Start Test 1 +--- !u!222 &2032664816 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} +--- !u!1 &2064235128 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2064235129} + - component: {fileID: 2064235132} + - component: {fileID: 2064235131} + - component: {fileID: 2064235130} + m_Layer: 5 + m_Name: HomeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2064235129 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2064235128} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 296382936} + m_Father: {fileID: 581481931} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -147} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2064235130 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2064235128} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2064235131} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 581481935} + m_MethodName: LoadSceneLoader + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &2064235131 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2064235128} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &2064235132 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2064235128} diff --git a/Assets/DownloadSpeedTest_Test1.unity.meta b/Assets/DownloadSpeedTest_Test1.unity.meta new file mode 100644 index 0000000..c6e971d --- /dev/null +++ b/Assets/DownloadSpeedTest_Test1.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3f6ac1db4bf9b6a4ca4407256064dd33 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DownloadSpeedTest_Test2.cs b/Assets/DownloadSpeedTest_Test2.cs new file mode 100644 index 0000000..8179a1d --- /dev/null +++ b/Assets/DownloadSpeedTest_Test2.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public sealed class DownloadSpeedTest_Test2 : MonoBehaviour +{ + public UnityEngine.UI.Text statusText; + + [NonSerialized] + ConcurrentDownloadManager_Test2 manager; + + private void Start() + { + Application.runInBackground = true; + //BestHTTP.HTTPUpdateDelegator.IsThreaded = true; + //BestHTTP.HTTPUpdateDelegator.ThreadFrequencyInMS = 100; + + int workerThreads, completionThreads; + //System.Threading.ThreadPool.GetAvailableThreads(out workerThreads, out completionThreads); + //Debug.Log("Available worker threads: " + workerThreads); + + System.Threading.ThreadPool.GetMinThreads(out workerThreads, out completionThreads); + Debug.Log("Min worker threads: " + workerThreads); + + System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out completionThreads); + Debug.Log("Max worker threads: " + workerThreads); + } + + public void On_StartTestButtonClicked() + { + manager = new ConcurrentDownloadManager_Test2(); + manager.Download(new BestHTTP.HTTPRequest(new Uri("https://data.panomoments.com/processed/58a7514e550d37000bfd46d2/5a90ce21d3df99000e981d11/uhd_dashinit.mp4")), 128); + } + + private void Update() + { + if (this.manager != null) + { + if (!this.manager.IsDownloadComplete()) + this.statusText.text = this.manager.GetPercentDone().ToString("F2"); + else + this.statusText.text = "Finished in " + this.manager.GetDownloadTime().TotalMilliseconds.ToString("N0") + "ms"; + } + } + +} \ No newline at end of file diff --git a/Assets/DownloadSpeedTest_Test2.cs.meta b/Assets/DownloadSpeedTest_Test2.cs.meta new file mode 100644 index 0000000..c502846 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73809a017b6174841924d4ca896f43a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DownloadSpeedTest_Test2.unity b/Assets/DownloadSpeedTest_Test2.unity new file mode 100644 index 0000000..d36c8b7 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test2.unity @@ -0,0 +1,865 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 8 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311918, g: 0.3807398, b: 0.35872716, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 9 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &292271640 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 292271641} + - component: {fileID: 292271644} + - component: {fileID: 292271643} + - component: {fileID: 292271642} + m_Layer: 5 + m_Name: HomeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &292271641 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2139469067} + m_Father: {fileID: 581481931} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -147} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &292271642 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 292271643} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 581481935} + m_MethodName: LoadSceneLoader + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &292271643 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &292271644 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} +--- !u!1 &451395639 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 451395642} + - component: {fileID: 451395641} + - component: {fileID: 451395640} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &451395640 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_Enabled: 1 +--- !u!20 &451395641 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &451395642 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &581481930 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 581481931} + - component: {fileID: 581481934} + - component: {fileID: 581481933} + - component: {fileID: 581481932} + - component: {fileID: 581481935} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &581481931 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 710223368} + - {fileID: 1622957196} + - {fileID: 292271641} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &581481932 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &581481933 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &581481934 +Canvas: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 1 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &581481935 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2d01d5a9483e5ad469c85f2a244a0ef3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &710223367 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 710223368} + - component: {fileID: 710223371} + - component: {fileID: 710223370} + - component: {fileID: 710223369} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &710223368 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2032664814} + m_Father: {fileID: 581481931} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &710223369 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 710223370} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 864711696} + m_MethodName: On_StartTestButtonClicked + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &710223370 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &710223371 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} +--- !u!1 &864711695 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 864711697} + - component: {fileID: 864711696} + m_Layer: 0 + m_Name: DownloadSpeedTest + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &864711696 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864711695} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 73809a017b6174841924d4ca896f43a7, type: 3} + m_Name: + m_EditorClassIdentifier: + statusText: {fileID: 1622957197} +--- !u!4 &864711697 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864711695} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1622957195 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1622957196} + - component: {fileID: 1622957198} + - component: {fileID: 1622957197} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1622957196 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 581481931} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: -70} + m_SizeDelta: {x: 0, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1622957197 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 0 +--- !u!222 &1622957198 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} +--- !u!1 &1664915794 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1664915797} + - component: {fileID: 1664915796} + - component: {fileID: 1664915795} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1664915795 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1664915796 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1664915797 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2032664813 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2032664814} + - component: {fileID: 2032664816} + - component: {fileID: 2032664815} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2032664814 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 710223368} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2032664815 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Start Test 2 +--- !u!222 &2032664816 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} +--- !u!1 &2139469066 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2139469067} + - component: {fileID: 2139469069} + - component: {fileID: 2139469068} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2139469067 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2139469066} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 292271641} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2139469068 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2139469066} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Home +--- !u!222 &2139469069 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2139469066} diff --git a/Assets/DownloadSpeedTest_Test2.unity.meta b/Assets/DownloadSpeedTest_Test2.unity.meta new file mode 100644 index 0000000..14b1e3a --- /dev/null +++ b/Assets/DownloadSpeedTest_Test2.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9cbb3c31394271c4cbe0ac795c141d31 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DownloadSpeedTest_Test3.cs b/Assets/DownloadSpeedTest_Test3.cs new file mode 100644 index 0000000..dde35ea --- /dev/null +++ b/Assets/DownloadSpeedTest_Test3.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using System.Collections; +using BestHTTP; + +public sealed class DownloadSpeedTest_Test3 : MonoBehaviour +{ + public UnityEngine.UI.Text statusText; + + [NonSerialized] + DistributedDownloadManager manager; + + private void Start() + { + Application.runInBackground = true; + BestHTTP.HTTPManager.Setup (); + } + + public void On_StartTestButtonClicked() + { + + manager = new DistributedDownloadManager(); + string[] uris = new string[] { + "http://cdn.panomoments.com/featured/shibuya_hq/N100.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N101.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N102.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N103.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N104.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N105.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N106.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N107.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N108.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N109.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N110.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N111.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N112.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N113.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N114.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N115.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N116.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N117.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N118.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N119.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N120.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N121.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N122.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N123.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N124.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N125.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N126.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N127.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N128.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N129.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N130.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N131.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N132.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N133.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N134.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N135.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N136.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N137.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N138.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N139.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N140.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N141.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N142.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N143.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N144.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N145.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N146.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N147.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N148.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N149.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N150.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N151.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N152.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N153.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N154.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N155.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N156.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N157.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N158.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N159.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N160.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N161.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N162.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N163.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N164.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N165.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N166.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N167.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N168.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N169.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N170.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N171.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N172.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N173.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N174.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N175.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N176.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N177.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N178.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N179.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N180.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N181.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N182.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N183.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N184.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N185.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N186.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N187.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N188.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N189.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N190.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N191.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N192.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N193.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N194.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N195.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N196.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N197.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N198.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N199.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N200.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N201.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N202.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N203.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N204.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N205.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N206.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N207.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N208.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N209.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N210.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N211.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N212.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N213.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N214.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N215.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N216.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N217.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N218.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N219.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N220.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N221.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N222.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N223.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N224.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N225.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N226.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N227.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N228.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N229.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N230.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N231.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N232.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N233.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N234.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N235.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N236.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N237.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N238.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N239.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N240.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N241.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N242.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N243.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N244.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N245.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N246.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N247.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N248.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N249.mp4", + "http://cdn.panomoments.com/featured/shibuya_hq/N250.mp4" + }; + RemoteFileMetadata fileMetadata = new RemoteFileMetadata(); + for (int i = 0; i < uris.Length; i++) { + fileMetadata.AddFileFragmentData(new Uri(uris[i]), (uint) i); + } + manager.Download(fileMetadata, 1); + + } + + private void Update() + { + + } + +} \ No newline at end of file diff --git a/Assets/DownloadSpeedTest_Test3.cs.meta b/Assets/DownloadSpeedTest_Test3.cs.meta new file mode 100644 index 0000000..419d287 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test3.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f595338affb73414bb031542c91c878c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DownloadSpeedTest_Test3.unity b/Assets/DownloadSpeedTest_Test3.unity new file mode 100644 index 0000000..435b486 --- /dev/null +++ b/Assets/DownloadSpeedTest_Test3.unity @@ -0,0 +1,865 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 8 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.37311918, g: 0.3807398, b: 0.35872716, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 9 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &292271640 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 292271641} + - component: {fileID: 292271644} + - component: {fileID: 292271643} + - component: {fileID: 292271642} + m_Layer: 5 + m_Name: HomeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &292271641 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2139469067} + m_Father: {fileID: 581481931} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -147} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &292271642 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 292271643} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 581481935} + m_MethodName: LoadSceneLoader + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &292271643 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &292271644 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 292271640} +--- !u!1 &451395639 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 451395642} + - component: {fileID: 451395641} + - component: {fileID: 451395640} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &451395640 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_Enabled: 1 +--- !u!20 &451395641 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &451395642 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 451395639} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &581481930 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 581481931} + - component: {fileID: 581481934} + - component: {fileID: 581481933} + - component: {fileID: 581481932} + - component: {fileID: 581481935} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &581481931 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 710223368} + - {fileID: 1622957196} + - {fileID: 292271641} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &581481932 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &581481933 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &581481934 +Canvas: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 1 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!114 &581481935 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 581481930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2d01d5a9483e5ad469c85f2a244a0ef3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &710223367 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 710223368} + - component: {fileID: 710223371} + - component: {fileID: 710223370} + - component: {fileID: 710223369} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &710223368 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2032664814} + m_Father: {fileID: 581481931} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &710223369 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 710223370} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 864711696} + m_MethodName: On_StartTestButtonClicked + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &710223370 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &710223371 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 710223367} +--- !u!1 &864711695 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 864711697} + - component: {fileID: 864711696} + m_Layer: 0 + m_Name: DownloadSpeedTest + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &864711696 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864711695} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f595338affb73414bb031542c91c878c, type: 3} + m_Name: + m_EditorClassIdentifier: + statusText: {fileID: 1622957197} +--- !u!4 &864711697 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864711695} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1622957195 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1622957196} + - component: {fileID: 1622957198} + - component: {fileID: 1622957197} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1622957196 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 581481931} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: -70} + m_SizeDelta: {x: 0, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1622957197 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 0 +--- !u!222 &1622957198 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1622957195} +--- !u!1 &1664915794 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1664915797} + - component: {fileID: 1664915796} + - component: {fileID: 1664915795} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1664915795 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1664915796 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1664915797 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1664915794} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2032664813 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2032664814} + - component: {fileID: 2032664816} + - component: {fileID: 2032664815} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2032664814 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 710223368} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2032664815 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Start Test 3 +--- !u!222 &2032664816 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2032664813} +--- !u!1 &2139469066 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2139469067} + - component: {fileID: 2139469069} + - component: {fileID: 2139469068} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2139469067 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2139469066} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 292271641} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2139469068 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2139469066} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Home +--- !u!222 &2139469069 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2139469066} diff --git a/Assets/DownloadSpeedTest_Test3.unity.meta b/Assets/DownloadSpeedTest_Test3.unity.meta new file mode 100644 index 0000000..ec6ec9a --- /dev/null +++ b/Assets/DownloadSpeedTest_Test3.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 69385c40248b7454ca8448d5bb20bcdd +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SceneLoader.cs b/Assets/SceneLoader.cs new file mode 100644 index 0000000..acc7880 --- /dev/null +++ b/Assets/SceneLoader.cs @@ -0,0 +1,24 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class SceneLoader : MonoBehaviour { + + public void LoadTest1() { + SceneManager.LoadScene ("DownloadSpeedTest_Test1"); + } + + public void LoadTest2() { + SceneManager.LoadScene ("DownloadSpeedTest_Test2"); + } + + public void LoadTest3() { + SceneManager.LoadScene ("DownloadSpeedTest_Test3"); + } + + public void LoadSceneLoader() { + SceneManager.LoadScene ("SceneLoader"); + } + +} diff --git a/Assets/SceneLoader.cs.meta b/Assets/SceneLoader.cs.meta new file mode 100644 index 0000000..6ec42d1 --- /dev/null +++ b/Assets/SceneLoader.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 2d01d5a9483e5ad469c85f2a244a0ef3 +timeCreated: 1537276118 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SceneLoader.unity b/Assets/SceneLoader.unity new file mode 100644 index 0000000..d1074a1 --- /dev/null +++ b/Assets/SceneLoader.unity @@ -0,0 +1,1019 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 8 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657826, g: 0.49641263, b: 0.57481676, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 9 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &370803529 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 370803532} + - component: {fileID: 370803531} + - component: {fileID: 370803530} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &370803530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 370803529} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &370803531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 370803529} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 5 +--- !u!4 &370803532 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 370803529} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &489846107 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 489846108} + - component: {fileID: 489846111} + - component: {fileID: 489846110} + - component: {fileID: 489846109} + m_Layer: 5 + m_Name: Test2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &489846108 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 489846107} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 823809061} + m_Father: {fileID: 1927007219} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 2} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &489846109 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 489846107} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 489846110} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1927007220} + m_MethodName: LoadTest2 + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &489846110 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 489846107} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &489846111 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 489846107} +--- !u!1 &823809060 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 823809061} + - component: {fileID: 823809063} + - component: {fileID: 823809062} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &823809061 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 823809060} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 489846108} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &823809062 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 823809060} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Partial - Test2 +--- !u!222 &823809063 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 823809060} +--- !u!1 &864917151 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 864917153} + - component: {fileID: 864917152} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &864917152 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864917151} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 4 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &864917153 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 864917151} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &928987132 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 928987133} + - component: {fileID: 928987135} + - component: {fileID: 928987134} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &928987133 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 928987132} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2044674739} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &928987134 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 928987132} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Multiple - Test3 +--- !u!222 &928987135 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 928987132} +--- !u!1 &1033610520 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1033610524} + - component: {fileID: 1033610523} + - component: {fileID: 1033610522} + - component: {fileID: 1033610521} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1033610521 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1033610520} + m_Enabled: 1 +--- !u!124 &1033610522 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1033610520} + m_Enabled: 1 +--- !u!20 &1033610523 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1033610520} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1033610524 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1033610520} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1347769285 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1347769286} + - component: {fileID: 1347769289} + - component: {fileID: 1347769288} + - component: {fileID: 1347769287} + m_Layer: 5 + m_Name: Test1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1347769286 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347769285} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1402749399} + m_Father: {fileID: 1927007219} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 200} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1347769287 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347769285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1347769288} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1927007220} + m_MethodName: LoadTest1 + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &1347769288 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347769285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1347769289 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347769285} +--- !u!1 &1402749398 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1402749399} + - component: {fileID: 1402749401} + - component: {fileID: 1402749400} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1402749399 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1402749398} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1347769286} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1402749400 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1402749398} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Partial - Test1 +--- !u!222 &1402749401 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1402749398} +--- !u!1 &1927007215 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1927007219} + - component: {fileID: 1927007218} + - component: {fileID: 1927007217} + - component: {fileID: 1927007216} + - component: {fileID: 1927007220} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1927007216 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1927007215} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1927007217 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1927007215} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &1927007218 +Canvas: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1927007215} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 1 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1927007219 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1927007215} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 1347769286} + - {fileID: 489846108} + - {fileID: 2044674739} + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &1927007220 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1927007215} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2d01d5a9483e5ad469c85f2a244a0ef3, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &2044674738 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2044674739} + - component: {fileID: 2044674742} + - component: {fileID: 2044674741} + - component: {fileID: 2044674740} + m_Layer: 5 + m_Name: Test3 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2044674739 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2044674738} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 928987133} + m_Father: {fileID: 1927007219} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -200} + m_SizeDelta: {x: 160, y: 60} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2044674740 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2044674738} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2044674741} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1927007220} + m_MethodName: LoadTest3 + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &2044674741 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2044674738} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &2044674742 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2044674738} diff --git a/Assets/SceneLoader.unity.meta b/Assets/SceneLoader.unity.meta new file mode 100644 index 0000000..e06621a --- /dev/null +++ b/Assets/SceneLoader.unity.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1df8d59b70851154b8192b35cc413a33 +timeCreated: 1537276274 +licenseType: Pro +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..da61125 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 0 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..78992f0 --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..bd092be --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: + - enabled: 1 + path: Assets/SceneLoader.unity + guid: 1df8d59b70851154b8192b35cc413a33 + - enabled: 1 + path: Assets/DownloadSpeedTest_Test1.unity + guid: 3f6ac1db4bf9b6a4ca4407256064dd33 + - enabled: 1 + path: Assets/DownloadSpeedTest_Test2.unity + guid: 9cbb3c31394271c4cbe0ac795c141d31 + - enabled: 1 + path: Assets/DownloadSpeedTest_Test3.unity + guid: 69385c40248b7454ca8448d5bb20bcdd diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..7b42695 --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Hidden Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 0 + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..a9bbfb0 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,64 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/NetworkManager.asset b/ProjectSettings/NetworkManager.asset new file mode 100644 index 0000000..5dc6a83 --- /dev/null +++ b/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..132ee6b --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 3 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_ChangeStopsCallbacks: 0 + m_CallbacksOnDisable: 1 + m_AutoSyncTransforms: 1 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..93aea57 --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,643 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 14 + productGUID: 48ceb0aedb19137418d05c00e384ad2f + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: BestHTTP + productName: BestHTTP_Test + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + tizenShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidBlitType: 0 + defaultIsFullScreen: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 0 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + macFullscreenMode: 2 + d3d11FullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + n3dsDisableStereoscopicView: 0 + n3dsEnableSharedListOpt: 1 + n3dsEnableVSync: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + videoMemoryForVertexBuffers: 0 + psp2PowerMode: 0 + psp2AcquireBGM: 1 + wiiUTVResolution: 0 + wiiUGamePadMSAA: 1 + wiiUSupportsNunchuk: 0 + wiiUSupportsClassicController: 0 + wiiUSupportsBalanceBoard: 0 + wiiUSupportsMotionPlus: 0 + wiiUSupportsProController: 0 + wiiUAllowScreenCapture: 1 + wiiUControllerCount: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 1.0 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 0 + xboxOneEnable7thCore: 0 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 0 + oculus: + sharedDepthBuffer: 0 + dashSupport: 0 + protectGraphicsMemory: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: + Android: com.BestHTTP.Test + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 23 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 0 + VertexChannelCompressionMask: + serializedVersion: 2 + m_Bits: 238 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 7.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + appleEnableAutomaticSigning: 0 + clonedFromGUID: 00000000000000000000000000000000 + AndroidTargetDevice: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidTVCompatibility: 1 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetBatching: [] + m_BuildTargetGraphicsAPIs: [] + m_BuildTargetVRSettings: [] + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + wiiUTitleID: 0005000011000000 + wiiUGroupID: 00010000 + wiiUCommonSaveSize: 4096 + wiiUAccountSaveSize: 2048 + wiiUOlvAccessKey: 0 + wiiUTinCode: 0 + wiiUJoinGameId: 0 + wiiUJoinGameModeMask: 0000000000000000 + wiiUCommonBossSize: 0 + wiiUAccountBossSize: 0 + wiiUAddOnUniqueIDs: [] + wiiUMainThreadStackSize: 3072 + wiiULoaderThreadStackSize: 1024 + wiiUSystemHeapSize: 128 + wiiUTVStartupScreen: {fileID: 0} + wiiUGamePadStartupScreen: {fileID: 0} + wiiUDrcBufferDisabled: 0 + wiiUProfilerLibPath: + playModeTestRunnerEnabled: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchSupportedNpadStyles: 3 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + psp2Splashimage: {fileID: 0} + psp2NPTrophyPackPath: + psp2NPSupportGBMorGJP: 0 + psp2NPAgeRating: 12 + psp2NPTitleDatPath: + psp2NPCommsID: + psp2NPCommunicationsID: + psp2NPCommsPassphrase: + psp2NPCommsSig: + psp2ParamSfxPath: + psp2ManualPath: + psp2LiveAreaGatePath: + psp2LiveAreaBackroundPath: + psp2LiveAreaPath: + psp2LiveAreaTrialPath: + psp2PatchChangeInfoPath: + psp2PatchOriginalPackage: + psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui + psp2KeystoneFile: + psp2MemoryExpansionMode: 0 + psp2DRMType: 0 + psp2StorageType: 0 + psp2MediaCapacity: 0 + psp2DLCConfigPath: + psp2ThumbnailPath: + psp2BackgroundPath: + psp2SoundPath: + psp2TrophyCommId: + psp2TrophyPackagePath: + psp2PackagedResourcesPath: + psp2SaveDataQuota: 10240 + psp2ParentalLevel: 1 + psp2ShortTitle: Not Set + psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF + psp2Category: 0 + psp2MasterVersion: 01.00 + psp2AppVersion: 01.00 + psp2TVBootMode: 0 + psp2EnterButtonAssignment: 2 + psp2TVDisableEmu: 0 + psp2AllowTwitterDialog: 1 + psp2Upgradable: 0 + psp2HealthWarning: 0 + psp2UseLibLocation: 0 + psp2InfoBarOnStartup: 0 + psp2InfoBarColor: 0 + psp2ScriptOptimizationLevel: 0 + psmSplashimage: {fileID: 0} + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 0 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLUseWasm: 0 + webGLCompressionFormat: 1 + scriptingDefineSymbols: {} + platformArchitecture: {} + scriptingBackend: + Android: 1 + incrementalIl2cppBuild: {} + additionalIl2CppArgs: + scriptingRuntimeVersion: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: BestHTTP_Test1 + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: BestHTTP_Test1 + wsaImages: {} + metroTileShortName: + metroCommandLineArgsFile: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + metroCompilationOverrides: 1 + tizenProductDescription: + tizenProductURL: + tizenSigningProfileName: + tizenGPSPermissions: 0 + tizenMicrophonePermissions: 0 + tizenDeploymentTarget: + tizenDeploymentTargetType: -1 + tizenMinOSVersion: 1 + n3dsUseExtSaveData: 0 + n3dsCompressStaticMem: 1 + n3dsExtSaveDataNumber: 0x12345 + n3dsStackSize: 131072 + n3dsTargetPlatform: 2 + n3dsRegion: 7 + n3dsMediaSize: 0 + n3dsLogoStyle: 3 + n3dsTitle: GameName + n3dsProductCode: + n3dsApplicationId: 0xFF3FF + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 0 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 0 + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: {} + facebookSdkVersion: 7.9.4 + apiCompatibilityLevel: 2 + cloudProjectId: + projectName: + organizationId: + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..f19791b --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1 @@ +m_EditorVersion: 2017.4.5f1 diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..05daac3 --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,191 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSM: 5 + PSP2: 2 + Standalone: 5 + Tizen: 2 + WebGL: 3 + WiiU: 5 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..1c92a78 --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..558a017 --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..3da14d5 --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + m_Enabled: 0 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes + m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate + m_Enabled: 0 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/UnityPackageManager/manifest.json b/UnityPackageManager/manifest.json new file mode 100644 index 0000000..526aca6 --- /dev/null +++ b/UnityPackageManager/manifest.json @@ -0,0 +1,4 @@ +{ + "dependencies": { + } +}