Skip to content

Commit fd2a784

Browse files
Add new parameters according to updated Sectigo API specification
1 parent bf5f9d9 commit fd2a784

9 files changed

Lines changed: 155 additions & 19 deletions

File tree

include/certifier/property.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ typedef enum CERTIFIER_OPT
215215
CERTIFIER_OPT_SECTIGO_SUBJECT_ALT_NAMES,
216216
CERTIFIER_OPT_SECTIGO_OWNER_EMAIL,
217217
CERTIFIER_OPT_SECTIGO_URL,
218+
CERTIFIER_OPT_SECTIGO_DEVHUB_ID,
219+
CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS,
220+
CERTIFIER_OPT_SECTIGO_KEY_TYPE,
218221

219222
} CERTIFIER_OPT;
220223

internal_headers/certifier/property_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ const char * get_default_ca_path();
9494

9595
const char * get_default_ca_info();
9696

97+
/**
98+
* Validate if a key type string is a supported Sectigo key type.
99+
* @param key_type The key type string to validate
100+
* @return 1 if valid, 0 otherwise
101+
*/
102+
int is_valid_sectigo_key_type(const char * key_type);
103+
97104
#ifdef __cplusplus
98105
}
99106
#endif

internal_headers/certifier/sectigo_client.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,21 @@ extern "C" {
3838

3939
#define IMPULSE_URL "https://certs-dev.xpki.io/"
4040
typedef struct{
41-
const char * auth_token;
42-
const char * common_name;
43-
const char * group_name;
44-
const char * group_email;
45-
const char * id;
46-
const char * owner_first_name;
47-
const char * owner_last_name;
48-
const char * project_name;
49-
const char * business_justification;
50-
const char * subject_alt_names;
51-
const char * owner_email;
52-
const char * sectigo_url;
53-
54-
41+
const char * auth_token;
42+
const char * common_name;
43+
const char * group_name;
44+
const char * group_email;
45+
const char * id;
46+
const char * owner_first_name;
47+
const char * owner_last_name;
48+
const char * project_name;
49+
const char * business_justification;
50+
const char * subject_alt_names;
51+
const char * owner_email;
52+
const char * sectigo_url;
53+
const char * devhub_id;
54+
size_t validity_days;
55+
const char * key_type;
5556
} sectigo_get_cert_param_t;
5657

5758

libcertifier.cfg.sample

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@
3333
"libcertifier.sectigo.id": "",
3434
"libcertifier.sectigo.owner.first.name": "",
3535
"libcertifier.sectigo.owner.last.name": "",
36+
"libcertifier.sectigo.owner.email": "",
3637
"libcertifier.sectigo.project.name": "",
3738
"libcertifier.sectigo.business.justification": "",
3839
"libcertifier.sectigo.subject.alt.names": [],
39-
"libcertifier.sectigo.owner.email": ""
40+
"libcertifier.sectigo.devhub.id": "",
41+
"libcertifier.sectigo.validity.days": 365,
42+
"libcertifier.sectigo.key.type": ""
4043
}

src/certifier_api_easy.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "certifier/types.h"
2828
#include "certifier/util.h"
2929
#include "certifier/sectigo_client.h"
30+
#include "certifier/property_internal.h"
3031

