|
@@ -0,0 +1,97 @@
|
|
|
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
|
|
+ *
|
|
|
+ * LibTomCrypt is a library that provides various cryptographic
|
|
|
+ * algorithms in a highly modular and flexible manner.
|
|
|
+ *
|
|
|
+ * The library is free for all purposes without any express
|
|
|
+ * guarantee it works.
|
|
|
+ */
|
|
|
+#include "tomcrypt_private.h"
|
|
|
+
|
|
|
+/**
|
|
|
+ @file ec25519_import_pkcs8.c
|
|
|
+ Generic import of a Curve/Ed25519 private key in PKCS#8 format, Steffen Jaeckel
|
|
|
+*/
|
|
|
+
|
|
|
+#ifdef LTC_CURVE25519
|
|
|
+
|
|
|
+/**
|
|
|
+ Generic import of a Curve/Ed25519 private key in PKCS#8 format
|
|
|
+ @param in The DER-encoded PKCS#8-formatted private key
|
|
|
+ @param inlen The length of the input data
|
|
|
+ @param passwd The password to decrypt the private key
|
|
|
+ @param passwdlen Password's length (octets)
|
|
|
+ @param key [out] Where to import the key to
|
|
|
+ @return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
|
|
+*/
|
|
|
+int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
|
|
+ const void *pwd, unsigned long pwdlen,
|
|
|
+ enum ltc_oid_id id, sk_to_pk fp,
|
|
|
+ curve25519_key *key)
|
|
|
+{
|
|
|
+ int err = CRYPT_INVALID_ARG;
|
|
|
+ ltc_asn1_list *l = NULL;
|
|
|
+ const char *oid;
|
|
|
+ ltc_asn1_list alg_id[1];
|
|
|
+ unsigned char private_key[34];
|
|
|
+ unsigned long version, key_len;
|
|
|
+ unsigned long tmpoid[16];
|
|
|
+
|
|
|
+ LTC_ARGCHK(in != NULL);
|
|
|
+ LTC_ARGCHK(key != NULL);
|
|
|
+ LTC_ARGCHK(fp != NULL);
|
|
|
+
|
|
|
+ if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {
|
|
|
+
|
|
|
+ LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid) / sizeof(tmpoid[0]));
|
|
|
+
|
|
|
+ key_len = sizeof(private_key);
|
|
|
+ if ((err = der_decode_sequence_multi(l->data, l->size,
|
|
|
+ LTC_ASN1_SHORT_INTEGER, 1uL, &version,
|
|
|
+ LTC_ASN1_SEQUENCE, 1uL, alg_id,
|
|
|
+ LTC_ASN1_OCTET_STRING, key_len, private_key,
|
|
|
+ LTC_ASN1_EOL, 0uL, NULL))
|
|
|
+ != CRYPT_OK) {
|
|
|
+ /* If there are attributes added after the private_key it is tagged with version 1 and
|
|
|
+ * we get an 'input too long' error but the rest is already decoded and can be
|
|
|
+ * handled the same as for version 0
|
|
|
+ */
|
|
|
+ if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
|
|
|
+ version = 0;
|
|
|
+ } else {
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((err = pk_get_oid(id, &oid)) != CRYPT_OK) {
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (version == 0) {
|
|
|
+ key_len = sizeof(key->priv);
|
|
|
+ if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
|
|
|
+ fp(key->pub, key->priv);
|
|
|
+ key->type = PK_PRIVATE;
|
|
|
+ key->algo = id;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ err = CRYPT_PK_INVALID_TYPE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+out:
|
|
|
+ if (l) der_free_sequence_flexi(l);
|
|
|
+#ifdef LTC_CLEAN_STACK
|
|
|
+ zeromem(private_key, sizeof(private_key));
|
|
|
+#endif
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+/* ref: $Format:%D$ */
|
|
|
+/* git commit: $Format:%H$ */
|
|
|
+/* commit time: $Format:%ai$ */
|