Exemple #1
0
        internal EcdsaCertificate(EVP_PKEY privateKey, X509 certificate, byte[] derCertData, string altNameString, byte[][] chain)
        {
            _certData      = derCertData;
            _key           = privateKey;
            _certificate   = certificate;
            _altNameString = altNameString;
            _chain         = chain ?? new byte[0][];

            _ecKey = EVP_PKEY_get0_EC_KEY(_key);
            var group     = EC_KEY_get0_group(_ecKey);
            var curveName = EC_GROUP_get_curve_name(group);

            _curveName = OBJ_nid2ln(curveName);
            switch (_curveName)
            {
            case "secp256r1":
                _scheme   = SignatureScheme.ecdsa_secp256r1_sha256;
                _hashType = HashType.SHA256;
                break;

            case "secp384r1":
                _scheme   = SignatureScheme.ecdsa_secp384r1_sha384;
                _hashType = HashType.SHA384;
                break;

            case "secp521r1":
                _scheme   = SignatureScheme.ecdsa_secp521r1_sha512;
                _hashType = HashType.SHA512;
                break;

            default:
                ExceptionHelper.ThrowException(new ArgumentException());
                break;
            }
        }
Exemple #2
0
        public unsafe int SignHash(IHashProvider provider, SignatureScheme scheme, ref WritableBuffer writer, byte *message, int messageLength)
        {
            var span   = new Span <byte>(message, messageLength);
            var result = _privateKey.SignData(span.ToArray(), GetHashName(scheme), GetPaddingMode(scheme));

            writer.Write(result);
            return(result.Length);
        }
Exemple #3
0
 public int Decrypt(SignatureScheme scheme, Span <byte> encryptedData, Span <byte> output)
 {
     if (_certificateType == CertificateType.rsa)
     {
         var padding = RSAEncryptionPadding.Pkcs1;
         var result  = _rsaPrivateKey.Decrypt(encryptedData.ToArray(), padding);
         result.CopyTo(output);
         return(result.Length);
     }
     throw new InvalidOperationException($"The {scheme} certificate type cannot be used to decrypt");
 }
Exemple #4
0
 public bool SupportsSignatureScheme(SignatureScheme scheme)
 {
     switch (scheme)
     {
     case SignatureScheme.rsa_pkcs1_sha256:
     case SignatureScheme.rsa_pkcs1_sha384:
     case SignatureScheme.rsa_pkcs1_sha512:
         return(true);
     }
     return(false);
 }
