Example #1
0
        public void CorrectNumberOfSctsReturnsSuccessTrusted()
        {
            foreach (var tp in _testParams)
            {
                var certMoq = new Moq.Mock <MoqX509Certificate2>();
                certMoq.Setup(c => c.MoqNotBefore).Returns(tp.Start);
                certMoq.Setup(c => c.MoqNotAfter).Returns(tp.End);

                var cert = certMoq.Object;
                var scts = new Dictionary <string, SctVerificationResult>();

                for (var i = 0; i < tp.SctsRequired; i++)
                {
                    scts[i.ToString()] = SctVerificationResult.Valid(DateTime.UtcNow, Guid.NewGuid().ToString());
                }

                for (var i = 0; i < 10; i++)
                {
                    scts[(i + 100).ToString()] = SctVerificationResult.FailedVerification(DateTime.UtcNow, Guid.NewGuid().ToString());
                }

                var result = new CtPolicyDefault().PolicyVerificationResult(cert, scts);

                Assert.True(result.Result == CtResult.Trusted, tp.Description);
            }
        }
Example #2
0
        public void FewerSctsThanRequiredReturnsFailure()
        {
            var rand = new Random();

            foreach (var tp in _testParams)
            {
                var certMoq = new Moq.Mock <MoqX509Certificate2>();
                certMoq.Setup(c => c.MoqNotBefore).Returns(tp.Start);
                certMoq.Setup(c => c.MoqNotAfter).Returns(tp.End);

                var cert = certMoq.Object;
                var scts = new Dictionary <string, SctVerificationResult>();

                var numScts = rand.Next(tp.SctsRequired);
                for (var i = 0; i < numScts; i++)
                {
                    scts[i.ToString()] = SctVerificationResult.Valid(DateTime.UtcNow, Guid.NewGuid().ToString());
                }

                for (var i = 0; i < 10; i++)
                {
                    scts[(i + 100).ToString()] = SctVerificationResult.FailedVerification(DateTime.UtcNow, Guid.NewGuid().ToString());
                }

                var result = new CtPolicyDefault().PolicyVerificationResult(cert, scts);

                Assert.True(tp.SctsRequired == result.MinSctCount, tp.Description);
                Assert.True(result.Result == CtResult.TooFewSctsTrusted, tp.Description);
            }
        }
Example #3
0
        private static SctVerificationResult VerifySctSignatureOverBytes(this SignedCertificateTimestamp sct, Log logServer, byte[] toVerify)
        {
            var(oid, sigAlg) = GetKeyAlgorithm(logServer.KeyBytes);
            //var signer = sigAlg switch
            //{
            //    CtSignatureAlgorithm.Ecdsa => SignerUtilities.GetSigner(Constants.Sha256WithEcdsa),
            //    CtSignatureAlgorithm.Rsa => SignerUtilities.GetSigner(Constants.Sha256WithRsa),
            //    _ => throw new NotImplementedException($"Signature algothrim '{sigAlg}' not supported, with OID '{oid}'"),
            //};

            ISigner signer;

            if (sigAlg == CtSignatureAlgorithm.Ecdsa)
            {
                signer = SignerUtilities.GetSigner(Constants.Sha256WithEcdsa);
            }
            else if (sigAlg == CtSignatureAlgorithm.Rsa)
            {
                signer = SignerUtilities.GetSigner(Constants.Sha256WithRsa);
            }
            else
            {
                throw new NotImplementedException($"Signature algothrim '{sigAlg}' not supported, with OID '{oid}'");
            }

            var pubKey = PublicKeyFactory.CreateKey(logServer.KeyBytes);

            signer.Init(false, pubKey);
            signer.BlockUpdate(toVerify, 0, toVerify.Length);
            var isValid = signer.VerifySignature(sct.Signature.SignatureData);

            return(isValid
                ? SctVerificationResult.Valid(sct.TimestampUtc, logServer.LogId, logServer.Description)
                : SctVerificationResult.FailedVerification(sct.TimestampUtc, logServer.LogId, logServer.Description, "Invalid Signature"));
        }
