Exemple #1
0
        public async Task LoginAsync(string email)
        {
            if (email == null)
            {
                throw new ArgumentNullException(nameof(email));
            }
            if (string.IsNullOrWhiteSpace(email))
            {
                throw new ArgumentException("Value cannot be empty or whitespace only string.", nameof(email));
            }
            if (this.client == null)
            {
                throw new ObjectDisposedException("AcmeContext");
            }

            Trace.Write($"Creating registration for '{email}'...");
            this.account = await this.client.NewRegistraton("mailto:" + email);

            this.account.Data.Agreement = this.account.GetTermsOfServiceUri();
            Trace.WriteLine("OK");

            Trace.Write($"Accepting TOS at {this.account.Data.Agreement}...");
            this.account = await this.client.UpdateRegistration(account);

            Trace.WriteLine("OK");
        }
Exemple #2
0
        /// <summary>
        /// Changes the registration key.
        /// </summary>
        /// <param name="account">The account.</param>
        /// <param name="newKey">The new registration key.</param>
        /// <returns>The awaitable.</returns>
        public async Task ChangeKey(AcmeAccount account, KeyInfo newKey)
        {
            var keyPair = new AccountKey(newKey);

            var body = new
            {
                account = account.Location,
                newKey  = keyPair.JsonWebKey,
            };

            var jws     = new JwsSigner(keyPair);
            var payload = jws.Sign(body);
            var payloadWithResourceType = new
            {
                payload.Header,
                payload.Payload,
                payload.Protected,
                payload.Signature,
                Resource = ResourceTypes.KeyChange
            };

            var uri = await this.handler.GetResourceUri(ResourceTypes.KeyChange);

            var result = await this.handler.Post(uri, payloadWithResourceType, key);

            ThrowIfError(result);

            this.key = keyPair;
        }
Exemple #3
0
        async Task ProcessAcmeFqdnAsync(AcmeAccount account, string fqdn, CancellationToken cancel)
        {
            cancel.ThrowIfCancellationRequested();

            DirectoryPath dir = this.AcmeDir.GetSubDirectory(fqdn);

            FilePath crtFileName = dir.Combine(dir.GetThisDirectoryName() + Consts.Extensions.Certificate_Acme);

            Certificate?currentCert = null;

            if (crtFileName.IsFileExists(cancel))
            {
                try
                {
                    currentCert = CertificateUtil.ImportChainedCertificates(crtFileName.ReadDataFromFile().Span).First();
                }
                catch (Exception ex)
                {
                    ex._Debug();
                }
            }

            if (currentCert == null || IsCertificateDateTimeToUpdate(currentCert.CertData.NotBefore, currentCert.CertData.NotAfter))
            {
                //Con.WriteLine($"fqdn = {fqdn}, currentCert = {currentCert}, crtFileName = {crtFileName}");

                await AcmeIssueAsync(account, fqdn, crtFileName, cancel);
            }
        }
