private async Task AddOrUpdateCertificate(IFormFile certificateFile) { var bytes = await certificateFile.ReadAsBytesAsync(); X509Certificate2 cert = null; try { cert = new X509Certificate2(bytes); } catch { } if (cert == null) { ModelState.AddModelError("Input.CertificateFile", "Not a valid certificate"); return; } var existingDomainCert = await _dataContext.DomainCertificates .FirstOrDefaultAsync(x => x.Thumbprint == cert.Thumbprint); if (existingDomainCert != null) { ModelState.AddModelError("Input.CertificateFile", "Certificate already exists"); } else { var domainCert = DomainCertificate.FromX509Certificate2(cert, CertificateSource.Uploaded); _dataContext.DomainCertificates.Add(domainCert); await _dataContext.SaveChangesAsync(); StatusMessage = "New certificate added"; } }
public DomainScan Scan() { return(NamedLocker.RunWithLock(_domain.Uri, () => { _logger.LogInformation($"Scanning domain {_domain.Uri}"); var uri = new Uri(_domain.Uri); var hostEntry = _lookupClient.GetHostEntry(uri.Host); if (hostEntry != null && hostEntry.AddressList.Any()) { var msg = $"{uri.Host} resolved to the following IP addresses: " + $"{string.Join(", ", hostEntry.AddressList.Select(x => x))}"; _messages.Add(msg); _logger.LogDebug(msg); var ip = hostEntry.AddressList.First(); OpenSslConnection(uri.Host, ip, uri.Port); } var domainCert = DomainCertificate.FromX509Certificate2(_certificate, CertificateSource.TrackedDomain); _certificate?.Dispose(); var domainScan = new DomainScan { DateScan = DateTime.UtcNow, DomainCertificate = domainCert, ScanResult = string.Join("\r\n", _messages), ScanSuccess = domainCert != null, ScanStatus = _scanStatus }; _logger.LogInformation($"Domain scan finished {(domainScan.ScanSuccess ? "successfully" : "unsuccessfully")} " + $"for {_domain.Uri}"); return domainScan; })); }
public static TrackedCertificate FromDomainCertificate(DomainCertificate domainCertificate) { var verifyResult = domainCertificate.Certificate.Verify(); return(new TrackedCertificate { Id = domainCertificate.DomainCertificateId, CertId = domainCertificate.DomainCertificateId, Order = int.MaxValue, DaysRemaining = (int)Math.Floor(domainCertificate.ValidNotAfter.Subtract(DateTime.Now).TotalDays), Subject = domainCertificate.Subject, RegistrableDomain = domainCertificate.RegistrableDomain, Issuer = domainCertificate?.IssuerName, DateModified = domainCertificate.DateCreated.ToLocalTime(), ValidFrom = domainCertificate.ValidNotBefore, ValidTo = domainCertificate.ValidNotAfter, IsValid = verifyResult, VerificationResult = verifyResult ? CertificateValidationResult.Valid : CertificateValidationResult.VerificationFailure, Thumbprint = domainCertificate.Thumbprint, Source = CertificateSource.Uploaded, PublicKeyHash = domainCertificate.Certificate.PublicKeyPinningHash() }); }
public async Task CreateCertificate() { var mockRequestExecutor = new MockedStringRequestExecutor(string.Empty); var client = new TestableOktaClient(mockRequestExecutor); var privateKeyMock = @"-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5cyk6x63iBJSW-----END PRIVATE KEY-----"; var certificateMock = @"-----BEGIN CERTIFICATE-----MIIFNzCCBB+gAwIBAgISBAXomJWRama3ypu8TIxdA9wzMA0GCSqGSIb3DQEBCwUA-----END CERTIFICATE-----"; var domainsClient = client.Domains; var domainCertificate = new DomainCertificate { PrivateKey = privateKeyMock, Certificate = certificateMock, Type = DomainCertificateType.Pem, }; await domainsClient.CreateCertificateAsync(domainCertificate, "domainId"); mockRequestExecutor.ReceivedHref.Should().Be("/api/v1/domains/domainId/certificate"); var expectedBody = $"{{\"privateKey\":\"{privateKeyMock}\",\"certificate\":\"{certificateMock}\",\"type\":\"{domainCertificate.Type}\"}}"; mockRequestExecutor.ReceivedBody.Should().Be(expectedBody); }
public async Task <AcmeOrder> Complete() { if (_acmeOrder.Status != AcmeOrderStatus.Validating) { return(_acmeOrder); } foreach (var cc in _authChallengeContainers) { cc.AuthorizationTask = cc.AuthorizationContext.Resource(); } var attempts = 5; do { // Kick off the authorization tasks for the tasks that haven't been run yet await Task.WhenAll(_authChallengeContainers .Where(x => !x.AuthorizationTask.IsCompleted) .Select(x => x.AuthorizationTask) .ToList()); var incompletes = 0; // After running the tasks, find all incomplete authz foreach (var cc in _authChallengeContainers) { var status = cc.AuthorizationTask.Result.Status; var completed = status == AuthorizationStatus.Valid || status == AuthorizationStatus.Invalid; if (!completed) { incompletes++; // Update the task such that it's a new task and it will be awaited above cc.AuthorizationTask = cc.AuthorizationContext.Resource(); } else { cc.Authorization = cc.AuthorizationTask.Result; } } // Find incomplete ones and try again _logger.LogDebug($"{incompletes} incomplete authorizations."); if (incompletes == 0) { break; } await Task.Delay(5000); } while (attempts-- > 0); // All authorizations have completed, save the results foreach (var cc in _authChallengeContainers) { cc.Authorization = cc.AuthorizationTask.Result; } // At this point, they're all complete and need to see which are valid/invalid // and obtain the cert if possible. try { var invalidResp = _authChallengeContainers .SelectMany(x => x.Authorization.Challenges) .Where(x => x.Error != null) .ToList(); var errors = string.Join("\r\n", invalidResp .Select(x => $"{x.Error.Status} {x.Error.Type} {x.Error.Detail}")); _acmeOrder.RequestCount = _authChallengeContainers.Count; _acmeOrder.InvalidResponseCount = invalidResp.Count; _acmeOrder.Errors = errors; _acmeOrder.Status = AcmeOrderStatus.Completed; if (invalidResp.Count > 0) { _acmeOrder.Status = AcmeOrderStatus.Invalid; return(_acmeOrder); } var cert = await _order.Generate( new CsrInfo { CommonName = _acmeCertificate.CsrCommonName, CountryName = _acmeCertificate.CsrCountryName, Locality = _acmeCertificate.CsrLocality, Organization = _acmeCertificate.CsrOrganization, OrganizationUnit = _acmeCertificate.CsrOrganizationUnit, State = _acmeCertificate.CsrState }, KeyFactory.FromPem(_acmeCertificate.Key.RawData)); var certBytes = cert.Certificate.ToDer(); var xCert = new X509Certificate2(certBytes); var domainCert = DomainCertificate.FromX509Certificate2(xCert, CertificateSource.AcmeCertificate); xCert.Dispose(); _acmeOrder.RawDataPem = cert.ToPem(); _acmeOrder.DomainCertificate = domainCert; return(_acmeOrder); } catch (AcmeRequestException e) { _acmeOrder.Status = AcmeOrderStatus.Error; _acmeOrder.Errors = $"{e.Error.Status} {e.Error.Type} {e.Error.Detail}"; } catch (Exception) { _acmeOrder.Status = AcmeOrderStatus.Error; _acmeOrder.Errors = "Unknown Error"; } return(_acmeOrder); }
public UserCertificate(ulong id, string username, DomainCertificate domainCertificate, DateTime issueDate, DateTime expireDate, HashFunctionType hashFunction = HashFunctionType.SHA1, uint ip = 0, byte[] ip6 = null) : base(id, issueDate, expireDate, hashFunction) { // assign type var cr = new BinaryList(); //id cr.AddUInt64(id); // ip this.ip = ip; this.ip6 = ip6; cr.AddUInt32(ip); if (ip6?.Length == 16) { cr.AddUInt8Array(ip6); } else { cr.AddUInt8Array(new byte[16]); } // dates this.issueDate = DateTime.UtcNow; this.expireDate = expireDate; cr.AddDateTime(issueDate) .AddDateTime(expireDate); // domain this.domainId = domainCertificate.Id; cr.AddUInt64(domainCertificate.Id); this.domain = domainCertificate.Domain; cr.AddUInt8((byte)domainCertificate.Domain.Length) .AddUInt8Array(Encoding.ASCII.GetBytes(domainCertificate.Domain)); // username this.username = username; cr.AddUInt8((byte)(username.Length)) .AddUInt8Array(Encoding.ASCII.GetBytes(username)); // hash function (SHA1) cr.AddUInt8((byte)((byte)hashFunction << 4));// (byte)0x10); // public key rsa = RSA.Create();// new RSACryptoServiceProvider(2048); rsa.KeySize = 2048; // write public certificate file var key = rsa.ExportParameters(true); publicRawData = new BinaryList().AddUInt8((byte)key.Exponent.Length) .AddUInt8Array(key.Exponent) .AddUInt16((ushort)key.Modulus.Length) .AddUInt8Array(key.Modulus).ToArray(); // sign it this.signature = domainCertificate.Sign(publicRawData); // store private info privateRawData = DC.Merge(key.D, key.DP, key.DQ, key.InverseQ, key.P, key.Q, signature); }