3132
#include <fcntl.h>
3233
#include <sys/stat.h>
@@ -1203,6 +1204,31 @@ static int process_command_line(CERTIFIER * easy)
12031204
return_code = certifier_set_property(easy->certifier, CERTIFIER_OPT_SECTIGO_OWNER_EMAIL, optarg);
12041205
}
12051206
break;
1207+
case 'D': // DevHub ID
1208+
if (optarg) {
1209+
return_code = certifier_set_property(easy->certifier, CERTIFIER_OPT_SECTIGO_DEVHUB_ID, optarg);
1210+
}
1211+
break;
1212+
case 'V': // Validity Days for Sectigo cert
1213+
if (optarg) {
1214+
if (atoi(optarg) > 0)
1215+
{
1216+
return_code =
1217+
certifier_set_property(easy->certifier, CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS, (const void *) (size_t) atoi(optarg));
1218+
}
1219+
else
1220+
{
1221+
log_error("Expected input to be of positive integer type");
1222+
return_code = 1;
1223+
}
1224+
}
1225+
break;
1226+
case 'W': // Key Type
1227+
if (!is_valid_sectigo_key_type(optarg)) {
1228+
log_error("Invalid key type. Supported key types: [RSA-2048, RSA-3072, RSA-4096, RSA-8192, ECC-PRIME256V1, ECC-SECP384R1]");
1229+
exit(0);
1230+
}
1231+
return_code = certifier_set_property(easy->certifier, CERTIFIER_OPT_SECTIGO_KEY_TYPE, optarg);
12061232
case '?':
12071233
/* Case when user enters the command as
12081234
* $ ./libCertifier -p

src/main.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ XPKI_CLIENT_ERROR_CODE process(XPKI_MODE mode, xc_parameter_t * xc_parameter, in
573573
}
574574

575575
// --- Sectigo Option Table ---
576-
static const char * const sectigo_get_cert_short_options = "C:I:e:s:N:r:b:A:x:K:u:G:E:O:J:Z:U:T:l:W:Y:h";
576+
static const char * const sectigo_get_cert_short_options = "C:I:e:s:N:r:b:A:x:K:u:G:E:O:J:Z:U:T:l:W:V:D:h";
577577
static const struct option sectigo_get_cert_long_opts[] = {
578578
{ "common-name", required_argument, NULL, 'C' },
579579
{ "id", required_argument, NULL, 'I' },
@@ -587,6 +587,9 @@ static const struct option sectigo_get_cert_long_opts[] = {
587587
{ "owner-first-name", required_argument, NULL, 'O' },
588588
{ "owner-last-name", required_argument, NULL, 'J' },
589589
{ "owner-email", required_argument, NULL, 'Z' },
590+
{ "devhub-id", required_argument, NULL, 'D' },
591+
{ "validity-days", required_argument, NULL, 'V' },
592+
{ "key-type", required_argument, NULL, 'W' },
590593
{ "config", required_argument, NULL, 'l' },
591594
{ "help", no_argument, NULL, 'h' },
592595
{ NULL, 0, NULL, 0 }
@@ -673,6 +676,18 @@ SECTIGO_CLIENT_ERROR_CODE sectigo_process(SECTIGO_MODE mode, sectigo_parameter_t
673676
sectigo_parameter->get_cert_param.sectigo_url = optarg;
674677
certifier_set_property(get_sectigo_certifier_instance(), CERTIFIER_OPT_SECTIGO_URL, optarg);
675678
break;
679+
case 'D':
680+
sectigo_parameter->get_cert_param.devhub_id = optarg;
681+
certifier_set_property(get_sectigo_certifier_instance(), CERTIFIER_OPT_SECTIGO_DEVHUB_ID, optarg);
682+
break;
683+
case 'V':
684+
sectigo_parameter->get_cert_param.validity_days = atol(optarg);
685+
certifier_set_property(get_sectigo_certifier_instance(), CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS, optarg);
686+
break;
687+
case 'W':
688+
sectigo_parameter->get_cert_param.key_type = optarg;
689+
certifier_set_property(get_sectigo_certifier_instance(), CERTIFIER_OPT_SECTIGO_KEY_TYPE, optarg);
690+
break;
676691
case '?':
677692
log_info("Invalid or missing Sectigo option");
678693
error_code = SECTIGO_CLIENT_INVALID_ARGUMENT;

src/property.c

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@
3636
#define DEFAULT_OUTPUT_P12_PATH "output.p12"
3737
#define DEFAULT_CFG_FILENAME "libcertifier.cfg"
3838
#define DEFAULT_USER_CFG_FILENAME "/usr/local/etc/certifier/libcertifier.cfg"
39+
40+
// Helper function to validate Sectigo key type
41+
int is_valid_sectigo_key_type(const char *key_type)
42+
{
43+
if (!key_type) {
44+
return 0;
45+
}
46+
47+
const char *valid_key_types[] = {
48+
"RSA-2048", "RSA-3072", "RSA-4096", "RSA-8192",
49+
"ECC-PRIME256V1", "ECC-SECP384R1"
50+
};
51+
52+
for (int i = 0; i < sizeof(valid_key_types) / sizeof(valid_key_types[0]); i++) {
53+
if (strcmp(key_type, valid_key_types[i]) == 0) {
54+
return 1;
55+
}
56+
}
57+
58+
return 0;
59+
}
3960
#define DEFAULT_GLOBAL_CFG_FILENAME "/etc/certifier/libcertifier.cfg"
4061
#define DEFAULT_AUTH_TYPE "X509"
4162
#define DEFAULT_CA_INFO "libcertifier-cert.crt"
@@ -202,7 +223,7 @@ struct _PropMap
202223
char * mtls_filename;
203224
char * mtls_p12_filename;
204225

205-
//Sectigo properties (common properties like auth_token, source, etc. are above)
226+
//Sectigo properties (common properties like auth_token, validity days, source, etc. are above)
206227
char * common_name;
207228
char * group_name;
208229
char * group_email;
@@ -214,6 +235,8 @@ struct _PropMap
214235
char * subject_alt_names;
215236
char * owner_email;
216237
char * sectigo_url;
238+
char * devhub_id;
239+
char * key_type;
217240
};
218241

219242
static void free_prop_map_values(CertifierPropMap * prop_map);
@@ -398,6 +421,15 @@ int sectigo_property_set(CertifierPropMap * prop_map, int name, const void * val
398421
case CERTIFIER_OPT_SECTIGO_URL:
399422
prop_map->sectigo_url = XSTRDUP((const char *)value);
400423
break;
424+
case CERTIFIER_OPT_SECTIGO_DEVHUB_ID:
425+
prop_map->devhub_id = XSTRDUP((const char *)value);
426+
break;
427+
case CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS:
428+
prop_map->validity_days = (int)(size_t)value;
429+
break;
430+
case CERTIFIER_OPT_SECTIGO_KEY_TYPE:
431+
prop_map->key_type = XSTRDUP((const char *)value);
432+
break;
401433
default:
402434
log_warn("sectigo_property_set: unrecognized property [%d]", name);
403435
retval = CERTIFIER_ERR_PROPERTY_SET_10;
@@ -901,7 +933,15 @@ void * property_get(CertifierPropMap * prop_map, CERTIFIER_OPT name)
901933
case CERTIFIER_OPT_SECTIGO_URL:
902934
retval = (void *) prop_map->sectigo_url;
903935
break;
904-
936+
case CERTIFIER_OPT_SECTIGO_DEVHUB_ID:
937+
retval = (void *) prop_map->devhub_id;
938+
break;
939+
case CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS:
940+
retval = (void *) (size_t) prop_map->validity_days;
941+
break;
942+
case CERTIFIER_OPT_SECTIGO_KEY_TYPE:
943+
retval = (void *) prop_map->key_type;
944+
break;
905945
default:
906946
log_warn("property_get: unrecognized property [%d]", name);
907947
retval = NULL;
@@ -1370,6 +1410,12 @@ static int load_sectigo_fields_from_json(CertifierPropMap *propMap, JSON_Object
13701410
continue;
13711411
}
13721412

1413+
if (strcmp(key, "libcertifier.sectigo.validity.days") == 0) {
1414+
int validity_days = json_object_get_number(root, key);
1415+
log_info("Loaded sectigo validity days: %d from config file.", validity_days);
1416+
sectigo_property_set(propMap, CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS, (void *) (size_t) validity_days);
1417+
}
1418+
13731419
const char *value_str = json_object_get_string(root, key);
13741420
if (value_str && strlen(value_str) > 0) { // Only process non-empty values
13751421
// Map config key to property enum
@@ -1417,6 +1463,18 @@ static int load_sectigo_fields_from_json(CertifierPropMap *propMap, JSON_Object
14171463
log_info("Loaded sectigo URL: %s from config file.", value_str);
14181464
sectigo_property_set(propMap, CERTIFIER_OPT_SECTIGO_URL, value_str);
14191465
}
1466+
else if (strcmp(key, "libcertifier.sectigo.devhub.id") == 0) {
1467+
log_info("Loaded sectigo devhub id: %s from config file.", value_str);
1468+
sectigo_property_set(propMap, CERTIFIER_OPT_SECTIGO_DEVHUB_ID, value_str);
1469+
}
1470+
else if (strcmp(key, "libcertifier.sectigo.key.type") == 0) {
1471+
if (!is_valid_sectigo_key_type(value_str)) {
1472+
log_error("Invalid key type '%s' in config file. Supported: [RSA-2048, RSA-3072, RSA-4096, RSA-8192, ECC-PRIME256V1, ECC-SECP384R1]", value_str);
1473+
exit(0);
1474+
}
1475+
log_info("Loaded sectigo key type: %s from config file.", value_str);
1476+
sectigo_property_set(propMap, CERTIFIER_OPT_SECTIGO_KEY_TYPE, value_str);
1477+
}
14201478
// Add more mappings as needed
14211479
}
14221480
}
@@ -1598,6 +1656,8 @@ static void free_prop_map_values(CertifierPropMap * prop_map)
15981656
FV(prop_map->subject_alt_names);
15991657
FV(prop_map->owner_email);
16001658
FV(prop_map->sectigo_url);
1659+
FV(prop_map->devhub_id);
1660+
FV(prop_map->key_type);
16011661
}
16021662

16031663
CertifierPropMap * property_new_sectigo(void)

src/sectigo_client.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ SECTIGO_CLIENT_ERROR_CODE xc_sectigo_get_default_cert_param(sectigo_get_cert_par
9797
param = certifier_get_property(certifier, CERTIFIER_OPT_SECTIGO_URL);
9898
params->sectigo_url = param ? XSTRDUP((const char *)param) : NULL;
9999

100+
param = certifier_get_property(certifier, CERTIFIER_OPT_SECTIGO_DEVHUB_ID);
101+
params->devhub_id = param ? XSTRDUP((const char *)param) : NULL;
102+
103+
param = certifier_get_property(certifier, CERTIFIER_OPT_SECTIGO_VALIDITY_DAYS);
104+
params->validity_days = param ? (size_t) param : 365;
105+
106+
param = certifier_get_property(certifier, CERTIFIER_OPT_SECTIGO_KEY_TYPE);
107+
params->key_type = param ? XSTRDUP((const char *)param) : NULL;
108+
100109
return SECTIGO_CLIENT_SUCCESS;
101110
}
102111

@@ -211,7 +220,16 @@ const char * node_address, const char * certifier_id, char ** out_cert)
211220
json_object_set_string(root_obj, "businessJustification", params.business_justification ? params.business_justification : "");
212221
json_object_set_string(root_obj, "certificateType", "comodo"); // Always "comodo"
213222
json_object_set_string(root_obj, "ownerEmailAddress", params.owner_email ? params.owner_email : "");
214-
// Always set subjectAltNames and ipAddresses, even if empty
223+
json_object_set_string(root_obj, "devhubId", params.devhub_id ? params.devhub_id : "");
224+
225+
// Convert validity_days to string
226+
if (params.validity_days > 0) {
227+
char validity_days_str[16];
228+
snprintf(validity_days_str, sizeof(validity_days_str), "%zu", params.validity_days);
229+
json_object_set_string(root_obj, "validityDays", validity_days_str);
230+
}
231+
232+
json_object_set_string(root_obj, "keyType", params.key_type ? params.key_type : "");
215233

216234
// subjectAltNames as array
217235
JSON_Value *san_array = json_value_init_array();

tests/xc_apis/xc_api_tests.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ static void test_get_sectigo_cert()
255255
params.subject_alt_names = "*";
256256
params.owner_email = "first_last@comcast.com";
257257
params.sectigo_url = "https://certs-dev.xpki.io/api/createCertificate";
258+
params.devhub_id = "12345";
259+
params.validity_days = 90;
260+
params.key_type = "RSA-8192";
258261

259262
// Call the API
260263
error = xc_sectigo_get_cert(&params);

0 commit comments

Comments
 (0)