Exemple #4
0
        async Task ProcessEnqueuedAcmeHostnameAsync(CancellationToken cancel)
        {
            List <string> queue;

            lock (AcmeQueueLockObj)
            {
                queue     = AcmeQueue;
                AcmeQueue = new List <string>();
            }

            if (queue.Count == 0)
            {
                // キューがない
                return;
            }

            using (AcmeClient client = new AcmeClient(new AcmeClientOptions(this.Settings.AcmeServiceDirectoryUrl !, this.TcpIp)))
            {
                AcmeAccount account = await client.LoginAccountAsync(this.AcmeAccountKey !, ("mailto:" + this.Settings.AcmeContactEmail)._SingleArray(), cancel);

                foreach (string fqdn in queue)
                {
                    if (CheckFqdnAllowedForAcme(fqdn))
                    {
                        if (this.Settings.AcmeEnableFqdnIpCheck == false || (await CheckFqdnHasIpAddressOfThisLocalHostAsync(fqdn, cancel)))
                        {
                            await ProcessAcmeFqdnAsync(account, fqdn, cancel);
                        }
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Creates a new registraton.
        /// </summary>
        /// <param name="contact">The contact method, e.g. <c>mailto:[email protected]</c>.</param>
        /// <returns>The ACME account created.</returns>
        public async Task <AcmeAccount> NewRegistraton(params string[] contact)
        {
            if (this.key == null)
            {
                this.key = new AccountKey();
            }

            var registration = new Registration
            {
                Contact  = contact,
                Resource = ResourceTypes.NewRegistration
            };

            var uri = await this.handler.GetResourceUri(registration.Resource);

            var result = await this.handler.Post(uri, registration, key);

            ThrowIfError(result);

            var account = new AcmeAccount
            {
                Links       = result.Links,
                Data        = result.Data,
                Json        = result.Json,
                Raw         = result.Raw,
                Location    = result.Location,
                Key         = key.Export(),
                ContentType = result.ContentType
            };

            return(account);
        }
Exemple #6
0
        public async Task CanUpdateRegistration()
        {
            var accountKey = await Helper.LoadkeyV1();

            var regLocation = new Uri("http://example.com/reg/1");
            var mock        = MockHttp(async req =>
            {
                if (req.Method == HttpMethod.Post && req.RequestUri == regLocation)
                {
                    var payload = await ParsePayload <RegistrationEntity>(req);
                    Assert.Equal(ResourceTypes.Registration, payload.Resource);
                    Assert.Equal(1, payload.Contact?.Count);
                    Assert.Equal($"another-{email}", payload.Contact[0]);
                    Assert.NotNull(payload.Agreement);

                    var respJson = new
                    {
                        contact   = payload.Contact,
                        agreement = payload.Agreement,
                        resource  = ResourceTypes.Registration
                    };

                    var resp = CreateResponse(respJson, HttpStatusCode.Created, regLocation);
                    resp.Headers.Add("Link", $"<{tos}>; rel=\"terms-of-service\"");
                    return(resp);
                }

                return(null);
            });

            using (var http = new HttpClient(mock.Object))
                using (var handler = new AcmeHttpHandler(server, http))
                {
                    using (var client = new AcmeClient(handler))
                    {
                        client.Use(accountKey.Export());

                        var account = new AcmeAccount
                        {
                            Location = regLocation,
                            Data     = new RegistrationEntity
                            {
                                Resource  = ResourceTypes.Registration,
                                Contact   = new[] { $"another-{email}" },
                                Agreement = tos
                            }
                        };

                        var result = await client.UpdateRegistration(account);

                        Assert.Equal(ResourceTypes.Registration, result.Data.Resource);
                        Assert.Equal(tos, account.Data.Agreement);
                        Assert.Equal(regLocation, account.Location);
                    }

                    mock.As <IDisposable>().Verify(x => x.Dispose(), Times.Never());
                }
        }
Exemple #7
0
        public DnsChallenge(AcmeAccount account, AcmeChallenge challenge, string identifier)
        {
            Account    = account;
            Challenge  = challenge;
            Identifier = identifier;

            Token            = challenge.Token;
            AuthorizationKey = CertificateUtility.CreateAuthorizationKey(account, challenge.Token);
        }
Exemple #8
0
        public async Task ACME_Test_03_GetAccount()
        {
            AcmeAccount Account = await this.client.GetAccount();

            Assert.IsNotNull(Account);
            Assert.AreEqual(AcmeAccountStatus.valid, Account.Status);
            Assert.IsNotNull(Account.Contact);
            Assert.IsTrue(Account.Contact.Length > 0);
            Assert.AreEqual("mailto:[email protected]", Account.Contact[0]);
        }
Exemple #9
0
        public async Task ACME_Test_02_CreateAccount()
        {
            AcmeAccount Account = await this.client.CreateAccount(new string[] { "mailto:[email protected]" }, true);

            Assert.IsNotNull(Account);
            Assert.AreEqual(AcmeAccountStatus.valid, Account.Status);
            Assert.IsNotNull(Account.Contact);
            Assert.IsTrue(Account.Contact.Length > 0);
            Assert.AreEqual("mailto:[email protected]", Account.Contact[0]);
        }
Exemple #10
0
        public async Task CanDeleteRegistration()
        {
            var accountKey = await Helper.LoadkeyV1();

            var regLocation = new Uri("http://example.com/reg/1");
            var mock        = MockHttp(async req =>
            {
                if (req.Method == HttpMethod.Post && req.RequestUri == regLocation)
                {
                    var payload = await ParsePayload <RegistrationEntity>(req);
                    Assert.Equal(ResourceTypes.Registration, payload.Resource);
                    Assert.True(payload.Delete);

                    var resp = CreateResponse(null, HttpStatusCode.OK, regLocation);
                    resp.Headers.Add("Link", $"<{tos}>; rel=\"terms-of-service\"");
                    return(resp);
                }

                return(null);
            });

            using (var http = new HttpClient(mock.Object))
                using (var handler = new AcmeHttpHandler(server, http))
                {
                    using (var client = new AcmeClient(handler))
                    {
                        var account = new AcmeAccount
                        {
                            Location = regLocation,
                            Data     = new RegistrationEntity
                            {
                                Resource  = ResourceTypes.Registration,
                                Contact   = new[] { $"another-{email}" },
                                Agreement = tos
                            }
                        };

                        try
                        {
                            await client.DeleteRegistration(account);

                            Assert.False(true);
                        }
                        catch (InvalidOperationException)
                        {
                        }

                        client.Use(accountKey.Export());
                        await client.DeleteRegistration(account);
                    }

                    mock.As <IDisposable>().Verify(x => x.Dispose(), Times.Never());
                }
        }
Exemple #11
0
        public async Task ACME_Test_04_UpdateAccount()
        {
            AcmeAccount Account = await this.client.GetAccount();

            Account = await Account.Update(new string[] { "mailto:[email protected]", "mailto:[email protected]" });

            Assert.IsNotNull(Account);
            Assert.AreEqual(AcmeAccountStatus.valid, Account.Status);
            Assert.IsNotNull(Account.Contact);
            Assert.IsTrue(Account.Contact.Length > 1);
            Assert.AreEqual("mailto:[email protected]", Account.Contact[0]);
            Assert.AreEqual("mailto:[email protected]", Account.Contact[1]);
        }
Exemple #12
0
        public async Task ACME_Test_04_UpdateAccount()
        {
            AcmeAccount Account = await this.client.GetAccount();

            Account = await Account.Update(new string[] { "mailto:[email protected]", "mailto:[email protected]" });

            Assert.IsNotNull(Account);
            Assert.AreEqual(AcmeAccountStatus.valid, Account.Status);
            Assert.IsNotNull(Account.Contact);
            Assert.IsTrue(Account.Contact.Length > 1);
            Assert.IsTrue(Array.IndexOf <string>(Account.Contact, "mailto:[email protected]") >= 0);
            Assert.IsTrue(Array.IndexOf <string>(Account.Contact, "mailto:[email protected]") >= 0);
        }
Exemple #13
0
        /// <summary>
        /// Deletes the registration.
        /// </summary>
        /// <returns>The awaitable.</returns>
        public async Task DeleteRegistration(AcmeAccount account)
        {
            if (this.key == null)
            {
                throw new InvalidOperationException();
            }

            await this.handler.Post(
                account.Location,
                new Registration
            {
                Delete = true
            }, key);
        }
        /// <summary>
        /// Deactivates an existing account
        /// </summary>
        /// <param name="account">Existing account</param>
        /// <returns></returns>
        public async Task DeactiveAsync(AcmeAccount account)
        {
            var directory = await _directoryCache.GetAsync();

            var nonce = await _nonceCache.GetAsync();

            var response = await _acmeApi.DeactivateAccountAsync(directory, nonce, account);

            if (response.Status == AcmeApiResponseStatus.Error)
            {
                throw new AcmeProtocolException(response.Message);
            }

            _nonceCache.Update(response.Nonce);
        }
Exemple #15
0
        /// <summary>
        /// Updates the registration.
        /// </summary>
        /// <param name="account">The account to update.</param>
        /// <returns>The updated ACME account.</returns>
        /// <exception cref="InvalidOperationException">If the account key is missing.</exception>
        public async Task <AcmeAccount> UpdateRegistration(AcmeAccount account)
        {
            if (this.key == null)
            {
                throw new InvalidOperationException();
            }

            var registration = account.Data;

            var result = await this.handler.Post(account.Location, registration, key);

            ThrowIfError(result);

            account.Data = result.Data;
            return(account);
        }
Exemple #16
0
        public async Task ACME_Test_12_GetOrders()
        {
            AcmeAccount Account = await this.client.GetAccount();

            AcmeOrder[] Orders = await Account.GetOrders();

            foreach (AcmeOrder Order in Orders)
            {
                Console.Out.WriteLine(Order.Location);
                Console.Out.WriteLine(Order.Status);
                Console.Out.WriteLine();

                AcmeAuthorization[] Authorizations = await Order.GetAuthorizations();

                this.Print(Authorizations);
            }
        }
Exemple #17
0
        public async Task ACME_Test_05_NewKey()
        {
            AcmeAccount Account = await this.client.GetAccount();

            await Account.NewKey();

            CspParameters CspParams = new CspParameters()
            {
                Flags            = CspProviderFlags.UseMachineKeyStore,
                KeyContainerName = directory
            };

            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096, CspParams))
            {
                RSA.ImportParameters(this.client.ExportAccountKey(true));
            }
        }
Exemple #18
0
        /// <summary>
        /// Gets challenges used to verify domain ownership.
        /// </summary>
        /// <param name="account">Existing account.</param>
        /// <param name="acmeCertificateFulfillmentPromise">The certificate fulfillment promise retrieved from the RequestCertificate call.</param>
        /// <param name="challengeType">The challenge type expected back.</param>
        /// <returns>Challenge used to verify domain ownership</returns>
        /// <remarks>If requesting a challenge for a wildcard domain, only dns challenge is supported.</remarks>
        /// <exception cref="NotSupportedException">If the challenge type is not supported.</exception>
        /// <exception cref="AcmeProtocolException">On all other Acme related exceptions</exception>
        public async Task <ChallengeCollection> GetChallengesAsync(AcmeAccount account, AcmeCertificateFulfillmentPromise acmeCertificateFulfillmentPromise, ChallengeType challengeType)
        {
            var response = await _acmeApi.GetChallengesAsync(acmeCertificateFulfillmentPromise);

            var errorResponse = response.Where(t => t.Status == AcmeApiResponseStatus.Error);

            if (errorResponse.Any())
            {
                throw new AcmeProtocolException(string.Join(" | ", errorResponse.Select(t => t.Message)));
            }

            ChallengeCollection challenges = new ChallengeCollection();

            foreach (var resp in response)
            {
                AcmeChallenge sChallenge = resp.Data.Challenges.FirstOrDefault(t => t.Type.Equals(challengeType.Value));
                if (sChallenge == null)
                {
                    throw new NotSupportedException($"{challengeType.Value} challenge type not supported in this context.");
                }
                IAcmeChallengeContent challengeContent = null;
                switch (challengeType.Value)
                {
                case ProtoacmeContants.CHALLENGE_HTTP:
                    challengeContent = new HttpChallenge(account, sChallenge, resp.Data.Identifier?.Value);
                    challenges.Add(challengeContent);
                    break;

                case ProtoacmeContants.CHALLENGE_DNS:
                    challengeContent = new DnsChallenge(account, sChallenge, resp.Data.Identifier?.Value);
                    challenges.Add(challengeContent);
                    break;

                case ProtoacmeContants.CHALLENGE_TLS:
                    challengeContent = new TlsChallenge(account, sChallenge, resp.Data.Identifier?.Value);
                    challenges.Add(challengeContent);
                    break;

                default:
                    break;
                }
            }

            return(challenges);
        }
Exemple #19
0
        async Task AcmeIssueAsync(AcmeAccount account, string fqdn, FilePath crtFileName, CancellationToken cancel)
        {
            cancel.ThrowIfCancellationRequested();

            AcmeOrder order = await account.NewOrderAsync(fqdn, cancel);

            if (this.IsGlobalCertVault)
            {
                GlobalCertVault.SetAcmeAccountForChallengeResponse(account);
            }

            CertificateStore store = await order.FinalizeAsync(this.AcmeCertKey !, cancel);

            IsAcmeCertUpdated = true;

            store.ExportChainedPem(out ReadOnlyMemory <byte> certData, out _);

            crtFileName.WriteDataToFile(certData, additionalFlags: FileFlags.AutoCreateDirectory);
        }
Exemple #20
0
        private void SaveAccountAndChallengeData(AcmeAccount account, IEnumerable <IAcmeChallengeContent> challenges, AcmeCertificateFulfillmentPromise promise)
        {
            string baseFolder = @"c:\temp";

            var serializedAccount = JsonConvert.SerializeObject(account, Formatting.None);

            serializedAccount = Convert.ToBase64String(Encoding.UTF8.GetBytes(serializedAccount));
            using (FileStream fs = new FileStream(Path.Combine(baseFolder, "myaccount.acc"), FileMode.Create))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(serializedAccount);
                fs.Write(buffer, 0, buffer.Length);
            }

            var sChallenges = JsonConvert.SerializeObject(challenges, Formatting.None);

            sChallenges = Convert.ToBase64String(Encoding.UTF8.GetBytes(sChallenges));
            using (FileStream fs = new FileStream(Path.Combine(baseFolder, "challenges.dat"), FileMode.Create))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(sChallenges);
                fs.Write(buffer, 0, buffer.Length);
            }

            var sCertificatePromise = JsonConvert.SerializeObject(promise);

            sCertificatePromise = Convert.ToBase64String(Encoding.UTF8.GetBytes(sCertificatePromise));
            using (FileStream fs = new FileStream(Path.Combine(baseFolder, "challengepromise.dat"), FileMode.Create))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(sCertificatePromise);
                fs.Write(buffer, 0, buffer.Length);
            }

            foreach (var challenge in challenges)
            {
                challenge.SaveToFile(Path.Combine(baseFolder, challenge.Token));
            }

            //Create Account Private Key
            using (TextWriter writer = new StreamWriter(Path.Combine(baseFolder, "account.key")))
            {
                CertificateUtility.ExportRSAPrivateKey(account.SecurityInfo, writer);
            }
        }