Example #4
0
        public async ValueTask <CtVerificationResult> IsValidAsync(IList <X509Certificate2> chain, CancellationToken cancellationToken)
        {
            if (chain?.Any() != true)
            {
                return(CtVerificationResult.NoCertificates());
            }

            var leaf = chain.First();
            var scts = leaf.GetSignedCertificateTimestamps();

            if (scts?.Any() != true)
            {
                return(CtVerificationResult.NoScts());
            }

            var logDictionary = await _logListService.GetLogDictionaryAsync(cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();

            if (logDictionary?.Any() != true)
            {
                return(CtVerificationResult.LogServersFailed());
            }

            var sctResults = scts.Select(sct =>
                                         logDictionary.TryGetValue(sct.LogIdBase64, out var log)
                    ? (sct.LogIdBase64, sct.VerifySignature(log, chain))
                    : (sct.LogIdBase64, SctVerificationResult.NoTrustedLogServerFound(sct.TimestampUtc)))
                             .ToDictionary(t => t.LogIdBase64, t => t.Item2);

            return(_ctPolicy.PolicyVerificationResult(leaf, sctResults));
        }
        public async Task <CtVerificationResult> IsValidAsync(IList <X509Certificate2> chain, CancellationToken cancellationToken)
        {
            if (chain?.Any() != true)
            {
                return(CtVerificationResult.NoCertificates());
            }

            var leaf = chain.First();
            var scts = leaf.GetSignedCertificateTimestamps();

            if (scts?.Any() != true)
            {
                return(CtVerificationResult.NoScts());
            }

            var logDictionary = await _logListService.GetLogDictionaryAsync(cancellationToken).ConfigureAwait(false);

            //foreach (var log in logDictionary)
            //{
            //    Console.WriteLine($"{BitConverter.ToString(Convert.FromBase64String(log.Key)).Replace("-", string.Empty).ToLowerInvariant()} {log.Value.Description}");
            //}

            cancellationToken.ThrowIfCancellationRequested();

            if (logDictionary?.Any() != true)
            {
                return(CtVerificationResult.LogServersFailed());
            }

            //var sctResults = scts.Select(sct =>
            //        logDictionary.TryGetValue(sct.LogIdBase64, out var log)
            //        ? new { LogIdBase64 = sct.LogIdBase64, Item2 = sct.VerifySignature(log, chain) }
            //        : new { LogIdBase64 = sct.LogIdBase64, Item2 = SctVerificationResult.NoTrustedLogServerFound(sct.TimestampUtc) })
            //    .ToDictionary(t => t.LogIdBase64, t => t.Item2);

            var sctResults = new Dictionary <string, SctVerificationResult>();

            foreach (var sct in scts)
            {
                SctVerificationResult result;
                if (logDictionary.TryGetValue(sct.LogIdBase64, out var log))
                {
                    result = sct.VerifySignature(log, chain);
                }
                else
                {
                    result = SctVerificationResult.NoTrustedLogServerFound(sct.TimestampUtc);
                }

                sctResults.Add(sct.LogIdBase64, result);
                Console.WriteLine($"{BitConverter.ToString(Convert.FromBase64String(sct.LogIdBase64)).Replace("-", string.Empty).ToLowerInvariant()} {result}");
            }

            return(_ctPolicy.PolicyVerificationResult(leaf, sctResults));
        }
Example #6
0
        internal static SctVerificationResult VerifySignature(this SignedCertificateTimestamp sct, Log logServer, IList <X509Certificate2> chain)
        {
            if (logServer == null || sct == null || chain?.Any() != true || logServer.LogId != sct.LogIdBase64)
            {
                return(SctVerificationResult.FailedVerification(sct.TimestampUtc, logServer?.LogId, "Invalid verification arguments"));
            }

            var nowUtc = DateTime.UtcNow;

            if (sct.TimestampUtc > nowUtc)
            {
                return(SctVerificationResult.FutureTimestamp(sct.TimestampUtc, logServer.LogId));
            }

            if (logServer.ValidUntilUtc.HasValue && sct.TimestampUtc > logServer.ValidUntilUtc)
            {
                return(SctVerificationResult.LogServerUntrusted(sct.TimestampUtc, logServer.LogId));
            }

            try
            {
                var leafCert      = chain.First();
                var notPreCert    = !leafCert.IsPreCertificate();
                var noEmbeddedSct = !leafCert.HasEmbeddedSct();
                if (notPreCert && noEmbeddedSct)
                {
                    // When verifying final cert without embedded SCTs, we don't need the issuer but can verify directly
                    var toVerify = sct.SerialiseSignedSctData(leafCert);
                    return(sct.VerifySctSignatureOverBytes(logServer, toVerify));
                }

                if (chain.Count < 2)
                {
                    return(SctVerificationResult.FailedVerification(sct.TimestampUtc, logServer.LogId, "Chain with PreCertificate or Certificate must contain issuer"));
                }

                // PreCertificate or final certificate with embedded SCTs, we want the issuerInformation
                var issuerCert = chain[1];
                var isPreCertificateSigningCert = issuerCert.IsPreCertificateSigningCert();

                var issuerInformation = default(IssuerInformation);

                if (!isPreCertificateSigningCert)
                {
                    issuerInformation = issuerCert.IssuerInformation();
                }
                else if (chain.Count < 3)
                {
                    return(SctVerificationResult.FailedVerification(sct.TimestampUtc, logServer.LogId, "Chain with PreCertificate signed by PreCertificate Signing Cert must contain issuer"));
                }
                else
                {
                    issuerInformation = issuerCert.IssuerInformationFromPreCertificate(chain[2]);
                }

                return(VerifySctOverPreCertificate(sct, logServer, leafCert, issuerInformation));
            }
            catch (Exception ex)
            {
                return(SctVerificationResult.FailedWithException(sct.TimestampUtc, logServer.LogId, ex));
            }
        }