Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# v2.1.11

### Certificates

#### Fixes
* c6621a5 fix(certificates): CSR enrollments set `certificate_pem` on create.
* c6621a5 fix(certificates): Fix JSON refs in request model for `certificate/download`.

# v2.1.10

### Certificates
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/keyfactor-pub/terraform-provider-keyfactor
go 1.21

require (
github.com/Keyfactor/keyfactor-go-client/v2 v2.2.9-rc.4
github.com/Keyfactor/keyfactor-go-client/v2 v2.2.9
github.com/hashicorp/terraform-plugin-framework v0.10.0
github.com/hashicorp/terraform-plugin-go v0.18.0
github.com/hashicorp/terraform-plugin-log v0.9.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ github.com/Keyfactor/keyfactor-go-client v1.4.3 h1:CmGvWcuIbDRFM0PfYOQH6UdtAgplv
github.com/Keyfactor/keyfactor-go-client v1.4.3/go.mod h1:3ZymLNCaSazglcuYeNfm9nrzn22wcwLjIWURrnUygBo=
github.com/Keyfactor/keyfactor-go-client-sdk v1.0.1 h1:cs8hhvsY3MJ2o1K11HLTRCjRT8SbsKhhi73Y4By2CI0=
github.com/Keyfactor/keyfactor-go-client-sdk v1.0.1/go.mod h1:Z5pSk8YFGXHbKeQ1wTzVN8A4P/fZmtAwqu3NgBHbDOs=
github.com/Keyfactor/keyfactor-go-client/v2 v2.2.9-rc.4 h1:uwM2lUgXytOpH46AbSnR+szgnk1FlIZSLjoHdXs3CCk=
github.com/Keyfactor/keyfactor-go-client/v2 v2.2.9-rc.4/go.mod h1:fiv/ai955uffPu+ZVye5OfOR+fHoVS/sbfVwTWokNrc=
github.com/Keyfactor/keyfactor-go-client/v2 v2.2.9 h1:E35dVylP5HfULDYRcY7vjGZ7wPDYd7ThG7H3ll9MvXs=
github.com/Keyfactor/keyfactor-go-client/v2 v2.2.9/go.mod h1:fiv/ai955uffPu+ZVye5OfOR+fHoVS/sbfVwTWokNrc=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
Expand Down
108 changes: 77 additions & 31 deletions keyfactor/data_source_keyfactor_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import (
"encoding/base64"
"encoding/pem"
"fmt"
"strconv"

"github.com/Keyfactor/keyfactor-go-client/v2/api"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"strconv"
)

type dataSourceCertificateType struct{}
Expand Down Expand Up @@ -189,7 +190,10 @@ func (r dataSourceCertificateType) GetSchema(_ context.Context) (tfsdk.Schema, d
}, nil
}

