X509CertificateChain* AJ_X509DecodeCertificateChainPEM(const char* pem) { AJ_Status status; X509CertificateChain* head = NULL; X509CertificateChain* curr = NULL; X509CertificateChain* node; const char* beg = pem; const char* end; beg = strstr(beg, PEM_CERT_BEG); while (beg) { beg = beg + strlen(PEM_CERT_BEG); end = strstr(beg, PEM_CERT_END); if (NULL == end) { return NULL; } node = (X509CertificateChain*) AJ_Malloc(sizeof (X509CertificateChain)); if (NULL == node) { /* Free the cert chain */ X509CertificateChain* tmp; while (head) { tmp = head; head = head->next; if (tmp) { AJ_Free(tmp); } } return NULL; } status = AJ_X509DecodeCertificatePEM(&node->certificate, beg, end - beg); if (AJ_OK != status) { /* Free the cert chain */ X509CertificateChain* tmp; while (head) { tmp = head; head = head->next; if (tmp) { AJ_Free(tmp); } } return NULL; } // Push on the tail node->next = NULL; if (curr) { curr->next = node; curr = node; } else { head = node; curr = node; } beg = strstr(beg, PEM_CERT_BEG); } return head; }
static void DeleteTxPacket(volatile TxPkt* pkt) { while (pkt != NULL) { volatile TxPkt* prev = pkt; pkt = pkt->next; AJ_Free(prev->payload); AJ_Free((void*) prev); prev = NULL; } }
AJ_Status AJ_X509DecodeCertificatePEM(X509Certificate* certificate, const char* pem, size_t len) { AJ_Status status; AJ_InfoPrintf(("AJ_X509DecodeCertificatePEM(certificate=%p, pem=%p, len=%zu)\n", certificate, pem, len)); certificate->der.size = 3 * len / 4; certificate->der.data = AJ_Malloc(certificate->der.size); if (NULL == certificate->der.data) { return AJ_ERR_RESOURCES; } status = AJ_B64ToRaw(pem, len, certificate->der.data, certificate->der.size); if (AJ_OK != status) { AJ_Free(certificate->der.data); return status; } if ('=' == pem[len - 1]) { certificate->der.size--; } if ('=' == pem[len - 2]) { certificate->der.size--; } return AJ_OK; }
AJ_Status AppHandleCat(AJ_Message* msg) { AJ_Status status = AJ_OK; AJ_Message reply; char* partA; char* partB; char* totalString; AJ_AlwaysPrintf(("%s:%d:%s %d\n", __FILE__, __LINE__, __FUNCTION__, 0)); AJ_UnmarshalArgs(msg, "ss", &partA, &partB); totalString = (char*) AJ_Malloc(strlen(partA) + strlen(partB) + 1); if (!totalString) { return AJ_ERR_RESOURCES; } strcpy(totalString, partA); strcpy(totalString + strlen(partA), partB); AJ_MarshalReplyMsg(msg, &reply); AJ_MarshalArgs(&reply, "s", totalString); status = AJ_DeliverMsg(&reply); AJ_Free(totalString); return status; }
void AJ_WSL_Free(void* ptr) { AJ_EnterCriticalRegion(); // if the address is within the WSL heap, free the pool entry, else fallback to free. if ((ptr > (void*)&wsl_heap) && (ptr < (void*)&wsl_heap[WSL_HEAP_WORD_COUNT])) { AJ_PoolFree(ptr); } else { AJ_Free(ptr); } AJ_LeaveCriticalRegion(); }
/** * Finish the hash calculation and free resources. * @param context the hash context * @param digest - the buffer to hold the digest. * Must be NULL or of size AJ_SHA256_DIGEST_LENGTH. * If the value is NULL, resources are freed but the digest * is not calculated. * @return AJ_OK if successful, otherwise error. */ AJ_Status AJ_SHA256_Final(AJ_SHA256_Context* context, uint8_t* digest) { AJ_Status status = AJ_OK; if (!digest) { AJ_MemZeroSecure(context, sizeof(*context)); AJ_Free(context); } else { status = getDigest(context, digest, 0); } return status; }
/* * Implements AES-CCM (Counter with CBC-MAC) decryption as described in RFC 3610 */ AJ_Status AJ_Decrypt_CCM(const uint8_t* key, uint8_t* msg, uint32_t msgLen, uint32_t hdrLen, uint8_t tagLen, const uint8_t* nonce, uint32_t nLen) { AJ_Status status = AJ_OK; CCM_Context* context; if (!(context = InitCCMContext(nonce, nLen, hdrLen, msgLen, tagLen))) { AJ_ErrPrintf(("AJ_Decrypt_CCM(): AJ_ERR_RESOURCES\n")); return AJ_ERR_RESOURCES; } /* * Do any platform specific operations to enable AES */ AJ_AES_Enable(key); /* * Decrypt the authentication field */ AJ_AES_CTR_128(key, msg + msgLen, msg + msgLen, tagLen, context->ivec.data); /* * Decrypt message. */ if (msgLen != hdrLen) { AJ_AES_CTR_128(key, msg + hdrLen, msg + hdrLen, msgLen - hdrLen, context->ivec.data); } /* * Compute and verify the authentication tag T. */ Compute_CCM_AuthTag(key, context, msg, msgLen - hdrLen, hdrLen); /* * Balance the enable call above */ AJ_AES_Disable(); if (AJ_Crypto_Compare(context->T.data, msg + msgLen, tagLen) != 0) { /* * Authentication failed Clear the decrypted data */ memset(msg, 0, msgLen + tagLen); AJ_ErrPrintf(("AJ_Decrypt_CCM(): AJ_ERR_SECURITY\n")); status = AJ_ERR_SECURITY; } /* * Done with the context */ AJ_Free(context); return status; }
/* * Implements AES-CCM (Counter with CBC-MAC) encryption as described in RFC 3610 */ AJ_Status AJ_Encrypt_CCM(const uint8_t* key, uint8_t* msg, uint32_t msgLen, uint32_t hdrLen, uint8_t tagLen, const uint8_t* nonce, uint32_t nLen) { AJ_Status status = AJ_OK; CCM_Context* context; if (!(context = InitCCMContext(nonce, nLen, hdrLen, msgLen, tagLen))) { AJ_ErrPrintf(("AJ_Encrypt_CCM(): AJ_ERR_RESOURCES\n")); return AJ_ERR_RESOURCES; } /* * Do any platform specific operations to enable AES */ AJ_AES_Enable(key); /* * Compute the authentication tag */ Compute_CCM_AuthTag(key, context, msg, msgLen - hdrLen, hdrLen); /* * Encrypt the authentication tag */ AJ_AES_CTR_128(key, context->T.data, msg + msgLen, tagLen, context->ivec.data); Trace("CTR Start", context->ivec.data, AJ_BLOCKSZ); /* * Encrypt the message */ if (msgLen != hdrLen) { AJ_AES_CTR_128(key, msg + hdrLen, msg + hdrLen, msgLen - hdrLen, context->ivec.data); } /* * Balance the enable call above */ AJ_AES_Disable(); /* * Done with the context */ AJ_Free(context); return status; }
AJ_Status AJ_DecodePrivateKeyPEM(ecc_privatekey* key, const char* pem) { AJ_Status status; const char* beg; const char* end; DER_Element der; uint8_t* buf = NULL; beg = strstr(pem, PEM_PRIV_BEG); if (NULL == beg) { return AJ_ERR_INVALID; } beg = pem + strlen(PEM_PRIV_BEG); end = strstr(beg, PEM_PRIV_END); if (NULL == end) { return AJ_ERR_INVALID; } der.size = 3 * (end - beg) / 4; der.data = AJ_Malloc(der.size); if (NULL == der.data) { return AJ_ERR_RESOURCES; } buf = der.data; status = AJ_B64ToRaw(beg, end - beg, der.data, der.size); if (AJ_OK != status) { goto Exit; } if ('=' == beg[end - beg - 1]) { der.size--; } if ('=' == beg[end - beg - 2]) { der.size--; } status = AJ_DecodePrivateKeyDER(key, &der); Exit: if (buf) { AJ_Free(buf); } return status; }
/** * Retrieve the digest * @param context the hash context * @param digest the buffer to hold the digest. Must be of size AJ_SHA256_DIGEST_LENGTH * @param keepAlive keep the digest process alive for continuing digest * @return AJ_OK if successful, otherwise error. */ static AJ_Status getDigest(AJ_SHA256_Context* context, uint8_t* digest, const uint8_t keepAlive) { AJ_SHA256_Context tempCtx; AJ_SHA256_Context* finalCtx; if (keepAlive) { memcpy(&tempCtx, context, sizeof(AJ_SHA256_Context)); finalCtx = &tempCtx; } else { finalCtx = context; } SHA256_Final(digest, &finalCtx->internal); AJ_MemZeroSecure(finalCtx, sizeof(*finalCtx)); if (!keepAlive) { AJ_Free(context); } return AJ_OK; }
static AJ_Status SetNameOwnerChangedRule(AJ_BusAttachment* bus, const char* oldOwner, uint8_t rule, uint32_t* serialNum) { AJ_Status status; size_t ruleLen; char* ruleStr; const char* rulePrefix = "type='signal',member='NameOwnerChanged',interface='org.freedesktop.DBus',arg1='"; const char* ruleSuffix = "',arg2=''"; ruleLen = strlen(rulePrefix) + strlen(oldOwner) + strlen(ruleSuffix); ruleStr = (char*) AJ_Malloc(ruleLen + 1 /* \0 */); if (ruleStr == NULL) { return AJ_ERR_RESOURCES; } strcpy(ruleStr, rulePrefix); strcat(ruleStr, oldOwner); strcat(ruleStr, ruleSuffix); status = AJ_BusSetSignalRuleSerial(bus, ruleStr, rule, 0, serialNum); AJ_Free(ruleStr); return status; }
static AJ_Status AuthResponse(AJ_Message* msg, char* inStr) { AJ_Status status; char* buf; if (authContext.sasl.state == AJ_SASL_AUTHENTICATED) { return GenSessionKey(msg); } /* * Need a short-lived buffer to compose the response */ buf = (char*)AJ_Malloc(AUTH_BUF_LEN); if (!buf) { status = AJ_ERR_RESOURCES; } else { status = AJ_SASL_Advance(&authContext.sasl, inStr, buf, AUTH_BUF_LEN); if (status == AJ_OK) { AJ_Message call; AJ_MarshalMethodCall(msg->bus, &call, AJ_METHOD_AUTH_CHALLENGE, msg->sender, 0, AJ_NO_FLAGS, AUTH_CALL_TIMEOUT); AJ_MarshalArgs(&call, "s", buf); status = AJ_DeliverMsg(&call); } AJ_Free(buf); } /* * If there was an error finalize the auth mechanism */ if (status != AJ_OK) { if (authContext.sasl.mechanism) { authContext.sasl.mechanism->Final(authContext.peerGuid); } /* * Report authentication failure to application */ if (status != AJ_OK) { PeerAuthComplete(status); } } return status; }
static AJ_Status AuthListenerCallback(uint32_t authmechanism, uint32_t command, AJ_Credential*cred) { AJ_Status status = AJ_ERR_INVALID; uint8_t* b8; size_t b8len; char* b64; size_t b64len; AJ_AlwaysPrintf(("AuthListenerCallback authmechanism %d command %d\n", authmechanism, command)); switch (authmechanism) { case AUTH_SUITE_ECDHE_NULL: cred->expiration = keyexpiration; status = AJ_OK; break; case AUTH_SUITE_ECDHE_PSK: switch (command) { case AJ_CRED_PUB_KEY: break; // Don't use username - use anon cred->mask = AJ_CRED_PUB_KEY; cred->data = (uint8_t*) psk_hint; cred->len = strlen(psk_hint); status = AJ_OK; break; case AJ_CRED_PRV_KEY: if (AJ_CRED_PUB_KEY == cred->mask) { AJ_AlwaysPrintf(("Request Credentials for PSK ID: %s\n", cred->data)); } cred->mask = AJ_CRED_PRV_KEY; cred->data = (uint8_t*) psk_char; cred->len = strlen(psk_char); cred->expiration = keyexpiration; status = AJ_OK; break; } break; case AUTH_SUITE_ECDHE_ECDSA: switch (command) { case AJ_CRED_PUB_KEY: b8len = 3 * strlen(ecc_pub_b64) / 4; b8 = (uint8_t*) AJ_Malloc(b8len); AJ_ASSERT(b8); status = AJ_B64ToRaw(ecc_pub_b64, strlen(ecc_pub_b64), b8, b8len); AJ_ASSERT(AJ_OK == status); status = AJ_BigEndianDecodePublicKey(&ecc_pub, b8); AJ_ASSERT(AJ_OK == status); cred->mask = AJ_CRED_PUB_KEY; cred->data = (uint8_t*) &ecc_pub; cred->len = sizeof (ecc_pub); cred->expiration = keyexpiration; AJ_Free(b8); break; case AJ_CRED_PRV_KEY: b8len = 3 * strlen(ecc_prv_b64) / 4; b8 = (uint8_t*) AJ_Malloc(b8len); AJ_ASSERT(b8); status = AJ_B64ToRaw(ecc_prv_b64, strlen(ecc_prv_b64), b8, b8len); AJ_ASSERT(AJ_OK == status); status = AJ_BigEndianDecodePrivateKey(&ecc_prv, b8); AJ_ASSERT(AJ_OK == status); cred->mask = AJ_CRED_PRV_KEY; cred->data = (uint8_t*) &ecc_prv; cred->len = sizeof (ecc_prv); cred->expiration = keyexpiration; AJ_Free(b8); break; case AJ_CRED_CERT_CHAIN: b8len = sizeof (AJ_Certificate); b8 = (uint8_t*) AJ_Malloc(b8len); AJ_ASSERT(b8); status = AJ_B64ToRaw(owner_cert1_b64, strlen(owner_cert1_b64), b8, b8len); AJ_ASSERT(AJ_OK == status); status = AJ_BigEndianDecodeCertificate(&root_cert, b8, b8len); AJ_ASSERT(AJ_OK == status); cred->mask = AJ_CRED_CERT_CHAIN; cred->data = (uint8_t*) &root_cert; cred->len = sizeof (root_cert); AJ_Free(b8); break; case AJ_CRED_CERT_TRUST: b64len = 4 * ((cred->len + 2) / 3) + 1; b64 = (char*) AJ_Malloc(b64len); AJ_ASSERT(b64); status = AJ_RawToB64(cred->data, cred->len, b64, b64len); AJ_ASSERT(AJ_OK == status); status = IsTrustedIssuer(b64); AJ_AlwaysPrintf(("TRUST: %s %d\n", b64, status)); AJ_Free(b64); break; case AJ_CRED_CERT_ROOT: b64len = 4 * ((cred->len + 2) / 3) + 1; b64 = (char*) AJ_Malloc(b64len); AJ_ASSERT(b64); status = AJ_RawToB64(cred->data, cred->len, b64, b64len); AJ_ASSERT(AJ_OK == status); AJ_AlwaysPrintf(("ROOT: %s\n", b64)); status = AJ_OK; AJ_Free(b64); break; } break; default: break; } return status; }
int AJ_Main() { AJ_Status status; while (1) { int windows = 1 << (rand() % 3); // randomize window width 1,2,4 int blocksize = 50 + (rand() % 1000); // randomize packet size 50 - 1050 AJ_AlwaysPrintf(("Windows:%i Blocksize:%i\n", windows, blocksize)); txBuffer = (uint8_t*) AJ_Malloc(blocksize); rxBuffer = (uint8_t*) AJ_Malloc(blocksize); memset(txBuffer, 0x41, blocksize); memset(rxBuffer, 'r', blocksize); #ifdef READTEST status = AJ_SerialInit("/dev/ttyUSB0", BITRATE, windows, blocksize); #else status = AJ_SerialInit("/dev/ttyUSB1", BITRATE, windows, blocksize); #endif AJ_AlwaysPrintf(("serial init was %u\n", status)); if (status != AJ_OK) { continue; // init failed perhaps from bad parameters, start the loop again } // Change the buffer transmission function to one that fuzzes the output. AJ_SetTxSerialTransmit(&FuzzBuffer); #ifdef READTEST AJ_Sleep(2000); // wait for the writing side to be running, this should test the queuing of data. // try to read everything at once int i = 0; while (1) { AJ_SerialRecv(rxBuffer, blocksize, 50000, NULL); } AJ_DumpBytes("Post serial recv", rxBuffer, blocksize); AJ_Sleep(500); #else AJ_Sleep(5000); int i = 0; while (1) { // change the packet to be sent every time through the loop. memset(txBuffer, 0x41 + (i % 26), blocksize); memset(rxBuffer, 0x41 + (i % 26), blocksize); AJ_SerialSend(txBuffer, blocksize); ++i; if (i % 20 == 0) { AJ_AlwaysPrintf(("Hit iteration %d\n", i)); break; } AJ_SerialRecv(rxBuffer, blocksize, 5000, NULL); } AJ_AlwaysPrintf(("post serial send\n")); #endif // clean up and start again AJ_SerialShutdown(); AJ_Free(txBuffer); AJ_Free(rxBuffer); } return(0); }
static AJ_Status StartClient(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, const char** interfaces, uint32_t* sessionId, char* serviceName, const AJ_SessionOpts* opts) { AJ_Status status = AJ_OK; AJ_Time timer; uint8_t found = FALSE; uint8_t clientStarted = FALSE; uint32_t elapsed = 0; char* rule; size_t ruleLen; const char* base = "interface='org.alljoyn.About',sessionless='t'"; const char* impl = ",implements='"; const char** ifaces; AJ_InfoPrintf(("AJ_StartClient(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., interface=\"%p\", sessionId=0x%p, serviceName=0x%p, opts=0x%p)\n", bus, daemonName, timeout, connected, interfaces, sessionId, serviceName, opts)); AJ_InitTimer(&timer); if ((name == NULL && interfaces == NULL) || (name != NULL && interfaces != NULL)) { return AJ_ERR_INVALID; } while (elapsed < timeout) { if (!connected) { status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); elapsed = AJ_GetElapsedTime(&timer, TRUE); if (status != AJ_OK) { elapsed += AJ_CONNECT_PAUSE; if (elapsed > timeout) { break; } AJ_WarnPrintf(("AJ_StartClient(): Failed to connect to bus, sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AJ_StartClient(): AllJoyn client connected to bus\n")); } if (name != NULL) { /* * Kick things off by finding the service names */ status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n")); } else { /* * Kick things off by finding all services that implement the interface */ ruleLen = strlen(base) + 1; ifaces = interfaces; while (*ifaces != NULL) { ruleLen += strlen(impl) + strlen(*ifaces) + 1; ifaces++; } rule = (char*) AJ_Malloc(ruleLen); if (rule == NULL) { status = AJ_ERR_RESOURCES; break; } strcpy(rule, base); ifaces = interfaces; while (*ifaces != NULL) { strcat(rule, impl); if ((*ifaces)[0] == '$') { strcat(rule, &(*ifaces)[1]); } else { strcat(rule, *ifaces); } strcat(rule, "'"); ifaces++; } status = AJ_BusSetSignalRule(bus, rule, AJ_BUS_SIGNAL_ALLOW); AJ_InfoPrintf(("AJ_StartClient(): Client SetSignalRule: %s\n", rule)); AJ_Free(rule); } if (status == AJ_OK) { break; } if (!connected) { AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } } if (elapsed > timeout) { AJ_WarnPrintf(("AJ_StartClient(): Client timed-out trying to connect to bus: status=%s.\n", AJ_StatusText(status))); return AJ_ERR_TIMEOUT; } timeout -= elapsed; if (status != AJ_OK) { return status; } *sessionId = 0; if (serviceName != NULL) { *serviceName = '\0'; } while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if ((status == AJ_ERR_TIMEOUT) && !found) { /* * Timeouts are expected until we find a name or service */ if (timeout < AJ_UNMARSHAL_TIMEOUT) { return status; } timeout -= AJ_UNMARSHAL_TIMEOUT; status = AJ_OK; continue; } if (status == AJ_ERR_NO_MATCH) { // Ignore unknown messages status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): status=%s\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_FIND_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); found = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_SIGNAL_ABOUT_ANNOUNCE: { uint16_t version, port; AJ_InfoPrintf(("AJ_StartClient(): AboutAnnounce from (%s)\n", msg.sender)); if (!found) { found = TRUE; AJ_UnmarshalArgs(&msg, "qq", &version, &port); status = AJ_BusJoinSession(bus, msg.sender, port, opts); if (serviceName != NULL) { strncpy(serviceName, msg.sender, AJ_MAX_NAME_SIZE); serviceName[AJ_MAX_NAME_SIZE] = '\0'; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): BusJoinSession failed (%s)\n", AJ_StatusText(status))); } } } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; } else { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION reply (%d)\n", replyCode)); status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } AJ_ErrPrintf(("AJ_StartClient(): AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_ERR_READ\n")); status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK && !connected) { AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
int AJ_Main() #endif { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; AJ_Status authStatus = AJ_ERR_NULL; /* * Buffer to hold the peer's full service name or unique name. */ #if defined (NGNS) || defined (ANNOUNCE_BASED_DISCOVERY) char peerServiceName[AJ_MAX_NAME_SIZE + 1]; #else char peerServiceName[AJ_MAX_SERVICE_NAME_SIZE]; #endif #ifdef SECURE_INTERFACE uint32_t suites[16]; size_t numsuites = 0; uint8_t clearkeys = FALSE; uint8_t enablepwd = FALSE; X509CertificateChain* node; #endif #ifdef MAIN_ALLOWS_ARGS #ifdef SECURE_INTERFACE ac--; av++; /* * Enable authentication mechanism by command line */ if (ac) { if (0 == strncmp(*av, "-ek", 3)) { clearkeys = TRUE; ac--; av++; } else if (0 == strncmp(*av, "-e", 2)) { ac--; av++; } if (!ac) { AJ_AlwaysPrintf(("-e(k) requires an auth mechanism.\n")); return 1; } while (ac) { if (0 == strncmp(*av, "ECDHE_ECDSA", 11)) { suites[numsuites++] = AUTH_SUITE_ECDHE_ECDSA; } else if (0 == strncmp(*av, "ECDHE_PSK", 9)) { suites[numsuites++] = AUTH_SUITE_ECDHE_PSK; } else if (0 == strncmp(*av, "ECDHE_NULL", 10)) { suites[numsuites++] = AUTH_SUITE_ECDHE_NULL; } else if (0 == strncmp(*av, "PIN", 3)) { enablepwd = TRUE; } ac--; av++; } } #endif #endif /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(ProxyObjects); AJ_RegisterObjects(NULL, ProxyObjects); while (TRUE) { AJ_Message msg; if (!connected) { #if defined (NGNS) || defined (ANNOUNCE_BASED_DISCOVERY) status = AJ_StartClientByInterface(&bus, NULL, CONNECT_TIMEOUT, FALSE, testInterfaceNames, &sessionId, peerServiceName, NULL); #else status = AJ_StartClientByName(&bus, NULL, CONNECT_TIMEOUT, FALSE, testServiceName, testServicePort, &sessionId, NULL, peerServiceName); #endif if (status == AJ_OK) { AJ_AlwaysPrintf(("StartClient returned %d, sessionId=%u, serviceName=%s\n", status, sessionId, peerServiceName)); AJ_AlwaysPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus))); connected = TRUE; #ifdef SECURE_INTERFACE if (enablepwd) { AJ_BusSetPasswordCallback(&bus, PasswordCallback); } AJ_BusEnableSecurity(&bus, suites, numsuites); AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); if (clearkeys) { status = AJ_ClearCredentials(); AJ_ASSERT(AJ_OK == status); } status = AJ_BusAuthenticatePeer(&bus, peerServiceName, AuthCallback, &authStatus); if (status != AJ_OK) { AJ_AlwaysPrintf(("AJ_BusAuthenticatePeer returned %d\n", status)); } #else authStatus = AJ_OK; #endif AJ_BusAddSignalRule(&bus, "my_signal", testInterfaceName, AJ_BUS_SIGNAL_ALLOW); } else { AJ_AlwaysPrintf(("StartClient returned %d\n", status)); break; } } if (authStatus != AJ_ERR_NULL) { if (authStatus != AJ_OK) { AJ_Disconnect(&bus); break; } authStatus = AJ_ERR_NULL; } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (status == AJ_ERR_TIMEOUT) { status = AppDoWork(&bus, sessionId, peerServiceName); continue; } if (status == AJ_OK) { switch (msg.msgId) { case PRX_MY_SIGNAL: AJ_AlwaysPrintf(("Received my_signal\n")); status = AJ_OK; break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } status = AJ_ERR_SESSION_LOST; break; default: /* * Pass to the built-in handlers */ status = AJ_BusHandleBusMessage(&msg); break; } } /* * Messages must be closed to free resources */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_SESSION_LOST) || (status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) { AJ_AlwaysPrintf(("AllJoyn disconnect\n")); AJ_AlwaysPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus))); AJ_Disconnect(&bus); connected = FALSE; } } AJ_AlwaysPrintf(("clientlite EXIT %d\n", status)); // Clean up certificate chain while (chain) { node = chain; chain = chain->next; AJ_Free(node->certificate.der.data); AJ_Free(node); } return status; }
static AJ_Status AuthListenerCallback(uint32_t authmechanism, uint32_t command, AJ_Credential*cred) { AJ_Status status = AJ_ERR_INVALID; X509CertificateChain* node; AJ_AlwaysPrintf(("AuthListenerCallback authmechanism %d command %d\n", authmechanism, command)); switch (authmechanism) { case AUTH_SUITE_ECDHE_NULL: cred->expiration = keyexpiration; status = AJ_OK; break; case AUTH_SUITE_ECDHE_PSK: switch (command) { case AJ_CRED_PUB_KEY: cred->data = (uint8_t*) psk_hint; cred->len = strlen(psk_hint); cred->expiration = keyexpiration; status = AJ_OK; break; case AJ_CRED_PRV_KEY: cred->data = (uint8_t*) psk_char; cred->len = strlen(psk_char); cred->expiration = keyexpiration; status = AJ_OK; break; } break; case AUTH_SUITE_ECDHE_ECDSA: switch (command) { case AJ_CRED_PRV_KEY: cred->len = sizeof (ecc_privatekey); status = AJ_DecodePrivateKeyPEM(&prv, pem_prv); if (AJ_OK != status) { return status; } cred->data = (uint8_t*) &prv; cred->expiration = keyexpiration; break; case AJ_CRED_CERT_CHAIN: switch (cred->direction) { case AJ_CRED_REQUEST: // Free previous certificate chain while (chain) { node = chain; chain = chain->next; AJ_Free(node->certificate.der.data); AJ_Free(node); } chain = AJ_X509DecodeCertificateChainPEM(pem_x509); if (NULL == chain) { return AJ_ERR_INVALID; } cred->data = (uint8_t*) chain; cred->expiration = keyexpiration; status = AJ_OK; break; case AJ_CRED_RESPONSE: node = (X509CertificateChain*) cred->data; while (node) { AJ_DumpBytes("CERTIFICATE", node->certificate.der.data, node->certificate.der.size); node = node->next; } status = AJ_OK; break; } break; } break; default: break; } return status; }
int AJ_Main(int argc, char** argv) { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; uint16_t state; uint16_t capabilities; uint16_t info; /* One time initialization before calling any other AllJoyn APIs. */ AJ_Initialize(); /* This is for debug purposes and is optional. */ AJ_PrintXML(AppObjects); AJ_RegisterObjects(AppObjects, NULL); while (TRUE) { AJ_Message msg; if (!connected) { status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServicePort, ServiceName, AJ_NAME_REQ_DO_NOT_QUEUE, NULL); if (status != AJ_OK) { continue; } AJ_InfoPrintf(("StartService returned %d, session_id=%u\n", status, sessionId)); connected = TRUE; AJ_BusEnableSecurity(&bus, suites, numsuites); AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); AJ_ManifestTemplateSet(&manifest); AJ_SecurityGetClaimConfig(&state, &capabilities, &info); /* Set app claimable if not already claimed */ if (APP_STATE_CLAIMED != state) { AJ_SecuritySetClaimConfig(&bus, APP_STATE_CLAIMABLE, CLAIM_CAPABILITY_ECDHE_PSK, 0); } } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { continue; } if (AJ_OK == status) { switch (msg.msgId) { case AJ_METHOD_ACCEPT_SESSION: { uint16_t port; char* joiner; AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner); if (port == ServicePort) { status = AJ_BusReplyAcceptSession(&msg, TRUE); AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", sessionId, joiner)); } else { status = AJ_ResetArgs(&msg); if (AJ_OK != status) { break; } status = AJ_BusHandleBusMessage(&msg); } } break; case BASIC_SERVICE_PING: status = AppHandlePing(&msg); break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* Force a disconnect. */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } status = AJ_ERR_SESSION_LOST; break; default: /* Pass to the built-in handlers. */ status = AJ_BusHandleBusMessage(&msg); break; } } /* Messages MUST be discarded to free resources. */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_READ) || (status == AJ_ERR_WRITE)) { AJ_Printf("AllJoyn disconnect.\n"); AJ_Disconnect(&bus); connected = FALSE; /* Sleep a little while before trying to reconnect. */ AJ_Sleep(SLEEP_TIME); } } AJ_Printf("Secure service exiting with status 0x%04x.\n", status); // Clean up certificate chain while (chain) { node = chain; chain = chain->next; AJ_Free(node->certificate.der.data); AJ_Free(node); } return status; }
int AJ_Main() { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; X509CertificateChain* node; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(AppObjects); AJ_RegisterObjects(AppObjects, NULL); AJ_AboutRegisterPropStoreGetter(AboutPropGetter); SetBusAuthPwdCallback(MyBusAuthPwdCB); while (TRUE) { AJ_Message msg; if (!connected) { status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServicePort, ServiceName, AJ_NAME_REQ_DO_NOT_QUEUE, NULL); if (status != AJ_OK) { continue; } AJ_InfoPrintf(("StartService returned AJ_OK\n")); AJ_InfoPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus))); AJ_SetIdleTimeouts(&bus, 10, 4); connected = TRUE; #ifdef SECURE_OBJECT status = AJ_SetObjectFlags("/org/alljoyn/alljoyn_test", AJ_OBJ_FLAG_SECURE, 0); if (status != AJ_OK) { AJ_ErrPrintf(("Error calling AJ_SetObjectFlags.. [%s] \n", AJ_StatusText(status))); return -1; } #endif #if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT) /* Register a callback for providing bus authentication password */ AJ_BusSetPasswordCallback(&bus, PasswordCallback); AJ_BusEnableSecurity(&bus, suites, numsuites); AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); #endif /* Configure timeout for the link to the daemon bus */ AJ_SetBusLinkTimeout(&bus, 60); // 60 seconds } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status && AJ_ERR_LINK_TIMEOUT == AJ_BusLinkStateProc(&bus)) { status = AJ_ERR_READ; } if (status != AJ_OK) { if (status == AJ_ERR_TIMEOUT) { AppDoWork(); continue; } } if (status == AJ_OK) { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_InfoPrintf(("Failed to add match\n")); status = AJ_ERR_FAILURE; } else { status = AJ_OK; } break; case AJ_METHOD_ACCEPT_SESSION: { uint16_t port; char* joiner; AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner); if (port == ServicePort) { status = AJ_BusReplyAcceptSession(&msg, TRUE); AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", sessionId, joiner)); } else { status = AJ_BusReplyAcceptSession(&msg, FALSE); AJ_InfoPrintf(("Accepted rejected session_id=%u joiner=%s\n", sessionId, joiner)); } } break; case APP_MY_PING: status = AppHandlePing(&msg); break; case APP_GET_PROP: status = AJ_BusPropGet(&msg, PropGetHandler, NULL); break; case APP_SET_PROP: status = AJ_BusPropSet(&msg, PropSetHandler, NULL); if (status == AJ_OK) { AJ_InfoPrintf(("Property successfully set to %d.\n", propVal)); } else { AJ_InfoPrintf(("Property set attempt unsuccessful. Status = 0x%04x.\n", status)); } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); if (CancelAdvertiseName) { status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0); } status = AJ_ERR_SESSION_LOST; } break; case AJ_SIGNAL_SESSION_JOINED: if (CancelAdvertiseName) { status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_STOP_ADVERTISING, 0); } break; case AJ_REPLY_ID(AJ_METHOD_CANCEL_ADVERTISE): case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } break; case AJ_REPLY_ID(AJ_METHOD_BUS_SET_IDLE_TIMEOUTS): { uint32_t disposition, idleTo, probeTo; if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } AJ_UnmarshalArgs(&msg, "uuu", &disposition, &idleTo, &probeTo); AJ_InfoPrintf(("SetIdleTimeouts response disposition=%u idleTimeout=%u probeTimeout=%u\n", disposition, idleTo, probeTo)); } break; case APP_MY_SIGNAL: AJ_InfoPrintf(("Received my_signal\n")); status = AJ_OK; if (ReflectSignal) { AJ_Message out; AJ_Arg arg; AJ_MarshalSignal(&bus, &out, APP_MY_SIGNAL, msg.sender, msg.sessionId, 0, 0); AJ_MarshalContainer(&out, &arg, AJ_ARG_ARRAY); AJ_MarshalCloseContainer(&out, &arg); AJ_DeliverMsg(&out); AJ_CloseMsg(&out); } break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } // Any received packets indicates the link is active, so call to reinforce the bus link state AJ_NotifyLinkActive(); } /* * Unarshaled messages must be closed to free resources */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) { AJ_InfoPrintf(("AllJoyn disconnect\n")); AJ_InfoPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus))); AJ_Disconnect(&bus); connected = FALSE; /* * Sleep a little while before trying to reconnect */ AJ_Sleep(10 * 1000); } } AJ_WarnPrintf(("svclite EXIT %d\n", status)); #if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT) // Clean up certificate chain while (chain) { node = chain; chain = chain->next; AJ_Free(node->certificate.der.data); AJ_Free(node); } #endif return status; }
AJ_Status AJ_PeerHandleAuthChallenge(AJ_Message* msg, AJ_Message* reply) { AJ_Status status; AJ_Arg arg; char* buf = NULL; const AJ_GUID* peerGuid = AJ_GUID_Find(msg->sender); /* * We expect to know the GUID of the sender */ if (!peerGuid) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected); } /* * Check for an authentication conversation in progress with a different peer */ if (authContext.peerGuid && (authContext.peerGuid != peerGuid)) { /* * Reject the request if the existing conversation has not expired */ if (AJ_GetElapsedTime(&authContext.timer, TRUE) < MAX_AUTH_TIME) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected); } memset(&authContext, 0, sizeof(AuthContext)); } if (authContext.sasl.state == AJ_SASL_IDLE) { /* * Remember which peer is being authenticated and initialize the timeout timer */ authContext.peerGuid = peerGuid; AJ_InitTimer(&authContext.timer); /* * Initialize SASL state machine */ AJ_SASL_InitContext(&authContext.sasl, authMechanisms, AJ_AUTH_CHALLENGER, msg->bus->pwdCallback); } if (AJ_UnmarshalArg(msg, &arg) != AJ_OK) { goto FailAuth; } /* * Need a short-lived buffer to compose the response */ buf = (char*)AJ_Malloc(AUTH_BUF_LEN); if (!buf) { status = AJ_ERR_RESOURCES; goto FailAuth; } status = AJ_SASL_Advance(&authContext.sasl, (char*)arg.val.v_string, buf, AUTH_BUF_LEN); if (status != AJ_OK) { goto FailAuth; } AJ_MarshalReplyMsg(msg, reply); AJ_MarshalArgs(reply, "s", buf); AJ_Free(buf); if (authContext.sasl.state == AJ_SASL_AUTHENTICATED) { status = authContext.sasl.mechanism->Final(peerGuid); memset(&authContext, 0, sizeof(AuthContext)); } return status; FailAuth: AJ_Free(buf); /* * Clear current authentication context then return an error response */ if (authContext.sasl.mechanism) { authContext.sasl.mechanism->Final(peerGuid); } memset(&authContext, 0, sizeof(AuthContext)); return AJ_MarshalErrorMsg(msg, reply, AJ_ErrSecurityViolation); }
int AJ_Main_certificate(int ac, char** av) { AJ_Status status = AJ_OK; size_t num = 2; size_t i; uint8_t* b8; char* pem; size_t pemlen; ecc_privatekey root_prvkey; ecc_publickey root_pubkey; uint8_t* manifest; size_t manifestlen; uint8_t digest[SHA256_DIGEST_LENGTH]; ecc_privatekey peer_prvkey; ecc_publickey peer_pubkey; AJ_Certificate* cert; AJ_GUID guild; /* * Create an owner key pair */ AJ_GenerateDSAKeyPair(&root_pubkey, &root_prvkey); b8 = (uint8_t*) AJ_Malloc(sizeof (ecc_publickey)); AJ_ASSERT(b8); status = AJ_BigEndianEncodePublicKey(&root_pubkey, b8); AJ_ASSERT(AJ_OK == status); pemlen = 4 * ((sizeof (ecc_publickey) + 2) / 3) + 1; pem = (char*) AJ_Malloc(pemlen); status = AJ_RawToB64(b8, sizeof (ecc_publickey), pem, pemlen); AJ_ASSERT(AJ_OK == status); AJ_Printf("Owner Public Key\n"); AJ_Printf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", pem); AJ_Free(b8); AJ_Free(pem); CreateManifest(&manifest, &manifestlen); ManifestDigest(manifest, &manifestlen, digest); AJ_RandBytes((uint8_t*) &guild, sizeof (AJ_GUID)); for (i = 0; i < num; i++) { AJ_GenerateDSAKeyPair(&peer_pubkey, &peer_prvkey); b8 = (uint8_t*) AJ_Malloc(sizeof (ecc_publickey)); AJ_ASSERT(b8); status = AJ_BigEndianEncodePublicKey(&peer_pubkey, b8); AJ_ASSERT(AJ_OK == status); pemlen = 4 * ((sizeof (ecc_publickey) + 2) / 3) + 1; pem = (char*) AJ_Malloc(pemlen); status = AJ_RawToB64(b8, sizeof (ecc_publickey), pem, pemlen); AJ_ASSERT(AJ_OK == status); AJ_Printf("Peer Public Key\n"); AJ_Printf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", pem); AJ_Free(b8); AJ_Free(pem); b8 = (uint8_t*) AJ_Malloc(sizeof (ecc_privatekey)); AJ_ASSERT(b8); status = AJ_BigEndianEncodePrivateKey(&peer_prvkey, b8); AJ_ASSERT(AJ_OK == status); pemlen = 4 * ((sizeof (ecc_privatekey) + 2) / 3) + 1; pem = (char*) AJ_Malloc(pemlen); status = AJ_RawToB64(b8, sizeof (ecc_privatekey), pem, pemlen); AJ_ASSERT(AJ_OK == status); AJ_Printf("Peer Private Key\n"); AJ_Printf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----\n", pem); AJ_Free(b8); AJ_Free(pem); cert = (AJ_Certificate*) AJ_Malloc(sizeof (AJ_Certificate)); AJ_ASSERT(cert); status = AJ_CreateCertificate(cert, 0, &peer_pubkey, NULL, NULL, digest, 0); AJ_ASSERT(AJ_OK == status); status = AJ_SignCertificate(cert, &peer_prvkey); AJ_ASSERT(AJ_OK == status); status = AJ_VerifyCertificate(cert); AJ_ASSERT(AJ_OK == status); b8 = (uint8_t*) AJ_Malloc(sizeof (AJ_Certificate)); AJ_ASSERT(b8); status = AJ_BigEndianEncodeCertificate(cert, b8, sizeof (AJ_Certificate)); AJ_ASSERT(AJ_OK == status); pemlen = 4 * ((sizeof (AJ_Certificate) + 2) / 3) + 1; pem = (char*) AJ_Malloc(pemlen); status = AJ_RawToB64(b8, cert->size, pem, pemlen); AJ_ASSERT(AJ_OK == status); AJ_Printf("Peer Certificate (Type 0)\n"); AJ_Printf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", pem); status = AJ_CreateCertificate(cert, 1, &root_pubkey, &peer_pubkey, NULL, digest, 0); AJ_ASSERT(AJ_OK == status); status = AJ_SignCertificate(cert, &root_prvkey); AJ_ASSERT(AJ_OK == status); status = AJ_VerifyCertificate(cert); AJ_ASSERT(AJ_OK == status); status = AJ_BigEndianEncodeCertificate(cert, b8, sizeof (AJ_Certificate)); AJ_ASSERT(AJ_OK == status); status = AJ_RawToB64(b8, cert->size, pem, pemlen); AJ_ASSERT(AJ_OK == status); AJ_Printf("Root Certificate (Type 1)\n"); AJ_Printf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", pem); status = AJ_CreateCertificate(cert, 2, &root_pubkey, &peer_pubkey, &guild, digest, 0); AJ_ASSERT(AJ_OK == status); status = AJ_SignCertificate(cert, &root_prvkey); AJ_ASSERT(AJ_OK == status); status = AJ_VerifyCertificate(cert); AJ_ASSERT(AJ_OK == status); status = AJ_BigEndianEncodeCertificate(cert, b8, sizeof (AJ_Certificate)); AJ_ASSERT(AJ_OK == status); status = AJ_RawToB64(b8, cert->size, pem, pemlen); AJ_ASSERT(AJ_OK == status); AJ_Printf("Root Certificate (Type 2)\n"); AJ_Printf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", pem); AJ_Free(cert); AJ_Free(b8); AJ_Free(pem); } AJ_Free(manifest); return 0; }
int AJ_Main(void) { AJ_Status status = AJ_OK; uint32_t i; AJ_AlwaysPrintf(("AES CCM unit test start\n")); for (i = 0; i < ArraySize(testVector); i++) { uint8_t key[16]; uint8_t input[64]; uint8_t* msg; uint8_t nonce[16]; uint32_t nlen = (uint32_t)strlen(testVector[i].nonce) / 2; uint32_t ilen = (uint32_t)strlen(testVector[i].input) / 2; uint32_t mlen = ilen * testVector[i].repeat; uint32_t j; char* out; size_t olen; AJ_HexToRaw(testVector[i].key, 0, key, sizeof(key)); AJ_HexToRaw(testVector[i].nonce, 0, nonce, nlen); AJ_HexToRaw(testVector[i].input, 0, input, mlen); msg = AJ_Malloc(mlen + testVector[i].authLen); if (!msg) { AJ_AlwaysPrintf(("Allocation failed for test #%zu\n", i)); goto ErrorExit; } for (j = 0; j < testVector[i].repeat; j++) { memcpy(&msg[ilen * j], &input[0], ilen); } olen = 2 * (mlen + testVector[i].authLen) + 1; out = AJ_Malloc(olen); if (!out) { AJ_AlwaysPrintf(("Allocation failed for test #%zu\n", i)); goto ErrorExit; } status = AJ_Encrypt_CCM(key, msg, mlen, testVector[i].hdrLen, testVector[i].authLen, nonce, nlen); if (status != AJ_OK) { AJ_AlwaysPrintf(("Encryption failed (%d) for test #%u\n", status, i)); goto ErrorExit; } AJ_RawToHex(msg, mlen + testVector[i].authLen, out, olen, FALSE); if (strcmp(out, testVector[i].output) != 0) { AJ_AlwaysPrintf(("Encrypt verification failure for test #%u\n%s\n", i, out)); goto ErrorExit; } /* * Verify decryption. */ status = AJ_Decrypt_CCM(key, msg, mlen, testVector[i].hdrLen, testVector[i].authLen, nonce, nlen); if (status != AJ_OK) { AJ_AlwaysPrintf(("Authentication failure (%d) for test #%u\n", status, i)); goto ErrorExit; } AJ_RawToHex(msg, mlen, out, olen, FALSE); for (j = 0; j < testVector[i].repeat; j++) { if (strncmp(&out[2 * ilen * j], testVector[i].input, ilen * 2) != 0) { AJ_AlwaysPrintf(("Decrypt verification failure for test #%u\n%s\n", i, out)); goto ErrorExit; } } AJ_AlwaysPrintf(("Passed and verified test #%zu\n", i)); AJ_Free(msg); AJ_Free(out); } AJ_AlwaysPrintf(("AES CCM unit test PASSED\n")); return 0; ErrorExit: AJ_AlwaysPrintf(("AES CCM unit test FAILED\n")); return 1; }