Exemple #5
0
        public ExternalCertificate(ReadableBuffer buffer)
        {
            var reader = new BigEndianAdvancingSpan(buffer.ToSpan());

            reader.Read <HandshakeHeader>();
            reader       = reader.ReadVector <UInt24>();
            _certificate = new X509Certificate2(reader.ReadVector <UInt24>().ToArray());

            if (reader.Length > 0)
            {
                _collection = new X509Certificate2Collection();
                while (reader.Length > 0)
                {
                    var cert = new X509Certificate2(reader.ReadVector <UInt24>().ToArray());
                    _collection.Add(cert);
                }
            }
            Debug.Assert(reader.Length == 0);

            _rsaPublicKey = _certificate.GetRSAPublicKey();
            if (_rsaPublicKey != null)
            {
                _certificateType = CertificateType.rsa;
                _signatureSize   = _rsaPublicKey.KeySize / 8;
                _certificateType = CertificateType.rsa;
                return;
            }
            _ecdsaPublicKey = _certificate.GetECDsaPublicKey();
            if (_ecdsaPublicKey != null)
            {
                _certificateType = CertificateType.ecdsa;
                switch (_ecdsaPublicKey.KeySize)
                {
                case 256:
                    _signatureScheme = SignatureScheme.ecdsa_secp256r1_sha256;
                    _signatureSize   = 72;
                    break;

                case 384:
                    _signatureScheme = SignatureScheme.ecdsa_secp384r1_sha384;
                    throw new NotImplementedException();

                case 521:
                    _signatureSize   = 132;
                    _signatureScheme = SignatureScheme.ecdsa_secp521r1_sha512;
                    break;

                default:
                    throw new InvalidOperationException($"Unsupported Ecdsa Keysize {_ecdsaPublicKey.KeySize}");
                }
                return;
            }
        }
        public void ReadEncryptedApplicationData_TLS_AES_128_GCM_SHA256_ResultIsExpected()
        {
            //Arrange
            var messageData                   = GetEncryptedApplicationData();
            var cerificateData                = GetCertificateData();
            var signatureData                 = GetSignatureData();
            var verifyData                    = GetVerifyData();
            var encryptionData                = GetEncryptionData();
            var parsedCertificateEntries      = new List <CertificateEntry>();
            var parsedSignatureData           = new Memory <byte>();
            var parsedCertificateVerifyScheme = new SignatureScheme();
            var parsedVerifyData              = new Memory <byte>();

            using var aead = Cipher.TLS_AES_128_GCM_SHA256.CreateAead(Utils.ParseHexString(encryptionData.Iv), Utils.ParseHexString(encryptionData.Key));

            //Act
            var cursor = new MemoryCursor(Utils.ParseHexString(messageData));
            var result = TlsRecord.TryParseEncrypted(cursor, aead, encryptionData.SeqNum, out var record);

            using (record.Payload.SetCursor(cursor))
            {
                result &= EncryptedExtensions.TrySlice(cursor);

                result &= Certificate.TryParse(cursor, out var certificate);
                foreach (var entry in certificate.Payload.GetCertificateEntryReader(cursor))
                {
                    parsedCertificateEntries.Add(entry);
                }

                result &= CertificateVerify.TryParse(cursor, out var certificateVerify);
                parsedSignatureData           = certificateVerify.Signature.Read(cursor);
                parsedCertificateVerifyScheme = certificateVerify.Scheme;

                result          &= Finished.TryParse(cursor, out var parsedVerifyDataBuffer);
                parsedVerifyData = parsedVerifyDataBuffer.Read(cursor);

                result &= cursor.IsEnd();
            }

            result &= cursor.IsEnd();

            //Assert
            Assert.True(result);
            Assert.Equal(RecordType.Handshake, record.Type);
            Assert.Equal(ProtocolVersion.Tls12, record.ProtocolVersion);
            var certificateEntry = Assert.Single(parsedCertificateEntries);

            Assert.Equal(cerificateData, Utils.ToHexString(certificateEntry.Data.Read(cursor).ToArray()), true);
            Assert.Equal(signatureData, Utils.ToHexString(parsedSignatureData.ToArray()), true);
            Assert.Equal(SignatureScheme.RSA_PSS_RSAE_SHA256, parsedCertificateVerifyScheme);
            Assert.Equal(verifyData, Utils.ToHexString(parsedVerifyData.ToArray()), true);
        }
