Skip to content

Commit f19a52c

Browse files
committed
Add X.509 APIs
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 71d72b2 commit f19a52c

File tree

11 files changed

+1969
-68
lines changed

11 files changed

+1969
-68
lines changed

src/headers/tomcrypt_macros.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#define LTC_TMPVAR_(n, l) LTC_TMPVAR__(n, l)
77
#define LTC_TMPVAR(n) LTC_TMPVAR_(LTC_ ## n ## _, __LINE__)
88

9+
#define LTC_BIT(n) (1u << (n))
10+
911
/* ---- HELPER MACROS ---- */
1012
#ifdef ENDIAN_NEUTRAL
1113

src/headers/tomcrypt_pk.h

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,4 +1058,248 @@ int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen,
10581058

10591059
int der_length_generalizedtime(const ltc_generalizedtime *gtime, unsigned long *outlen);
10601060

1061+
/* X.509 specific enums, structs and APIs */
1062+
1063+
typedef enum ltc_x509_details {
1064+
/* The Serial is an integer, but we provide it as a hex string. */
1065+
LTC_X509_SERIAL = 0,
1066+
/* The most commonly used elements in an X.509 Name.
1067+
* These ones will be converted to a UTF-8 String and
1068+
* stored inside the `str` pointer of the `ltc_x509_string`.
1069+
*/
1070+
/* CommonName */
1071+
LTC_X509_CN,
1072+
/* Country Code */
1073+
LTC_X509_C,
1074+
/* Locality */
1075+
LTC_X509_L,
1076+
/* State or Province */
1077+
LTC_X509_ST,
1078+
/* Organisation */
1079+
LTC_X509_O,
1080+
/* OrganisationalUnit */
1081+
LTC_X509_OU,
1082+
/* EmailAddress */
1083+
LTC_X509_EMAIL,
1084+
1085+
/* GeneralName subtypes
1086+
* GeneralName ::= CHOICE {
1087+
* otherName [0] OtherName,
1088+
* rfc822Name [1] IA5String,
1089+
* dNSName [2] IA5String,
1090+
* x400Address [3] ORAddress,
1091+
* directoryName [4] Name,
1092+
* ediPartyName [5] EDIPartyName,
1093+
* uniformResourceIdentifier [6] IA5String,
1094+
* iPAddress [7] OCTET STRING,
1095+
* registeredID [8] OBJECT IDENTIFIER }
1096+
*/
1097+
LTC_X509_OTHER_NAME = 30,
1098+
LTC_X509_RFC822_NAME,
1099+
LTC_X509_DNS_NAME,
1100+
LTC_X509_X400_ADDRESS,
1101+
LTC_X509_DIRECTORY_NAME,
1102+
LTC_X509_EDI_PARTY_NAME,
1103+
LTC_X509_UNIFORM_RESOURCE_IDENTIFIER,
1104+
LTC_X509_IP_ADDRESS,
1105+
LTC_X509_REGISTERED_ID,
1106+
1107+
/* Value was encoded as an OCTET STRING */
1108+
LTC_X509_OCTET_STRING,
1109+
1110+
/* The most commonly used X.509 Certificate Extension. */
1111+
/* AuthorityKeyIdentifier */
1112+
LTC_X509_CE_AUTHORITY_KEY_ID = 100,
1113+
/* SubjectKeyIdentifier */
1114+
LTC_X509_CE_SUBJECT_KEY_ID,
1115+
/* KeyUsage */
1116+
LTC_X509_CE_KEY_USAGE,
1117+
/* SubjectAltName */
1118+
LTC_X509_CE_SUBJECT_ALT_NAME,
1119+
/* BasicConstraints */
1120+
LTC_X509_CE_BASIC_CONSTRAINTS,
1121+
/* ExtendedKeyUsage */
1122+
LTC_X509_CE_EXT_KEY_USAGE,
1123+
1124+
/* The rest will not be decoded and has to be treated
1125+
* manually through the `asn1` pointer of the struct.
1126+
*/
1127+
LTC_X509_UNKNOWN = 0x7fff,
1128+
} ltc_x509_details;
1129+
1130+
typedef struct ltc_x509_string {
1131+
ltc_x509_details type;
1132+
const char *str;
1133+
const ltc_asn1_list *asn1;
1134+
} ltc_x509_string;
1135+
1136+
typedef struct ltc_x509_name {
1137+
const ltc_x509_string *names;
1138+
unsigned long names_num;
1139+
const ltc_asn1_list *asn1;
1140+
} ltc_x509_name;
1141+
1142+
typedef struct ltc_x509_time {
1143+
union {
1144+
ltc_utctime *utc;
1145+
ltc_generalizedtime *generalized;
1146+
} u;
1147+
int utc;
1148+
const char *str;
1149+
const ltc_asn1_list *asn1;
1150+
} ltc_x509_time;
1151+
1152+
typedef struct ltc_x509_signature_algorithm {
1153+
enum ltc_pka_id pka;
1154+
union {
1155+
const char *hash;
1156+
ltc_rsa_parameters rsa_params;
1157+
} u;
1158+
const ltc_asn1_list *asn1;
1159+
} ltc_x509_signature_algorithm;
1160+
1161+
typedef struct ltc_x509_validity {
1162+
ltc_x509_time not_before, not_after;
1163+
} ltc_x509_validity;
1164+
1165+
/*
1166+
* Certificate Extensions
1167+
*/
1168+
1169+
/* KeyUsage ::= BIT STRING */
1170+
typedef enum ltc_x509_ce_key_usage {
1171+
/* digitalSignature (0) */
1172+
LTC_KU_DS = LTC_BIT(0),
1173+
/* contentCommitment (1) */
1174+
LTC_KU_CC = LTC_BIT(1),
1175+
/* keyEncipherment (2) */
1176+
LTC_KU_KE = LTC_BIT(2),
1177+
/* dataEncipherment (3) */
1178+
LTC_KU_DE = LTC_BIT(3),
1179+
/* keyAgreement (4) */
1180+
LTC_KU_KA = LTC_BIT(4),
1181+
/* keyCertSign (5) */
1182+
LTC_KU_KCS = LTC_BIT(5),
1183+
/* cRLSign (6) */
1184+
LTC_KU_CRLS = LTC_BIT(6),
1185+
/* encipherOnly (7) */
1186+
LTC_KU_EO = LTC_BIT(7),
1187+
/* decipherOnly (8) */
1188+
LTC_KU_DO = LTC_BIT(8),
1189+
} ltc_x509_ce_key_usage;
1190+
1191+
/* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1192+
* KeyPurposeId ::= OBJECT IDENTIFIER
1193+
*/
1194+
typedef enum ltc_x509_ce_ext_key_usage {
1195+
/* anyExtendedKeyUsage */
1196+
LTC_EKU_ANY = LTC_BIT(0),
1197+
/* serverAuth */
1198+
LTC_EKU_SA = LTC_BIT(1),
1199+
/* clientAuth */
1200+
LTC_EKU_CA = LTC_BIT(2),
1201+
/* codeSigning */
1202+
LTC_EKU_CS = LTC_BIT(3),
1203+
/* emailProtection */
1204+
LTC_EKU_EP = LTC_BIT(4),
1205+
/* timeStamping */
1206+
LTC_EKU_TS = LTC_BIT(5),
1207+
/* OCSPSigning */
1208+
LTC_EKU_OS = LTC_BIT(6),
1209+
} ltc_x509_ce_ext_key_usage;
1210+
1211+
typedef struct ltc_x509_extension {
1212+
ltc_x509_details type;
1213+
const ltc_asn1_list *oid;
1214+
int critical;
1215+
union {
1216+
/* .type = LTC_X509_AUTHORITY_KEY_ID */
1217+
struct {
1218+
ltc_x509_string key_identifier;
1219+
ltc_x509_string authority_cert_issuer;
1220+
ltc_x509_string authority_cert_serial_number;
1221+
} authority_key_id;
1222+
/* .type = LTC_X509_SUBJECT_KEY_ID */
1223+
ltc_x509_string subject_key_identifier;
1224+
/* .type = LTC_X509_KEY_USAGE
1225+
* Bitmask of `enum ltc_x509_ce_key_usage`
1226+
*/
1227+
ulong32 key_usage;
1228+
/* .type = LTC_X509_SUBJECT_ALT_NAME */
1229+
ltc_x509_name subject_alt_name;
1230+
/* .type = LTC_X509_BASIC_CONSTRAINTS */
1231+
struct {
1232+
int ca;
1233+
/* pathLenConstraint is marked as OPTIONAL:
1234+
* -1 -> value missing
1235+
* 0..INT_MAX -> valid values
1236+
*/
1237+
int path_len;
1238+
} basic_constraints;
1239+
/* .type = LTC_X509_EXT_KEY_USAGE
1240+
* Bitmask of `enum ltc_x509_ce_ext_key_usage`
1241+
*/
1242+
ulong32 ext_key_usage;
1243+
} u;
1244+
const ltc_asn1_list *asn1;
1245+
} ltc_x509_extension;
1246+
1247+
typedef struct ltc_x509_extensions {
1248+
const ltc_x509_extension *extensions;
1249+
unsigned long extensions_num;
1250+
const ltc_asn1_list *asn1;
1251+
1252+
const ltc_x509_extension *authority_key_id;
1253+
const ltc_x509_extension *subject_key_identifier;
1254+
const ltc_x509_extension *key_usage;
1255+
const ltc_x509_extension *subject_alt_name;
1256+
const ltc_x509_extension *basic_constraints;
1257+
const ltc_x509_extension *ext_key_usage;
1258+
/* let's pre-reserve this for future extensions */
1259+
const ltc_x509_extension *more[7];
1260+
} ltc_x509_extensions;
1261+
1262+
typedef struct ltc_x509_tbs_certificate {
1263+
unsigned long version;
1264+
ltc_x509_string serial_number;
1265+
ltc_x509_signature_algorithm signature_algorithm;
1266+
ltc_x509_name issuer;
1267+
ltc_x509_validity validity;
1268+
ltc_x509_name subject;
1269+
ltc_pka_key subject_public_key_info;
1270+
const ltc_asn1_list *issuer_uid;
1271+
const ltc_asn1_list *subject_uid;
1272+
ltc_x509_extensions extensions;
1273+
const ltc_asn1_list *asn1;
1274+
} ltc_x509_tbs_certificate;
1275+
1276+
typedef struct ltc_x509_signature {
1277+
const unsigned char *signature;
1278+
/* The signature length is given in bits, but it is stored as bytes.
1279+
* I.e. a signature of 123 bits will be stored in 128bits resp. 16bytes.
1280+
*/
1281+
unsigned long signature_len;
1282+
const ltc_asn1_list *asn1;
1283+
} ltc_x509_signature;
1284+
1285+
typedef struct ltc_x509_certificate {
1286+
ltc_x509_tbs_certificate tbs_certificate;
1287+
ltc_x509_signature_algorithm signature_algorithm;
1288+
ltc_x509_signature signature;
1289+
const ltc_asn1_list *asn1;
1290+
} ltc_x509_certificate;
1291+
1292+
int x509_import(const unsigned char *asn1_cert, unsigned long asn1_len, const ltc_x509_certificate **out);
1293+
#ifdef LTC_PEM
1294+
int x509_import_pem(const char *pem, unsigned long *pem_len, const ltc_x509_certificate **out);
1295+
#ifndef LTC_NO_FILE
1296+
int x509_import_pem_filehandle(FILE *f, const ltc_x509_certificate **out);
1297+
#endif /* LTC_NO_FILE */
1298+
#endif /* LTC_PEM */
1299+
int x509_cert_is_signed_by(const ltc_x509_certificate *cert, const ltc_pka_key *key, int *stat);
1300+
int x509_cmp_name(const ltc_x509_name *a, const ltc_x509_name *b);
1301+
int x509_name_detail_get(const ltc_x509_name *name, ltc_x509_details type, const ltc_x509_string **str);
1302+
const char *x509_name_detail_desc(ltc_x509_details type);
1303+
void x509_free(const ltc_x509_certificate **cert);
1304+
10611305
#endif

