From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/Runtime/common/crypto/key.cpp | 557 +++++++++++++++++++++++++++++++++ 1 file changed, 557 insertions(+) create mode 100644 src/VBox/Runtime/common/crypto/key.cpp (limited to 'src/VBox/Runtime/common/crypto/key.cpp') diff --git a/src/VBox/Runtime/common/crypto/key.cpp b/src/VBox/Runtime/common/crypto/key.cpp new file mode 100644 index 00000000..e3c68e75 --- /dev/null +++ b/src/VBox/Runtime/common/crypto/key.cpp @@ -0,0 +1,557 @@ +/* $Id: key.cpp $ */ +/** @file + * IPRT - Crypto - Cryptographic Keys. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#define LOG_GROUP RTLOGGROUP_CRYPTO +#include "internal/iprt.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal/magics.h" +#include "key-internal.h" + + +/** + * Internal crypto key instance creator. + * + * This does most of the common work, caller does the 'u' and cBits jobs. + * + * @returns IPRT status code. + * @param ppThis Where to return the key instance. + * @param enmType The key type. + * @param fFlags The key flags. + * @param pvEncoded The encoded key bits. + * @param cbEncoded The size of the encoded key bits (in bytes). + */ +DECLHIDDEN(int) rtCrKeyCreateWorker(PRTCRKEYINT *ppThis, RTCRKEYTYPE enmType, uint32_t fFlags, + void const *pvEncoded, uint32_t cbEncoded) +{ + PRTCRKEYINT pThis = (PRTCRKEYINT)RTMemAllocZ(sizeof(*pThis) + (fFlags & RTCRKEYINT_F_SENSITIVE ? 0 : cbEncoded)); + if (pThis) + { + pThis->enmType = enmType; + pThis->fFlags = fFlags; +#if defined(IPRT_WITH_OPENSSL) + pThis->fFlags |= RTCRKEYINT_F_INCLUDE_ENCODED; + pThis->cbEncoded = cbEncoded; + if (!(fFlags & RTCRKEYINT_F_SENSITIVE)) + pThis->pbEncoded = (uint8_t *)(pThis + 1); + else + { + pThis->pbEncoded = (uint8_t *)RTMemSaferAllocZ(cbEncoded); + if (!pThis->pbEncoded) + { + RTMemFree(pThis); + return VERR_NO_MEMORY; + } + } + memcpy(pThis->pbEncoded, pvEncoded, cbEncoded); +#else + RT_NOREF(pvEncoded, cbEncoded); +#endif + pThis->cRefs = 1; + pThis->u32Magic = RTCRKEYINT_MAGIC; + *ppThis = pThis; + return VINF_SUCCESS; + } + return VERR_NO_MEMORY; +} + + +/** + * Creates an RSA public key from a DER encoded RTCRRSAPUBLICKEY blob. + * + * @returns IPRT status code. + * @param phKey Where to return the key handle. + * @param pvKeyBits The DER encoded RTCRRSAPUBLICKEY blob. + * @param cbKeyBits The size of the blob. + * @param pErrInfo Where to supply addition error details. Optional. + * @param pszErrorTag Error tag. Optional. + */ +DECLHIDDEN(int) rtCrKeyCreateRsaPublic(PRTCRKEY phKey, const void *pvKeyBits, uint32_t cbKeyBits, + PRTERRINFO pErrInfo, const char *pszErrorTag) +{ + /* + * Decode the key data first since that's what's most likely to fail here. + */ + RTASN1CURSORPRIMARY PrimaryCursor; + RTAsn1CursorInitPrimary(&PrimaryCursor, pvKeyBits, cbKeyBits, pErrInfo, &g_RTAsn1DefaultAllocator, + RTASN1CURSOR_FLAGS_DER, pszErrorTag ? pszErrorTag : "rsa"); + RTCRRSAPUBLICKEY PublicKey; + RT_ZERO(PublicKey); + int rc = RTCrRsaPublicKey_DecodeAsn1(&PrimaryCursor.Cursor, 0, &PublicKey, pszErrorTag ? pszErrorTag : "PublicKey"); + if (RT_SUCCESS(rc)) + { + /* + * Create a key instance for it. + */ + PRTCRKEYINT pThis; + rc = rtCrKeyCreateWorker(&pThis, RTCRKEYTYPE_RSA_PUBLIC, RTCRKEYINT_F_PUBLIC, pvKeyBits, cbKeyBits); + if (RT_SUCCESS(rc)) + { + rc = RTAsn1Integer_ToBigNum(&PublicKey.Modulus, &pThis->u.RsaPublic.Modulus, 0); + if (RT_SUCCESS(rc)) + { + pThis->cBits = RTBigNumBitWidth(&pThis->u.RsaPublic.Modulus); + rc = RTAsn1Integer_ToBigNum(&PublicKey.PublicExponent, &pThis->u.RsaPublic.Exponent, 0); + if (RT_SUCCESS(rc)) + { + + /* Done. */ + RTAsn1VtDelete(&PublicKey.SeqCore.Asn1Core); + *phKey = pThis; + return VINF_SUCCESS; + } + } + RTCrKeyRelease(pThis); + } + RTAsn1VtDelete(&PublicKey.SeqCore.Asn1Core); + } + *phKey = NIL_RTCRKEY; + return rc; +} + + +/** + * Creates an EC (ECDSA) public key from a DER encoded RTCRX50-PUBLICKEY blob. + * + * @returns IPRT status code. + * @param phKey Where to return the key handle. + * @param pParameters The algorithm parameters, typically namedCurve OID. + * @param pvKeyBits The DER encoded RTCRRSAPUBLICKEY blob. + * @param cbKeyBits The size of the blob. + * @param pErrInfo Where to supply addition error details. Optional. + * @param pszErrorTag Error tag. Optional. + */ +DECLHIDDEN(int) rtCrKeyCreateEcdsaPublic(PRTCRKEY phKey, PCRTASN1DYNTYPE pParameters, const void *pvKeyBits, uint32_t cbKeyBits, + PRTERRINFO pErrInfo, const char *pszErrorTag) +{ +#if 0 + /* + * Decode the key data first since that's what's most likely to fail here. + */ + RTASN1CURSORPRIMARY PrimaryCursor; + RTAsn1CursorInitPrimary(&PrimaryCursor, pvKeyBits, cbKeyBits, pErrInfo, &g_RTAsn1DefaultAllocator, + RTASN1CURSOR_FLAGS_DER, pszErrorTag ? pszErrorTag : "rsa"); + RTCRRSAPUBLICKEY PublicKey; + RT_ZERO(PublicKey); + int rc = RTCrRsaPublicKey_DecodeAsn1(&PrimaryCursor.Cursor, 0, &PublicKey, pszErrorTag ? pszErrorTag : "PublicKey"); +#else + RT_NOREF(pszErrorTag); + int rc = VINF_SUCCESS; +#endif + if (RT_SUCCESS(rc)) + { + /* + * Check the parameter (see RTC-5480, section 2.1.1). + */ + if ( pParameters + && pParameters->enmType == RTASN1TYPE_OBJID + && RTAsn1ObjId_IsPresent(&pParameters->u.ObjId) /* paranoia */) + { + /* + * Create a key instance for it. + */ + PRTCRKEYINT pThis; + rc = rtCrKeyCreateWorker(&pThis, RTCRKEYTYPE_ECDSA_PUBLIC, RTCRKEYINT_F_PUBLIC, pvKeyBits, cbKeyBits); + if (RT_SUCCESS(rc)) + { + rc = RTAsn1ObjId_Clone(&pThis->u.EcdsaPublic.NamedCurve, &pParameters->u.ObjId, &g_RTAsn1DefaultAllocator); + if (RT_SUCCESS(rc)) + { + /* Done. */ +#if 0 + RTAsn1VtDelete(&PublicKey.SeqCore.Asn1Core); +#endif + *phKey = pThis; + return VINF_SUCCESS; + } + RTCrKeyRelease(pThis); + } + } + else if (!pParameters || pParameters->enmType == RTASN1TYPE_NOT_PRESENT) + rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_MISSING, + "%s: ECDSA public key expected a namedCurve parameter", pszErrorTag); + else if (pParameters->enmType == RTASN1TYPE_NULL) + rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNKNOWN, + "%s: ECDSA public key expected a namedCurve parameter, found implicitCurve (NULL) instead", + pszErrorTag); + else + rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNKNOWN, + "%s: ECDSA public key expected namedCurve parameter, found %d", + pszErrorTag, pParameters->enmType); +#if 0 + RTAsn1VtDelete(&PublicKey.SeqCore.Asn1Core); +#endif + } + *phKey = NIL_RTCRKEY; + return rc; +} + + +RTDECL(int) RTCrKeyCreateFromPublicAlgorithmAndBits(PRTCRKEY phKey, PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters, + PCRTASN1BITSTRING pPublicKey, PRTERRINFO pErrInfo, const char *pszErrorTag) +{ + /* + * Validate input. + */ + AssertPtrReturn(phKey, VERR_INVALID_POINTER); + *phKey = NIL_RTCRKEY; + + AssertPtrReturn(pAlgorithm, VERR_INVALID_POINTER); + AssertReturn(RTAsn1ObjId_IsPresent(pAlgorithm), VERR_INVALID_PARAMETER); + + AssertPtrReturn(pPublicKey, VERR_INVALID_POINTER); + AssertReturn(RTAsn1BitString_IsPresent(pPublicKey), VERR_INVALID_PARAMETER); + + /* + * Identify the key type from the algorithm ID + */ + const char * const pszEncryptionOid = RTCrX509AlgorithmIdentifier_GetEncryptionOidFromOid(pAlgorithm->szObjId, + false /*fMustIncludeHash*/); + if (pszEncryptionOid) + { + if (strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_RSA) == 0) + return rtCrKeyCreateRsaPublic(phKey, + RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey), + RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey), + pErrInfo, pszErrorTag); + if (strcmp(pszEncryptionOid, RTCRX509ALGORITHMIDENTIFIERID_ECDSA) == 0) + return rtCrKeyCreateEcdsaPublic(phKey, + pParameters, + RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey), + RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey), + pErrInfo, pszErrorTag); + } + Assert(pszEncryptionOid == NULL); + return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN, "oid=%s", pAlgorithm->szObjId); +} + + +RTDECL(int) RTCrKeyCreateFromSubjectPublicKeyInfo(PRTCRKEY phKey, struct RTCRX509SUBJECTPUBLICKEYINFO const *pSrc, + PRTERRINFO pErrInfo, const char *pszErrorTag) +{ + AssertPtrReturn(pSrc, VERR_INVALID_POINTER); + AssertReturn(RTCrX509SubjectPublicKeyInfo_IsPresent(pSrc), VERR_INVALID_PARAMETER); + return RTCrKeyCreateFromPublicAlgorithmAndBits(phKey, &pSrc->Algorithm.Algorithm, &pSrc->Algorithm.Parameters, + &pSrc->SubjectPublicKey, pErrInfo, pszErrorTag); +} + + +/** + * Creates an RSA private key from a DER encoded RTCRRSAPRIVATEKEY blob. + * + * @returns IPRT status code. + * @param phKey Where to return the key handle. + * @param pvKeyBits The DER encoded RTCRRSAPRIVATEKEY blob. + * @param cbKeyBits The size of the blob. + * @param pErrInfo Where to supply addition error details. Optional. + * @param pszErrorTag Error tag. Optional. + */ +DECLHIDDEN(int) rtCrKeyCreateRsaPrivate(PRTCRKEY phKey, const void *pvKeyBits, uint32_t cbKeyBits, + PRTERRINFO pErrInfo, const char *pszErrorTag) +{ + /* + * Decode the key data first since that's what's most likely to fail here. + */ + RTASN1CURSORPRIMARY PrimaryCursor; + RTAsn1CursorInitPrimary(&PrimaryCursor, pvKeyBits, cbKeyBits, pErrInfo, &g_RTAsn1SaferAllocator, + RTASN1CURSOR_FLAGS_DER, pszErrorTag ? pszErrorTag : "rsa"); + RTCRRSAPRIVATEKEY PrivateKey; + RT_ZERO(PrivateKey); + int rc = RTCrRsaPrivateKey_DecodeAsn1(&PrimaryCursor.Cursor, 0, &PrivateKey, pszErrorTag ? pszErrorTag : "PrivateKey"); + if (RT_SUCCESS(rc)) + { + /* + * Create a key instance for it. + */ + PRTCRKEYINT pThis; + rc = rtCrKeyCreateWorker(&pThis, RTCRKEYTYPE_RSA_PRIVATE, RTCRKEYINT_F_PRIVATE | RTCRKEYINT_F_SENSITIVE, + pvKeyBits, cbKeyBits); + if (RT_SUCCESS(rc)) + { + rc = RTAsn1Integer_ToBigNum(&PrivateKey.Modulus, &pThis->u.RsaPrivate.Modulus, 0); + if (RT_SUCCESS(rc)) + { + pThis->cBits = RTBigNumBitWidth(&pThis->u.RsaPrivate.Modulus); + rc = RTAsn1Integer_ToBigNum(&PrivateKey.PrivateExponent, &pThis->u.RsaPrivate.PrivateExponent, 0); + if (RT_SUCCESS(rc)) + { + rc = RTAsn1Integer_ToBigNum(&PrivateKey.PublicExponent, &pThis->u.RsaPrivate.PublicExponent, 0); + if (RT_SUCCESS(rc)) + { + /* Done. */ + RTAsn1VtDelete(&PrivateKey.SeqCore.Asn1Core); + RTMemWipeThoroughly(&PrivateKey, sizeof(PrivateKey), 3); + *phKey = pThis; + return VINF_SUCCESS; + } + } + } + RTCrKeyRelease(pThis); + } + RTAsn1VtDelete(&PrivateKey.SeqCore.Asn1Core); + RTMemWipeThoroughly(&PrivateKey, sizeof(PrivateKey), 3); + } + *phKey = NIL_RTCRKEY; + return rc; +} + + +RTDECL(uint32_t) RTCrKeyRetain(RTCRKEY hKey) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, UINT32_MAX); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, UINT32_MAX); + + uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); + AssertMsg(cRefs > 1 && cRefs < 1024, ("%#x\n", cRefs)); + return cRefs; +} + + +/** + * Destructor. + * + * @returns 0 + * @param pThis The key to destroy. + */ +static int rtCrKeyDestroy(PRTCRKEYINT pThis) +{ + /* Invalidate the object. */ + pThis->u32Magic = ~RTCRKEYINT_MAGIC; + + /* Type specific cleanup. */ + switch (pThis->enmType) + { + case RTCRKEYTYPE_RSA_PUBLIC: + RTBigNumDestroy(&pThis->u.RsaPublic.Modulus); + RTBigNumDestroy(&pThis->u.RsaPublic.Exponent); + break; + + case RTCRKEYTYPE_RSA_PRIVATE: + RTBigNumDestroy(&pThis->u.RsaPrivate.Modulus); + RTBigNumDestroy(&pThis->u.RsaPrivate.PrivateExponent); + RTBigNumDestroy(&pThis->u.RsaPrivate.PublicExponent); + break; + + case RTCRKEYTYPE_ECDSA_PUBLIC: + RTAsn1ObjId_Delete(&pThis->u.EcdsaPublic.NamedCurve); + break; + + case RTCRKEYTYPE_ECDSA_PRIVATE: /* not yet implemented */ + case RTCRKEYTYPE_INVALID: + case RTCRKEYTYPE_END: + case RTCRKEYTYPE_32BIT_HACK: + AssertFailed(); + } + pThis->enmType = RTCRKEYTYPE_INVALID; + +#if defined(IPRT_WITH_OPENSSL) + /* Free the encoded form if sensitive (otherwise it follows pThis). */ + if (pThis->pbEncoded) + { + if (pThis->fFlags & RTCRKEYINT_F_SENSITIVE) + RTMemSaferFree((uint8_t *)pThis->pbEncoded, pThis->cbEncoded); + else + Assert(pThis->pbEncoded == (uint8_t *)(pThis + 1)); + pThis->pbEncoded = NULL; + } +#endif + + /* Finally, free the key object itself. */ + RTMemFree(pThis); + return 0; +} + + +RTDECL(uint32_t) RTCrKeyRelease(RTCRKEY hKey) +{ + if (hKey == NIL_RTCRKEY) + return 0; + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, UINT32_MAX); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, UINT32_MAX); + + uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); + AssertMsg(cRefs < 1024, ("%#x\n", cRefs)); + if (cRefs != 0) + return cRefs; + return rtCrKeyDestroy(pThis); +} + + +RTDECL(RTCRKEYTYPE) RTCrKeyGetType(RTCRKEY hKey) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, RTCRKEYTYPE_INVALID); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, RTCRKEYTYPE_INVALID); + return pThis->enmType; +} + + +RTDECL(bool) RTCrKeyHasPrivatePart(RTCRKEY hKey) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, false); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, false); + return RT_BOOL(pThis->fFlags & RTCRKEYINT_F_PRIVATE); +} + + +RTDECL(bool) RTCrKeyHasPublicPart(RTCRKEY hKey) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, false); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, false); + return RT_BOOL(pThis->fFlags & RTCRKEYINT_F_PUBLIC); +} + + +RTDECL(uint32_t) RTCrKeyGetBitCount(RTCRKEY hKey) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, 0); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, 0); + return pThis->cBits; +} + + +RTDECL(int) RTCrKeyQueryRsaModulus(RTCRKEY hKey, PRTBIGNUM pModulus) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, VERR_INVALID_HANDLE); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, VERR_INVALID_HANDLE); + AssertReturn(pThis->enmType == RTCRKEYTYPE_RSA_PRIVATE || pThis->enmType == RTCRKEYTYPE_RSA_PUBLIC, VERR_WRONG_TYPE); + AssertPtrReturn(pModulus, VERR_INVALID_POINTER); + + if (pThis->enmType == RTCRKEYTYPE_RSA_PRIVATE) + return RTBigNumAssign(pModulus, &pThis->u.RsaPrivate.Modulus); + return RTBigNumAssign(pModulus, &pThis->u.RsaPublic.Modulus); +} + + +RTDECL(int) RTCrKeyQueryRsaPrivateExponent(RTCRKEY hKey, PRTBIGNUM pPrivateExponent) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, VERR_INVALID_HANDLE); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, VERR_INVALID_HANDLE); + AssertReturn(pThis->enmType == RTCRKEYTYPE_RSA_PRIVATE, VERR_WRONG_TYPE); + AssertPtrReturn(pPrivateExponent, VERR_INVALID_POINTER); + + return RTBigNumAssign(pPrivateExponent, &pThis->u.RsaPrivate.PrivateExponent); +} + + +RTDECL(int) RTCrKeyVerifyParameterCompatibility(RTCRKEY hKey, PCRTASN1DYNTYPE pParameters, bool fForSignature, + PCRTASN1OBJID pAlgorithm, PRTERRINFO pErrInfo) +{ + PRTCRKEYINT pThis = hKey; + AssertPtrReturn(pThis, VERR_INVALID_HANDLE); + AssertReturn(pThis->u32Magic == RTCRKEYINT_MAGIC, VERR_INVALID_HANDLE); + RT_NOREF(pAlgorithm); + + switch (pThis->enmType) + { + /* + * No parameters. Ignore NULL. + */ + case RTCRKEYTYPE_RSA_PRIVATE: + case RTCRKEYTYPE_RSA_PUBLIC: + if ( !pParameters + || pParameters->enmType == RTASN1TYPE_NOT_PRESENT + || pParameters->enmType == RTASN1TYPE_NULL) + return VINF_SUCCESS; + return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNEXPECTED, + "RSA keys does not generally take parameters (enmType=%d)", pParameters->enmType); + + /* + * ECDSA requires a parameter. Currently only the named curve choice is supported. + * RFC-3279 section 2.2.3 states that for ecdsa-with-SHA1 the parameter MUST be + * omitted. ASSUMING the same applies to the other ecdsa-with-xxxx variants. + */ + case RTCRKEYTYPE_ECDSA_PUBLIC: + if (!fForSignature) + { + /* Key rules: Parameters required. */ + if (pParameters) + { + if (pParameters->enmType == RTASN1TYPE_OBJID) + { + if (RTAsn1ObjId_Compare(&pParameters->u.ObjId, &pThis->u.EcdsaPublic.NamedCurve) == 0) + return VINF_SUCCESS; + return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_MISMATCH, + "ECDSA NamedCurve difference: %s, key uses %s", + pParameters->u.ObjId.szObjId, pThis->u.EcdsaPublic.NamedCurve.szObjId); + } + /* We don't implement the other variants. */ + return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNKNOWN, + "Unexpected ECDSA parameter: enmType=%d", pParameters->enmType); + } + return RTERRINFO_LOG_SET(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_MISSING, "ECDSA keys requires parameter(s)"); + } + + /* Hash+ecdsa parameter rules: No parameters */ + if ( !pParameters + || pParameters->enmType == RTASN1TYPE_NOT_PRESENT + || pParameters->enmType == RTASN1TYPE_NULL) + return VINF_SUCCESS; + return RTERRINFO_LOG_SET_F(pErrInfo, VERR_CR_KEY_ALGO_PARAMS_UNEXPECTED, + "ECDSA signature should have no parameters (enmType=%d)", pParameters->enmType); + + case RTCRKEYTYPE_ECDSA_PRIVATE: + AssertFailedReturn(VERR_NOT_IMPLEMENTED); + + case RTCRKEYTYPE_INVALID: + case RTCRKEYTYPE_END: + case RTCRKEYTYPE_32BIT_HACK: + break; + } + AssertFailedReturn(VERR_INTERNAL_ERROR_5); +} + -- cgit v1.2.3