Exemple #21
0
        public async Task IssueWildCardCertificate()
        {
            var restApi = new AcmeRestApi(ProtoacmeContants.LETSENCRYPT_STAGING_ENDPOINT);
            var client  = new ProtoacmeClient(restApi);

            //1. Load up the account and challenge data.
            AcmeAccount account = AcmeAccount.FromFile(@"c:\temp\account.dat");
            AcmeCertificateFulfillmentPromise promise = AcmeCertificateFulfillmentPromise.FromFile(@"c:\temp\promise.dat");
            ChallengeCollection challenges            = ChallengeCollection.FromFile <DnsChallenge>(@"c:\temp\challenge.dat");

            //2. Tell Lets Encrypt to verify our challenge.
            var startVerifyResult = await client.Challenge.ExecuteChallengeVerification(challenges[0]);

            AcmeChallengeStatus challengeStatus = null;

            while (challengeStatus == null || challengeStatus.Status == "pending")
            {
                challengeStatus = await client.Challenge.GetChallengeVerificationStatus(challenges[0]);

                await Task.Delay(3000);
            }
            if (challengeStatus.Status != "valid")
            {
                throw new Exception($"Failed to validate challenge token");
            }

            //3. Create the CSR
            CSR csr = CertificateUtility.GenerateCsr(wildCardDns);

            SaveCRTPrivateKey(csr);

            //4. Download the certificate
            var cert = await client.Certificate.DownloadCertificateAsync(account, promise, csr, CertificateType.Cert);

            //5. Save the certificate
            using (FileStream fs = new FileStream(@"c:\temp\mycert.cer", FileMode.Create))
            {
                byte[] buffer = cert.Array;
                fs.Write(buffer, 0, buffer.Length);
            }
        }
        private string GenerateCSR(AcmeAccount account, params string[] domainNames)
        {
            HashAlgorithmName hashName = HashAlgorithmName.SHA256;

            var builder = new SubjectAlternativeNameBuilder();

            foreach (var name in domainNames)
            {
                builder.AddDnsName(name);
            }

            RSA rsa = RSA.Create(4096);
            //rsa.ImportParameters(account.SecurityInfo);

            var dn  = new X500DistinguishedName($"CN={domainNames.First()}");
            var csr = new CertificateRequest(dn, rsa, hashName, RSASignaturePadding.Pkcs1);

            csr.CertificateExtensions.Add(builder.Build());

            return(Base64Tool.Encode(csr.CreateSigningRequest()));
        }
