Skip to content

Commit d9fe4de

Browse files
committed
[M]:added CSR support; added plugins for CSR generation
1 parent 24e1767 commit d9fe4de

File tree

2 files changed

+197
-0
lines changed

2 files changed

+197
-0
lines changed

dsm/data_source_csr.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// **********
2+
// Terraform Provider - DSM: data source: csr
3+
// **********
4+
// - Author: fyoo at fortanix dot com
5+
// - Version: 0.5.15
6+
// - Date: 26/05/2022
7+
// **********
8+
9+
package dsm
10+
11+
import (
12+
"context"
13+
"fmt"
14+
15+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
16+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
17+
)
18+
19+
func dataSourceCsr() *schema.Resource {
20+
return &schema.Resource{
21+
ReadContext: dataSourceCsrRead,
22+
Schema: map[string]*schema.Schema{
23+
"kid": {
24+
Type: schema.TypeString,
25+
Required: true,
26+
},
27+
"value": {
28+
Type: schema.TypeString,
29+
Computed: true,
30+
},
31+
"ou": {
32+
Type: schema.TypeString,
33+
Optional: true,
34+
Default: "",
35+
},
36+
"o": {
37+
Type: schema.TypeString,
38+
Optional: true,
39+
Default: "",
40+
},
41+
"l": {
42+
Type: schema.TypeString,
43+
Optional: true,
44+
Default: "",
45+
},
46+
"c": {
47+
Type: schema.TypeString,
48+
Optional: true,
49+
Default: "",
50+
},
51+
"cn": {
52+
Type: schema.TypeString,
53+
Required: true,
54+
},
55+
"id": {
56+
Type: schema.TypeString,
57+
Computed: true,
58+
},
59+
},
60+
}
61+
}
62+
63+
func dataSourceCsrRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
64+
var diags diag.Diagnostics
65+
66+
subject_dn := make(map[string]interface{})
67+
68+
if cn := d.Get("cn").(string); len(cn) > 0 {
69+
subject_dn["CN"] = cn
70+
}
71+
72+
if ou := d.Get("ou").(string); len(ou) > 0 {
73+
subject_dn["OU"] = ou
74+
}
75+
76+
if l := d.Get("l").(string); len(l) > 0 {
77+
subject_dn["L"] = l
78+
}
79+
80+
if c := d.Get("c").(string); len(c) > 0 {
81+
subject_dn["C"] = c
82+
}
83+
84+
if o := d.Get("o").(string); len(o) > 0 {
85+
subject_dn["O"] = o
86+
}
87+
88+
plugin_object := map[string]interface{}{
89+
"subject_key": d.Get("kid").(string),
90+
"subject_dn": subject_dn,
91+
}
92+
93+
reqfpi, err := m.(*api_client).FindPluginId("Terraform Plugin - CSR")
94+
if err != nil {
95+
diags = append(diags, diag.Diagnostic{
96+
Severity: diag.Error,
97+
Summary: "[DSM SDK] Unable to call DSM provider API client",
98+
Detail: fmt.Sprintf("[E]: API: GET sys/v1/plugins: %v", err),
99+
})
100+
return diags
101+
}
102+
var endpoint = fmt.Sprintf("sys/v1/plugins/%s", string(reqfpi))
103+
var operation = "POST"
104+
105+
req, err := m.(*api_client).APICallBody(operation, endpoint, plugin_object)
106+
if err != nil {
107+
diags = append(diags, diag.Diagnostic{
108+
Severity: diag.Error,
109+
Summary: "[DSM SDK] Unable to call DSM provider API client",
110+
Detail: fmt.Sprintf("[E]: API: POST sys/v1/plugins: %v", err),
111+
})
112+
return diags
113+
}
114+
115+
if err := d.Set("kid", req["kid"].(string)); err != nil {
116+
return diag.FromErr(err)
117+
}
118+
if err := d.Set("id", req["id"].(string)); err != nil {
119+
return diag.FromErr(err)
120+
}
121+
if err := d.Set("value", req["value"].(string)); err != nil {
122+
return diag.FromErr(err)
123+
}
124+
125+
d.SetId(d.Get("id").(string))
126+
return nil
127+
}

plugins/Terraform-Plugin-CSR.lua

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--
2+
--
3+
-- IMPORT: Name "Terraform Plugin - CSR"
4+
--
5+
--
6+
-- EXAMPLES:
7+
--
8+
-- ```
9+
-- {
10+
-- "subject_key": "my server key",
11+
-- "cert_lifetime": 86400,
12+
-- "subject_dn": { "CN": "localhost", "OU": "Testing" }
13+
-- }
14+
-- ```
15+
16+
function check(input)
17+
if type(input) ~= 'table' then
18+
return nil, 'invalid input'
19+
end
20+
if not input.subject_dn then
21+
return nil, 'must provide subject DN'
22+
end
23+
if not input.subject_key then
24+
return nil, 'must provide subject key'
25+
end
26+
end
27+
28+
function format_pem(b64, type)
29+
local wrap_at = 64
30+
local len = string.len(b64)
31+
local pem = ""
32+
33+
pem = pem .. "-----BEGIN " .. type .. "-----\n"
34+
35+
for i = 1, len, wrap_at do
36+
local stop = i + wrap_at - 1
37+
pem = pem .. string.sub(b64, i, stop) .. "\n"
38+
end
39+
40+
pem = pem .. "-----END " .. type .. "-----\n"
41+
42+
return pem
43+
end
44+
45+
function load_dn(dn)
46+
local name = X509Name.new()
47+
48+
for k,v in pairs(dn)
49+
do
50+
name:set(Oid.from_str(k), v, 'utf8')
51+
end
52+
53+
return name
54+
end
55+
56+
function run(input)
57+
local something_key = assert(Sobject { kid = input.subject_key })
58+
59+
local subject_dn = load_dn(input.subject_dn)
60+
-- log the DN here?
61+
62+
local csr = Pkcs10Csr.new(something_key.name, subject_dn)
63+
64+
local conv = Blob.from_bytes(csr:to_der())
65+
return {
66+
value = format_pem(conv:base64(), "CERTIFICATE REQUEST"),
67+
kid = something_key.kid,
68+
id = tostring(Time.now_insecure()[1])
69+
}
70+
end

0 commit comments

Comments
 (0)