Giter VIP home page Giter VIP logo

digicert's Introduction

Digicert

Build Status Code Climate Gem Version

The Ruby client for the official Digicert API.

Installation

Add this line to your application's Gemfile:

gem "digicert"

And then execute:

bundle install

Or install it yourself as:

gem install digicert

Configure

Once you have your API key then you can configure it by adding an initializer with the following code

Digicert.configure do |config|
  config.api_key = "SECRET_DEV_API_KEY"

  # Default response type is `object`, but you can configure it if
  # necessary, and all the further response will be return as config
  # supported options are `object` and `hash`.
  #
  # config.response_type = :object
end

Or

Digicert.configuration.api_key = "SECRET_DEV_API_KEY"

Usage

Container

Container is an Operational Division used to model your organizational structure. The features of the container you create are determined by its Container Template.

List Containers

Use this interface to retrieve a list of existing containers.

Note: This is an undocumented endpoint of the DigiCert Services API.

Digicert::Container.all

Create a Container

Use this interface to create new container, and this interface also expects us to provide parent_container along with the others attributes as container_id.

Digicert::Container.create(
  container_id: 123_456_789,
  template_id: 5,
  name: "History Department",
  description: "History, Civ, Ancient Languages",

  user: {
    first_name: "Awesome",
    last_name: "User",
    email: "[email protected]",
    username: "[email protected]",
    access_roles: [{ id: 1 }],
  },
)

View a Container

Information about a specific container can be retrieved through this interface, including its name, description, template, and parent container id.

Digicert::Container.fetch(container_id)

Container Template

Container Templates define a set of features that are available to a container.

List Container Templates

Use this interface to retrieve a list of the templates that are available to use to create child containers.

Digicert::ContainerTemplate.all(container_id)

View a Container Template

Use this interface to retrieve information about a specific container template, including which user access roles are available under this template.

Digicert::ContainerTemplate.fetch(
  template_id: template_id, container_id: container_id,
)

Organization

Create an Organization

Use this interface to create a new organization. The organization information will be used by DigiCert for validation and may appear on certificates.

# Create a new organization
# Please pay close attension bellow
# on building the organization_attributes
#
Digicert::Organization.create(organization_attributes)

# Organization attributes hash
#
organization_attributes = {
  name: "digicert, inc.",
  address: "333 s 520 w",
  zip: 84042,
  city: "lindon",
  state: "utah",
  country: "us",
  telephone: 8015551212,
  container: { id: 17 },

  organization_contact: {
    first_name: "Some",
    last_name: "Guy",
    email: "[email protected]",
    telephone: 8015551212,
  },

  # Optional attributes
  assumed_name: "DigiCert",
  address2: "Suite 500",
}

View an Organization

Use this interface to view information about an organization.

Digicert::Organization.fetch(organization_id)

List all organizations

Use this interface to retrieve a list of organizations.

Digicert::Organization.all

Domain

Create a new Domain

Use this interface to add a domain for an organization in a container. You must specify at least one validation type for the domain.

# Create a new domain in an organization
# Please pay close attension in building the attibutes hash
#
Digicert::Domain.create(domain_attributes)

# Domain attributes hash
#
domain_attributes = {
  name: "digicert.com",
  organization: { id: 117483 },
  validations: [
    {
      type: "ev",
      user: { id: 12 }
    },
  ],

  dcv: { method: "email" },
}

Activate a Domain

Use this interface to activate a domain that was previously deactivated.

domain = Digicert::Domain.find(domain_id)
domain.activate

Deactivate a Domain

Use this interface to deactivate a domain.

domain = Digicert::Domain.find(domain_id)
domain.deactivate

View a Domain

Use this interface to view a domain, This interface also allows you to pass an additional hash to specify if you want to retrieve additional data with the response.

Digicert::Domain.fetch(domain_id, include_dcv: true)

List Domains

Use this interface to retrieve a list of domains. This interface also supports an additional filter_params hash, which can be used to filter the list we want the interface to return.

Digicert::Domain.all(filter_params_hash)

Submitting Orders

Important Note

