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 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; }
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; }