Skip to content

Commit

Permalink
feat: add basic issuers support
Browse files Browse the repository at this point in the history
  • Loading branch information
andronov-alexey authored and stormshield-gt committed Apr 19, 2024
1 parent 04f7bde commit 98ef115
Show file tree
Hide file tree
Showing 5 changed files with 650 additions and 4 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ and this project adheres to
### Added

- Generate intermediate CSR using existing issuer (see `cert::ca::int::cross_sign`)
- Generate intermediate CSR (see `issuer::int::generate`)
- Read issuer's certificate (see `issuer::read`)
- Sign intermediate (see `issuer::sign_intermediate`)
- Import issuer (see `issuer::import`)
- Set default issuer (see `issuer::set_default`)
- Delete issuer (see `issuer::delete`)
- Delete key (see `key::delete`)

## [0.7.0] - 2023-03-25

Expand Down
208 changes: 205 additions & 3 deletions src/api/pki/requests.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use super::responses::{
GenerateCertificateResponse, GenerateIntermediateResponse, GenerateRootResponse,
CrossSignResponse, GenerateCertificateResponse, GenerateIntermediateCSRResponse,
GenerateIntermediateResponse, GenerateRootResponse, ImportIssuerResponse,
ListCertificatesResponse, ListRolesResponse, ReadCRLConfigResponse, ReadCertificateResponse,
ReadRoleResponse, ReadURLsResponse, RevokeCertificateResponse, RotateCRLsResponse,
SignCertificateResponse, SignIntermediateResponse, SignSelfIssuedResponse,
ReadIssuerCertificateResponse, ReadRoleResponse, ReadURLsResponse, RevokeCertificateResponse,
RotateCRLsResponse, SetDefaultIssuerResponse, SignCertificateResponse,
SignIntermediateIssuerResponse, SignIntermediateResponse, SignSelfIssuedResponse,
};
use rustify_derive::Endpoint;
use serde::Serialize;

/// ## Submit CA Information
/// This endpoint allows submitting the CA information for the backend via a PEM
Expand Down Expand Up @@ -645,3 +648,202 @@ pub struct TidyRequest {
pub tidy_revoked_certs: Option<bool>,
pub safety_buffer: Option<String>,
}

/// ## Read issuer certificate
/// This endpoint retrieves the specified issuer's certificate and CA chain.
///
/// * Path: {self.mount}/issuer/{self.issuer}/json
/// * Method: GET
/// * Response: [ReadIssuerCertificateResponse]
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#read-issuer-certificate
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "{self.mount}/issuer/{self.issuer}/json",
response = "ReadIssuerCertificateResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ReadIssuerCertificateRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub issuer: String,
}

/// ## Sign Intermediate
/// This endpoint uses the configured CA certificate to issue a certificate with
/// appropriate values for acting as an intermediate CA.
///
/// * Path: {self.mount}/issuers/{self.issuer}/sign-intermediate
/// * Method: POST
/// * Response: [SignIntermediateIssuerResponse]
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#sign-intermediate
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "{self.mount}/issuer/{self.issuer}/sign-intermediate",
method = "POST",
response = "SignIntermediateIssuerResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct SignIntermediateIssuerRequest {
#[endpoint(skip)]
pub mount: String,
pub alt_names: Option<String>,
pub csr: String,
pub common_name: String,
pub country: Option<Vec<String>>,
pub exclude_cn_from_sans: Option<bool>,
pub format: Option<String>,
pub ip_sans: Option<String>,
pub issuer: String,
pub locality: Option<Vec<String>>,
pub max_path_length: Option<i32>,
pub not_after: Option<String>,
pub not_before_duration: Option<u64>,
pub organization: Option<Vec<String>>,
pub other_sans: Option<Vec<String>>,
pub ou: Option<Vec<String>>,
pub postal_code: Option<Vec<String>>,
pub province: Option<Vec<String>>,
pub permitted_dns_domains: Vec<String>,
pub serial_number: Option<String>,
pub signature_bits: Option<u16>,
pub skid: Option<String>,
pub street_address: Option<Vec<String>>,
pub ttl: Option<String>,
pub uri_sans: Option<String>,
pub use_pss: Option<bool>,
pub use_csr_values: Option<bool>,
}

/// ## Import issuer
/// This endpoint allows submitting the CA information for the backend via a PEM
/// file containing the CA certificate and its private key, concatenated.
///
/// * Path: {self.mount}/issuers/import/bundle
/// * Method: POST
/// * Response: [ImportIssuerResponse]
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#import-ca-certificates-and-keys
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "{self.mount}/issuers/import/bundle",
method = "POST",
response = "ImportIssuerResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ImportIssuerRequest {
#[endpoint(skip)]
pub mount: String,
pub pem_bundle: String,
}

/// ## Set default issuer
/// This endpoint allows setting the value of the default issuer.
///
/// * Path: {self.mount}/config/issuers
/// * Method: POST
/// * Response: "SetDefaultIssuerResponse"
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#set-issuers-configuration
#[derive(Builder, Debug, Default, Endpoint, Serialize)]
#[endpoint(
path = "{self.mount}/config/issuers",
method = "POST",
response = "SetDefaultIssuerResponse",
builder = "false"
)]
#[builder(setter(into, strip_option), default)]
pub struct SetDefaultIssuerRequest {
#[endpoint(skip)]
pub mount: String,
#[serde(rename = "default")]
pub default_issuer: String,
}