Exemple #7
0
        /// <summary>
        /// Initializes a new instance of the Pkcs11Signature class
        /// </summary>
        /// <param name="libraryPath">Path to the unmanaged PCKS#11 library</param>
        /// <param name="tokenSerial">Serial number of the token (smartcard) that contains signing key. May be null if tokenLabel is specified.</param>
        /// <param name="tokenLabel">Label of of the token (smartcard) that contains signing key. May be null if tokenSerial is specified.</param>
        /// <param name="pin">PIN for the token (smartcard)</param>
        /// <param name="ckaLabel">Label (value of CKA_LABEL attribute) of the private key used for signing. May be null if ckaId is specified.</param>
        /// <param name="ckaId">Identifier (value of CKA_ID attribute) of the private key used for signing. May be null if ckaLabel is specified.</param>
        /// <param name="hashAlgorihtm">Hash algorihtm used for the signature creation</param>
        /// <param name="signatureScheme">Signature scheme used for the signature creation</param>
        private void InitializePkcs7RsaSignature(string libraryPath, string tokenSerial, string tokenLabel, byte[] pin, string ckaLabel, byte[] ckaId, HashAlgorithm hashAlgorihtm, SignatureScheme signatureScheme)
        {
            try
            {
                if (string.IsNullOrEmpty(libraryPath))
                {
                    throw new ArgumentNullException("libraryPath");
                }

                _pkcs11 = new Pkcs11(libraryPath, AppType.MultiThreaded);

                _slot = FindSlot(tokenSerial, tokenLabel);
                if (_slot == null)
                {
                    throw new TokenNotFoundException(string.Format("Token with serial \"{0}\" and label \"{1}\" was not found", tokenSerial, tokenLabel));
                }

                _session = _slot.OpenSession(SessionType.ReadOnly);
                _session.Login(CKU.CKU_USER, pin);

                _privateKeyHandle = FindPrivateKey(ckaLabel, ckaId);

                _ckaLabel = ckaLabel;
                _ckaId    = ckaId;

                if (!Enum.IsDefined(typeof(HashAlgorithm), hashAlgorihtm))
                {
                    throw new ArgumentException("Invalid hash algorithm specified");
                }

                _hashAlgorihtm   = hashAlgorihtm;
                _signatureScheme = signatureScheme;
            }
            catch
            {
                if (_session != null)
                {
                    _session.Dispose();
                    _session = null;
                }

                if (_pkcs11 != null)
                {
                    _pkcs11.Dispose();
                    _pkcs11 = null;
                }

                throw;
            }
        }
Exemple #8
0
 public ReadOnlySpan <byte> SignHash(IHashProvider provider, SignatureScheme scheme, Span <byte> message)
 {
     if (_certificateType == CertificateType.rsa)
     {
         var result = _rsaPrivateKey.SignData(message.ToArray(), GetHashName(scheme), GetPaddingMode(scheme));
         return(new ReadOnlySpan <byte>(result));
     }
     else if (_certificateType == CertificateType.ecdsa)
     {
         var result = _ecdsaPrivateKey.SignData(message.ToArray(), GetHashName(scheme));
         return(new ReadOnlySpan <byte>(result));
     }
     Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "Certificate signing failed");
     return(default);
Exemple #9
0
        public ManagedCertificate(X509Certificate2 certificate, X509Certificate2Collection chain)
        {
            if (chain == null || chain.Count == 0)
            {
                _certificateChain = new byte[0][];
            }
            else
            {
                _certificateChain = new byte[chain.Count][];
                for (var i = 0; i < _certificateChain.Length; i++)
                {
                    _certificateChain[i] = chain[i].RawData;
                }
            }
            _rsaPrivateKey = certificate.GetRSAPrivateKey();
            if (_rsaPrivateKey != null)
            {
                _certificateType = CertificateType.rsa;
                _certificateData = certificate.RawData;
                _signatureSize   = _rsaPrivateKey.KeySize / 8;
                return;
            }
            _ecdsaPrivateKey = certificate.GetECDsaPrivateKey();
            if (_ecdsaPrivateKey != null)
            {
                _certificateType = CertificateType.ecdsa;
                _certificateData = certificate.RawData;
                switch (_ecdsaPrivateKey.KeySize)
                {
                case 256:
                    _ecDsaSignatureScheme = SignatureScheme.ecdsa_secp256r1_sha256;
                    _signatureSize        = 72;
                    break;

                case 384:
                    _ecDsaSignatureScheme = SignatureScheme.ecdsa_secp384r1_sha384;
                    throw new NotImplementedException();

                case 521:
                    _signatureSize        = 132;
                    _ecDsaSignatureScheme = SignatureScheme.ecdsa_secp521r1_sha512;
                    break;

                default:
                    throw new InvalidOperationException($"Unsupported Ecdsa Keysize {_ecdsaPrivateKey.KeySize}");
                }
                return;
            }
            throw new CryptographicException("Unable to get a private key from the certificate");
        }