Recently DigiCert improved the certificate issuance process to allow for immediate certificate issuance. It does not require us to change anything on our API calls but now the response will be different based on your DigiCert account settings.

If you have everything setup in place and any order is eligible for immediate issuance then the certificate will be included with the response. Please check the certificate download spec for inspiration.

View Product List

Use this interface to retrieve a list of available products for an account.

Digicert::Product.all

View Product Details

Use this interface to retrieve a full set of details for a product.

Digicert::Product.fetch(name_id)

Generate the CSR content

This interface will allow us to generate the CSR content on the fly, it will return the content that we can use for order creation.

Digicert::CSRGenerator.generate(
  common_name: "example.com",
  san_names: ["example.com", "www.example.com"],
  rsa_key: File.read("your_rsa_key_file_path"),
  organization: Digicert::Organization.all.first,
)

Create any type of order

Use this interface to create a new order, this expect two arguments one is name_id for the order and another one is the attributes hash.

order = Digicert::Order.create(
  name_id, order_attributes_hash,
)

# Pay close attension building the order attributes
# hash, it requries to format the data in a specific
# format and once that is satisfied only then it will
# perfrom the API operation otherwise it will raise
# invalid argument errors.
#
order_attributes = {
  certificate: {
    common_name: "digicert.com",
    csr: "------ [CSR HERE] ------",
    signature_hash: "sha256",

    organization_units: ["Developer Operations"],
    server_platform: { id: 45 },
    profile_option: "some_ssl_profile",
  },

  organization: { id: 117483 },
  validity_years: 3,
  custom_expiration_date: "2017-05-18",
  comments: "Comments for the the approver",
  disable_renewal_notifications: false,
  renewal_of_order_id: 314152,
  payment_method: "balance",
}

The supported value for name_id are ssl_plus, ssl_wildcard, ssl_ev_plus, client_premium, email_security_plus and digital_signature_plus. Please check the Digicert documentation for more details on those.

If you want to create a new order by yourself by following each of the specific class then please check out the interfaces specified bellow.

Order SSL Plus Certificate

Use this interface to order a SSL Plus Certificate.

Digicert::SSLCertificate::SSLPlus.create(
  certificate: {
    common_name: "digicert.com",
    csr: "------ [CSR HERE] ------",
    signature_hash: "sha256",

    organization_units: ["Developer Operations"],
    server_platform: { id: 45 },
    profile_option: "some_ssl_profile",
  },

  organization: { id: 117483 },
  validity_years: 3,
  custom_expiration_date: "2017-05-18",
  comments: "Comments for the the approver",
  disable_renewal_notifications: false,
  renewal_of_order_id: 314152,
  payment_method: "balance",
)

Order SSL Wildcard Certificate

Use this interface to order a SSL Wildcard Certificate.

Digicert::SSLCertificate::SSLWildcard.create(
  certificate: {
    common_name: "digicert.com",
    csr: "------ [CSR HERE] ------",
    signature_hash: "sha256",

    organization_units: ["Developer Operations"],
    server_platform: { id: 45 },
    profile_option: "some_ssl_profile",
  },

  organization: { id: 117483 },
  validity_years: 3,
  custom_expiration_date: "2017-05-18",
  comments: "Comments for the the approver",
  disable_renewal_notifications: false,
  renewal_of_order_id: 314152,
)

Order SSL EV Plus Certificate

Use this interface to order a SSL EV Plus Certificate.

Digicert::SSLCertificate::SSLEVPlus.create(
  certificate: {
    common_name: "digicert.com",
    csr: "------ [CSR HERE] ------",
    signature_hash: "sha256",

    organization_units: ["Developer Operations"],
    server_platform: { id: 45 },
    profile_option: "some_ssl_profile",
  },

  organization: { id: 117483 },
  validity_years: 3,
  custom_expiration_date: "2017-05-18",
  comments: "Comments for the the approver",
  disable_renewal_notifications: false,
  renewal_of_order_id: 314152,
)

Order Client Premium Certificate

Use this interface to order a Client Premium Certificate.