Exemple #23
0
        public async Task ChangeKey_ShouldUpdateLastNonce()
        {
            //ARRANGE
            var acmeApiMock        = new Mock <IAcmeRestApi>();
            var directoryCacheMock = new Mock <ICachedRepository <AcmeDirectory> >();
            var nonceCacheMock     = new Mock <ICachedRepository <string> >();

            AcmeApiResponse successResponse = TestHelpers.AcmeEmptyResponseWithNonce;
            AcmeAccount     account         = TestHelpers.AcmeAccountResponse.Data;

            acmeApiMock.Setup(method => method.RollOverAccountKeyAsync(It.IsAny <AcmeDirectory>(), It.IsAny <string>(), It.IsAny <AcmeAccount>()))
            .ReturnsAsync(successResponse);

            AcmeAccountService srv = new AcmeAccountService(acmeApiMock.Object, directoryCacheMock.Object, nonceCacheMock.Object);

            //ACT
            await srv.ChangeKeyAsync(account);

            //ASSERT
            nonceCacheMock.Verify(method => method.Update(successResponse.Nonce), Times.Once());
        }
Exemple #24
0
        public async Task <string> RegisterAndLoginAsync(string email)
        {
            if (email == null)
            {
                throw new ArgumentNullException(nameof(email));
            }
            if (string.IsNullOrWhiteSpace(email))
            {
                throw new ArgumentException("Value cannot be empty or whitespace only string.", nameof(email));
            }
            if (client == null)
            {
                throw new ObjectDisposedException(nameof(AutoAcmeContext));
            }
            context = new AcmeContext(serverAddress, null, client);
            Log.Write($"Creating registration for '{email}' and accept TOS...");
            var contacts       = new[] { "mailto:" + email };
            var accountContext = await context.NewAccount(contacts, true).ConfigureAwait(true);

            Log.WriteLine("OK");
            // For compatibility with earlier versions, use the V1 account object for storage
            AcmeAccount legacyAccount = new AcmeAccount()
            {
                ContentType = "application/json",
                Key         = new KeyInfo()
                {
                    PrivateKeyInfo = context.AccountKey.ToDer()
                },
                Data =
                {
                    Contact  = contacts,
                    Resource = "reg"
                },
                Location = accountContext.Location
            };

            legacyAccount.Data.Agreement = await context.TermsOfService().ConfigureAwait(true);

            return(JsonConvert.SerializeObject(legacyAccount));
        }
        public static string CreateAuthorizationKey(AcmeAccount account, string challengeToken)
        {
            string jwkThumbprint = string.Empty;

            //Compute the JWK Thumbprint
            var jwk = new
            {
                e   = Base64Tool.Encode(account.SecurityInfo.Exponent),
                kty = "RSA",
                n   = Base64Tool.Encode(account.SecurityInfo.Modulus)
            };

            string sjwk = JsonConvert.SerializeObject(jwk, Formatting.None);

            using (HashAlgorithm sha = SHA256.Create())
            {
                byte[] bjwk = Encoding.UTF8.GetBytes(sjwk);
                jwkThumbprint = Base64Tool.Encode(sha.ComputeHash(bjwk));
            }

            return($"{challengeToken}.{jwkThumbprint}");
        }