Exemple #10
0
 public void CheckSignature(IHashProvider hashProvider, SignatureScheme signatureScheme, Span <byte> signature, Span <byte> data)
 {
     //Screwed at the moment.
     return;
     //var hashName = ManagedCertificate.GetHashName(signatureScheme);
     //if (_rsaPublicKey != null)
     //{
     //    var padding = ManagedCertificate.GetPaddingMode(signatureScheme);
     //    if(!_rsaPublicKey.VerifyData(data.ToArray(), signature.ToArray(), hashName, padding))
     //    {
     //        Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, "Could not verify the signature");
     //    }
     //    return;
     //}
     //throw new NotImplementedException();
 }
Exemple #11
0
 public ICertificate GetCertificate(string host, SignatureScheme type)
 {
     for (int i = 0; i < _certificates.Count; i++)
     {
         //if (_certificates[i].HostName != host && host != null)
         //{
         //    continue;
         //}
         var cert = _certificates[i];
         if (!cert.SupportsSignatureScheme(type))
         {
             continue;
         }
         return(_certificates[i]);
     }
     return(null);
 }
Exemple #12
0
        private System.Security.Cryptography.HashAlgorithmName GetHashName(SignatureScheme scheme)
        {
            switch (scheme)
            {
            case SignatureScheme.rsa_pkcs1_sha256:
            case SignatureScheme.rsa_pss_sha256:
                return(System.Security.Cryptography.HashAlgorithmName.SHA256);

            case SignatureScheme.rsa_pkcs1_sha384:
            case SignatureScheme.rsa_pss_sha384:
                return(System.Security.Cryptography.HashAlgorithmName.SHA384);

            case SignatureScheme.rsa_pkcs1_sha512:
            case SignatureScheme.rsa_pss_sha512:
                return(System.Security.Cryptography.HashAlgorithmName.SHA512);
            }
            throw new InvalidOperationException();
        }
Exemple #13
0
        private System.Security.Cryptography.RSASignaturePadding GetPaddingMode(SignatureScheme scheme)
        {
            switch (scheme)
            {
            case SignatureScheme.rsa_pkcs1_sha256:
            case SignatureScheme.rsa_pkcs1_sha384:
            case SignatureScheme.rsa_pkcs1_sha512:
                return(System.Security.Cryptography.RSASignaturePadding.Pkcs1);

            case SignatureScheme.rsa_pss_sha256:
            case SignatureScheme.rsa_pss_sha384:
            case SignatureScheme.rsa_pss_sha512:
                return(System.Security.Cryptography.RSASignaturePadding.Pss);

            default:
                throw new NotImplementedException();
            }
        }
Exemple #14
0
        public unsafe int SignHash(IHashProvider provider, SignatureScheme scheme, ref WritableBuffer writer, byte *message, int messageLength)
        {
            var hash = provider.GetHashInstance(_hashType);

            hash.HashData(message, messageLength);

            var digest = new byte[hash.HashSize];

            fixed(byte *dPtr = digest)
            {
                hash.InterimHash(dPtr, digest.Length);
            }

            writer.Ensure(_privateKey.KeySize);
            var result = _privateKey.SignHash(digest);

            writer.Write(result);
            return(result.Length);
        }
Exemple #15
0
        public unsafe int SignHash(IHashProvider provider, SignatureScheme scheme, ref WritableBuffer writer, byte *message, int messageLength)
        {
            var hash = provider.GetHashInstance(_hashType);

            hash.HashData(message, messageLength);

            var digest = new byte[hash.HashSize];

            fixed(byte *dPtr = digest)
            {
                hash.InterimHash(dPtr, digest.Length);
            }

            var result = _privateKey.SignHash(digest);
            var enc    = new System.Security.Cryptography.AsnEncodedData(_certificate.SignatureAlgorithm, result);

            writer.Write(result);
            return(result.Length);
        }