Digicert::ClientCertificate::Premium.create(
  certificate: {
    common_name: "Full Name",
    emails: ["[email protected]", "[email protected]"],
    csr: "------ [CSR HERE] ------",
    signature_hash: "sha256",

    organization_units: ["Developer Operations"],
    server_platform: { id: 45 },
    profile_option: "some_ssl_profile",
  },

  organization: { id: 117483 },
  validity_years: 3,
  custom_expiration_date: "2017-05-18",
  comments: "Comments for the the approver",
  disable_renewal_notifications: false,
  renewal_of_order_id: 314152,
)

Order Private Client Premium Certificate

Use this interface to order a Private Client Premium Certificate.

Digicert::ClientCertificate::PrivatePremium.create(
  certificate: {
    organization_units: ["Developer Operations"],

    csr: "------ [CSR HERE] ------",
    emails: ["[email protected]"],
    common_name: "Common Name",
    signature_hash: "sha256",
  },
  organization: { id: "12345" },
  validity_years: 3,
  auto_renew: nil,
  container: { id: "654321" },
  payment_method: "balance",
)

Order Email Security Plus

Use this interface to order a Email Security Plus Certificate

Digicert::ClientCertificate::EmailSecurityPlus.create(
  certificate: {
    common_name: "Full Name",
    emails: ["[email protected]", "[email protected]"],
    signature_hash: "sha256",

    organization_units: ["Developer Operations"],
    server_platform: { id: 45 },
    profile_option: "some_ssl_profile",
  },

  organization: { id: 117483 },
  validity_years: 3,
  auto_renew: 10,
  renewal_of_order_id: 314152,
)

Order Client Digital Signature Plus

Use this interface to order a Client Digital Signature Plus

Digicert::Order::DigitalSignaturePlus.create(
  certificate: {
    common_name: "Full Name",
    emails: ["[email protected]", "[email protected]"],
    csr: "-----BEGIN CERTIFICATE REQUEST----- ...",
    signature_hash: "sha256",
  },

  organization: { id: 117483 },
  validity_years: 3,
  auto_renew: 10,
  renewal_of_order_id: 314152,
)

Request Management

List certificate requests

Use this interface to retrieve a list of certificate requests.

Digicert::CertificateRequest.all

Certificate Request details

Use this interface to retrieve the details for a certificate request.

Digicert::CertificateRequest.fetch(request_id)

Update Request Status

Use this interface to update the status of a previously submitted certificate request.

Digicert::CertificateRequest.update(
  request_id, status: "approved", processor_comment: "Your domain is approved",
)

Order Management

View a Certificate Order

Use this interface to retrieve a certificate order and the response includes all the order attributes along with a certificate in it.

Digicert::Order.fetch(order_id)

List Certificate Orders

Use this interface to retrieve a list of all certificate orders.

Digicert::Order.all

This interface also supports query params like limit, offset, sort and filters. We can use those to retrieve more precised orders.

Digicert::Order.all(
  limit: 20,
  offset: 0,
  sort: 'date_created',

  filters: {
    status: "approved",
    common_name: "ribosetest.com"
  }
)

There is also another interface .filter, which is basically an alias around the .all interface but it passes each of the argument as a filters attributes

Digicert::Order.filter(status: "approved", common_name: "ribosetest.com")

# Similar functionality with all interface
#
Digicert::Order.all(
  filters: { status: "approved", common_name: "ribosetest.com" }
)

List of Email Validations

Use this interface to view the status of all emails that require validation on a client certificate order.

Digicert::EmailValidation.all(order_id: order_id)

# If you prefer then there is an alternative alias method
# on the order class, you can invoke that on any of its
# instances. Usages
#
order = Digicert::Order.find(order_id)
order.email_validations

Validate an Email Address

Use this interface to verify control of an email address, using an email address/token pair.

Digicert::EmailValidation.valid?(token: token, email: email)
# => true or false

Reissue a Certificate Order

Use this interface to reissue a certificate order. A reissue replaces the existing certificate with a new one that has different information such as common name, CSR, etc. The simplest interface to reissue an update an existing order is

order = Digicert::Order.find(order_id)
order.reissue

# Alternative and prefereed in most case
Digicert::OrderReissuer.create(order_id: order_id)

