コード例 #1
0
        public async Task <X509Certificate2> GetActiveCertificateAsync(long fromTimeStamp, long toTimeStamp)
        {
            if (toTimeStamp < fromTimeStamp)
            {
                throw new ArgumentOutOfRangeException(
                          $"Invalid time range. FromTimeStamp {fromTimeStamp}, ToTimeStamp {toTimeStamp}");
            }

            FileSystemPrivateKeyFormat     keyFormat       = null;
            FileSystemCertFormat           certFormat      = null;
            FileSystemCertCollectionFormat certsCollection = await GetFileSystemCertCollectionFormat();

            FileSystemKeysCollectionFormat keysCollection = await GetFileSystemKeyCollectionFormat();

            foreach (KeyValuePair <string, FileSystemCertFormat> keyValuePair in certsCollection.Certs)
            {
                string orderUrl = keyValuePair.Key;
                if (keysCollection.Keys.TryGetValue(orderUrl, out FileSystemPrivateKeyFormat currentPrivateKey))
                {
                    FileSystemCertFormat currentCert = keyValuePair.Value;
                    if (currentCert.NotAfter > fromTimeStamp && currentCert.NotBefore <= toTimeStamp)
                    {
                        if (certFormat == null || certFormat.NotAfter < currentCert.NotAfter)
                        {
                            certFormat = currentCert;
                            keyFormat  = currentPrivateKey;
                        }
                    }
                }
            }

            if (certFormat == null)
            {
                return(null);
            }

            byte[]          certBytes   = Convert.FromBase64String(certFormat.Val);
            X509Certificate certificate = _certCodec.Decode(certBytes);

            byte[]         privateKeyBytes = Convert.FromBase64String(keyFormat.Val);
            CertPrivateKey privateKey      = _privateKeyCodec.Decode(privateKeyBytes);

            return(CertHelper.ToX509Certificate2(privateKey, certificate));
        }
コード例 #2
0
        protected async Task <bool> ResolveCertificate(AcmeProtocolClient acme)
        {
            if (_state.Certificate != null)
            {
                _logger.LogInformation("Certificate is already resolved");
                return(true);
            }

            CertPrivateKey key = null;

            _logger.LogInformation("Refreshing Order status");
            _state.Order = await acme.GetOrderDetailsAsync(_state.Order.OrderUrl, _state.Order);

            Save(_state.OrderFile, _state.Order);

            if (AcmeState.PendingStatus == _state.Order.Payload.Status)
            {
                _logger.LogInformation("Generating CSR");
                byte[] csr;
                switch (_options.CertificateKeyAlgor)
                {
                case "rsa":
                    key = CertHelper.GenerateRsaPrivateKey(
                        _options.CertificateKeySize ?? AcmeOptions.DefaultRsaKeySize);
                    csr = CertHelper.GenerateRsaCsr(_options.DnsNames, key);
                    break;

                case "ec":
                    key = CertHelper.GenerateEcPrivateKey(
                        _options.CertificateKeySize ?? AcmeOptions.DefaultEcKeySize);
                    csr = CertHelper.GenerateEcCsr(_options.DnsNames, key);
                    break;

                default:
                    throw new Exception("Unknown Certificate Key Algorithm: "
                                        + _options.CertificateKeyAlgor);
                }

                using (var keyPem = new MemoryStream())
                {
                    CertHelper.ExportPrivateKey(key, EncodingFormat.PEM, keyPem);
                    keyPem.Position = 0L;
                    Save(_state.CertificateKeysFile, keyPem);
                }
                Save(_state.CertificateRequestFile, csr);

                _logger.LogInformation("Finalizing Order");
                _state.Order = await acme.FinalizeOrderAsync(_state.Order.Payload.Finalize, csr);

                Save(_state.OrderFile, _state.Order);
            }

            if (AcmeState.ValidStatus != _state.Order.Payload.Status)
            {
                _logger.LogWarning("Order is NOT VALID");
                return(false);
            }

            if (string.IsNullOrEmpty(_state.Order.Payload.Certificate))
            {
                _logger.LogWarning("Order Certificate is NOT READY YET");
                var now = DateTime.Now;
                do
                {
                    _logger.LogInformation("Waiting...");
                    // We wait in 5s increments
                    await Task.Delay(5000);

                    _state.Order = await acme.GetOrderDetailsAsync(_state.Order.OrderUrl, _state.Order);

                    Save(_state.OrderFile, _state.Order);

                    if (!string.IsNullOrEmpty(_state.Order.Payload.Certificate))
                    {
                        break;
                    }

                    if (DateTime.Now < now.AddSeconds(_options.WaitForCertificate))
                    {
                        _logger.LogWarning("Timed Out!");
                        return(false);
                    }
                } while (true);
            }

            _logger.LogInformation("Retreiving Certificate");
            var certBytes = await acme.GetOrderCertificateAsync(_state.Order);

            Save(_state.CertificateChainFile, certBytes);

            if (key == null)
            {
                _logger.LogInformation("Loading private key");
                key = CertHelper.ImportPrivateKey(EncodingFormat.PEM,
                                                  Load <Stream>(_state.CertificateKeysFile).value);
            }

            using (var crtStream = new MemoryStream(certBytes))
                using (var pfxStream = new MemoryStream())
                {
                    _logger.LogInformation("Reading in Certificate chain (PEM)");
                    var cert = CertHelper.ImportCertificate(EncodingFormat.PEM, crtStream);
                    _logger.LogInformation("Writing out Certificate archive (PKCS12)");
                    CertHelper.ExportArchive(key, new[] { cert }, ArchiveFormat.PKCS12, pfxStream);
                    pfxStream.Position = 0L;
                    Save(_state.CertificateFile, pfxStream);
                }

            _logger.LogInformation("Loading PKCS12 archive as active certificate");
            _state.Certificate = new X509Certificate2(Load <byte[]>(_state.CertificateFile).value);

            return(true);
        }