/// ## Delete issuer
/// This endpoint deletes the issuer.
///
/// * Path: {self.mount}/issuer/{self.issuer}
/// * Method: DELETE
/// * Response: N/A
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#delete-issuer
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "{self.mount}/issuer/{self.issuer}",
method = "DELETE",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct DeleteIssuerRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub issuer: String,
}

/// ## Generate intermediate CSR
/// This endpoint returns a new CSR for signing, optionally generating a new private key.
///
/// * Path: {self.mount}/issuers/generate/intermediate/{self.request_type}
/// * Method: POST
/// * Response: [GenerateIntermediateCSRResponse]
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#generate-intermediate-csr
#[derive(Builder, Debug, Default, Endpoint, Serialize)]
#[endpoint(
path = "{self.mount}/issuers/generate/intermediate/{self.request_type}",
method = "POST",
response = "GenerateIntermediateCSRResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct GenerateIntermediateCSRRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
#[serde(rename = "type")]
pub request_type: String,
pub add_basic_constraints: Option<bool>,
pub alt_names: Option<String>,
pub common_name: Option<String>,
pub country: Option<Vec<String>>,
pub exclude_cn_from_sans: Option<bool>,
pub format: Option<String>,
pub ip_sans: Option<String>,
pub key_bits: Option<u64>,
pub key_name: Option<String>,
pub key_ref: Option<String>,
pub key_type: Option<String>,
pub locality: Option<Vec<String>>,
pub organization: Option<Vec<String>>,
pub other_sans: Option<Vec<String>>,
pub ou: Option<Vec<String>>,
pub postal_code: Option<Vec<String>>,
pub private_key_format: Option<String>,
pub province: Option<Vec<String>>,
pub serial_number: Option<String>,
pub signature_bits: u16,
pub street_address: Option<Vec<String>>,
pub uri_sans: Option<String>,
}

/// ## Delete key
/// This endpoint deletes the key.
///
/// * Path: {self.mount}/key/{self.key}
/// * Method: DELETE
/// * Response: N/A
/// * Reference: https://developer.hashicorp.com/vault/api-docs/secret/pki#delete-key
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "{self.mount}/key/{self.key}",
method = "DELETE",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct DeleteKeyRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub key: String,
}
58 changes: 58 additions & 0 deletions src/api/pki/responses.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

/// Response from executing
Expand Down Expand Up @@ -104,26 +106,32 @@ pub struct ReadRoleResponse {
pub allow_localhost: bool,
pub allow_subdomains: bool,
pub allow_token_displayname: bool,
pub allow_wildcard_certificates: bool,
pub allowed_domains: Vec<String>,
pub allowed_domains_template: bool,
pub allowed_other_sans: Vec<String>,
pub allowed_serial_numbers: Vec<String>,
pub allowed_uri_sans: Vec<String>,
pub allowed_uri_sans_template: bool,
pub allowed_user_ids: Vec<String>,
pub basic_constraints_valid_for_non_ca: bool,
pub client_flag: bool,
pub cn_validations: Vec<String>,
pub code_signing_flag: bool,
pub country: Vec<String>,
pub email_protection_flag: bool,
pub enforce_hostnames: bool,
pub ext_key_usage: Vec<String>,
pub ext_key_usage_oids: Vec<String>,
pub generate_lease: bool,
pub issuer_ref: String,
pub key_bits: u64,
pub key_type: String,
pub key_usage: Vec<String>,
pub locality: Vec<String>,
pub max_ttl: u64,
pub no_store: bool,
pub not_after: String,
pub not_before_duration: u64,
pub organization: Vec<String>,
pub ou: Vec<String>,
Expand All @@ -132,10 +140,12 @@ pub struct ReadRoleResponse {
pub province: Vec<String>,
pub require_cn: bool,
pub server_flag: bool,
pub signature_bits: u16,
pub street_address: Vec<String>,
pub ttl: u64,
pub use_csr_common_name: bool,
pub use_csr_sans: bool,
pub use_pss: bool,
}

/// Response from executing
Expand Down Expand Up @@ -165,3 +175,51 @@ pub struct SignSelfIssuedResponse {
pub certificate: String,
pub issuing_ca: String,
}

/// Response from executing
/// [ReadIssuerCertificateRequest][crate::api::pki::requests::ReadIssuerCertificateRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct ReadIssuerCertificateResponse {
pub certificate: String,
pub ca_chain: Vec<String>,
pub issuer_id: String,
pub issuer_name: String,
}

/// Response from executing
/// [SignIntermediateIssuerRequest][crate::api::pki::requests::SignIntermediateIssuerRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct SignIntermediateIssuerResponse {
pub certificate: String,
pub ca_chain: Vec<String>,
pub issuing_ca: String,
pub serial_number: String,
pub expiration: u64,
}

/// Response from executing
/// [ImportIssuerRequest][crate::api::pki::requests::ImportIssuerRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct ImportIssuerResponse {
pub imported_issuers: Option<Vec<String>>,
pub imported_keys: Option<Vec<String>>,
pub existing_issuers: Option<Vec<String>>,
pub existing_keys: Option<Vec<String>>,
pub mapping: Option<HashMap<String, String>>,
}

/// Response from executing
/// [SetDefaultIssuerRequest][crate::api::pki::requests::SetDefaultIssuerRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct SetDefaultIssuerResponse {
pub default: String,
pub default_follows_latest_issuer: bool,
}

/// Response from executing
/// [GenerateIntermediateCSRRequest][crate::api::pki::requests::GenerateIntermediateCSRRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct GenerateIntermediateCSRResponse {
pub csr: String,
pub key_id: Option<String>,
}
Loading

0 comments on commit 98ef115

Please sign in to comment.