And if there are some updated information like csr, common_name or etc then you can use the same interface but pass the :certificate option. Please remember if any required fields are missing then it will use the data that already exists for that order.

Digicert::OrderReissuer.create(
  order: order_id,
  common_name: certificate_common_name,
  dns_names: [certificate_dns_name],
  csr: certificate_csr,
  signature_hash: certificate_signature_hash,
  server_platform: { id: certificate_server_platform_id },
)

Duplicate a Certificate Order

Use this interface to request a duplicate certificate for an order. A duplicate shares the expiration date as the existing certificate and is identical with the exception of the CSR and a possible change in the server platform and signature hash. The common name and sans need to be the same as the original order.

Digicert::OrderDuplicator.create(
  order: order_id,
  common_name: certificate_common_name,
  dns_names: [certificate_dns_name],
  csr: certificate_csr,
  signature_hash: certificate_signature_hash,
  server_platform: { id: certificate_server_platform_id },
)

Find a Duplicate Certificate

As of now, the Digicert API, does not have an easier way to find a duplicate certificate, as the certificate duplication returns existing order_id with a request node which only has an id.

So to find out a duplicate certificate, we need to retrieve the details for that specific request and from that response retrieve the date_created for the duplicate certificate and then use that date_created to find out the correct certificate from the duplications of that specific order.

This requires lots of work, so this following interface will do all of its underlying tasks, and all we need to do is pass the requests id that we will have form the certificate duplication.

# Duplicate an existing certificate order
#
order = Digicert::Order.find(order_id)
duplicate_order = order.duplicate

# Use the request id to find out the certificate
#
request_id = duplicate_order.requests.first.id
Digicert::DuplicateCertificateFinder.find_by(request_id: request_id)

List Duplicate Certificates

Use this interface to view all duplicate certificates for an order.

Digicert::DuplicateCertificate.all(order_id: order_id)

# Alternative interface for duplicate certificates
order = Digicert::Order.find(order_id)
order.duplicate_certificates

Cancel a Certificate Order

Use this interface to update the status of an order. Currently this endpoint only allows updating the status to 'CANCELED'

order = Digicert::Order.find(order_id)
order.cancel(note: "Cancellation note")

# Or use the actual interface for more control
Digicert::OrderCancellation.create(
  order_id: order_id, status: "CANCELED", note: "your_note", send_emails: true,
)

Reports

Expiring Orders

Use this interface to retrieve the number of orders that have certificates expiring within 90, 60, and 30 days. The number of orders that have already expired certificates within the last 7 days is also returned.

Digicert::ExpiringOrder.all(container_id: container_id)

Certificate Management

Download a Certificate

This request will return an SSL Certificate file from an order. By default, it uses the platform specified by the order.

# Fetch the certficate details that includes a http status code
# and the file content in the `#body`, so you can choose if you
# want to write it to your filesystem or directly upload it to
# your host, and the contents it returns is `zip` archieve.
#
certificate = Digicert::CertificateDownloader.fetch(certificate_id, **attributes)

# write to content to somewhere in your filesystem.
#
File.write("path_to_file_system/certificate.zip", certificate.body)

# Alaternative to fetch it through certificate instance
#
certificate = Digicert::Certificate.find(certificate_id)
certificate_content_object = certificate.download

Additionally, if you want the gem to handle the file writing then it also provides another helper interface fetch_to_path, and that will fetch the file content and write the content to supplied path.

Digicert::CertificateDownloader.fetch_to_path(
  certificate_id,
  ext: "zip",
  path: File.expand_path("./file/download/path"),
  **other_attributes_hash_like_platform_or_format,
)

# Alternative through a certificate instance
#
certificate = Digicert::Certificate.find(certificate_id)
certificate.download_to_path(path: "file/path", ext: "zip", format: "zip")

Download a Certificate By Format

This interface will return an SSL Certificate file from an order. The certificate will be return in the format you specify, but one thing to remember the certificate will be archived as zip along with the instructions, so you need to write that as zip archive.

Digicert::CertificateDownloader.fetch_by_format(
  certificate_id, format: format,
)

