Beispiel #1
0
 public SetSignatureAlgorithm()
 {
     _encryptionKey  = new SharedSecretEncryptionKey("The_Big_Secret");
     _unencryptedKey = "s3cr3t";
     _dataRecord     = new ClientDataRecord {
         V = ClientDataRecord.GetV()
     };
 }
Beispiel #2
0
 public ToSignatureAlgorithm()
 {
     _encryptionKey  = new SharedSecretEncryptionKey("The_Big_Secret");
     _unencryptedKey = "s3cr3t";
     _dataRecord     = new ClientDataRecord {
         SigType                 = "HMAC",
         SigParameter            = new FakeStringProtector().Protect(_unencryptedKey),
         SigHashAlgorithm        = HashAlgorithmName.MD5.Name,
         IsSigParameterEncrypted = true,
         V = ClientDataRecord.GetV()
     };
 }
        public async Task Register(Client client)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            var clientRecord = new ClientDataRecord {
                Id                    = client.Id,
                Name                  = client.Name,
                NonceLifetime         = client.NonceLifetime.TotalSeconds,
                ClockSkew             = client.ClockSkew.TotalSeconds,
                RequestTargetEscaping = client.RequestTargetEscaping.ToString(),
                Claims                = client.Claims?.Select(c => ClaimDataRecord.FromClaim(client.Id, c))?.ToList() ?? new List <ClaimDataRecord>(),
                V = ClientDataRecord.GetV()
            };

            _signatureAlgorithmConverter.SetSignatureAlgorithm(clientRecord, client.SignatureAlgorithm, _settings.SharedSecretEncryptionKey);

            using (var connection = new SqlConnection(_settings.ConnectionString)) {
                await connection.OpenAsync();

                try {
                    using (var transaction = connection.BeginTransaction()) {
                        await connection.ExecuteAsync(_mergeClientSql.Value, clientRecord, transaction).ConfigureAwait(continueOnCapturedContext: false);

                        await connection.ExecuteAsync(_deleteClientClaimsSql.Value, new { ClientId = client.Id.Value }, transaction).ConfigureAwait(continueOnCapturedContext: false);

                        if (clientRecord.Claims.Count > 0)
                        {
                            foreach (var claim in clientRecord.Claims)
                            {
                                await connection.ExecuteAsync(_insertClientClaimSql.Value, claim, transaction).ConfigureAwait(continueOnCapturedContext: false);
                            }
                        }
                        transaction.Commit();
                    }
                }
                finally {
                    connection.Close();
                }
            }
        }
Beispiel #4
0
        private string GetUnencryptedParameter(ClientDataRecord dataRecord, SharedSecretEncryptionKey encryptionKey)
        {
            if (encryptionKey == SharedSecretEncryptionKey.Empty)
            {
                return(dataRecord.SigParameter);
            }

            if (!dataRecord.IsSigParameterEncrypted)
            {
                return(dataRecord.SigParameter);                                     // The value in the data store is not encrypted
            }
            var protector = _stringProtectorFactory.CreateSymmetric(encryptionKey);

            try {
                return(protector.Unprotect(dataRecord.SigParameter));
            }
            catch (Exception ex) {
                throw new SecurityException("Something went wrong during acquisition of the unencrypted symmetric key. See inner exception for details.", ex);
            }
        }
Beispiel #5
0
        public void SetSignatureAlgorithm(ClientDataRecord dataRecord, ISignatureAlgorithm signatureAlgorithm, SharedSecretEncryptionKey encryptionKey)
        {
            if (dataRecord == null)
            {
                throw new ArgumentNullException(nameof(dataRecord));
            }
            if (signatureAlgorithm == null)
            {
                throw new ArgumentNullException(nameof(signatureAlgorithm));
            }

            switch (signatureAlgorithm)
            {
            case RSASignatureAlgorithm rsa:
                dataRecord.SigType                 = rsa.Name;
                dataRecord.SigHashAlgorithm        = rsa.HashAlgorithm.Name;
                dataRecord.SigParameter            = rsa.GetPublicKey().ToXml();
                dataRecord.IsSigParameterEncrypted = false;
                break;

            case ECDsaSignatureAlgorithm ecdsa:
                dataRecord.SigType                 = ecdsa.Name;
                dataRecord.SigHashAlgorithm        = ecdsa.HashAlgorithm.Name;
                dataRecord.SigParameter            = ecdsa.GetPublicKey().ToXml();
                dataRecord.IsSigParameterEncrypted = false;
                break;

            case HMACSignatureAlgorithm hmac:
                dataRecord.SigType                 = hmac.Name;
                dataRecord.SigHashAlgorithm        = hmac.HashAlgorithm.Name;
                dataRecord.SigParameter            = GetParameterWithEncryption(hmac, encryptionKey, out var isEncrypted);
                dataRecord.IsSigParameterEncrypted = isEncrypted;
                break;

            default:
                throw new NotSupportedException($"The specified signature algorithm of type {signatureAlgorithm.GetType().Name} cannot be serialized.");
            }
        }
Beispiel #6
0
        public ISignatureAlgorithm ToSignatureAlgorithm(ClientDataRecord dataRecord, SharedSecretEncryptionKey encryptionKey)
        {
            if (dataRecord == null)
            {
                throw new ArgumentNullException(nameof(dataRecord));
            }

            switch (dataRecord.SigType)
            {
            case string str when str.Equals("rsa", StringComparison.OrdinalIgnoreCase):
                using (var rsaForVerification = new RSACryptoServiceProvider())
                {
                    rsaForVerification.FromXml(dataRecord.SigParameter);
                    var paramsForVerification = rsaForVerification.ExportParameters(false);

                    return(SignatureAlgorithm.CreateForVerification(paramsForVerification, new HashAlgorithmName(dataRecord.SigHashAlgorithm)));
                }

            case string str when str.Equals("ecdsa", StringComparison.OrdinalIgnoreCase):
                using (var ecdsaForVerification = ECDsa.Create())
                {
                    ecdsaForVerification.FromXml(dataRecord.SigParameter);
                    var paramsForVerification = ecdsaForVerification.ExportParameters(false);

                    return(SignatureAlgorithm.CreateForVerification(paramsForVerification, new HashAlgorithmName(dataRecord.SigHashAlgorithm)));
                }

            case string str when str.Equals("hmac", StringComparison.OrdinalIgnoreCase):
                var unencryptedKey = GetUnencryptedParameter(dataRecord, encryptionKey);

                return(SignatureAlgorithm.CreateForVerification(unencryptedKey, new HashAlgorithmName(dataRecord.SigHashAlgorithm)));

            default:
                throw new NotSupportedException($"The specified signature algorithm type ({dataRecord.SigHashAlgorithm ?? "[null]"}) cannot be deserialized.");
            }
        }