src/headers/tomcrypt_private.h

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,33 @@ enum ltc_oid_id {
6363
LTC_OID_RSA_OAEP,
6464
LTC_OID_RSA_MGF1,
6565
LTC_OID_RSA_PSS,
66+
LTC_OID_RSA_WITH_MD5,
67+
LTC_OID_RSA_WITH_SHA1,
68+
LTC_OID_RSA_WITH_SHA224,
69+
LTC_OID_RSA_WITH_SHA256,
70+
LTC_OID_RSA_WITH_SHA384,
71+
LTC_OID_RSA_WITH_SHA512,
72+
LTC_OID_RSA_WITH_SHA512_224,
73+
LTC_OID_RSA_WITH_SHA512_512,
74+
LTC_OID_ECDSA_WITH_SHA1,
75+
LTC_OID_ECDSA_WITH_SHA224,
76+
LTC_OID_ECDSA_WITH_SHA256,
77+
LTC_OID_ECDSA_WITH_SHA384,
78+
LTC_OID_ECDSA_WITH_SHA512,
79+
LTC_OID_DSA_WITH_SHA1,
80+
LTC_OID_DSA_WITH_SHA224,
81+
LTC_OID_DSA_WITH_SHA256,
82+
LTC_OID_DSA_WITH_SHA384,
83+
LTC_OID_DSA_WITH_SHA512,
84+
LTC_OID_ECDSA_WITH_SHA3_224,
85+
LTC_OID_ECDSA_WITH_SHA3_256,
86+
LTC_OID_ECDSA_WITH_SHA3_384,
87+
LTC_OID_ECDSA_WITH_SHA3_512,
88+
LTC_OID_RSA_WITH_SHA3_224,
89+
LTC_OID_RSA_WITH_SHA3_256,
90+
LTC_OID_RSA_WITH_SHA3_384,
91+
LTC_OID_RSA_WITH_SHA3_512,
92+
6693
LTC_OID_NUM
6794
};
6895