Exemple #16
0
        public EcdsaCertificate(X509Certificate2 certificate, X509Certificate2Collection chain)
        {
            _certificate = certificate;
            _privateKey  = _certificate.GetECDsaPrivateKey();
            var curve = _privateKey.ExportParameters(false);

            if (curve.Curve.CurveType != System.Security.Cryptography.ECCurve.ECCurveType.Named)
            {
                ExceptionHelper.ThrowException(new InvalidOperationException());
            }
            switch (curve.Curve.Oid.FriendlyName)
            {
            case "nistP256":
                _certificateType          = CertificateType.Ecdsa_secp256r1;
                _supportedSignatureScheme = SignatureScheme.ecdsa_secp256r1_sha256;
                _hashType = HashType.SHA256;
                break;

            case "nistP384":
                _certificateType          = CertificateType.Ecdsa_secp384r1;
                _supportedSignatureScheme = SignatureScheme.ecdsa_secp384r1_sha384;
                _hashType = HashType.SHA384;
                break;

            case "nistP521":
                _certificateType          = CertificateType.Ecdsa_secp521r1;
                _supportedSignatureScheme = SignatureScheme.ecdsa_secp521r1_sha512;
                _hashType = HashType.SHA512;
                break;

            default:
                ExceptionHelper.ThrowException(new InvalidOperationException());
                break;
            }
            _certificateChain = new byte[chain.Count][];
            for (var i = 0; i < chain.Count; i++)
            {
                _certificateChain[i] = chain[i].RawData;
            }
        }
Exemple #17
0
 public static @string String(this SignatureScheme i)
 {
     if (i == 513L)
     {
         return(_SignatureScheme_name_0);
     }
     else if (i == 515L)
     {
         return(_SignatureScheme_name_1);
     }
     else if (i == 1025L)
     {
         return(_SignatureScheme_name_2);
     }
     else if (i == 1027L)
     {
         return(_SignatureScheme_name_3);
     }
     else if (i == 1281L)
     {
         return(_SignatureScheme_name_4);
     }
     else if (i == 1283L)
     {
         return(_SignatureScheme_name_5);
     }
     else if (i == 1537L)
     {
         return(_SignatureScheme_name_6);
     }
     else if (i == 1539L)
     {
         return(_SignatureScheme_name_7);
     }
     else if (2052L <= i && i <= 2055L)
     {
         i -= 2052L;
     }
     return(_SignatureScheme_name_8[_SignatureScheme_index_8[i].._SignatureScheme_index_8[i + 1L]]);
        public ServerKeyExchangeParser(ReadableBuffer reader)
        {
            var originalSpan = reader.ToSpan();
            var span         = new BigEndianAdvancingSpan(originalSpan);

            span.Read <HandshakeHeader>();
            _curveType = span.Read <ECCurveType>();
            if (_curveType != ECCurveType.named_curve)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "We only support named curves");
            }

            _namedGroup = span.Read <NamedGroup>();
            _key        = span;
            span.ReadVector <byte>();
            var dataLength = originalSpan.Length - span.Length;

            _data = originalSpan.Slice(4, dataLength - 4);

            _signatureScheme = span.Read <SignatureScheme>();
            _signature       = span.ReadVector <ushort>().ToSpan();
            Debug.Assert(span.Length == 0);
        }
Exemple #19
0
        public unsafe int SignHash(IHashProvider provider, SignatureScheme scheme, ref WritableBuffer writer, byte *message, int messageLength)
        {
            var hash = provider.GetHashInstance(_hashType);

            hash.HashData(message, messageLength);

            var digest = new byte[hash.HashSize];

            fixed(byte *dPtr = digest)
            {
                hash.InterimHash(dPtr, digest.Length);
            }

            writer.Ensure(ECDSA_size(_ecKey));
            GCHandle handle;
            var      output = writer.Memory.GetPointer(out handle);

            try
            {
                fixed(byte *iPtr = digest)
                {
                    var sigSize = writer.Memory.Length;

                    ThrowOnError(ECDSA_sign(0, iPtr, digest.Length, output, ref sigSize, _ecKey));
                    writer.Advance(sigSize);
                    return(sigSize);
                }
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }
        }
        public void SetPeerKey(SequenceReader <byte> peerKey, X509Certificate2 certificate, SignatureScheme scheme)
        {
            var buffer = peerKey.Sequence.Slice(peerKey.Position);

            SetPeerKey(buffer, certificate, scheme);
        }
