36 #include <system_error>
40 using namespace scc::crypto;
42 static void throw_err(
const std::string& msg)
44 throw std::runtime_error(msg);
47 static oid_value s_rsa_key = {1, 2, 840, 113549, 1, 1, 1};
48 static oid_value s_ec_key = {1, 2, 840, 10045, 2, 1};
49 static std::map<KeyAlgoType, oid_value> s_ec_param =
66 s <<
"ecdsa 192";
break;
68 s <<
"ecdsa 224";
break;
70 s <<
"ecdsa 256";
break;
72 s <<
"ecdsa 384";
break;
74 s <<
"ecdsa 521";
break;
75 case KeyAlgoType::unknown:
76 s <<
"unknown";
break;
78 os.write(s.str().c_str(), s.str().size());
90 auto it = std::find_if(s_ec_param.begin(), s_ec_param.end(), [&](
auto& i)
92 return parameters->object_id() == i.second;
95 if (it != s_ec_param.end())
return it->first;
98 return KeyAlgoType::unknown;
107 if (!base || !base->is_seq()) throw_err(
"PublicKeyInfoCert parse: base not a sequence");
108 if (base->contain().size() != 2 ) throw_err(
"PublicKeyInfoCert parse: wrong base sequence size");
110 if (!base->contain()[0]->is_seq()) throw_err(
"PublicKeyInfoCert parse: missing algorithm id element");
111 if (!base->contain()[1]->is_bit_string()) throw_err(
"PublicKeyInfoCert parse: missing public key element");
113 auto& seq = base->contain()[0]->contain();
115 if (!seq.size() || seq.size() > 2) throw_err(
"PublicKeyInfoCert parse: algorithm id empty");
117 if (!seq[0]->is_object_id()) throw_err(
"PublicKeyInfoCert parse: algorithm element not oid");
129 auto bits = base->contain()[1]->bit_string();
139 seq->emplace_back(algseq);
142 algseq->emplace_back(oid);
153 seq->emplace_back(bits);
198 if (t == KeyAlgoType::unknown || t ==
KeyAlgoType::rsa) throw_err(
"PublicKeyCert get ec: wrong algorithm type");
209 if (algo == KeyAlgoType::unknown || algo ==
KeyAlgoType::rsa) throw_err(
"PublicKeyCert set ec: wrong algorithm type");
215 auto it = s_ec_param.find(algo);
216 if (it == s_ec_param.end()) throw_err(
"PublicKeyCert set ec: algorithm error");
217 oid->data() = it->second;
230 if (!base || !base->is_seq()) throw_err(
"rsa pub cert parse: base element not sequence");
232 auto& seq = base->contain();
234 if (seq.size() != 2) throw_err(
"rsa pub cert parse: size error");
236 if (!seq[0]->is_integer() || !seq[1]->is_integer()) throw_err(
"rsa pub cert parse: element error");
238 key.set(seq[0]->integer(), seq[1]->integer());
261 if (!base || !base->is_seq()) throw_err(
"rsa priv cert parse: base element not sequence");
263 auto seq = base->contain();
265 if (seq.size() != 9) throw_err(
"rsa priv cert parse: size error");
267 if ( !seq[0]->is_integer() || !seq[1]->is_integer() || !seq[2]->is_integer()
268 || !seq[3]->is_integer() || !seq[4]->is_integer() || !seq[5]->is_integer()
269 || !seq[6]->is_integer() || !seq[7]->is_integer() || !seq[8]->is_integer())
271 throw_err(
"private key parse: data type error");
274 if (seq[0]->integer() != 0) throw_err(
"private key parse: version error");
276 key.set(seq[1]->integer(), seq[2]->integer(), seq[3]->integer(), seq[4]->integer(),
277 seq[5]->integer(), seq[6]->integer(), seq[7]->integer(), seq[8]->integer());
282 Bignum n, e, d, p, q, ep, eq, qinv;
283 key.get(n, e, d, p, q, ep, eq, qinv);
291 seq->emplace_back(ver_p);
292 seq->emplace_back(n_p);
293 seq->emplace_back(e_p);
294 seq->emplace_back(d_p);
295 seq->emplace_back(p_p);
296 seq->emplace_back(q_p);
297 seq->emplace_back(ep_p);
298 seq->emplace_back(eq_p);
299 seq->emplace_back(qinv_p);
308 qinv_p->
data() = qinv;
315 if (!b || !b->is_object_id()) throw_err(
"ec params parse: base element not oid");
317 auto it = std::find_if(s_ec_param.begin(), s_ec_param.end(), [&b](
auto& i)
319 return b->object_id() == i.second;
322 if (it != s_ec_param.end()) algo = it->first;
323 else algo = KeyAlgoType::unknown;
328 auto it = s_ec_param.find(algo);
330 if (it == s_ec_param.end()) throw_err(
"ec params dump: invalid algorithm");
334 oid->data() = it->second;
341 char* b = (
char*)loc;
343 if (len < 2 || b ==
nullptr || *b !=
'\x04') throw_err(
"ec public key parse: data error");
359 case KeyAlgoType::unknown:
360 throw_err(
"ec public key parse: invalid algorithm");
363 pub.
set(b+1, len-1, curve);
368 if (!b || !b->is_bit_string()) throw_err(
"ec public key parse: not bit string");
371 b->bit_string().get(v);
380 v.insert(v.begin(),
'\x04');
384 bst->set(v, v.size()*8);
393 v.insert(v.begin(),
'\x04');
396 uv.insert(uv.begin(), v.begin(), v.end());
402 v.insert(v.begin(),
'\x04');
407 if (!b || !b->is_seq()) throw_err(
"ec private parse: base not sequence");
409 if (b->contain().size() != 4) throw_err(
"ec private parse: wrong sequence size");
411 auto& seq = b->contain();
413 if (!seq[0]->is_integer() || seq[0]->integer() != 1) throw_err(
"ec private parse: version error");
415 if (!seq[1]->is_octet_string()) throw_err(
"ec private parse: private key error");
418 seq[1]->string_get(v);
420 priv.
set(v.data(), v.size());
422 if (!seq[2]->context_class() || seq[2]->
id() != 0) throw_err(
"ec private parse: param error");
426 if (!seq[3]->context_class() || seq[3]->
id() != 1) throw_err(
"ec private parse: pub key error");
437 seq->emplace_back(ver);
442 priv.
get(v.data(), v.size());
444 seq->emplace_back(pk);
X.509 and RSA certificates.
void get(void *, int) const
Octal (byte) output of a positive number.
void set(uint32_t)
Set to a word.
int len() const
Required length of get() output in bytes.
void set(const std::vector< uint8_t > &v, size_t w)
Set the bit string from a bit string input.
static BasePtr explicit_to_context(const BasePtr &BasePtr, uint32_t)
Convert explicit to context.
static BasePtr context_to_explicit(const BasePtr &)
Change a context element to explicit.
static void dump_element(const BasePtr &, std::vector< uint8_t > &)
Dump an element to a data vector.
static BasePtr parse_element(const std::vector< uint8_t > &, size_t=0)
Parse an element from a data vector.
scc::crypto::Bignum & data()
Return the integer (an scc::crypto::Bignum)
void set(const oid_value &v)
Set oid values.
An ASN.1 SEQUENCE or SEQUENCE OF type.
void get(scc::crypto::Bignum &, scc::crypto::Bignum &) const
Get the coordinates.
void set(const scc::crypto::Bignum &, const scc::crypto::Bignum &)
Set point.
Elliptic curve cryptography over Galois prime field GF(p) curve.
void reset(Type type)
Reset the curve to a new standard type.
@ std_p224r1
standard curve secp224r1 (112 bit security level)
@ std_p192r1
standard curve secp192r1 (96 bit security level)
@ std_p256r1
standard curve secp256r1 (128 bit security level)
@ std_p521r1
standard curve secp521r1 (256 bit security level)
@ std_p384r1
standard curve secp384r1 (192 bit security level)
void resize(typename std::vector< T >::size_type)
Resize the vector.
void clear() noexcept
Zero the original vector and clear it.
KeyAlgoType
Key algorithm type.
@ ec_p192r1
parameter {1, 2, 840, 10045, 3, 1, 1}
@ ec_p256r1
parameter {1, 2, 840, 10045, 3, 1, 7}
@ ec_p384r1
parameter {1, 3, 132, 0, 34}
@ ec_p224r1
parameter {1, 3, 132, 0, 33}
@ ec_p521r1
parameter {1, 3, 132, 0, 35}
Binary to hex string converter.
std::ostream & operator<<(std::ostream &, const scc::net::InetAddr &)
Print the socket address details to an output stream.
static void parse(const BasePtr &, KeyAlgoType &)
Parse from an object id.
static BasePtr dump(const KeyAlgoType &)
Dump to an object id.
static BasePtr dump(const Bignum &, const KeyAlgoType &, const EccGfpPoint &)
Dump to a sequence.
static void parse(const BasePtr &, Bignum &, KeyAlgoType &, EccGfpPoint &)
Parse from a sequence.
static void parse(const BasePtr &, const KeyAlgoType &, EccGfpPoint &)
Parse from a bit string for a specific curve.
static BasePtr dump(const EccGfpPoint &)
Dump to an uncompressed bit string.
BasePtr dump() const
Dump to a sequence.
void parse(const BasePtr)
Parse from a sequence.
void set(const RsaPublicKey &key)
Set rsa public key.
KeyAlgoType type() const
Return the embedded public key type.
std::vector< uint8_t > public_key
The uninterpreted public key.
BasePtr parameters
The optional parameters (may be null)
std::string str() const
Print descriptive string.
oid_value algorithm_id
Algorithm id.
void get(RsaPublicKey &key) const
Get rsa public key.
static BasePtr dump(const RsaPrivateKey &)
Dump to a sequence.
static void parse(const BasePtr &, RsaPrivateKey &)
Parse from a sequence.
static BasePtr dump(const RsaPublicKey &)
Dump to a sequence.
static void parse(const BasePtr &, RsaPublicKey &)
Parse from a sequence.