* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <stdint.h>
#include <string.h>
#include "bsl_errno.h"
#include "auth_errno.h"
#include "auth_privpass_token.h"
#include "bsl_err_internal.h"
#include "bsl_sal.h"
#include "bsl_bytes.h"
#include "privpass_token.h"
static int32_t DecodeTokenChallengeReq(PrivPass_TokenChallengeReq *tokenChallengeReq, const uint8_t *buffer,
uint32_t buffLen)
{
uint8_t *data = (uint8_t *)BSL_SAL_Dump(buffer, buffLen);
if (data == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
tokenChallengeReq->challengeReq = data;
tokenChallengeReq->challengeReqLen = buffLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t EncodeTokenChallengeReq(const PrivPass_TokenChallengeReq *tokenChallengeReq, uint8_t *buffer,
uint32_t *buffLen)
{
if (tokenChallengeReq->challengeReqLen == 0) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_REQ);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_REQ;
}
if (buffer == NULL) {
*buffLen = tokenChallengeReq->challengeReqLen;
return HITLS_AUTH_SUCCESS;
}
if (*buffLen < tokenChallengeReq->challengeReqLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(buffer, tokenChallengeReq->challengeReq, tokenChallengeReq->challengeReqLen);
*buffLen = tokenChallengeReq->challengeReqLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t ValidateInitialParams(uint32_t remainLen)
{
if (remainLen < 2 + 2 + 1 + 2) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeTokenTypeAndValidate(uint16_t *tokenType, const uint8_t **curr, uint32_t *remainLen)
{
*tokenType = BSL_ByteToUint16(*curr);
if (*tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
}
*curr += 2;
*remainLen -= 2;
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeIssuerName(uint8_t **issueName, uint32_t *issuerNameLen, const uint8_t **curr, uint32_t *remainLen)
{
*issuerNameLen = (uint32_t)BSL_ByteToUint16(*curr);
*curr += 2;
*remainLen -= 2;
if (*issuerNameLen == 0 || *remainLen < *issuerNameLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
*issueName = BSL_SAL_Dump(*curr, *issuerNameLen);
if (*issueName == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
*curr += *issuerNameLen;
*remainLen -= *issuerNameLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeRedemption(uint8_t **redemption, uint32_t *redemptionLen, const uint8_t **curr,
uint32_t *remainLen)
{
if (*remainLen < 1) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
*redemptionLen = (uint32_t)**curr;
*curr += 1;
*remainLen -= 1;
if (*remainLen < *redemptionLen || (*redemptionLen != PRIVPASS_REDEMPTION_LEN && *redemptionLen != 0)) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
if (*redemptionLen != 0) {
*redemption = BSL_SAL_Dump(*curr, *redemptionLen);
if (*redemption == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
*curr += *redemptionLen;
*remainLen -= *redemptionLen;
}
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeOriginInfo(uint8_t **originInfo, uint32_t *originInfoLen, const uint8_t **curr,
uint32_t *remainLen)
{
if (*remainLen < 2) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
*originInfoLen = (uint32_t)BSL_ByteToUint16(*curr);
*curr += 2;
*remainLen -= 2;
if (*remainLen != *originInfoLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
if (*originInfoLen > 0) {
*originInfo = BSL_SAL_Dump(*curr, *originInfoLen);
if (*originInfo == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
}
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeTokenChallenge(PrivPass_TokenChallenge *challenge, const uint8_t *buffer, uint32_t buffLen)
{
int32_t ret = ValidateInitialParams(buffLen);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
const uint8_t *curr = buffer;
uint32_t remainLen = buffLen;
ret = DecodeTokenTypeAndValidate(&challenge->tokenType, &curr, &remainLen);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
ret = DecodeIssuerName(&challenge->issuerName.data, &challenge->issuerName.dataLen, &curr, &remainLen);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
ret = DecodeRedemption(&challenge->redemption.data, &challenge->redemption.dataLen, &curr, &remainLen);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
return DecodeOriginInfo(&challenge->originInfo.data, &challenge->originInfo.dataLen, &curr, &remainLen);
}
static int32_t CheckTokenChallengeParam(const PrivPass_TokenChallenge *challenge)
{
if (challenge->issuerName.dataLen == 0 || challenge->issuerName.dataLen > PRIVPASS_MAX_ISSUER_NAME_LEN ||
challenge->originInfo.dataLen > PRIVPASS_MAX_ORIGIN_INFO_LEN ||
(challenge->redemption.dataLen != 0 && challenge->redemption.dataLen != PRIVPASS_REDEMPTION_LEN)) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
return HITLS_AUTH_SUCCESS;
}
static int32_t EncodeTokenChallenge(const PrivPass_TokenChallenge *challenge,
uint8_t *buffer, uint32_t *outBuffLen)
{
int32_t ret = CheckTokenChallengeParam(challenge);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
uint64_t totalLen = 2 + 2 + challenge->issuerName.dataLen + 1 + challenge->redemption.dataLen + 2 +
(uint64_t)challenge->originInfo.dataLen;
if (totalLen > UINT32_MAX) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE;
}
if (buffer == NULL) {
*outBuffLen = (uint32_t)totalLen;
return HITLS_AUTH_SUCCESS;
}
if (*outBuffLen < (uint32_t)totalLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
uint8_t *curr = buffer;
BSL_Uint16ToByte(challenge->tokenType, curr);
BSL_Uint16ToByte((uint16_t)challenge->issuerName.dataLen, curr + 2);
curr += 4;
if (challenge->issuerName.dataLen > 0 && challenge->issuerName.data != NULL) {
memcpy(curr, challenge->issuerName.data, challenge->issuerName.dataLen);
curr += challenge->issuerName.dataLen;
}
*curr++ = (uint8_t)challenge->redemption.dataLen;
if (challenge->redemption.dataLen > 0 && challenge->redemption.data != NULL) {
memcpy(curr, challenge->redemption.data, challenge->redemption.dataLen);
curr += challenge->redemption.dataLen;
}
BSL_Uint16ToByte((uint16_t)challenge->originInfo.dataLen, curr);
curr += 2;
if (challenge->originInfo.dataLen > 0 && challenge->originInfo.data != NULL) {
memcpy(curr, challenge->originInfo.data, challenge->originInfo.dataLen);
}
*outBuffLen = (uint32_t)totalLen;
return HITLS_AUTH_SUCCESS;
}
static uint32_t ObtainAuthenticatorLen(uint16_t tokenType)
{
if (tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
return (uint32_t)PRIVPASS_TOKEN_NK;
}
return 0;
}
static int32_t DecodeTokenRequest(PrivPass_TokenRequest *tokenRequest, const uint8_t *buffer, uint32_t buffLen)
{
if (buffLen < 2) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
uint16_t tokenType = BSL_ByteToUint16(buffer);
if (tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_REQUEST);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_REQUEST;
}
uint32_t blindedMsgLen = ObtainAuthenticatorLen(tokenType);
if (buffLen != (2 + 1 + blindedMsgLen)) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
int32_t offset = 2;
uint8_t truncatedTokenKeyId = buffer[offset++];
uint8_t *blindedMsg = (uint8_t *)BSL_SAL_Dump(buffer + offset, blindedMsgLen);
if (blindedMsg == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
tokenRequest->tokenType = tokenType;
tokenRequest->blindedMsg.data = blindedMsg;
tokenRequest->blindedMsg.dataLen = blindedMsgLen;
tokenRequest->truncatedTokenKeyId = truncatedTokenKeyId;
return HITLS_AUTH_SUCCESS;
}
static int32_t CheckTokenRequest(const PrivPass_TokenRequest *request)
{
if (request->tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE &&
(request->blindedMsg.data != NULL && request->blindedMsg.dataLen == PRIVPASS_TOKEN_NK)) {
return HITLS_AUTH_SUCCESS;
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_REQUEST);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_REQUEST;
}
static int32_t EncodeTokenRequest(const PrivPass_TokenRequest *request, uint8_t *buffer, uint32_t *outBuffLen)
{
int32_t ret = CheckTokenRequest(request);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
uint32_t authenticatorLen = ObtainAuthenticatorLen(request->tokenType);
uint32_t totalLen = 2 + 1 + authenticatorLen;
if (buffer == NULL) {
*outBuffLen = totalLen;
return HITLS_AUTH_SUCCESS;
}
if (*outBuffLen < totalLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
int32_t offset = 0;
BSL_Uint16ToByte(request->tokenType, buffer);
offset += 2;
buffer[offset++] = request->truncatedTokenKeyId;
memcpy(buffer + offset, request->blindedMsg.data, authenticatorLen);
*outBuffLen = totalLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodePubTokenResp(PrivPass_TokenResponse *tokenResp, const uint8_t *buffer, uint32_t buffLen)
{
tokenResp->st.pubResp.blindSig = (uint8_t *)BSL_SAL_Dump(buffer, buffLen);
if (tokenResp->st.pubResp.blindSig == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
tokenResp->st.pubResp.blindSigLen = buffLen;
tokenResp->type = HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB;
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeTokenResp(PrivPass_TokenResponse *tokenResp, const uint8_t *buffer, uint32_t buffLen)
{
if (buffLen == PRIVPASS_TOKEN_NK) {
return DecodePubTokenResp(tokenResp, buffer, buffLen);
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
}
static int32_t EncodeTokenPubResp(const PrivPass_TokenPubResponse *resp, uint8_t *buffer, uint32_t *buffLen)
{
if (resp->blindSig == NULL || resp->blindSigLen != PRIVPASS_TOKEN_NK) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_RESPONSE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_RESPONSE;
}
if (buffer == NULL) {
*buffLen = resp->blindSigLen;
return HITLS_AUTH_SUCCESS;
}
if (*buffLen < resp->blindSigLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(buffer, resp->blindSig, resp->blindSigLen);
*buffLen = resp->blindSigLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t EncodeTokenResp(const PrivPass_TokenResponse *resp, uint8_t *buffer, uint32_t *buffLen)
{
if (resp->type == HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB) {
return EncodeTokenPubResp(&resp->st.pubResp, buffer, buffLen);
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_RESPONSE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_RESPONSE;
}
static int32_t CheckToken(const PrivPass_TokenInstance *token)
{
if (token->tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE &&
(token->authenticator.data != NULL && token->authenticator.dataLen == PRIVPASS_TOKEN_NK)) {
return HITLS_AUTH_SUCCESS;
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_INSTANCE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_INSTANCE;
}
static int32_t EncodeToken(const PrivPass_TokenInstance *token, uint8_t *buffer, uint32_t *outBuffLen)
{
int32_t ret = CheckToken(token);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
uint32_t totalLen = 2 + PRIVPASS_TOKEN_NONCE_LEN + PRIVPASS_TOKEN_SHA256_SIZE + PRIVPASS_TOKEN_SHA256_SIZE +
token->authenticator.dataLen;
if (buffer == NULL) {
*outBuffLen = totalLen;
return HITLS_AUTH_SUCCESS;
}
if (*outBuffLen < totalLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
int32_t offset = 0;
BSL_Uint16ToByte(token->tokenType, buffer);
offset += 2;
memcpy(buffer + offset, token->nonce, PRIVPASS_TOKEN_NONCE_LEN);
offset += PRIVPASS_TOKEN_NONCE_LEN;
memcpy(buffer + offset, token->challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
offset += PRIVPASS_TOKEN_SHA256_SIZE;
memcpy(buffer + offset, token->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
offset += PRIVPASS_TOKEN_SHA256_SIZE;
memcpy(buffer + offset, token->authenticator.data, token->authenticator.dataLen);
*outBuffLen = totalLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t DecodeToken(PrivPass_TokenInstance *token, const uint8_t *buffer, uint32_t buffLen)
{
if (buffLen < 2) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
uint16_t tokenType = BSL_ByteToUint16(buffer);
if (tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
}
token->tokenType = tokenType;
uint32_t authenticatorLen = ObtainAuthenticatorLen(tokenType);
if (buffLen != (2 + PRIVPASS_TOKEN_NONCE_LEN + PRIVPASS_TOKEN_SHA256_SIZE + PRIVPASS_TOKEN_SHA256_SIZE +
authenticatorLen)) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
int32_t offset = 2;
memcpy(token->nonce, buffer + offset, PRIVPASS_TOKEN_NONCE_LEN);
offset += PRIVPASS_TOKEN_NONCE_LEN;
memcpy(token->challengeDigest, buffer + offset, PRIVPASS_TOKEN_SHA256_SIZE);
offset += PRIVPASS_TOKEN_SHA256_SIZE;
memcpy(token->tokenKeyId, buffer + offset, PRIVPASS_TOKEN_SHA256_SIZE);
offset += PRIVPASS_TOKEN_SHA256_SIZE;
token->authenticator.data = (uint8_t *)BSL_SAL_Dump(buffer + offset, authenticatorLen);
if (token->authenticator.data == NULL) {
BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
return BSL_DUMP_FAIL;
}
token->authenticator.dataLen = authenticatorLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t CheckDeserializationInput(int32_t tokenType, const uint8_t *buffer, uint32_t buffLen,
HITLS_AUTH_PrivPassToken **object)
{
if (buffer == NULL || buffLen == 0 || object == NULL || *object != NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
switch (tokenType) {
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE_REQUEST:
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE:
case HITLS_AUTH_PRIVPASS_TOKEN_REQUEST:
case HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE:
case HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE:
return HITLS_AUTH_SUCCESS;
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
}
}
int32_t HITLS_AUTH_PrivPassDeserialization(HITLS_AUTH_PrivPassCtx *ctx, int32_t tokenType, const uint8_t *buffer,
uint32_t buffLen, HITLS_AUTH_PrivPassToken **object)
{
(void)ctx;
int32_t ret = CheckDeserializationInput(tokenType, buffer, buffLen, object);
if (ret != HITLS_AUTH_SUCCESS) {
return ret;
}
HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(tokenType);
if (output == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return BSL_MALLOC_FAIL;
}
switch (tokenType) {
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE_REQUEST:
ret = DecodeTokenChallengeReq(output->st.tokenChallengeReq, buffer, buffLen);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE:
ret = DecodeTokenChallenge(output->st.tokenChallenge, buffer, buffLen);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_REQUEST:
ret = DecodeTokenRequest(output->st.tokenRequest, buffer, buffLen);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE:
ret = DecodeTokenResp(output->st.tokenResponse, buffer, buffLen);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE:
ret = DecodeToken(output->st.token, buffer, buffLen);
break;
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
ret = HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
break;
}
if (ret != HITLS_AUTH_SUCCESS) {
HITLS_AUTH_PrivPassFreeToken(output);
return ret;
}
*object = output;
return HITLS_AUTH_SUCCESS;
}
int32_t HITLS_AUTH_PrivPassSerialization(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *object,
uint8_t *buffer, uint32_t *outBuffLen)
{
(void)ctx;
if (object == NULL || outBuffLen == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
switch (object->type) {
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE_REQUEST:
return EncodeTokenChallengeReq(object->st.tokenChallengeReq, buffer, outBuffLen);
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE:
return EncodeTokenChallenge(object->st.tokenChallenge, buffer, outBuffLen);
case HITLS_AUTH_PRIVPASS_TOKEN_REQUEST:
return EncodeTokenRequest(object->st.tokenRequest, buffer, outBuffLen);
case HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE:
return EncodeTokenResp(object->st.tokenResponse, buffer, outBuffLen);
case HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE:
return EncodeToken(object->st.token, buffer, outBuffLen);
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
}
}
HITLS_AUTH_PrivPassToken *HITLS_AUTH_PrivPassNewToken(int32_t tokenType)
{
HITLS_AUTH_PrivPassToken *object = (HITLS_AUTH_PrivPassToken *)BSL_SAL_Calloc(1u, sizeof(HITLS_AUTH_PrivPassToken));
if (object == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return NULL;
}
switch (tokenType) {
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE_REQUEST:
object->st.tokenChallengeReq = (PrivPass_TokenChallengeReq *)BSL_SAL_Calloc(1u,
sizeof(PrivPass_TokenChallengeReq));
if (object->st.tokenChallengeReq == NULL) {
goto ERR;
}
break;
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE:
object->st.tokenChallenge = (PrivPass_TokenChallenge *)BSL_SAL_Calloc(1u, sizeof(PrivPass_TokenChallenge));
if (object->st.tokenChallenge == NULL) {
goto ERR;
}
break;
case HITLS_AUTH_PRIVPASS_TOKEN_REQUEST:
object->st.tokenRequest = (PrivPass_TokenRequest *)BSL_SAL_Calloc(1u, sizeof(PrivPass_TokenRequest));
if (object->st.tokenRequest == NULL) {
goto ERR;
}
break;
case HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE:
object->st.tokenResponse = (PrivPass_TokenResponse *)BSL_SAL_Calloc(1u, sizeof(PrivPass_TokenResponse));
if (object->st.tokenResponse == NULL) {
goto ERR;
}
break;
case HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE:
object->st.token = (PrivPass_TokenInstance *)BSL_SAL_Calloc(1u, sizeof(PrivPass_TokenInstance));
if (object->st.token == NULL) {
goto ERR;
}
break;
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
BSL_SAL_Free(object);
return NULL;
}
object->type = tokenType;
return object;
ERR:
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
BSL_SAL_Free(object);
return NULL;
}
static void FreeTokenChallengeReq(PrivPass_TokenChallengeReq *challengeReq)
{
if (challengeReq == NULL) {
return;
}
BSL_SAL_FREE(challengeReq->challengeReq);
BSL_SAL_Free(challengeReq);
}
static void FreeTokenChallenge(PrivPass_TokenChallenge *challenge)
{
if (challenge == NULL) {
return;
}
BSL_SAL_FREE(challenge->issuerName.data);
BSL_SAL_FREE(challenge->originInfo.data);
BSL_SAL_FREE(challenge->redemption.data);
BSL_SAL_Free(challenge);
}
static void FreeTokenResponse(PrivPass_TokenResponse *response)
{
if (response == NULL) {
return;
}
if (response->type == HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB) {
BSL_SAL_FREE(response->st.pubResp.blindSig);
}
BSL_SAL_Free(response);
}
static void FreeTokenRequest(PrivPass_TokenRequest *request)
{
if (request == NULL) {
return;
}
BSL_SAL_FREE(request->blindedMsg.data);
BSL_SAL_Free(request);
}
static void FreeToken(PrivPass_TokenInstance *token)
{
if (token == NULL) {
return;
}
BSL_SAL_FREE(token->authenticator.data);
BSL_SAL_Free(token);
}
void HITLS_AUTH_PrivPassFreeToken(HITLS_AUTH_PrivPassToken *object)
{
if (object == NULL) {
return;
}
switch (object->type) {
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE_REQUEST:
FreeTokenChallengeReq(object->st.tokenChallengeReq);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE:
FreeTokenChallenge(object->st.tokenChallenge);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_REQUEST:
FreeTokenRequest(object->st.tokenRequest);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE:
FreeTokenResponse(object->st.tokenResponse);
break;
case HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE:
FreeToken(object->st.token);
break;
default:
break;
}
BSL_SAL_Free(object);
}
HITLS_AUTH_PrivPassCtx *HITLS_AUTH_PrivPassNewCtx(int32_t protocolType)
{
if (protocolType != HITLS_AUTH_PRIVPASS_PUB_VERIFY_TOKENS) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOEKN_PROTOCOL_TYPE);
return NULL;
}
HITLS_AUTH_PrivPassCtx *ctx = (HITLS_AUTH_PrivPassCtx *)BSL_SAL_Calloc(1u, sizeof(HITLS_AUTH_PrivPassCtx));
if (ctx == NULL) {
BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
return NULL;
}
ctx->method = PrivPassCryptPubCb();
return ctx;
}
void HITLS_AUTH_PrivPassFreeCtx(HITLS_AUTH_PrivPassCtx *ctx)
{
if (ctx == NULL) {
return;
}
if (ctx->method.freePkeyCtx != NULL) {
if (ctx->prvKeyCtx != NULL) {
ctx->method.freePkeyCtx(ctx->prvKeyCtx);
}
if (ctx->pubKeyCtx != NULL) {
ctx->method.freePkeyCtx(ctx->pubKeyCtx);
}
}
BSL_SAL_CleanseData(ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
BSL_SAL_Free(ctx);
}
int32_t HITLS_AUTH_PrivPassSetCryptCb(HITLS_AUTH_PrivPassCtx *ctx, int32_t cbType, void *cryptCb)
{
if (ctx == NULL || cryptCb == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
switch (cbType) {
case HITLS_AUTH_PRIVPASS_NEW_PKEY_CTX_CB:
ctx->method.newPkeyCtx = (HITLS_AUTH_PrivPassNewPkeyCtx)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_FREE_PKEY_CTX_CB:
ctx->method.freePkeyCtx = (HITLS_AUTH_PrivPassFreePkeyCtx)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_DIGEST_CB:
ctx->method.digest = (HITLS_AUTH_PrivPassDigest)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_BLIND_CB:
ctx->method.blind = (HITLS_AUTH_PrivPassBlind)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_UNBLIND_CB:
ctx->method.unBlind = (HITLS_AUTH_PrivPassUnblind)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_SIGNDATA_CB:
ctx->method.signData = (HITLS_AUTH_PrivPassSignData)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_VERIFY_CB:
ctx->method.verify = (HITLS_AUTH_PrivPassVerify)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_DECODE_PUBKEY_CB:
ctx->method.decodePubKey = (HITLS_AUTH_PrivPassDecodePubKey)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_DECODE_PRVKEY_CB:
ctx->method.decodePrvKey = (HITLS_AUTH_PrivPassDecodePrvKey)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_CB:
ctx->method.checkKeyPair = (HITLS_AUTH_PrivPassCheckKeyPair)cryptCb;
break;
case HITLS_AUTH_PRIVPASS_RANDOM_CB:
ctx->method.random = (HITLS_AUTH_PrivPassRandom)cryptCb;
break;
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_CRYPTO_CALLBACK_TYPE);
return HITLS_AUTH_PRIVPASS_INVALID_CRYPTO_CALLBACK_TYPE;
}
return HITLS_AUTH_SUCCESS;
}
static int32_t PrivPassGetTokenChallengeRequest(HITLS_AUTH_PrivPassToken *ctx, BSL_Param *param)
{
if (param == NULL || ctx->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE_REQUEST ||
ctx->st.tokenChallengeReq == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (ctx->st.tokenChallengeReq->challengeReq == NULL || ctx->st.tokenChallengeReq->challengeReqLen == 0) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_REQUEST);
return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_REQUEST;
}
BSL_Param *output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_REQUEST);
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output->valueLen < ctx->st.tokenChallengeReq->challengeReqLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
memcpy(output->value, ctx->st.tokenChallengeReq->challengeReq, ctx->st.tokenChallengeReq->challengeReqLen);
output->useLen = ctx->st.tokenChallengeReq->challengeReqLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t GetTokenChallengeContent(PrivPass_TokenChallenge *challenge, BSL_Param *param, int32_t target,
uint8_t *targetBuff, uint32_t targetLen)
{
BSL_Param *output = BSL_PARAM_FindParam(param, target);
if (target == AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_TYPE) {
if (output != NULL && output->valueType == BSL_PARAM_TYPE_UINT16) {
return BSL_PARAM_SetValue(output, target, BSL_PARAM_TYPE_UINT16, &challenge->tokenType, targetLen);
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output->valueLen < targetLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(output->value, targetBuff, targetLen);
output->useLen = targetLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t PrivPassGetTokenChallengeContent(HITLS_AUTH_PrivPassToken *obj, int32_t cmd, BSL_Param *param)
{
if (param == NULL || obj->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE || obj->st.tokenChallenge == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
PrivPass_TokenChallenge *challenge = obj->st.tokenChallenge;
int32_t target = 0;
uint8_t *targetBuff = 0;
uint32_t targetLen = 0;
switch (cmd) {
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_TYPE:
target = AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_TYPE;
targetLen = (uint32_t)sizeof(challenge->tokenType);
break;
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_ISSUERNAME:
if (challenge->issuerName.data == NULL || challenge->issuerName.dataLen == 0) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_ISSUERNAME);
return HITLS_AUTH_PRIVPASS_NO_ISSUERNAME;
}
target = AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_ISSUERNAME;
targetBuff = challenge->issuerName.data;
targetLen = challenge->issuerName.dataLen;
break;
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_REDEMPTION:
target = AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_REDEMPTION;
targetBuff = challenge->redemption.data;
targetLen = challenge->redemption.dataLen;
break;
default:
target = AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_ORIGININFO;
targetBuff = challenge->originInfo.data;
targetLen = challenge->originInfo.dataLen;
break;
}
return GetTokenChallengeContent(challenge, param, target, targetBuff, targetLen);
}
static int32_t PrivPassGetTokenRequestContent(HITLS_AUTH_PrivPassToken *obj, int32_t cmd, BSL_Param *param)
{
if (param == NULL || obj->type != HITLS_AUTH_PRIVPASS_TOKEN_REQUEST || obj->st.tokenRequest == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
PrivPass_TokenRequest *request = obj->st.tokenRequest;
BSL_Param *output = NULL;
switch (cmd) {
case HITLS_AUTH_PRIVPASS_GET_TOKENREQUEST_TYPE:
output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_TOKENREQUEST_TYPE);
if (output != NULL && output->valueType == BSL_PARAM_TYPE_UINT16) {
return BSL_PARAM_SetValue(output, AUTH_PARAM_PRIVPASS_TOKENREQUEST_TYPE, BSL_PARAM_TYPE_UINT16,
&request->tokenType, (uint32_t)sizeof(request->tokenType));
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
case HITLS_AUTH_PRIVPASS_GET_TOKENREQUEST_TRUNCATEDTOKENKEYID:
output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_TOKENREQUEST_TRUNCATEDTOKENKEYID);
if (output != NULL && output->valueType == BSL_PARAM_TYPE_UINT8) {
return BSL_PARAM_SetValue(output, AUTH_PARAM_PRIVPASS_TOKENREQUEST_TRUNCATEDTOKENKEYID,
BSL_PARAM_TYPE_UINT8, &request->truncatedTokenKeyId, 1);
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
default:
output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_TOKENREQUEST_BLINDEDMSG);
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (request->blindedMsg.data == NULL || request->blindedMsg.dataLen == 0) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_BLINDEDMSG);
return HITLS_AUTH_PRIVPASS_NO_BLINDEDMSG;
}
if (output->valueLen < request->blindedMsg.dataLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(output->value, request->blindedMsg.data, request->blindedMsg.dataLen);
output->useLen = request->blindedMsg.dataLen;
return HITLS_AUTH_SUCCESS;
}
}
static int32_t PrivPassGetTokenResponseContent(HITLS_AUTH_PrivPassToken *ctx, BSL_Param *param)
{
if (param == NULL || ctx->type != HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE || ctx->st.tokenResponse == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (ctx->st.tokenResponse->st.pubResp.blindSig == NULL || ctx->st.tokenResponse->st.pubResp.blindSigLen == 0) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_RESPONSE_INFO);
return HITLS_AUTH_PRIVPASS_NO_RESPONSE_INFO;
}
BSL_Param *output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_TOKENRESPONSE_INFO);
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output->valueLen < ctx->st.tokenResponse->st.pubResp.blindSigLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(output->value, ctx->st.tokenResponse->st.pubResp.blindSig, ctx->st.tokenResponse->st.pubResp.blindSigLen);
output->useLen = ctx->st.tokenResponse->st.pubResp.blindSigLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t CopyTokenContent(PrivPass_TokenInstance *token, BSL_Param *param, int32_t target, uint8_t *targetBuff,
uint32_t targetLen)
{
BSL_Param *output = BSL_PARAM_FindParam(param, target);
if (target == AUTH_PARAM_PRIVPASS_TOKEN_TYPE) {
if (output != NULL && output->valueType == BSL_PARAM_TYPE_UINT16) {
return BSL_PARAM_SetValue(output, target, BSL_PARAM_TYPE_UINT16, &token->tokenType,
(uint32_t)sizeof(token->tokenType));
}
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (target == AUTH_PARAM_PRIVPASS_TOKEN_AUTHENTICATOR && targetBuff == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_AUTHENTICATOR);
return HITLS_AUTH_PRIVPASS_NO_AUTHENTICATOR;
}
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output->valueLen < targetLen) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(output->value, targetBuff, targetLen);
output->useLen = targetLen;
return HITLS_AUTH_SUCCESS;
}
static int32_t PrivPassGetTokenContent(HITLS_AUTH_PrivPassToken *obj, int32_t cmd, BSL_Param *param)
{
if (param == NULL || obj->type != HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE || obj->st.token == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
PrivPass_TokenInstance *token = obj->st.token;
int32_t target;
uint8_t *targetBuff = 0;
uint32_t targetLen = 0;
switch (cmd) {
case HITLS_AUTH_PRIVPASS_GET_TOKEN_TYPE:
target = AUTH_PARAM_PRIVPASS_TOKEN_TYPE;
targetLen = (uint32_t)sizeof(token->tokenType);
break;
case HITLS_AUTH_PRIVPASS_GET_TOKEN_NONCE:
target = AUTH_PARAM_PRIVPASS_TOKEN_NONCE;
targetBuff = token->nonce;
targetLen = PRIVPASS_TOKEN_NONCE_LEN;
break;
case HITLS_AUTH_PRIVPASS_GET_TOKEN_CHALLENGEDIGEST:
target = AUTH_PARAM_PRIVPASS_TOKEN_CHALLENGEDIGEST;
targetBuff = token->challengeDigest;
targetLen = PRIVPASS_TOKEN_SHA256_SIZE;
break;
case HITLS_AUTH_PRIVPASS_GET_TOKEN_TOKENKEYID:
target = AUTH_PARAM_PRIVPASS_TOKEN_TOKENKEYID;
targetBuff = token->tokenKeyId;
targetLen = PRIVPASS_TOKEN_SHA256_SIZE;
break;
default:
target = AUTH_PARAM_PRIVPASS_TOKEN_AUTHENTICATOR;
targetBuff = token->authenticator.data;
targetLen = token->authenticator.dataLen;
break;
}
return CopyTokenContent(token, param, target, targetBuff, targetLen);
}
int32_t HITLS_AUTH_PrivPassTokenCtrl(HITLS_AUTH_PrivPassToken *object, int32_t cmd, void *param, uint32_t paramLen)
{
if (object == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
(void)paramLen;
switch (cmd) {
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGEREQUEST_INFO:
return PrivPassGetTokenChallengeRequest(object, param);
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_TYPE:
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_ISSUERNAME:
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_REDEMPTION:
case HITLS_AUTH_PRIVPASS_GET_TOKENCHALLENGE_ORIGININFO:
return PrivPassGetTokenChallengeContent(object, cmd, param);
case HITLS_AUTH_PRIVPASS_GET_TOKENREQUEST_TYPE:
case HITLS_AUTH_PRIVPASS_GET_TOKENREQUEST_TRUNCATEDTOKENKEYID:
case HITLS_AUTH_PRIVPASS_GET_TOKENREQUEST_BLINDEDMSG:
return PrivPassGetTokenRequestContent(object, cmd, param);
case HITLS_AUTH_PRIVPASS_GET_TOKENRESPONSE_INFO:
return PrivPassGetTokenResponseContent(object, param);
case HITLS_AUTH_PRIVPASS_GET_TOKEN_TYPE:
case HITLS_AUTH_PRIVPASS_GET_TOKEN_NONCE:
case HITLS_AUTH_PRIVPASS_GET_TOKEN_CHALLENGEDIGEST:
case HITLS_AUTH_PRIVPASS_GET_TOKEN_TOKENKEYID:
case HITLS_AUTH_PRIVPASS_GET_TOKEN_AUTHENTICATOR:
return PrivPassGetTokenContent(object, cmd, param);
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_CMD);
return HITLS_AUTH_PRIVPASS_INVALID_CMD;
}
}
static int32_t PrivPassGetCtxContent(HITLS_AUTH_PrivPassCtx *ctx, int32_t cmd, BSL_Param *param)
{
BSL_Param *output = NULL;
switch (cmd) {
case HITLS_AUTH_PRIVPASS_GET_CTX_NONCE:
output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_CTX_NONCE);
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output->valueLen < PRIVPASS_TOKEN_NONCE_LEN) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(output->value, ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
output->useLen = PRIVPASS_TOKEN_NONCE_LEN;
return HITLS_AUTH_SUCCESS;
case HITLS_AUTH_PRIVPASS_GET_CTX_TRUNCATEDTOKENKEYID:
if (ctx->pubKeyCtx == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
}
output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_CTX_TRUNCATEDTOKENKEYID);
if (output == NULL || output->valueType != BSL_PARAM_TYPE_UINT8) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
return BSL_PARAM_SetValue(output, AUTH_PARAM_PRIVPASS_CTX_TRUNCATEDTOKENKEYID, BSL_PARAM_TYPE_UINT8,
&ctx->tokenKeyId[PRIVPASS_TOKEN_SHA256_SIZE - 1], 1);
default:
if (ctx->pubKeyCtx == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
}
output = BSL_PARAM_FindParam(param, AUTH_PARAM_PRIVPASS_CTX_TOKENKEYID);
if (output == NULL || output->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
if (output->valueLen < PRIVPASS_TOKEN_SHA256_SIZE) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH);
return HITLS_AUTH_PRIVPASS_BUFFER_NOT_ENOUGH;
}
memcpy(output->value, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
output->useLen = PRIVPASS_TOKEN_SHA256_SIZE;
return HITLS_AUTH_SUCCESS;
}
}
int32_t HITLS_AUTH_PrivPassCtxCtrl(HITLS_AUTH_PrivPassCtx *ctx, int32_t cmd, void *param, uint32_t paramLen)
{
if (ctx == NULL || param == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
}
(void)paramLen;
switch (cmd) {
case HITLS_AUTH_PRIVPASS_GET_CTX_TOKENKEYID:
case HITLS_AUTH_PRIVPASS_GET_CTX_TRUNCATEDTOKENKEYID:
case HITLS_AUTH_PRIVPASS_GET_CTX_NONCE:
return PrivPassGetCtxContent(ctx, cmd, param);
default:
BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_CMD);
return HITLS_AUTH_PRIVPASS_INVALID_CMD;
}
}