func (r dataSourceCertificateType) NewDataSource(ctx context.Context, p tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
func (r dataSourceCertificateType) NewDataSource(ctx context.Context, p tfsdk.Provider) (
tfsdk.DataSource,
diag.Diagnostics,
) {
return dataSourceCertificate{
p: *(p.(*provider)),
}, nil
Expand All @@ -199,7 +203,11 @@ type dataSourceCertificate struct {
p provider
}

func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataSourceRequest, response *tfsdk.ReadDataSourceResponse) {
func (r dataSourceCertificate) Read(
ctx context.Context,
request tfsdk.ReadDataSourceRequest,
response *tfsdk.ReadDataSourceResponse,
) {
var state KeyfactorCertificate

tflog.Info(ctx, "Reading terraform data resource 'certificate'.")
Expand Down Expand Up @@ -283,9 +291,13 @@ func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataS
password = generatePassword(32, 4, 4, 4)
}
tflog.Info(ctx, "Requested certificate has a private key attempting to recover from Keyfactor Command.")
//pKeyO, _, chainO, dErrO := r.p.client.RecoverCertificate(cResp.Id, "", "", "", password)
pKeyO, _, chainO, dErrO := r.p.client.RecoverCertificate(cResp.Id, "", "", "", password, collectionIdInt)
if dErrO != nil {
tflog.Error(ctx, fmt.Sprintf("Unable to recover private key for certificate '%v' from Keyfactor Command.", cResp.Id))
tflog.Error(
ctx,
fmt.Sprintf("Unable to recover private key for certificate '%v' from Keyfactor Command.", cResp.Id),
)
response.Diagnostics.AddWarning(
ERR_SUMMARY_CERTIFICATE_RESOURCE_READ,
fmt.Sprintf("Could not retrieve certificate '%s' from Keyfactor Command: "+dErrO.Error(), cResp.Id),
Expand All @@ -300,22 +312,33 @@ func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataS
if lbErr != nil {
response.Diagnostics.AddError(
ERR_SUMMARY_CERTIFICATE_RESOURCE_READ,
fmt.Sprintf("Could not retrieve certificate '%s' from Keyfactor Command: "+lbErr.Error(), state.ID.Value),
fmt.Sprintf(
"Could not retrieve certificate '%s' from Keyfactor Command: "+lbErr.Error(),
state.ID.Value,
),
)
return
}
leaf = string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: lBytes,
}))
leaf = string(
pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: lBytes,
},
),
)
tflog.Debug(ctx, "Recovered leaf certificate from Keyfactor Command:")
tflog.Debug(ctx, leaf)
tflog.Debug(ctx, "Recovered certificate chain from Keyfactor Command:")
for _, cert := range chainO {
chainLink := string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
}))
chainLink := string(
pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
},
),
)
chain = chain + chainLink
tflog.Debug(ctx, chainLink)
}
Expand All @@ -327,10 +350,14 @@ func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataS
tflog.Debug(ctx, "Recovered RSA private key from Keyfactor Command:")
buf := x509.MarshalPKCS1PrivateKey(rsa)
if len(buf) > 0 {
pKey = string(pem.EncodeToMemory(&pem.Block{
Bytes: buf,
Type: "RSA PRIVATE KEY",
}))
pKey = string(
pem.EncodeToMemory(
&pem.Block{
Bytes: buf,
Type: "RSA PRIVATE KEY",
},
),
)
tflog.Trace(ctx, pKey)
} else {
tflog.Debug(ctx, "Empty Key Recovered from Keyfactor Command.")
Expand All @@ -344,10 +371,14 @@ func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataS
tflog.Debug(ctx, "Recovered ECC private key from Keyfactor Command:")
buf, _ := x509.MarshalECPrivateKey(ecc)
if len(buf) > 0 {
pKey = string(pem.EncodeToMemory(&pem.Block{
Bytes: buf,
Type: "EC PRIVATE KEY",
}))
pKey = string(
pem.EncodeToMemory(
&pem.Block{
Bytes: buf,
Type: "EC PRIVATE KEY",
},
),
)
tflog.Trace(ctx, pKey)
}
}
Expand All @@ -361,16 +392,23 @@ func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataS
tflog.Error(ctx, lbErr.Error())
response.Diagnostics.AddError(
ERR_SUMMARY_CERTIFICATE_RESOURCE_READ,
fmt.Sprintf("Could not retrieve certificate '%s' from Keyfactor Command: "+lbErr.Error(), state.ID.Value),
fmt.Sprintf(
"Could not retrieve certificate '%s' from Keyfactor Command: "+lbErr.Error(),
state.ID.Value,
),
)
return
}

tflog.Debug(ctx, "Decoding leaf cert.")
leaf = string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: lBytes,
}))
leaf = string(
pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: lBytes,
},
),
)
tflog.Debug(ctx, "Recovered leaf certificate from Keyfactor Command:")
tflog.Debug(ctx, leaf)

Expand All @@ -381,16 +419,24 @@ func (r dataSourceCertificate) Read(ctx context.Context, request tfsdk.ReadDataS
tflog.Error(ctx, "Error downloading certificate chain from Keyfactor Command.")
response.Diagnostics.AddWarning(
"Certificate Download Error",
fmt.Sprintf("Could not dowload certificate '%s' from Keyfactor. Chain will not be included: %s", state.ID.Value, dChainErr.Error()),
fmt.Sprintf(
"Could not dowload certificate '%s' from Keyfactor. Chain will not be included: %s",
state.ID.Value,
dChainErr.Error(),
),
)
}
if dChain != nil {
tflog.Debug(ctx, "Recovered certificate chain from Keyfactor Command:")
for _, cert := range dChain {
chainLink := string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
}))
chainLink := string(
pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
},
),
)