# Alternative using the certificate instance
#
certificate = Digicert::Certificate.find(certificate_id)
certificate_content_object = certificate.download(format: format)

Download a Certificate By Platform

This interface will return an SSL Certificate file from an order using the platform specified.

certificate = Digicert::CertificateDownloader.fetch_by_platform(
  certificate_id, platform: "apache",
)

# Alternative using the certificate instance
#
certificate = Digicert::Certificate.find(certificate_id)
certificate_content_object = certificate.download(platform: "apache")

Download a Certificate content

This interface will fetch a SSL Certificate and extract all of its subsidiary certificates content and return as a hash with certificate, root_certificate and intermediate_certificate keys.

Digicert::CertificateDownloader.fetch_content(certificate_id)

# Alternative using certificate instance
#
certificate = Digicert::Certificate.find(certificate_id)
certificate.download_content

Revoke a Certificate

This interface will revoke a previously issued SSL Certificate.

Digicert::Certificate.revoke(certificate_id, comments: "Your comment")

Development

We are following Sandi Metz's Rules for this gem, you can read the description of the rules here All new code should follow these rules. If you make changes in a pre-existing file that violates these rules you should fix the violations as part of your contribution.

Setup

Clone the repository.

git clone https://github.com/riboseinc/digicert

Setup your environment.

bin/setup

Run the test suite

bin/rspec

Play Box

The API Play Box provides an interactive console so we can easily test out the actual API interaction. But before moving forward let's configure the your key.

Setup the client configuration.

cp .sample.pryrc .pryrc
vim .pryrc

Start the console.

bin/console

Start playing with it.

Digicert::Product.all

Contributing

First, thank you for contributing! We love pull requests from everyone. By participating in this project, you hereby grant Ribose Inc. the right to grant or transfer an unlimited number of non exclusive licenses or sub-licenses to third parties, under the copyright covering the contribution to use the contribution by all means.

Here are a few technical guidelines to follow:

  1. Open an issue to discuss a new feature.
  2. Write tests to support your new feature.
  3. Make sure the entire test suite passes locally and on CI.
  4. Open a Pull Request.
  5. Squash your commits after receiving feedback.
  6. Party!

Credits

This gem is developed, maintained and funded by Ribose Inc.

digicert's People

Contributors

abunashir avatar davidcpell avatar dbollaer avatar francescm avatar kwkwan avatar ronaldtse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

digicert's Issues

Did we update the `order` response recently?

Hi @ronaldtse, I was testing out the order duplication and reissuing funcitonality recently, but looks lik there might be some changes in the order response. For example, the order response does not include the certificate.server_platform related details anymore, could you please erify those changes so I can update the client?

Expected one:

screenshot 2018-07-22 15 22 26

Current response

screenshot 2018-07-22 15 19 00

cc: @clintwilson

Current issues with Digicert Service v2 API

This is a placeholder for existing issues we have with the Digicert Services API. @abunashir could you fill in the details? Thanks!

  • Reissue order - unable to correlate with the new certificate via request ID
  • View request response has a cached certificate object that is stale (shows "needs_approval" even when the certificate is "issued")
  • Create duplicate certificate - unable to correlate which is the newest certificate given the order
  • Certificate download - we'd like to directly access the content instead of having to "download a file"
  • Renew order - we can't correlate which is the new order because the old order doesn't link to the new one.

Class methods should return objects with expected classes

Hi @abunashir ,

When I was testing out the code I noticed that some responses do not return properly 'classed' objects.

For example,

Digicert::Product.all.first.class
=> Digicert::ResponseObject

But the expectation of someone running this should be Digicert::Product.

Could you help go through the code and see which calls are returning the generic ResponseObject and give them the proper classes?

Thanks!

Digicert::DuplicateCertificateFinder.find_by doesn't work as expected

Digicert::DuplicateCertificateFinder.find_by(request_id: request_id)

Is supposed to return the certificate object. The API request and responses are correct, however nil is returned instead.

