diff options
author | David Zeuthen <zeuthen@google.com> | 2021-09-11 13:59:43 -0400 |
---|---|---|
committer | David Zeuthen <zeuthen@google.com> | 2022-01-10 15:12:33 -0500 |
commit | 1eb12b29728adcbbe5b8694f671c67b8a624fe4a (patch) | |
tree | e62dafc3d8e318621ec258811ac02b9af7f61039 /identity/aidl/default/libeic/EicSession.c | |
parent | 02d2df7135351dad3ae5f11295fca50a483f8754 (diff) |
identity: Add multi-document presentation support.
This new IPresentationSession interface enables an application to do a
multi-document presentation, something which isn't possible with the
existing API. As a practical example of this consider presenting both
your Mobile Driving License and your Vaccination Certificate in a single
transaction.
Bug: 197965513
Test: New CTS tests and new screen in CtsVerifier
Change-Id: I11712dca35df7f1224debf454731bc17ea9bfb37
Diffstat (limited to 'identity/aidl/default/libeic/EicSession.c')
-rw-r--r-- | identity/aidl/default/libeic/EicSession.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c new file mode 100644 index 0000000000..d0c7a0d77e --- /dev/null +++ b/identity/aidl/default/libeic/EicSession.c @@ -0,0 +1,120 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <inttypes.h> + +#include "EicCommon.h" +#include "EicSession.h" + +// Global used for assigning ids for session objects. +// +static uint32_t gSessionLastIdAssigned = 0; + +// The current session object or NULL if never initialized or if it has been shut down. +// +static EicSession* gSessionCurrent = NULL; + +EicSession* eicSessionGetForId(uint32_t sessionId) { + if (gSessionCurrent != NULL && gSessionCurrent->id == sessionId) { + return gSessionCurrent; + } + return NULL; +} + +bool eicSessionInit(EicSession* ctx) { + eicMemSet(ctx, '\0', sizeof(EicSession)); + + if (!eicNextId(&gSessionLastIdAssigned)) { + eicDebug("Error getting id for object"); + return false; + } + ctx->id = gSessionLastIdAssigned; + + do { + if (!eicOpsRandom((uint8_t*)&(ctx->authChallenge), sizeof(ctx->authChallenge))) { + eicDebug("Failed generating random challenge"); + return false; + } + } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET); + + if (!eicOpsCreateEcKey(ctx->ephemeralPrivateKey, ctx->ephemeralPublicKey)) { + eicDebug("Error creating ephemeral key-pair"); + return false; + } + + gSessionCurrent = ctx; + eicDebug("Initialized session with id %" PRIu32, ctx->id); + return true; +} + +bool eicSessionShutdown(EicSession* ctx) { + if (ctx->id == 0) { + eicDebug("Trying to shut down session with id 0"); + return false; + } + eicDebug("Shut down session with id %" PRIu32, ctx->id); + eicMemSet(ctx, '\0', sizeof(EicSession)); + gSessionCurrent = NULL; + return true; +} + +bool eicSessionGetId(EicSession* ctx, uint32_t* outId) { + *outId = ctx->id; + return true; +} + +bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge) { + *outAuthChallenge = ctx->authChallenge; + return true; +} + +bool eicSessionGetEphemeralKeyPair(EicSession* ctx, + uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) { + eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE); + return true; +} + +bool eicSessionSetReaderEphemeralPublicKey( + EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) { + eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE); + return true; +} + +bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript, + size_t sessionTranscriptSize) { + // Only accept the SessionTranscript if X and Y from the ephemeral key + // we created is somewhere in SessionTranscript... + // + if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey, + EIC_P256_PUB_KEY_SIZE / 2) == NULL) { + eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript"); + return false; + } + if (eicMemMem(sessionTranscript, sessionTranscriptSize, + ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2, + EIC_P256_PUB_KEY_SIZE / 2) == NULL) { + eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript"); + return false; + } + + // To save space we only store the SHA-256 of SessionTranscript + // + EicSha256Ctx shaCtx; + eicOpsSha256Init(&shaCtx); + eicOpsSha256Update(&shaCtx, sessionTranscript, sessionTranscriptSize); + eicOpsSha256Final(&shaCtx, ctx->sessionTranscriptSha256); + return true; +} |