コード例 #3
0
        private async Task ResolveCertificate(AcmeClient acme)
        {
            _logger.LogInformation("Refreshing Order status");
            _order = await acme.GetOrderDetailsAsync(_order);

            // FIXME, wait for ready
            if (OrderStatus.Ready == _order.Status)
            {
                CertPrivateKey key = null;
                _logger.LogInformation("Generating CSR");
                byte[] csr;
                switch (_options.CertificateKeyAlgor)
                {
                case "rsa":
                    key = CertHelper.GenerateRsaPrivateKey(
                        _options.CertificateKeySize ?? AcmeOptions.DefaultRsaKeySize);
                    csr = CertHelper.GenerateRsaCsr(_options.DnsNames, key);
                    break;

                case "ec":
                    key = CertHelper.GenerateEcPrivateKey(
                        _options.CertificateKeySize ?? AcmeOptions.DefaultEcKeySize);
                    csr = CertHelper.GenerateEcCsr(_options.DnsNames, key);
                    break;

                default:
                    throw new Exception("Unknown Certificate Key Algorithm: " + _options.CertificateKeyAlgor);
                }

                await _stateStore.SavePrivateKeyAsync(_order.Url, key.KeyPair, _order.Expires);

                _logger.LogInformation("Finalizing Order");
                _order = await acme.FinalizeOrderAsync(_order, csr);
            }

            // FIXME extract out
            if (string.IsNullOrEmpty(_order.CertificateUrl))
            {
                _logger.LogWarning("Order Certificate is NOT READY YET");
                var now = DateTime.Now;
                do
                {
                    _logger.LogInformation("Waiting...");
                    await Task.Delay(5000);

                    _order = await acme.GetOrderDetailsAsync(_order);

                    if (!string.IsNullOrEmpty(_order.CertificateUrl))
                    {
                        break;
                    }

                    _logger.LogInformation($"order status {_order.Status}");

                    if (DateTime.Now > now.AddSeconds(_options.WaitForCertificate))
                    {
                        throw new TimeoutException("Failed to get certificate url");
                    }
                } while (true);

                await _stateStore.SaveOrderAsync(_order);
            }

            _logger.LogInformation("Retrieving Certificate");
            X509Certificate newCert = await acme.GetOrderCertificateAsync(_order);

            await _stateStore.SaveCertificateAsync(_order.Url, newCert);
        }