@@ -424,13 +451,14 @@ int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng);
424451

425452
int pk_get_oid(enum ltc_oid_id id, const char **st);
426453
int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka);
454+
int pk_get_sig_alg(enum ltc_oid_id id, ltc_x509_signature_algorithm *sig_alg);
427455
int pk_get_oid_id(enum ltc_pka_id pka, enum ltc_oid_id *oid);
456+
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen);
457+
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);
428458
#ifdef LTC_DER
429459
int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id);
460+
int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2);
430461
#endif
431-
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen);
432-
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);
433-
434462
int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size);
435463

436464
/* ---- DH Routines ---- */
@@ -695,6 +723,7 @@ int ec25519_crypto_ctx( unsigned char *out, unsigned long *outlen,
695723
#define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t)))
696724

697725
/* DER handling */
726+
int der_decode_sequence_flexi_limited(const unsigned char *in, unsigned long *inlen, long max_depth, ltc_asn1_list **out);
698727
int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
699728
ltc_asn1_list *root,
700729
ltc_asn1_list *list, unsigned long outlen, unsigned int flags);
@@ -713,6 +742,12 @@ int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
713742
int der_length_object_identifier_full(const unsigned long *words, unsigned long nwords,
714743
unsigned long *outlen, unsigned long *datalen);
715744

745+
int der_decode_ia5_string_data(const unsigned char *in, unsigned long inlen,
746+
char *out, unsigned long *outlen);
747+
int der_decode_object_identifier_data(const unsigned char *in, unsigned long inlen,
748+
unsigned long *words, unsigned long *outlen);
749+
750+
716751
int der_ia5_char_encode(int c);
717752
int der_ia5_value_decode(int v);
718753

@@ -784,9 +819,11 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i
784819
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len);
785820

786821
int x509_get_pka(const ltc_asn1_list *pub, enum ltc_pka_id *pka);
787-
int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root);
788-
789-
int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2);
822+
int x509_get_sig_alg(const ltc_asn1_list *pub, ltc_x509_signature_algorithm *sig_alg);
823+
int x509_import_spki(const unsigned char *buf, unsigned long len, ltc_pka_key *k, ltc_asn1_list **root);
824+
int x509_get_extensions(const ltc_asn1_list *seq, ltc_x509_extensions *extensions);
825+
void x509_free_extensions(const ltc_x509_extensions *extensions);
826+
int x509_get_serial(const ltc_asn1_list *asn1, ltc_x509_string *serial);
790827

791828
#endif /* LTC_DER */
792829

0 commit comments

Comments
 (0)