[URI] GET https://www.digicert.com/services/v2/order/certificate/123/duplicate
[Headers] {"content-type"=>["application/json"], "x-dc-devkey"=>["XXX"], "host"=>["www.digicert.com"]}
[Response] #<Net::HTTPOK 200 OK readbody=true>
[Response Body] {"certificates":[{"id":}, {...}]}

# => `nil`

Streamline order duplication flow

Hi @abunashir ,

Here's the flow that we wish to utilize in our certificate generation code. Could you have a look and see what gaps we still need to fill? Thanks.

order = Digicert::Order.filter(
  common_name: "*.example.com",
  product_type: Digicert::Product::WildcardSsl
)

%(name1 name2).each do |name|

  key = load_key(keypath[name])
  csr = Digicert::Csr.new(
    order: order, # obtain attributes from order that aren't provided here
    key: key # only change the key in this CSR
  )

  duplicate_request = order.duplicate(csr: csr)

  downloaded_certs = duplicate_request.download_certificate(format: "zip")

  root_cert = downloaded_certs[:root]
  intermediate_cert = downloaded_certs[:intermediate]
  cert = downloaded_certs[:cert]
end

Method to set API KEY in config is confusing

Now we have to run this to set the ~/.digicertrc file:

digicert config [API_KEY]

Help shows this:

$ bin/digicert config 
ERROR: "digicert config" was called with no arguments
Usage: "digicert config API_KEY"

It would be better to call:

digicert configure-api-key MYAPIKEY

or

digicert config api-key MYAPIKEY

digicert config should show help like this:

$ bin/digicert config 
ERROR: "digicert config" was called with no arguments
Usage: "digicert config api-key [YOURAPIKEY]"

Report API issues to Digicert

Here the issues we encountered:

  • Certificate generation process does not directly link the reissue request to the resulting certificate. Workaround: we use certificate issue time to correlate the issuance
  • Request endpoint often contains stale cached certificate objects (i.e. an embedded certificate object that has status “needs_approval” but the request is “issued”)

@abunashir could you help add additional issues that I missed? Thanks!

When there are no duplicate certificates, don't error out

When there are no duplicate certificates, the following calls will error out.

order.duplicate_certificates
# or
Digicert::DuplicateCertificateFinder.find_by(request_id: request_id)

Will lead to this error:

===============[API Reqeust Begin]================
[URI] GET https://www.digicert.com/services/v2/order/certificate/order_id/duplicate
[Headers] {"content-type"=>["application/json"], "x-dc-devkey"=>["xxxxxxxxx"], "host"=>["www.digicert.com"]}
[Response] #<Net::HTTPOK 200 OK readbody=true>
[Response Body] {}
================[API Reqeust End]=================
NoMethodError: private method `select' called for nil:NilClass
from /Users/user/src/digicert/lib/digicert/duplicate_certificate_finder.rb:24:in `certificates_by_date_created'

It would be more appropriate to return an empty array.

Allow output option `--output json`

--output json will provide JSON output that can be parsed by jq.

For example, a table like this
screenshot 2017-06-13 14 34 56

Could produce a jq parseable output of:

{
  "order":  {
    "id": 1002019,
    "common-name": "*.ribosetest.com",
    "san-names": [
      "*.ribosetest.com",
      "ribosetest.com"
    ],
    "status": "approved",
    "valid-from": "2017-06-13T00:00:00Z",
    "valid-utill": "2017-06-15T00:00:00Z"
  }
}

Rubocop errors

@abunashir we're having the following errors. Are these due to the recent updates?

Could we fix them? Thanks!

.rubocop.yml: Style/AccessorMethodName has the wrong namespace - should be Na...
.rubocop.yml: Style/AccessorMethodName has the wrong namespace - should be Naming
.rubocop.yml: Style/AsciiIdentifiers has the wrong namespace - should be Naming
.rubocop.yml: Style/DotPosition has the wrong namespace - should be Layout
.rubocop.yml: Style/ExtraSpacing has the wrong namespace - should be Layout
.rubocop.yml: Style/FileName has the wrong namespace - should be Naming
.rubocop.yml: Style/MultilineOperationIndentation has the wrong namespace - should be Layout
.rubocop.yml: Style/MultilineMethodCallIndentation has the wrong namespace - should be Layout
.rubocop.yml: Style/PredicateName has the wrong namespace - should be Naming
.rubocop.yml: Style/InitialIndentation has the wrong namespace - should be Layout
Error: The `Lint/InvalidCharacterLiteral` cop has been removed since it was never being actually triggered.
(obsolete configuration found in .rubocop.yml, please update it)
The `Style/DeprecatedHashMethods` cop has been renamed to `Style/PreferredHashMethods`.
The `Style/OpMethod` cop has been renamed and moved to `Naming/BinaryOperatorParameterName`.

