@@ -723,9 +723,10 @@ typedef struct ltc_asn1_list_ {
723723#define LTC_SET_ASN1_CUSTOM_PRIMITIVE (list , index , Class , Tag , Type , Data , Size ) \
724724 do { \
725725 int LTC_TMPVAR(SACP) = (index); \
726+ ltc_asn1_list *LTC_TMPVAR(SACP_list) = (list); \
726727 LTC_SET_ASN1(list, LTC_TMPVAR(SACP), LTC_ASN1_CUSTOM_TYPE, Data, Size); \
727728 LTC_SET_ASN1_IDENTIFIER(list, LTC_TMPVAR(SACP), Class, LTC_ASN1_PC_PRIMITIVE, Tag); \
728- list [LTC_TMPVAR(SACP)].used = (int)(Type); \
729+ LTC_TMPVAR(SACP_list) [LTC_TMPVAR(SACP)].used = (int)(Type); \
729730 } while (0)
730731
731732extern const char * der_asn1_class_to_string_map [];
@@ -933,4 +934,244 @@ int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen,
933934
934935int der_length_generalizedtime (const ltc_generalizedtime * gtime , unsigned long * outlen );
935936
937+ /* X.509 specific enums, structs and APIs */
938+
939+ typedef enum ltc_x509_details {
940+ /* The Serial is an integer, but we provide it as a hex string. */
941+ LTC_X509_SERIAL = 0 ,
942+ /* The most commonly used elements in an X.509 Name.
943+ * These ones will be converted to a UTF-8 String and
944+ * stored inside the `str` pointer of the `ltc_x509_string`.
945+ */
946+ /* CommonName */
947+ LTC_X509_CN ,
948+ /* Country Code */
949+ LTC_X509_C ,
950+ /* Locality */
951+ LTC_X509_L ,
952+ /* State or Province */
953+ LTC_X509_ST ,
954+ /* Organisation */
955+ LTC_X509_O ,
956+ /* OrganisationalUnit */
957+ LTC_X509_OU ,
958+ /* EmailAddress */
959+ LTC_X509_EMAIL ,
960+
961+ /* GeneralName subtypes
962+ * GeneralName ::= CHOICE {
963+ * otherName [0] OtherName,
964+ * rfc822Name [1] IA5String,
965+ * dNSName [2] IA5String,
966+ * x400Address [3] ORAddress,
967+ * directoryName [4] Name,
968+ * ediPartyName [5] EDIPartyName,
969+ * uniformResourceIdentifier [6] IA5String,
970+ * iPAddress [7] OCTET STRING,
971+ * registeredID [8] OBJECT IDENTIFIER }
972+ */
973+ LTC_X509_OTHER_NAME = 30 ,
974+ LTC_X509_RFC822_NAME ,
975+ LTC_X509_DNS_NAME ,
976+ LTC_X509_X400_ADDRESS ,
977+ LTC_X509_DIRECTORY_NAME ,
978+ LTC_X509_EDI_PARTY_NAME ,
979+ LTC_X509_UNIFORM_RESOURCE_IDENTIFIER ,
980+ LTC_X509_IP_ADDRESS ,
981+ LTC_X509_REGISTERED_ID ,
982+
983+ /* Value was encoded as an OCTET STRING */
984+ LTC_X509_OCTET_STRING ,
985+
986+ /* The most commonly used X.509 Certificate Extension. */
987+ /* AuthorityKeyIdentifier */
988+ LTC_X509_CE_AUTHORITY_KEY_ID = 100 ,
989+ /* SubjectKeyIdentifier */
990+ LTC_X509_CE_SUBJECT_KEY_ID ,
991+ /* KeyUsage */
992+ LTC_X509_CE_KEY_USAGE ,
993+ /* SubjectAltName */
994+ LTC_X509_CE_SUBJECT_ALT_NAME ,
995+ /* BasicConstraints */
996+ LTC_X509_CE_BASIC_CONSTRAINTS ,
997+ /* ExtendedKeyUsage */
998+ LTC_X509_CE_EXT_KEY_USAGE ,
999+
1000+ /* The rest will not be decoded and has to be treated
1001+ * manually through the `asn1` pointer of the struct.
1002+ */
1003+ LTC_X509_UNKNOWN = 0x7fff ,
1004+ } ltc_x509_details ;
1005+
1006+ typedef struct ltc_x509_string {
1007+ ltc_x509_details type ;
1008+ const char * str ;
1009+ const ltc_asn1_list * asn1 ;
1010+ } ltc_x509_string ;
1011+
1012+ typedef struct ltc_x509_name {
1013+ const ltc_x509_string * names ;
1014+ unsigned long names_num ;
1015+ const ltc_asn1_list * asn1 ;
1016+ } ltc_x509_name ;
1017+
1018+ typedef struct ltc_x509_time {
1019+ union {
1020+ ltc_utctime * utc ;
1021+ ltc_generalizedtime * generalized ;
1022+ } u ;
1023+ int utc ;
1024+ const char * str ;
1025+ const ltc_asn1_list * asn1 ;
1026+ } ltc_x509_time ;
1027+
1028+ typedef struct ltc_x509_signature_algorithm {
1029+ enum ltc_pka_id pka ;
1030+ const char * hash ;
1031+ } ltc_x509_signature_algorithm ;
1032+
1033+ typedef struct ltc_x509_validity {
1034+ ltc_x509_time not_before , not_after ;
1035+ } ltc_x509_validity ;
1036+
1037+ /*
1038+ * Certificate Extensions
1039+ */
1040+
1041+ /* KeyUsage ::= BIT STRING */
1042+ typedef enum ltc_x509_ce_key_usage {
1043+ /* digitalSignature (0) */
1044+ LTC_KU_DS = LTC_BIT (0 ),
1045+ /* contentCommitment (1) */
1046+ LTC_KU_CC = LTC_BIT (1 ),
1047+ /* keyEncipherment (2) */
1048+ LTC_KU_KE = LTC_BIT (2 ),
1049+ /* dataEncipherment (3) */
1050+ LTC_KU_DE = LTC_BIT (3 ),
1051+ /* keyAgreement (4) */
1052+ LTC_KU_KA = LTC_BIT (4 ),
1053+ /* keyCertSign (5) */
1054+ LTC_KU_KCS = LTC_BIT (5 ),
1055+ /* cRLSign (6) */
1056+ LTC_KU_CRLS = LTC_BIT (6 ),
1057+ /* encipherOnly (7) */
1058+ LTC_KU_EO = LTC_BIT (7 ),
1059+ /* decipherOnly (8) */
1060+ LTC_KU_DO = LTC_BIT (8 ),
1061+ } ltc_x509_ce_key_usage ;
1062+
1063+ /* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1064+ * KeyPurposeId ::= OBJECT IDENTIFIER
1065+ */
1066+ typedef enum ltc_x509_ce_ext_key_usage {
1067+ /* anyExtendedKeyUsage */
1068+ LTC_EKU_ANY = LTC_BIT (0 ),
1069+ /* serverAuth */
1070+ LTC_EKU_SA = LTC_BIT (1 ),
1071+ /* clientAuth */
1072+ LTC_EKU_CA = LTC_BIT (2 ),
1073+ /* codeSigning */
1074+ LTC_EKU_CS = LTC_BIT (3 ),
1075+ /* emailProtection */
1076+ LTC_EKU_EP = LTC_BIT (4 ),
1077+ /* timeStamping */
1078+ LTC_EKU_TS = LTC_BIT (5 ),
1079+ /* OCSPSigning */
1080+ LTC_EKU_OS = LTC_BIT (6 ),
1081+ } ltc_x509_ce_ext_key_usage ;
1082+
1083+ typedef struct ltc_x509_extensions ltc_x509_extensions ;
1084+
1085+ typedef struct ltc_x509_extension {
1086+ ltc_x509_details type ;
1087+ const ltc_asn1_list * oid ;
1088+ int critical ;
1089+ union {
1090+ /* .type = LTC_X509_AUTHORITY_KEY_ID */
1091+ struct {
1092+ ltc_x509_string key_identifier ;
1093+ ltc_x509_string authority_cert_issuer ;
1094+ ltc_x509_string authority_cert_serial_number ;
1095+ } authority_key_id ;
1096+ /* .type = LTC_X509_SUBJECT_KEY_ID */
1097+ ltc_x509_string subject_key_identifier ;
1098+ /* .type = LTC_X509_KEY_USAGE
1099+ * Bitmask of `enum ltc_x509_ce_key_usage`
1100+ */
1101+ ulong32 key_usage ;
1102+ /* .type = LTC_X509_SUBJECT_ALT_NAME */
1103+ ltc_x509_name subject_alt_name ;
1104+ /* .type = LTC_X509_BASIC_CONSTRAINTS */
1105+ struct {
1106+ int ca ;
1107+ /* pathLenConstraint is marked as OPTIONAL:
1108+ * -1 -> value missing
1109+ * 0..INT_MAX -> valid values
1110+ */
1111+ int path_len ;
1112+ } basic_constraints ;
1113+ /* .type = LTC_X509_EXT_KEY_USAGE
1114+ * Bitmask of `enum ltc_x509_ce_ext_key_usage`
1115+ */
1116+ ulong32 ext_key_usage ;
1117+ } u ;
1118+ const ltc_asn1_list * asn1 ;
1119+ } ltc_x509_extension ;
1120+
1121+ struct ltc_x509_extensions {
1122+ const ltc_x509_extension * extensions ;
1123+ unsigned long extensions_num ;
1124+ const ltc_asn1_list * asn1 ;
1125+
1126+ const ltc_x509_extension * authority_key_id ;
1127+ const ltc_x509_extension * subject_key_identifier ;
1128+ const ltc_x509_extension * key_usage ;
1129+ const ltc_x509_extension * subject_alt_name ;
1130+ const ltc_x509_extension * basic_constraints ;
1131+ const ltc_x509_extension * ext_key_usage ;
1132+ /* let's pre-reserve this for future extensions */
1133+ const ltc_x509_extension * more [7 ];
1134+ };
1135+
1136+ typedef struct ltc_x509_tbs_certificate {
1137+ unsigned long version ;
1138+ ltc_x509_string serial_number ;
1139+ ltc_x509_signature_algorithm signature_algorithm ;
1140+ ltc_x509_name issuer ;
1141+ ltc_x509_validity validity ;
1142+ ltc_x509_name subject ;
1143+ ltc_pka_key subject_public_key_info ;
1144+ const ltc_asn1_list * issuer_uid ;
1145+ const ltc_asn1_list * subject_uid ;
1146+ ltc_x509_extensions extensions ;
1147+ const ltc_asn1_list * asn1 ;
1148+ } ltc_x509_tbs_certificate ;
1149+
1150+ typedef struct ltc_x509_signature {
1151+ const unsigned char * signature ;
1152+ /* The signature length is given in bits, but it is stored as bytes.
1153+ * I.e. a signature of 123 bits will be stored in 128bits resp. 16bytes.
1154+ */
1155+ unsigned long signature_len ;
1156+ const ltc_asn1_list * asn1 ;
1157+ } ltc_x509_signature ;
1158+
1159+ typedef struct ltc_x509_certificate {
1160+ ltc_x509_tbs_certificate tbs_certificate ;
1161+ ltc_x509_signature_algorithm signature_algorithm ;
1162+ ltc_x509_signature signature ;
1163+ const ltc_asn1_list * asn1 ;
1164+ } ltc_x509_certificate ;
1165+
1166+ int x509_import (const unsigned char * asn1_cert , unsigned long asn1_len , const ltc_x509_certificate * * out );
1167+ int x509_import_pem (const char * pem , unsigned long * pem_len , const ltc_x509_certificate * * out );
1168+ #ifndef LTC_NO_FILE
1169+ int x509_import_pem_filehandle (FILE * f , const ltc_x509_certificate * * out );
1170+ #endif
1171+ int x509_cert_is_signed_by (const ltc_x509_certificate * cert , const ltc_pka_key * key , int * stat );
1172+ int x509_cmp_name (const ltc_x509_name * a , const ltc_x509_name * b );
1173+ int x509_name_detail_get (const ltc_x509_name * name , ltc_x509_details type , const ltc_x509_string * * str );
1174+ int x509_extension_by_oid (const ltc_x509_certificate * cert , const char * oid , const ltc_x509_extension * * extension );
1175+ void x509_free (const ltc_x509_certificate * * cert );
1176+
9361177#endif
0 commit comments