AuroraRuntime/Source/Extensions/LTC/LTCExport.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;
}
}