/// <inheritdoc/> public async Task <CertificateRequestModel> AddAsync( CertificateRequestModel request, CancellationToken ct) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var recordId = await _index.AllocateAsync(); while (true) { request.Index = recordId; request.Record.State = CertificateRequestState.New; request.Record.RequestId = "req" + Guid.NewGuid(); try { var result = await _requests.AddAsync(request.ToDocument(), ct); return(result.Value.ToServiceModel()); } catch (ConflictingResourceException) { continue; } catch { await Try.Async(() => _index.FreeAsync(recordId)); throw; } } }
public IActionResult IssueCertificate([FromQuery] CertificateRequestModel request) { var certificateRequest = new CertificateRequest { CommonName = request.CommonName, Hostnames = request.Hostname.ToList(), IpAddresses = request.IpAddress.ToList(), Password = request.Password, ValidtyInDays = request.ValidityInDays }; var certificateWithKey = service.GenerateSslCertificate(certificateRequest); if (request.Format == CertificateFormat.Pfx) { var resultFilename = string.Concat(request.Filename.Trim('.'), ".pfx"); var pfx = converter.ConvertToPfx(certificateWithKey, request.Password); return(File(pfx, MediaTypeNames.Application.Octet, resultFilename)); } else { var resultFilename = string.Concat(request.Filename.Trim('.'), ".zip"); var pem = converter.ConvertToPemArchive(certificateWithKey, resultFilename); return(File(pem, MediaTypeNames.Application.Zip, resultFilename)); } }
/// <summary> /// Process signing request /// </summary> /// <param name="request"></param> /// <param name="ct"></param> /// <returns></returns> public async Task ProcessSigningRequestAsync(CertificateRequestModel request, CancellationToken ct = default) { var csr = request.SigningRequest.ToCertificationRequest(); var extensions = request.Entity.ToX509Extensions(); if (csr.Extensions != null) { extensions = extensions.Concat(csr.Extensions); } var subject = csr.Subject; if (!string.IsNullOrEmpty(request.Entity.SubjectName)) { subject = new X500DistinguishedName(request.Entity.SubjectName); } var now = DateTime.UtcNow.AddDays(-1); var notBefore = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0, DateTimeKind.Utc); // Call into issuer to issue new certificate for given public key var certKeyPair = await _issuer.CreateSignedCertificateAsync( request.Record.GroupId /* issuer cert */, request.Entity.Id /* issued cert name == entity id */, csr.PublicKey, subject, notBefore, sn => extensions, ct); await _workflow.CompleteRequestAsync(request.Record.RequestId, record => { record.Certificate = certKeyPair.ToServiceModel(); }, ct); }
/// <summary> /// Create request event /// </summary> /// <param name="type"></param> /// <param name="request"></param> /// <returns></returns> private static CertificateRequestEventModel Wrap(CertificateRequestEventType type, CertificateRequestModel request) { return(new CertificateRequestEventModel { EventType = type, Request = request }); }
/// <inheritdoc/> public async Task OnCertificateRequestApprovedAsync(CertificateRequestModel request) { try { if (request.Record.Type == CertificateRequestType.SigningRequest) { await ProcessSigningRequestAsync(request); } } catch (Exception ex) { await Try.Async(() => _workflow.FailRequestAsync(request.Record.RequestId, ex)); } }
/// <inheritdoc/> public async Task OnCertificateRequestApprovedAsync(CertificateRequestModel request) { try { if (request.Record.Type == CertificateRequestType.KeyPairRequest) { await CreateNewKeyPairAsync(request); } } catch (Exception ex) { await Try.Async(() => _workflow.FailRequestAsync(request.Record.RequestId, ex)); } }
/// <inheritdoc/> public async Task OnCertificateRequestSubmittedAsync(CertificateRequestModel request) { if (!_config.AutoApprove) { return; } await _management.ApproveRequestAsync(request.Record.RequestId, request.Record.Submitted); _logger.Information("Request {@request} for {@entity} was auto-approved.", request.Record, request.Entity); }
/// <summary> /// Create new key pair /// </summary> /// <param name="request"></param> /// <param name="ct"></param> /// <returns></returns> private async Task CreateNewKeyPairAsync(CertificateRequestModel request, CancellationToken ct = default) { var now = DateTime.UtcNow.AddDays(-1); var notBefore = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0, DateTimeKind.Utc); // Call into issuer service to issue new certificate and private key var certKeyPair = await _issuer.CreateCertificateAndPrivateKeyAsync( request.Record.GroupId /* issuer cert */, request.Entity.Id /* issued cert name == entity id */, new X500DistinguishedName(request.Entity.SubjectName), notBefore, new CreateKeyParams { Type = KeyType.RSA, // TODO - should come from request KeySize = 2048 // TODO - should come from request }, sn => request.Entity.ToX509Extensions(), ct); await _workflow.CompleteRequestAsync(request.Record.RequestId, record => { record.KeyHandle = _serializer.SerializeHandle(certKeyPair.KeyHandle); record.Certificate = certKeyPair.ToServiceModel(); }, ct); }
/// <inheritdoc/> public Task OnCertificateRequestDeletedAsync(CertificateRequestModel request) { return(Task.CompletedTask); }
/// <inheritdoc/> public Task OnCertificateRequestDeletedAsync(CertificateRequestModel request) { return(_bus.PublishAsync(Wrap(CertificateRequestEventType.Deleted, request))); }