124 lines
3.8 KiB
C
124 lines
3.8 KiB
C
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: LTCExport.c
|
|
Date: 2021-6-24
|
|
Author: Reece
|
|
***/
|
|
#include "tomcrypt_private.h"
|
|
#include "LTCExtensions.h"
|
|
|
|
int rsa_basic_export(unsigned char *out, unsigned long *outlen, const rsa_key *key, int flags)
|
|
{
|
|
unsigned long zero = 0;
|
|
LTC_ARGCHK(out != NULL);
|
|
LTC_ARGCHK(outlen != NULL);
|
|
LTC_ARGCHK(key != NULL);
|
|
|
|
|
|
if ((flags & kRsaFlagPublic) == 0)
|
|
{
|
|
if (key->type == PK_PUBLIC)
|
|
{
|
|
return CRYPT_INVALID_ARG;
|
|
}
|
|
|
|
/* private key */
|
|
/* output is
|
|
Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p
|
|
*/
|
|
return der_encode_sequence_multi(out, outlen,
|
|
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
|
|
LTC_ASN1_INTEGER, 1UL, key->N,
|
|
LTC_ASN1_INTEGER, 1UL, key->e,
|
|
LTC_ASN1_INTEGER, 1UL, key->d,
|
|
LTC_ASN1_INTEGER, 1UL, key->p,
|
|
LTC_ASN1_INTEGER, 1UL, key->q,
|
|
LTC_ASN1_INTEGER, 1UL, key->dP,
|
|
LTC_ASN1_INTEGER, 1UL, key->dQ,
|
|
LTC_ASN1_INTEGER, 1UL, key->qP,
|
|
LTC_ASN1_EOL, 0UL, NULL);
|
|
}
|
|
else
|
|
{
|
|
/* public key */
|
|
|
|
return der_encode_sequence_multi(out, outlen,
|
|
LTC_ASN1_INTEGER, 1UL, key->N,
|
|
LTC_ASN1_INTEGER, 1UL, key->e,
|
|
LTC_ASN1_EOL, 0UL, NULL);
|
|
}
|
|
}
|
|
|
|
int rsa_pkcs8_export(unsigned char *out, unsigned long *outlen, const rsa_key * key, int flags)
|
|
{
|
|
int ret;
|
|
char temp[4096];
|
|
unsigned long length = sizeof(temp);
|
|
|
|
if ((ret = rsa_basic_export(temp, &length, key, flags)) != CRYPT_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
if ((flags & kRsaFlagPKCS1) != 0)
|
|
{
|
|
*outlen = length;
|
|
if (*outlen < length)
|
|
{
|
|
return CRYPT_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
memcpy(out, temp, length);
|
|
return CRYPT_OK;
|
|
}
|
|
else
|
|
{
|
|
unsigned long oid[16];
|
|
const char *oidReference;
|
|
|
|
ret = pk_get_oid(PKA_RSA, &oidReference);
|
|
if (ret != CRYPT_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
unsigned long oidArraySize = 16;
|
|
ret = pk_oid_str_to_num(oidReference, oid, &oidArraySize);
|
|
if (ret != CRYPT_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
if ((flags & kRsaFlagPublic) == 0)
|
|
{
|
|
if (key->type == PK_PUBLIC)
|
|
{
|
|
return CRYPT_INVALID_ARG;
|
|
}
|
|
|
|
ltc_asn1_list alg_seq[2], top_seq[3];
|
|
unsigned long zero = 0;
|
|
|
|
LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidArraySize);
|
|
LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_NULL, NULL, 0UL);
|
|
LTC_SET_ASN1(top_seq, 0, LTC_ASN1_SHORT_INTEGER, &zero, 1UL);
|
|
LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL);
|
|
LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, temp, length);
|
|
ret = der_encode_sequence(top_seq, 3, out, outlen);
|
|
}
|
|
else
|
|
{
|
|
ltc_asn1_list alg_seq[2];
|
|
LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidArraySize);
|
|
// TODO: return false?
|
|
ret = der_encode_sequence_multi(out, outlen,
|
|
LTC_ASN1_SEQUENCE, 1, alg_seq,
|
|
LTC_ASN1_BIT_STRING, length, temp,
|
|
LTC_ASN1_EOL, 0UL, NULL);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
}
|