OrderDuplicator fails on default request due to API issue

# This order has product_name_id: "ssl_ev_plus"
order = Digicert::Order.find(order_id)
order.dns_names # => ["www.myhost.com", "myhost.com"] # <=== this is the problem
duplicate_request = order.duplicate

This fails with error:

Digicert::Errors::RequestError: A request to Digicert API failed:
[{"code":"invalid_dns_name_on_duplicate","message":"Invalid DNS name on duplicate request. The DNS names must match what was on the original order."}]

But if we only use the first hostname in dns_names, it works:

duplicate_request = order.duplicate(
  dns_names: ["www.myhost.com"]
)

I believe the problem is an EV SSL certificate should not have two dns_names when returned:

order.dns_names # => ["www.myhost.com", "myhost.com"] # <=== this is the problem

@ronaldtse @abunashir can you confirm this is a Digicert API issue?

Update to use latest 'Immediate Issuance' API response type

As notified by Clint there is a new response type called "Immediate Issuance" for the "Request Certificate" endpoint.

Documentation here:

Clint:

If requests.status is “approved”, there should be two additional properties: certificate_id and certificate_chain. If there is an issue with the CA returning the certificate, it’s possible only the certificate_id will be returned. However, this also obsoletes the need to use the requests.id or id properties as you can now call the download endpoint directly using this certificate_id.

The additional response properties applies for SSL certs, including new orders, renewals, reissues, and duplicates.

Looks like it's time for a new version!

Getting Digicert::Errors::ServerError when calling Digicert::Order.all

I am calling Digicert::Order.all(sort: :expires_at) and getting the following error:

Digicert::Errors::ServerError: [{"code"=>"internal_error", "message"=>"An internal error has occurred processing your request."}]

If I hit the Digicert API endpoint directly at https://www.digicert.com/services/v2/documentation/order/order-list, then there are no errors.

Looks like this gem is encountering some unexpected results from the Digicert API endpoint.

Order filtering by attributes

@abunashir , we actually just ran into this issue today with one of our certificates expired.

In Digicert, a renewed order will have a different order ID from the original one. This means that we shouldn't hard code an order ID in generation.

It is useful in this case to allow fetching / filtering orders by:

  • common name
  • expiry date
  • product type

Given this function we can perform the following without :

order = Digicert::Order.filter(
  common_name: "*.example.com", 
  product_type: Digicert::Product::WildcardSsl
).first
duplicate_request = order.duplicate

Return textual certificate content after certificate download

Hi @abunashir ,

We want to directly access the textual content from a certificate after download.

Here's an example:

duplicate_request = order.duplicate(csr: csr)

# this method
downloaded_certs = duplicate_request.download_certificate(format: :text)
root_cert = downloaded_certs[:root]
intermediate_cert = downloaded_certs[:intermediate]
cert = downloaded_certs[:cert]

Could we implement this method to make it easier to utilize the downloaded content? Thanks!

Issues with finding a reissued order

We are working on a CLI, where we are automating the order reissuing process and download the reissued certificate and then provision it to our host, but the problem we have had is with finding out the correct reissued certificate.

In the reissuing process, if we try to retrieve the status for the newly created request then it returns approved or another status, which does not clearly identify if that certificate has been issued.

And the order node in the request provides the details for that request, but the status always states needs_approval although the request has already been approved or issued.

Currently, we did some comparison of the last_reissued_date and dates to find out the reissued order but an easier interface would help.

screenshot 2017-05-20 17 25 47

Reference: #117

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.