Exemple #26
0
        private void LoadAccountAndChallengeData <TChallengeType>(out AcmeAccount account, out List <TChallengeType> challenges, out AcmeCertificateFulfillmentPromise promise)
            where TChallengeType : IAcmeChallengeContent
        {
            string baseFolder = @"c:\temp";

            using (FileStream fs = new FileStream(Path.Combine(baseFolder, "myaccount.acc"), FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    var sAccount = sr.ReadToEnd();
                    var bAccount = Convert.FromBase64String(sAccount);
                    sAccount = Encoding.UTF8.GetString(bAccount);
                    account  = JsonConvert.DeserializeObject <AcmeAccount>(sAccount);
                }
            }

            using (FileStream fs = new FileStream(Path.Combine(baseFolder, "challenges.dat"), FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    var sChallenges = sr.ReadToEnd();
                    var bChallenges = Convert.FromBase64String(sChallenges);
                    sChallenges = Encoding.UTF8.GetString(bChallenges);
                    challenges  = JsonConvert.DeserializeObject <List <TChallengeType> >(sChallenges);
                }
            }

            using (FileStream fs = new FileStream(Path.Combine(baseFolder, "challengepromise.dat"), FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    var sPromise = sr.ReadToEnd();
                    var bPromise = Convert.FromBase64String(sPromise);
                    sPromise = Encoding.UTF8.GetString(bPromise);
                    promise  = JsonConvert.DeserializeObject <AcmeCertificateFulfillmentPromise>(sPromise);
                }
            }
        }
        /// <summary>
        /// Downloads the SSL Certificate.
        /// </summary>
        /// <param name="account">Existing account</param>
        /// <param name="completedPromise">The completed certificate fulfillment promise</param>
        /// <param name="csr">Certificate request</param>
        /// <param name="certificateType">The type of certificate.</param>
        /// <returns>The certificate.</returns>
        public async Task <ArraySegment <byte> > DownloadCertificateAsync(AcmeAccount account, AcmeCertificateFulfillmentPromise completedPromise, Protoacme.Utility.Certificates.CSR csr, CertificateType certificateType)
        {
            var directory = await _directoryCache.GetAsync();

            var nonce = await _nonceCache.GetAsync();

            var finalizeResponse = await _acmeApi.FinalizeCertificatePromiseAsync(account, nonce, completedPromise, csr.Base64UrlEncoded);

            if (finalizeResponse.Status == AcmeApiResponseStatus.Error)
            {
                throw new AcmeProtocolException(finalizeResponse.Message);
            }

            var response = await _acmeApi.GetCertificateAsync(finalizeResponse.Data, certificateType);

            if (response.Status == AcmeApiResponseStatus.Error)
            {
                throw new AcmeProtocolException(response.Message);
            }

            _nonceCache.Update(finalizeResponse.Nonce);

            return(response.Data);
        }
Exemple #28
0
        public async Task ACME_Test_90_DeactivateAccount()
        {
            AcmeAccount Account = await this.client.GetAccount();

            Account = await Account.Deactivate();
        }
Exemple #29
0
 public AcmeOrder(AcmeAccount account, string url, AcmeOrderPayload info)
 {
     this.Account = account;
     this.Url     = url;
     this.Info    = info;
 }
Exemple #30
0
        private async Task <AcmeOrder> OrderCertificate(params string[] Domains)
        {
            AcmeAccount Account = await this.client.GetAccount();

            return(await Account.OrderCertificate(Domains, null, null));
        }