//check if chain is equal to leaf and if it is, skip it
if chainLink == leaf {
Expand Down
76 changes: 52 additions & 24 deletions keyfactor/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import (
"encoding/json"
"encoding/pem"
"fmt"
"github.com/Keyfactor/keyfactor-go-client/v2/api"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"log"
"math/rand"
"regexp"
"sort"
"strconv"
"strings"

"github.com/Keyfactor/keyfactor-go-client/v2/api"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var (
Expand Down Expand Up @@ -54,13 +55,22 @@ func generatePassword(passwordLength, minSpecialChar, minNum, minUpperCase int)
password.WriteString(string(allCharSet[random]))
}
inRune := []rune(password.String())
rand.Shuffle(len(inRune), func(i, j int) {
inRune[i], inRune[j] = inRune[j], inRune[i]
})
rand.Shuffle(
len(inRune), func(i, j int) {
inRune[i], inRune[j] = inRune[j], inRune[i]
},
)
return string(inRune)
}

func expandSubject(subject string) (types.String, types.String, types.String, types.String, types.String, types.String) {
func expandSubject(subject string) (
types.String,
types.String,
types.String,
types.String,
types.String,
types.String,
) {
var (
cn string
ou string
Expand Down Expand Up @@ -168,7 +178,12 @@ func flattenMetadata(metadata interface{}) types.Map {
return result
}

func flattenSANs(sans []api.SubjectAltNameElements, tfDNSSANs types.List, tfIPSANs types.List, tfURISANs types.List) (types.List, types.List, types.List) {
func flattenSANs(
sans []api.SubjectAltNameElements,
tfDNSSANs types.List,
tfIPSANs types.List,
tfURISANs types.List,
) (types.List, types.List, types.List) {
sanIP4Array := types.List{
ElemType: types.StringType,
Elems: []attr.Value{},
Expand Down Expand Up @@ -290,22 +305,26 @@ func flattenEnrollmentFields(efs []api.TemplateEnrollmentFields) types.List {
for _, ef := range efs {
var options []attr.Value
for _, op := range ef.Options {
options = append(options, types.String{
Value: op,
})
options = append(
options, types.String{
Value: op,
},
)
}
result.Elems = append(result.Elems, types.Map{
ElemType: types.StringType,
Elems: map[string]attr.Value{
"id": types.Int64{Value: int64(ef.Id)},
"name": types.String{Value: ef.Name},
"type": types.String{Value: strconv.Itoa(ef.DataType)},
"options": types.List{
Elems: options,
ElemType: types.StringType,
result.Elems = append(
result.Elems, types.Map{
ElemType: types.StringType,
Elems: map[string]attr.Value{
"id": types.Int64{Value: int64(ef.Id)},
"name": types.String{Value: ef.Name},
"type": types.String{Value: strconv.Itoa(ef.DataType)},
"options": types.List{
Elems: options,
ElemType: types.StringType,
},
},
},
})
)
}

return result
Expand Down Expand Up @@ -353,7 +372,12 @@ func isNullId(i int) bool {
return false
}

func downloadCertificate(id int, collectionId int, kfClient *api.Client, password string, csrEnrollment bool) (string, string, string, error) {
func downloadCertificate(id int, collectionId int, kfClient *api.Client, password string, csrEnrollment bool) (
string,
string,
string,
error,
) {
log.Printf("[DEBUG] enter downloadCertificate")
log.Printf("[INFO] Downloading certificate with ID: %d", id)

Expand All @@ -375,7 +399,10 @@ func downloadCertificate(id int, collectionId int, kfClient *api.Client, passwor
log.Printf("[INFO] Looking up certificate template with ID: %d", certificateContext.TemplateId)
template, err := kfClient.GetTemplate(certificateContext.TemplateId)
if err != nil {
log.Printf("[ERROR] Error looking up certificate template: %s returning integer value rater than common name", err)
log.Printf(
"[ERROR] Error looking up certificate template: %s returning integer value rater than common name",
err,
)
template = nil
}

Expand All @@ -391,6 +418,7 @@ func downloadCertificate(id int, collectionId int, kfClient *api.Client, passwor

if recoverable && !csrEnrollment {
log.Printf("[INFO] Recovering certificate with ID: %d", id)
//priv, leaf, chain, rErr := kfClient.RecoverCertificate(id, "", "", "", password)
priv, leaf, chain, rErr := kfClient.RecoverCertificate(id, "", "", "", password, collectionId)
if rErr != nil {
log.Printf("[ERROR] Error recovering certificate: %s", rErr)
Expand Down
Loading