Exemple #21
0
 public void CheckSignature(IHashProvider hashProvider, SignatureScheme signatureScheme, Span <byte> signature, Span <byte> data)
 {
     throw new NotImplementedException();
 }
Exemple #22
0
 /// <summary>
 /// Initializes a new instance of the Pkcs7Signature class
 /// </summary>
 /// <param name="libraryPath">Path to the unmanaged PCKS#11 library</param>
 /// <param name="tokenSerial">Serial number of the token (smartcard) that contains signing key. May be null if tokenLabel is specified.</param>
 /// <param name="tokenLabel">Label of of the token (smartcard) that contains signing key. May be null if tokenSerial is specified.</param>
 /// <param name="pin">PIN for the token (smartcard)</param>
 /// <param name="ckaLabel">Label (value of CKA_LABEL attribute) of the private key used for signing. May be null if ckaId is specified.</param>
 /// <param name="ckaId">Hex encoded string with identifier (value of CKA_ID attribute) of the private key used for signing. May be null if ckaLabel is specified.</param>
 /// <param name="hashAlgorihtm">Hash algorihtm used for the signature creation</param>
 /// <param name="signatureScheme">Signature scheme used for the signature creation</param>
 public Pkcs7SignatureGenerator(string libraryPath, string tokenSerial, string tokenLabel, string pin, string ckaLabel, string ckaId, HashAlgorithm hashAlgorihtm, SignatureScheme signatureScheme)
 {
     byte[] pinValue   = (pin == null) ? null : ConvertUtils.Utf8StringToBytes(pin);
     byte[] ckaIdValue = (ckaId == null) ? null : ConvertUtils.HexStringToBytes(ckaId);
     InitializePkcs7RsaSignature(libraryPath, tokenSerial, tokenLabel, pinValue, ckaLabel, ckaIdValue, hashAlgorihtm, signatureScheme);
 }
Exemple #23
0
 /// <summary>
 /// Initializes a new instance of the Pkcs11Signature class
 /// </summary>
 /// <param name="libraryPath">Path to the unmanaged PCKS#11 library</param>
 /// <param name="tokenSerial">Serial number of the token (smartcard) that contains signing key. May be null if tokenLabel is specified.</param>
 /// <param name="tokenLabel">Label of of the token (smartcard) that contains signing key. May be null if tokenSerial is specified.</param>
 /// <param name="pin">PIN for the token (smartcard)</param>
 /// <param name="ckaLabel">Label (value of CKA_LABEL attribute) of the private key used for signing. May be null if ckaId is specified.</param>
 /// <param name="ckaId">Identifier (value of CKA_ID attribute) of the private key used for signing. May be null if ckaLabel is specified.</param>
 /// <param name="hashAlgorihtm">Hash algorihtm used for the signature creation</param>
 /// <param name="signatureScheme">Signature scheme used for the signature creation</param>
 public Pkcs7SignatureGenerator(string libraryPath, string tokenSerial, string tokenLabel, byte[] pin, string ckaLabel, byte[] ckaId, HashAlgorithm hashAlgorihtm, SignatureScheme signatureScheme)
 {
     InitializePkcs7RsaSignature(libraryPath, tokenSerial, tokenLabel, pin, ckaLabel, ckaId, hashAlgorihtm, signatureScheme);
 }
 public certificateVerifyMsg(slice <byte> raw = default, bool hasSignatureAlgorithm = default, SignatureScheme signatureAlgorithm = default, slice <byte> signature = default)
 {
     this.raw = raw;
     this.hasSignatureAlgorithm = hasSignatureAlgorithm;
     this.signatureAlgorithm    = signatureAlgorithm;
     this.signature             = signature;
 }
