scclib
Stable Cloud Computing C++ Library
cert.h
Go to the documentation of this file.
1 /*
2 BSD 3-Clause License
3 
4 Copyright (c) 2022, Stable Cloud Computing, Inc.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 1. Redistributions of source code must retain the above copyright notice, this
10  list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright notice,
13  this list of conditions and the following disclaimer in the documentation
14  and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #ifndef _SCC_CRYPTO_CERT_H
32 #define _SCC_CRYPTO_CERT_H
33 
34 #include <map>
35 #include <memory>
36 #include <set>
37 #include <system_error>
38 #include <fstream>
39 #include <algorithm>
40 #include <crypto/der.h>
41 #include <crypto/rsa.h>
42 #include <crypto/ecc.h>
43 #include <crypto/bignum.h>
44 
45 namespace scc::crypto {
46 
78 {
79  unknown = 0,
80  rsa,
86 };
87 
105 {
106  PublicKeyCert() {}
107  virtual ~PublicKeyCert() {}
108 
109  oid_value algorithm_id;
110  BasePtr parameters;
111  std::vector<uint8_t> public_key;
112 
114  KeyAlgoType type() const;
115 
117  void parse(const BasePtr);
118  void parse(const DerDocument& doc)
119  {
120  parse(doc.root_ptr());
121  }
122 
124  BasePtr dump() const;
125 
127  std::string str() const;
128 
130  void get(RsaPublicKey& key) const;
132  void set(const RsaPublicKey& key);
133 
135  void get(EccGfpPoint&) const;
137  void set(const KeyAlgoType&, const EccGfpPoint&);
138 };
139 
152 {
154  static void parse(const BasePtr&, RsaPublicKey&);
155  static void parse(const DerDocument& doc, RsaPublicKey& key)
156  {
157  parse(doc.root_ptr(), key);
158  }
159 
161  static BasePtr dump(const RsaPublicKey&);
162 };
163 
184 {
186  static void parse(const BasePtr&, RsaPrivateKey&);
187  static void parse(const DerDocument& doc, RsaPrivateKey& key)
188  {
189  parse(doc.root_ptr(), key);
190  }
191 
193  static BasePtr dump(const RsaPrivateKey&);
194 };
195 
210 {
215  static void parse(const BasePtr&, KeyAlgoType&);
216  static void parse(const DerDocument& doc, KeyAlgoType& alg)
217  {
218  parse(doc.root_ptr(), alg);
219  }
220 
223  static BasePtr dump(const KeyAlgoType&);
224 };
225 
248 {
255  static void parse(const BasePtr&, const KeyAlgoType&, EccGfpPoint&);
256  static void parse(const DerDocument& doc, const KeyAlgoType& alg, EccGfpPoint& p)
257  {
258  parse(doc.root_ptr(), alg, p);
259  }
261  static void parse(const void*, int, const KeyAlgoType&, EccGfpPoint&);
262  static void parse(const std::vector<char>& v, const KeyAlgoType& a, EccGfpPoint& p)
263  {
264  parse(v.data(), v.size(), a, p);
265  }
266  static void parse(const std::vector<uint8_t>& v, const KeyAlgoType& a, EccGfpPoint& p)
267  {
268  parse(v.data(), v.size(), a, p);
269  }
270 
272  static BasePtr dump(const EccGfpPoint&);
274  static void dump(const EccGfpPoint&, std::vector<char>&);
275  static void dump(const EccGfpPoint&, std::vector<uint8_t>&);
276 };
277 
298 {
300  static void parse(const BasePtr&, Bignum&, KeyAlgoType&, EccGfpPoint&);
301  static void parse(const DerDocument& doc, Bignum& priv, KeyAlgoType& alg, EccGfpPoint& pub)
302  {
303  parse(doc.root_ptr(), priv, alg, pub);
304  }
305 
307  static BasePtr dump(const Bignum&, const KeyAlgoType&, const EccGfpPoint&);
308 };
309 
325 struct DirectoryString : public std::string
326 {
327  enum class Type
328  {
329  printable,
330  utf8,
331  universal,
332  bmp,
333  teletex,
334  ia5,
335  visible,
336  };
337 
338  DirectoryString::Type type;
339 
340  DirectoryString() : type(DirectoryString::Type::printable) {}
341  DirectoryString(const std::string& b, DirectoryString::Type t = Type::printable) : type(t)
342  {
343  assign(b);
344  }
345  DirectoryString(const BasePtr& b)
346  {
347  parse(b);
348  }
349  virtual ~DirectoryString() {}
350 
355  int compare(const DirectoryString& b) const
356  {
357  return std::string::compare(b);
358  }
359 
360  bool operator==(const DirectoryString& b) const { return compare(b) == 0; }
361  bool operator!=(const DirectoryString& b) const { return compare(b) != 0; }
362 
364  void parse(BasePtr);
365 
367  std::string str() const;
368 
369  BasePtr dump() const;
370 };
371 
381 enum class AttributeType
382 {
383  unknown,
384  name,
385  surname,
386  given_name,
388  common_name,
389  locality_name,
393  title,
394  dn_qualifier,
395  country_name,
396  serial_number,
397  pseudonym,
401  email_address,
402 };
403 
426 using RDNPair = std::pair<oid_value, DirectoryString>;
427 
428 struct RDNComp
429 {
430  bool operator()(const RDNPair& lhs, const RDNPair& rhs) const
431  {
432  return lhs.first < rhs.first;
433  }
434 };
435 
436 struct RelativeDistinguishedName : public std::set<RDNPair, RDNComp>
437 {
439  RelativeDistinguishedName(BasePtr b)
440  {
441  parse(b);
442  }
443  virtual ~RelativeDistinguishedName() {}
444 
446  void parse(BasePtr);
448  BasePtr dump() const;
450  std::string str() const;
451 
452  static AttributeType type(const oid_value&);
453 
454  static const oid_value name;
455  static const oid_value surname;
456  static const oid_value given_name;
457  static const oid_value generation_qualifier;
458  static const oid_value common_name;
459  static const oid_value locality_name;
460  static const oid_value state_or_province_name;
461  static const oid_value organization_name;
462  static const oid_value organizational_unit_name;
463  static const oid_value title;
464  static const oid_value dn_qualifier;
465  static const oid_value country_name;
466  static const oid_value serial_number;
467  static const oid_value pseudonym;
468  static const oid_value organization_id;
469  static const oid_value street_address;
470  static const oid_value domain_component;
471  static const oid_value email_address;
472 };
473 
511 {
512  enum class Type : int
513  {
514  other_name = 0, // base_val
515  rfc822_name = 1, // string_val
516  dns_name = 2, // string_val
517  x400_address = 3, // base_val
518  directory_name = 4, // name_val
519  edi_party_name = 5, // base_val
520  uniform_resource_identifier = 6, // string_val
521  ip_address = 7, // string_val
522  registered_id = 8, // oid_val
523  };
524 
525  Type type;
526 
528  GeneralName(Type t = Type::directory_name);
529  virtual ~GeneralName() {}
530 
531  BasePtr base;
532  std::string string_val;
533  std::vector<RelativeDistinguishedName> name_val;
534  oid_value oid_val;
535 
536  void clear()
537  {
538  string_val.clear();
539  name_val.clear();
540  oid_val.clear();
541  base.reset();
542  }
543 
544  bool compare(const GeneralName& b) const
545  {
546  if (type != b.type) return false;
547 
548  switch (type)
549  {
550  case Type::registered_id:
551  return oid_val == b.oid_val;
552  case Type::rfc822_name:
553  case Type::dns_name:
554  case Type::uniform_resource_identifier:
555  case Type::ip_address:
556  return string_val.compare(b.string_val) == 0;
557  case Type::directory_name:
558  return name_val == b.name_val;
559  case Type::other_name:
560  case Type::x400_address:
561  case Type::edi_party_name:
562  return false; // not possible to compare raw elements
563  }
564  return false;
565  }
566 
567  bool operator==(const GeneralName& b) const { return compare(b); }
568  bool operator!=(const GeneralName& b) const { return !compare(b); }
569 
571  void parse(BasePtr);
573  BasePtr dump();
575  std::string str(bool = false) const;
576 };
577 
578 enum class ExtType
579 {
580  subject_alternative_name, // oid = {2, 5, 29, 17}
581  authority_key_identifier, // oid = {2, 5, 29, 35}
582  subject_key_identifier, // oid = {2, 5, 29, 14}
583  issuer_alternative_name, // oid = {2, 5, 29, 18}
584  basic_constraints, // oid = {2, 5, 29, 19}
585  key_usage, // oid = {2, 5, 29, 15}
586  extended_key_usage, // oid = {2, 5, 29, 37}
587 /*
588  Not implemented:
589 
590  certificate_policies, // oid = {2, 5, 29, 32}
591  policy_mappings, // oid = {2, 5, 29, 33}
592  subject_directory_attributes, // oid = {2, 5, 29, 9}
593  name_constraints, // oid = {2, 5, 29, 30}
594  policy_constraints, // oid = {2, 5, 29, 36}
595  crl_distribution_points, // oid = {2, 5, 29, 31}
596  inhibit_any_policy, // oid = {2, 5, 29, 54}
597  freshest_crl, // oid = {2, 5, 29, 46}
598  authority_information_access, // oid = {1, 3, 6, 1, 5, 5, 7, 1, 1}
599  subject_information_access, // oid = {1, 3, 6, 1, 5, 5, 7, 1, 11}
600  signed_certificate_timestamp_list, // oid = {1, 3, 6, 1, 4, 1, 11129, 2, 4, 2}
601 */
602 };
603 
604 class ExtBase;
605 using ExtBasePtr = std::shared_ptr<ExtBase>;
606 
620 struct ExtBase
621 {
622  oid_value oid;
623  bool critical;
624  BasePtr value;
625 
626  ExtBase(bool crit = false) : critical(crit) {}
627  virtual ~ExtBase() {}
628 
630  virtual std::string name() const { return "ExtUnknown"; }
632  virtual std::string str(bool = false) const;
634  virtual void parse() {}
636  virtual void dump() {}
641  virtual bool implemented() const { return false; }
642 
647  static ExtBasePtr create(BasePtr);
648 
651  BasePtr dump_seq();
652 
654  static oid_value find_oid(ExtType);
655 };
656 
666 {
667  ExtSubjectAlternativeName(bool crit=false) : ExtBase(crit)
668  {
669  oid = ExtBase::find_oid(ExtType::subject_alternative_name);
670  }
671  virtual ~ExtSubjectAlternativeName() {}
672 
673  std::string name() const { return "ExtSubjectAlternativeName"; }
674  virtual std::string str(bool = false) const;
675  virtual void parse();
676  virtual void dump();
677  virtual bool implemented() const { return true; }
678 
679  static bool is_castable(ExtBasePtr b)
680  {
681  return typeid(*b) == typeid(ExtSubjectAlternativeName);
682  }
683  static ExtSubjectAlternativeName& cast(ExtBasePtr b)
684  {
685  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtSubjectAlternativeName: invalid cast");
686  return *dynamic_cast<ExtSubjectAlternativeName*>(b.get());
687  }
688 
689  std::vector<GeneralName> names;
690 };
691 
705 {
706  ExtAuthorityKeyIdentifier(bool crit=false) : ExtBase(crit)
707  {
708  oid = ExtBase::find_oid(ExtType::authority_key_identifier);
709  }
710  virtual ~ExtAuthorityKeyIdentifier() {}
711 
712  std::string name() const { return "ExtAuthorityKeyIdentifier"; }
713  virtual std::string str(bool = false) const;
714  virtual void parse();
715  virtual void dump();
716  virtual bool implemented() const { return true; }
717 
718  static bool is_castable(ExtBasePtr b)
719  {
720  return typeid(*b) == typeid(ExtAuthorityKeyIdentifier);
721  }
722  static ExtAuthorityKeyIdentifier& cast(ExtBasePtr b)
723  {
724  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtAuthorityKeyIdentifier: invalid cast");
725  return *dynamic_cast<ExtAuthorityKeyIdentifier*>(b.get());
726  }
727 
728  std::vector<char> key_identifier;
729  std::vector<GeneralName> authority_cert_issuer;
731 };
732 
733 
741 {
742  ExtSubjectKeyIdentifier(bool crit=false) : ExtBase(crit)
743  {
744  oid = ExtBase::find_oid(ExtType::subject_key_identifier);
745  }
746  virtual ~ExtSubjectKeyIdentifier() {}
747 
748  std::string name() const { return "ExtSubjectKeyIdentifier"; }
749  virtual std::string str(bool = false) const;
750  virtual void parse();
751  virtual void dump();
752  virtual bool implemented() const { return true; }
753 
754  static bool is_castable(ExtBasePtr b)
755  {
756  return typeid(*b) == typeid(ExtSubjectKeyIdentifier);
757  }
758  static ExtSubjectKeyIdentifier& cast(ExtBasePtr b)
759  {
760  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtSubjectKeyIdentifier: invalid cast");
761  return *dynamic_cast<ExtSubjectKeyIdentifier*>(b.get());
762  }
763 
764  std::vector<char> key_identifier;
765 };
766 
774 {
775  ExtIssuerAlternativeName(bool crit=false) : ExtBase(crit)
776  {
777  oid = ExtBase::find_oid(ExtType::issuer_alternative_name);
778  }
779  virtual ~ExtIssuerAlternativeName() {}
780 
781  std::string name() const { return "ExtIssuerAlternativeName"; }
782  virtual std::string str(bool = false) const;
783  virtual void parse();
784  virtual void dump();
785  virtual bool implemented() const { return true; }
786 
787  static bool is_castable(ExtBasePtr b)
788  {
789  return typeid(*b) == typeid(ExtIssuerAlternativeName);
790  }
791  static ExtIssuerAlternativeName& cast(ExtBasePtr b)
792  {
793  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtIssuerAlternativeName: invalid cast");
794  return *dynamic_cast<ExtIssuerAlternativeName*>(b.get());
795  }
796 
797  std::vector<GeneralName> names;
798 };
799 
811 {
812  ExtBasicConstraints(bool crit=false, bool ca=false, unsigned plen=0) : ExtBase(crit), conditional_access(ca), max_path_len(plen)
813  {
814  oid = ExtBase::find_oid(ExtType::basic_constraints);
815  }
816  virtual ~ExtBasicConstraints() {}
817 
818  std::string name() const { return "ExtBasicConstraints"; }
819  virtual std::string str(bool = false) const;
820  virtual void parse();
821  virtual void dump();
822  virtual bool implemented() const { return true; }
823 
824  static bool is_castable(ExtBasePtr b)
825  {
826  return typeid(*b) == typeid(ExtBasicConstraints);
827  }
828  static ExtBasicConstraints& cast(ExtBasePtr b)
829  {
830  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtBasicConstraints: invalid cast");
831  return *dynamic_cast<ExtBasicConstraints*>(b.get());
832  }
833 
836 };
837 
852 struct ExtKeyUsage : public ExtBase
853 {
854  ExtKeyUsage(bool crit=false) : ExtBase(crit)
855  {
856  oid = ExtBase::find_oid(ExtType::key_usage);
857  clear();
858  }
859  virtual ~ExtKeyUsage() {}
860 
861  std::string name() const { return "ExtKeyUsage"; }
862  virtual std::string str(bool = false) const;
863  virtual void parse();
864  virtual void dump();
865  virtual bool implemented() const { return true; }
866 
867  static bool is_castable(ExtBasePtr b)
868  {
869  return typeid(*b) == typeid(ExtKeyUsage);
870  }
871  static ExtKeyUsage& cast(ExtBasePtr b)
872  {
873  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtKeyUsage: invalid cast");
874  return *dynamic_cast<ExtKeyUsage*>(b.get());
875  }
876 
877  void clear()
878  {
879  digital_signature = false;
880  content_commitment = false;
881  key_encipherment = false;
882  data_encipherment = false;
883  key_agreement = false;
884  key_cert_sign = false;
885  crl_sign = false;
886  encipher_only = false;
887  decipher_only = false;
888  }
889 
896  bool crl_sign;
899 };
900 
912 {
913  ExtExtendedKeyUsage(bool crit=false) : ExtBase(crit)
914  {
915  oid = ExtBase::find_oid(ExtType::extended_key_usage);
916  clear();
917  }
918  virtual ~ExtExtendedKeyUsage() {}
919 
920  std::string name() const { return "ExtExtendedKeyUsage"; }
921  virtual std::string str(bool = false) const;
922  virtual void parse();
923  virtual void dump();
924  virtual bool implemented() const { return true; }
925 
926  static bool is_castable(ExtBasePtr b)
927  {
928  return typeid(*b) == typeid(ExtExtendedKeyUsage);
929  }
930  static ExtExtendedKeyUsage& cast(ExtBasePtr b)
931  {
932  if (b == nullptr || !is_castable(b)) throw std::runtime_error("ExtExtendedKeyUsage: invalid cast");
933  return *dynamic_cast<ExtExtendedKeyUsage*>(b.get());
934  }
935 
936  void clear()
937  {
938  server_auth = false;
939  client_auth = false;
940  code_signing = false;
941  email_protection = false;
942  time_stamping = false;
943  ocsp_signing = false;
944  additional_usage_ids.clear();
945  }
946 
947  bool permit_any;
948  bool server_auth;
949  bool client_auth;
954 
955  std::vector<oid_value> additional_usage_ids;
956 };
957 
958 #if 0
959 
966 class ExtSignedCertificateTimestampList : public ExtBase
967 {
968  static int struct_size(const void*, unsigned int);
969  bool add_sct(const void*, int, std::string&);
970  int dump_scts(std::vector<char>&);
971 public:
972  std::string name() const { return "ExtSignedCertificateTimestampList"; }
973  static const oid_value s_oid;
974  oid_value oid() const { return s_oid; }
975 
976  std::vector<char> val;
977 
978  enum class HashAlgorithm : int
979  {
980  none = 0,
981  md5,
982  sha1,
983  sha224,
984  sha256,
985  sha384,
986  sha512,
987  };
988 
989  enum class SigAlgorithm : int
990  {
991  anonymous = 0,
992  rsa,
993  dsa,
994  ecdsa,
995  };
996 
997  struct SCT
998  {
999  std::vector<char> log_id;
1000  uint64_t timestamp;
1001  HashAlgorithm hash;
1002  SigAlgorithm sig_algo;
1003  std::vector<char> signature;
1004  };
1005 
1006  std::vector<SCT> sct_list;
1007 
1008  std::string str() const;
1009  bool parse(std::string&);
1010  void dump();
1011 };
1012 
1014 class ExtAuthorityInformationAccess : public ExtBase
1015 {
1016 public:
1017  std::string name() const { return "ExtAuthorityInformationAccess"; }
1018  static const oid_value s_oid;
1019  oid_value oid() const { return s_oid; }
1020 
1021  DerSequence val;
1022 
1023  std::string str() const;
1024  bool parse(std::string&);
1025  void dump();
1026 };
1027 
1060 class ExtCertificatePolicies : public ExtBase
1061 {
1062 public:
1063  std::string name() const { return "ExtCertificatePolicies"; }
1064  static const oid_value s_oid;
1065  oid_value oid() const { return s_oid; }
1066 
1067  enum class PolicyQualifierId
1068  {
1069  cps,
1070  unotice,
1071  };
1072 
1073  struct DisplayText
1074  {
1075  enum Type
1076  {
1077  ia5_string,
1078  visible_string,
1079  bmp_string,
1080  utf8_string,
1081  };
1082  Type type;
1083  std::string string;
1084 
1085  DisplayText() : type(Type::ia5_string) {}
1086  };
1087 
1088  struct NoticeReference
1089  {
1090  DisplayText organization;
1091  std::vector<Bignum> notice_numbers;
1092  };
1093 
1094  struct UserNotice
1095  {
1096  NoticeReference notice_ref;
1097  DisplayText explicit_text;
1098  };
1099 
1100  struct PolicyQualifierInfo
1101  {
1102  PolicyQualifierId id;
1103  std::string cps_qual;
1104  UserNotice user_notice;
1105  };
1106 
1107  struct PolicyInfo
1108  {
1109  oid_value policy_qualifier_id;
1110  std::vector<PolicyQualifierInfo> policy_qualifiers;
1111  };
1112 
1113  std::vector<PolicyInfo> certificate_policies;
1114 
1115  //DerSequence val; ///< Does not interpret contents.
1116 
1117  std::string str() const;
1118  bool parse(std::string&);
1119  void dump();
1120 };
1121 
1123 class ExtPolicyMappings : public ExtBase
1124 {
1125 public:
1126  std::string name() const { return "ExtPolicyMappings"; }
1127  static const oid_value s_oid;
1128  oid_value oid() const { return s_oid; }
1129 
1130  DerSequence val;
1131 
1132  std::string str() const;
1133  bool parse(std::string&);
1134  void dump();
1135 };
1136 
1138 class ExtSubjectDirectoryAttributes : public ExtBase
1139 {
1140 public:
1141  std::string name() const { return "ExtSubjectDirectoryAttributes"; }
1142  static const oid_value s_oid;
1143  oid_value oid() const { return s_oid; }
1144 
1145  std::vector<std::pair<AttributeType, DirectoryString>> directory_attributes;
1146 
1147  std::string str() const;
1148  bool parse(std::string&);
1149  void dump();
1150 };
1151 
1153 class ExtNameConstraints : public ExtBase
1154 {
1155 public:
1156  std::string name() const { return "ExtNameConstraints"; }
1157  static const oid_value s_oid;
1158  oid_value oid() const { return s_oid; }
1159 
1160  DerSequence val;
1161 
1162  std::string str() const;
1163  bool parse(std::string&);
1164  void dump();
1165 };
1166 
1168 class ExtPolicyConstraints : public ExtBase
1169 {
1170 public:
1171  std::string name() const { return "ExtPolicyConstraints"; }
1172  static const oid_value s_oid;
1173  oid_value oid() const { return s_oid; }
1174 
1175  DerSequence val;
1176 
1177  std::string str() const;
1178  bool parse(std::string&);
1179  void dump();
1180 };
1181 
1183 class ExtCrlDistributionPoints : public ExtBase
1184 {
1185 public:
1186  std::string name() const { return "ExtCrlDistributionPoints"; }
1187  static const oid_value s_oid;
1188  oid_value oid() const { return s_oid; }
1189 
1190  DerSequence val;
1191 
1192  std::string str() const;
1193  bool parse(std::string&);
1194  void dump();
1195 };
1196 
1198 class ExtInhibitAnyPolicy : public ExtBase
1199 {
1200 public:
1201  std::string name() const { return "ExtInhibitAnyPolicy"; }
1202  static const oid_value s_oid;
1203  oid_value oid() const { return s_oid; }
1204 
1205  Bignum val;
1206 
1207  std::string str() const;
1208  bool parse(std::string&);
1209  void dump();
1210 };
1211 
1213 class ExtFreshestCrl : public ExtBase
1214 {
1215 public:
1216  std::string name() const { return "ExtFreshestCrl"; }
1217  static const oid_value s_oid;
1218  oid_value oid() const { return s_oid; }
1219 
1220  DerSequence val;
1221 
1222  std::string str() const;
1223  bool parse(std::string&);
1224  void dump();
1225 };
1226 
1227 
1229 class ExtSubjectInformationAccess : public ExtBase
1230 {
1231 public:
1232  std::string name() const { return "ExtSubjectInformationAccess"; }
1233  static const oid_value s_oid;
1234  oid_value oid() const { return s_oid; }
1235 
1236  DerSequence val;
1237 
1238  std::string str() const;
1239  bool parse(std::string&);
1240  void dump();
1241 };
1242 
1243 
1244 #endif
1245 
1257 enum class X509SignatureAlgo : int
1258 {
1259  unknown = 0x0,
1260  rsa_md5 = 0x01,
1261  rsa_sha1 = 0x02,
1262  rsa_sha224 = 0x03,
1263  rsa_sha256 = 0x04,
1264  rsa_sha384 = 0x05,
1265  rsa_sha512 = 0x06,
1266  ecdsa_sha1 = 0x10,
1267  ecdsa_sha224 = 0x20,
1268  ecdsa_sha256 = 0x30,
1269  ecdsa_sha384 = 0x40,
1270  ecdsa_sha512 = 0x50,
1271 };
1272 
1304 struct X509Cert
1305 {
1306  X509Cert() {}
1307  virtual ~X509Cert() {}
1308 
1310  std::vector<RelativeDistinguishedName> issuer;
1311  std::chrono::system_clock::time_point valid_start;
1312  std::chrono::system_clock::time_point valid_end;
1313  std::vector<RelativeDistinguishedName> subject;
1314  std::vector<char> issuer_unique_id;
1315  std::vector<char> subject_unique_id;
1316  std::vector<ExtBasePtr> extensions;
1317 
1318  ExtBasePtr find_ext(ExtType t) const
1319  {
1320  auto it = std::find_if(extensions.begin(), extensions.end(), [&t](auto& i)
1321  {
1322  return i->oid == ExtBase::find_oid(ExtType::subject_alternative_name);
1323  });
1324  ExtBasePtr ret;
1325  if (it != extensions.end()) ret = *it;
1326  return ret;
1327  }
1328 
1330 
1331  std::vector<char> cert_bin;
1332  oid_value sig_algo_oid;
1333  oid_value sig_algo_params;
1334  std::vector<uint8_t> signature;
1335 
1336  bool bin_compare(const X509Cert& other) const
1337  {
1338  return cert_bin == other.cert_bin;
1339  }
1340 
1341  X509SignatureAlgo sig_algo() const;
1342 
1349  void parse(const DerDocument&);
1350 
1355  std::string str(bool = false) const;
1356 
1361  bool validate(const X509Cert&) const;
1362 
1367  bool validate() const
1368  {
1369  return validate(*this);
1370  }
1371 
1377  bool validate(const RsaPublicKey&) const;
1378 
1387  bool validate(const EccGfpPoint&) const;
1388 
1390  BasePtr dump_cert() const;
1391 
1401 
1415 
1416 };
1417 
1431 struct CertBundle : std::vector<std::shared_ptr<X509Cert>>
1432 {
1433  CertBundle() {}
1434  CertBundle(std::istream& s)
1435  {
1436  parse(s);
1437  }
1438  virtual ~CertBundle() {}
1439 
1444  void parse(std::istream& s);
1445 };
1446 
1450 } // namespace
1451 
1452 std::ostream& operator<<(std::ostream&, const scc::crypto::X509Cert&);
1453 std::ostream& operator<<(std::ostream&, const scc::crypto::KeyAlgoType&);
1454 std::ostream& operator<<(std::ostream&, const scc::crypto::X509SignatureAlgo&);
1455 
1456 #endif
Big number arithmetic.
Big number.
Definition: bignum.h:59
DER document.
Definition: der.h:824
BasePtr root_ptr() const
Return the root pointer.
Definition: der.h:936
RSA Private Key.
Definition: rsa.h:185
RSA Public Key.
Definition: rsa.h:69
Distinguished encoding rules (DER).
Elliptic curve cryptography.
std::pair< oid_value, DirectoryString > RDNPair
An x.509 relative distingushed name is a set of attribute / directory string names.
Definition: cert.h:426
KeyAlgoType
Key algorithm type.
Definition: cert.h:78
X509SignatureAlgo
Signature algorithms for X.509 certificates.
Definition: cert.h:1258
AttributeType
Attribute types.
Definition: cert.h:382
@ ec_p192r1
parameter {1, 2, 840, 10045, 3, 1, 1}
Definition: cert.h:81
@ ec_p256r1
parameter {1, 2, 840, 10045, 3, 1, 7}
Definition: cert.h:83
@ ec_p384r1
parameter {1, 3, 132, 0, 34}
Definition: cert.h:84
@ rsa
parameter null
Definition: cert.h:80
@ ec_p224r1
parameter {1, 3, 132, 0, 33}
Definition: cert.h:82
@ ec_p521r1
parameter {1, 3, 132, 0, 35}
Definition: cert.h:85
@ rsa_sha512
{1, 2, 840, 113549, 1, 1, 13}
@ ecdsa_sha512
{1, 2, 840, 10045, 4, 3, 4}
@ ecdsa_sha224
{1, 2, 840, 10045, 4, 3, 1}
@ rsa_sha224
{1, 2, 840, 113549, 1, 1, 14}
@ ecdsa_sha1
{1, 2, 840, 10045, 4, 1}
@ rsa_md5
{1, 2, 840, 113549, 1, 1, 4}
@ rsa_sha1
{1, 2, 840, 113549, 1, 1, 5}
@ ecdsa_sha256
{1, 2, 840, 10045, 4, 3, 2}
@ ecdsa_sha384
{1, 2, 840, 10045, 4, 3, 3}
@ rsa_sha384
{1, 2, 840, 113549, 1, 1, 12}
@ rsa_sha256
{1, 2, 840, 113549, 1, 1, 11}
@ pseudonym
{2, 5, 4, 65} },
@ organization_id
{2, 5, 4, 97} },
@ generation_qualifier
{2, 5, 4, 44} },
@ state_or_province_name
{2, 5, 4, 8} },
@ domain_component
{ 0, 9, 2342, 19200300, 100, 1, 25 } },
@ locality_name
{2, 5, 4, 7} },
@ serial_number
{2, 5, 4, 5} },
@ street_address
{2, 5, 4, 9} },
@ given_name
{2, 5, 4, 42} },
@ name
{2, 5, 4, 41} },
@ email_address
{1, 2, 840, 113549, 1, 9, 1} },
@ country_name
{2, 5, 4, 6} },
@ dn_qualifier
{2, 5, 4, 46} },
@ organizational_unit_name
{2, 5, 4, 11} },
@ title
{2, 5, 4, 12} },
@ organization_name
{2, 5, 4, 10} },
@ surname
{2, 5, 4, 4} },
@ common_name
{2, 5, 4, 3} },
std::ostream & operator<<(std::ostream &, const scc::net::InetAddr &)
Print the socket address details to an output stream.
Definition: inet.cc:320
RSA public key cryptography.
Certificate bundle.
Definition: cert.h:1432
void parse(std::istream &s)
Parse bundle from stream.
An x.509 directory string is used to store generic names.
Definition: cert.h:326
std::string str() const
Descriptive string <chars> <type>.
int compare(const DirectoryString &b) const
Compare two directory strings.
Definition: cert.h:355
void parse(BasePtr)
Parse the string from a base object.
From: https://tools.ietf.org/html/rfc3279#section-2.3.5.
Definition: cert.h:210
static void parse(const BasePtr &, KeyAlgoType &)
Parse from an object id.
Definition: cert.cc:313
static BasePtr dump(const KeyAlgoType &)
Dump to an object id.
Definition: cert.cc:326
Private key certificate utility.
Definition: cert.h:298
static BasePtr dump(const Bignum &, const KeyAlgoType &, const EccGfpPoint &)
Dump to a sequence.
Definition: cert.cc:431
static void parse(const BasePtr &, Bignum &, KeyAlgoType &, EccGfpPoint &)
Parse from a sequence.
Definition: cert.cc:405
Elliptic curve public key.
Definition: cert.h:248
static void parse(const BasePtr &, const KeyAlgoType &, EccGfpPoint &)
Parse from a bit string for a specific curve.
Definition: cert.cc:366
static BasePtr dump(const EccGfpPoint &)
Dump to an uncompressed bit string.
Definition: cert.cc:375
Authority key identifier.
Definition: cert.h:705
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
virtual void dump()
Dump sub-class data into the value.
std::vector< char > key_identifier
Identifies the private key used to sign.
Definition: cert.h:728
std::string name() const
Return the name of the extension.
Definition: cert.h:712
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:716
Bignum authority_cert_serial_number
Serial number of the certificate.
Definition: cert.h:730
std::vector< GeneralName > authority_cert_issuer
Certificate issuer.
Definition: cert.h:729
virtual void parse()
Parse value into the the local sub-class data.
X.509 extensions.
Definition: cert.h:621
virtual void parse()
Parse value into the the local sub-class data.
Definition: cert.h:634
oid_value oid
The oid of the extension.
Definition: cert.h:622
BasePtr dump_seq()
Dump the extension into an Extension sequence.
static ExtBasePtr create(BasePtr)
Create an extension.
virtual std::string name() const
Return the name of the extension.
Definition: cert.h:630
bool critical
Is the extension marked critical? If a CRL contains a critical extension that cannot be processed,...
Definition: cert.h:623
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
BasePtr value
Parsed extension value.
Definition: cert.h:624
static oid_value find_oid(ExtType)
Find the oid associated with the extension type.
virtual void dump()
Dump sub-class data into the value.
Definition: cert.h:636
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:641
Basic constraints.
Definition: cert.h:811
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:822
std::string name() const
Return the name of the extension.
Definition: cert.h:818
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
virtual void dump()
Dump sub-class data into the value.
virtual void parse()
Parse value into the the local sub-class data.
bool conditional_access
Is this a conditional access certificate? If so, the public key can be used to verify certificate.
Definition: cert.h:834
Bignum max_path_len
If conditional access, the maximum number of intermediate certificates in the certification path.
Definition: cert.h:835
Extended key usage.
Definition: cert.h:912
bool server_auth
TLS WWW server auth. Consistent with digital_signature, key_encipherment, key_agreement.
Definition: cert.h:948
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:924
std::vector< oid_value > additional_usage_ids
Key usage ids not in the list above.
Definition: cert.h:955
bool client_auth
TLS WWW client auth. Consistent with digital_signature, key_agreement.
Definition: cert.h:949
virtual void dump()
Dump sub-class data into the value.
virtual void parse()
Parse value into the the local sub-class data.
std::string name() const
Return the name of the extension.
Definition: cert.h:920
bool time_stamping
Binding the hash of an object to a time. Consistent with digital_signature, content_commitment.
Definition: cert.h:952
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
bool code_signing
Signing of downloadable code. Consistent with digital_signature.
Definition: cert.h:950
bool ocsp_signing
Signing OCSP responses. Consistent with digital_signature, content_commitment.
Definition: cert.h:953
bool email_protection
Email protection. Consistent with digital_signature, content_commitment, key_encipherment,...
Definition: cert.h:951
bool permit_any
Permit any usage. Used for applications that must include this extension, but do not wish to specify ...
Definition: cert.h:947
Issuer alternative name.
Definition: cert.h:774
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:785
virtual void dump()
Dump sub-class data into the value.
std::string name() const
Return the name of the extension.
Definition: cert.h:781
virtual void parse()
Parse value into the the local sub-class data.
bool digital_signature
Public key is used for verifying digital signatures other than certificates and CRLs.
Definition: cert.h:890
std::string name() const
Return the name of the extension.
Definition: cert.h:861
virtual void dump()
Dump sub-class data into the value.
bool key_cert_sign
Public key is used for verifying signatures on public key certificates. ExtBasicConstraints condition...
Definition: cert.h:895
bool data_encipherment
Public key is used to encipher data. This should be rare, as most applications will use key transport...
Definition: cert.h:893
bool decipher_only
If key_agreement set, public key can only be used for deciphering data while performing key agreement...
Definition: cert.h:898
virtual void parse()
Parse value into the the local sub-class data.
bool encipher_only
If key_agreement set, public key can only be used for enciphering data while performing key agreement...
Definition: cert.h:897
bool key_encipherment
Public key is used to encipher private keys, e.g. in key transport.
Definition: cert.h:892
bool key_agreement
Public key is used for key agreement, e.g. Diffie-Hellman key management.
Definition: cert.h:894
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
bool content_commitment
Public key is used for verifying digital signatures in a content commitment (non-repudiation) service...
Definition: cert.h:891
bool crl_sign
Public key is used for verifying certificates on certificate revocation lists, e.g....
Definition: cert.h:896
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:865
Subject alternative name.
Definition: cert.h:666
std::vector< GeneralName > names
Alternative names.
Definition: cert.h:689
std::string name() const
Return the name of the extension.
Definition: cert.h:673
virtual void parse()
Parse value into the the local sub-class data.
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:677
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
virtual void dump()
Dump sub-class data into the value.
Subject key identifier.
Definition: cert.h:741
std::string name() const
Return the name of the extension.
Definition: cert.h:748
virtual std::string str(bool=false) const
Print to string, optionally printing the value.
virtual bool implemented() const
Is this implemented (sub-classed)?
Definition: cert.h:752
virtual void dump()
Dump sub-class data into the value.
virtual void parse()
Parse value into the the local sub-class data.
General name.
Definition: cert.h:511
GeneralName(Type t=Type::directory_name)
Create the base sequence.
void parse(BasePtr)
Parse an input as an implicit element (must have id corresponding to the type above.
Type type
Value type.
Definition: cert.h:525
BasePtr dump()
Reset the base pointer and dump the element to a context-class element.
std::string str(bool=false) const
Print contents.
Public key information certificate.
Definition: cert.h:105
BasePtr dump() const
Dump to a sequence.
Definition: cert.cc:133
void parse(const BasePtr)
Parse from a sequence.
Definition: cert.cc:101
void set(const RsaPublicKey &key)
Set rsa public key.
Definition: cert.cc:181
KeyAlgoType type() const
Return the embedded public key type.
Definition: cert.cc:82
std::vector< uint8_t > public_key
The uninterpreted public key.
Definition: cert.h:111
BasePtr parameters
The optional parameters (may be null)
Definition: cert.h:110
std::string str() const
Print descriptive string.
Definition: cert.cc:159
oid_value algorithm_id
Algorithm id.
Definition: cert.h:109
void get(RsaPublicKey &key) const
Get rsa public key.
Definition: cert.cc:172
void parse(BasePtr)
Parse from RelativeDistinguishedName.
BasePtr dump() const
Dump and return an element of type set.
std::string str() const
Print contents.
RSA private key certificate.
Definition: cert.h:184
static BasePtr dump(const RsaPrivateKey &)
Dump to a sequence.
Definition: cert.cc:280
static void parse(const BasePtr &, RsaPrivateKey &)
Parse from a sequence.
Definition: cert.cc:259
RSA public key certificate.
Definition: cert.h:152
static BasePtr dump(const RsaPublicKey &)
Dump to a sequence.
Definition: cert.cc:241
static void parse(const BasePtr &, RsaPublicKey &)
Parse from a sequence.
Definition: cert.cc:228
X.509 certificate.
Definition: cert.h:1305
Bignum serial_number
The certificate serial number.
Definition: cert.h:1309
std::vector< char > subject_unique_id
Subject unique id. Optional: size 0 means not present.
Definition: cert.h:1315
std::vector< ExtBasePtr > extensions
Extensions.
Definition: cert.h:1316
std::vector< RelativeDistinguishedName > issuer
Issuer name.
Definition: cert.h:1310
std::vector< char > issuer_unique_id
Issuer unique id. Optional: size 0 means not present.
Definition: cert.h:1314
bool validate(const X509Cert &) const
Validate this certificate against another.
BasePtr dump_cert() const
Dump the certificate to a sequence.
std::string str(bool=false) const
Descriptive string.
bool validate(const EccGfpPoint &) const
Validate signature against an ECDSA algorithm and public key.
oid_value sig_algo_oid
Algorithm used to sign this certificate.
Definition: cert.h:1332
bool validate() const
Validate this certificate against it's own public key.
Definition: cert.h:1367
PublicKeyCert public_key
Certificate owner's public key.
Definition: cert.h:1329
void sign_and_dump(DerDocument &, const KeyAlgoType &, const Bignum &, Bignum &, const X509SignatureAlgo &)
Sign the certificate and dump to a document using the ECDSA signature algorithm.
std::chrono::system_clock::time_point valid_end
Time after which this certificate is invalid.
Definition: cert.h:1312
void sign_and_dump(DerDocument &, const RsaPrivateKey &, const X509SignatureAlgo &)
Sign the certificate and dump to a document using the RSA signature algorithm.
oid_value sig_algo_params
Signature algorithm parameters.
Definition: cert.h:1333
std::chrono::system_clock::time_point valid_start
Time before which this certificate is invalid.
Definition: cert.h:1311
bool validate(const RsaPublicKey &) const
Validate signature against an RSA public key.
std::vector< uint8_t > signature
Digital signature of this certificate signed using the issuer's private key.
Definition: cert.h:1334
void parse(const DerDocument &)
Parse from a document.
std::vector< RelativeDistinguishedName > subject
Subject name.
Definition: cert.h:1313
std::vector< char > cert_bin
Binary form of certificate from latest dump() or parse(), signed by the issuer.
Definition: cert.h:1331