Exemple #25
0
 public int SignatureSize(SignatureScheme scheme)
 {
     return(ECDSA_size(_ecKey));
 }
Exemple #26
0
 public bool SupportsSignatureScheme(SignatureScheme scheme)
 {
     return(((ushort)scheme & 0x00FF) == ((ushort)_scheme & 0x00FF));
 }
Exemple #27
0
 public SignatureScheme ModifySignatureScheme(SignatureScheme signatureScheme)
 {
     return(_scheme);
 }
 public abstract void SetPeerKey(ReadOnlySequence <byte> peerKey, X509Certificate2 certificate, SignatureScheme scheme);
Exemple #29
0
        public unsafe int SignHash(IHashProvider provider, SignatureScheme scheme, ref WritableBuffer writer, byte *message, int messageLength)
        {
            var    keySize = SignatureSize(scheme);
            IntPtr hashType;

            switch (scheme)
            {
            case SignatureScheme.rsa_pkcs1_sha256:
            case SignatureScheme.rsa_pss_sha256:
                hashType = EVP_sha256;
                break;

            case SignatureScheme.rsa_pkcs1_sha512:
            case SignatureScheme.rsa_pss_sha512:
                hashType = EVP_sha512;
                break;

            case SignatureScheme.rsa_pkcs1_sha384:
            case SignatureScheme.rsa_pss_sha384:
                hashType = EVP_sha384;
                break;

            default:
                ExceptionHelper.ThrowException(new ArgumentOutOfRangeException(nameof(scheme)));
                hashType = IntPtr.Zero;
                break;
            }

            EVP_MD_CTX   ctx = EVP_MD_CTX_new();
            EVP_PKEY_CTX pctx;
            GCHandle     handle;

            try
            {
                ThrowOnError(EVP_DigestSignInit(ctx, &pctx, hashType, IntPtr.Zero, _key));
                ThrowIfNegative(EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_type.EVP_PKEY_RSA, EVP_PKEY_Ctrl_OP.EVP_PKEY_OP_TYPE_SIG,
                                                  EVP_PKEY_Ctrl_Command.EVP_PKEY_CTRL_MD, 0, (void *)hashType));
                if ((((ushort)scheme) & 0x00FF) == 1)
                {
                    ThrowIfNegative(EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_type.EVP_PKEY_RSA, EVP_PKEY_Ctrl_OP.EVP_PKEY_OP_NONE
                                                      , EVP_PKEY_Ctrl_Command.EVP_PKEY_CTRL_RSA_PADDING, (int)RSA_PADDING.RSA_PKCS1_PADDING, null));
                }
                else
                {
                    //PSS Padding
                    ThrowIfNegative(EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_type.EVP_PKEY_RSA, EVP_PKEY_Ctrl_OP.EVP_PKEY_OP_SIGN
                                                      , EVP_PKEY_Ctrl_Command.EVP_PKEY_CTRL_RSA_PADDING, (int)RSA_PADDING.RSA_PKCS1_PSS_PADDING, null));
                    ThrowIfNegative(EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_type.EVP_PKEY_RSA, EVP_PKEY_Ctrl_OP.EVP_PKEY_OP_SIGN
                                                      , EVP_PKEY_Ctrl_Command.EVP_PKEY_CTRL_RSA_PSS_SALTLEN, 32, null));
                }
                ThrowOnError(EVP_DigestUpdate(ctx, message, messageLength));
                var size = UIntPtr.Zero;
                ThrowOnError(EVP_DigestSignFinal(ctx, null, ref size));
                writer.Ensure((int)size);
                var output = writer.Memory.GetPointer(out handle);
                ThrowOnError(EVP_DigestSignFinal(ctx, output, ref size));
                writer.Advance((int)size);
                return((int)size);
            }
            finally
            {
                ctx.Free();
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }
        }
Exemple #30
0
 public int SignatureSize(SignatureScheme scheme)
 {
     return(EVP_PKEY_size(_key));
 }