Example #1
0
static AJ_Status DecodeCertificateSig(DER_Element* der, ecc_signature* signature)
{
    AJ_Status status;
    DER_Element seq;
    DER_Element int1;
    DER_Element int2;
    uint8_t tags[] = { ASN_INTEGER, ASN_INTEGER };

    status = AJ_ASN1DecodeElement(der, ASN_SEQ, &seq);
    if (AJ_OK != status) {
        return status;
    }
    status = AJ_ASN1DecodeElements(&seq, tags, sizeof (tags), &int1, &int2);
    if (AJ_OK != status) {
        return status;
    }

    /*
     * Skip over unused bits.
     */
    if ((0 < int1.size) && (0 == *int1.data)) {
        int1.data++;
        int1.size--;
    }
    if ((0 < int2.size) && (0 == *int2.data)) {
        int2.data++;
        int2.size--;
    }

    memset(signature, 0, sizeof (ecc_signature));
    AJ_BigvalDecode(int1.data, &signature->r, int1.size);
    AJ_BigvalDecode(int2.data, &signature->s, int2.size);

    return status;
}
Example #2
0
static AJ_Status DecodeCertificatePub(DER_Element* der, AJ_KeyInfo* keyinfo)
{
    AJ_Status status;
    DER_Element seq;
    DER_Element bit;
    DER_Element oid1;
    DER_Element oid2;
    uint8_t tags1[] = { ASN_SEQ, ASN_BITS };
    uint8_t tags2[] = { ASN_OID, ASN_OID };

    status = AJ_ASN1DecodeElements(der, tags1, sizeof (tags1), &seq, &bit);
    if (AJ_OK != status) {
        return status;
    }

    /*
     * We only accept NISTP256 ECC keys at the moment.
     */
    status = AJ_ASN1DecodeElements(&seq, tags2, sizeof (tags2), &oid1, &oid2);
    if (AJ_OK != status) {
        return status;
    }
    if (sizeof (OID_KEY_ECC) != oid1.size) {
        return AJ_ERR_INVALID;
    }
    if (0 != memcmp(OID_KEY_ECC, oid1.data, oid1.size)) {
        return AJ_ERR_INVALID;
    }
    if (sizeof (OID_CRV_PRIME256V1) != oid2.size) {
        return AJ_ERR_INVALID;
    }
    if (0 != memcmp(OID_CRV_PRIME256V1, oid2.data, oid2.size)) {
        return AJ_ERR_INVALID;
    }

    /*
     * We only accept uncompressed ECC points.
     */
    if ((2 + KEY_ECC_PUB_SZ) != bit.size) {
        return AJ_ERR_INVALID;
    }
    if ((0x00 != bit.data[0]) || (0x04 != bit.data[1])) {
        return AJ_ERR_INVALID;
    }
    bit.data += 2;
    bit.size -= 2;

    memset(keyinfo, 0, sizeof (AJ_KeyInfo));
    keyinfo->fmt = KEY_FMT_ALLJOYN;
    keyinfo->use = KEY_USE_SIG;
    keyinfo->kty = KEY_TYP_ECC;
    keyinfo->alg = KEY_ALG_ECDSA_SHA256;
    keyinfo->crv = KEY_CRV_NISTP256;
    AJ_BigvalDecode(bit.data, &keyinfo->key.publickey.x, KEY_ECC_SZ);
    bit.data += KEY_ECC_SZ;
    bit.size -= KEY_ECC_SZ;
    AJ_BigvalDecode(bit.data, &keyinfo->key.publickey.y, KEY_ECC_SZ);

    return status;
}
Example #3
0
static AJ_Status DecodeCertificatePub(ecc_publickey* pub, DER_Element* der)
{
    AJ_Status status;
    DER_Element seq;
    DER_Element bit;
    DER_Element oid1;
    DER_Element oid2;
    const uint8_t tags1[] = { ASN_SEQ, ASN_BITS };
    const uint8_t tags2[] = { ASN_OID, ASN_OID };

    memset(pub, 0, sizeof (ecc_publickey));

    status = AJ_ASN1DecodeElements(der, tags1, sizeof (tags1), &seq, &bit);
    if (AJ_OK != status) {
        return status;
    }

    /*
     * We only accept NISTP256 ECC keys at the moment.
     */
    status = AJ_ASN1DecodeElements(&seq, tags2, sizeof (tags2), &oid1, &oid2);
    if (AJ_OK != status) {
        return status;
    }
    if (!CompareOID(&oid1, OID_KEY_ECC, sizeof (OID_KEY_ECC))) {
        return AJ_ERR_INVALID;
    }
    if (!CompareOID(&oid2, OID_CRV_PRIME256V1, sizeof (OID_CRV_PRIME256V1))) {
        return AJ_ERR_INVALID;
    }

    /*
     * We only accept uncompressed ECC points.
     */
    if ((2 + KEY_ECC_PUB_SZ) != bit.size) {
        return AJ_ERR_INVALID;
    }
    if ((0x00 != bit.data[0]) || (0x04 != bit.data[1])) {
        return AJ_ERR_INVALID;
    }
    bit.data += 2;
    bit.size -= 2;
    AJ_BigvalDecode(bit.data, &pub->x, KEY_ECC_SZ);
    bit.data += KEY_ECC_SZ;
    bit.size -= KEY_ECC_SZ;
    AJ_BigvalDecode(bit.data, &pub->y, KEY_ECC_SZ);

    return status;
}
Example #4
0
AJ_Status AJ_DecodePrivateKeyDER(ecc_privatekey* key, DER_Element* der)
{
    AJ_Status status;
    DER_Element seq;
    DER_Element ver;
    DER_Element prv;
    DER_Element alg;
    const uint8_t tags1[] = { ASN_SEQ };
    const uint8_t tags2[] = { ASN_INTEGER, ASN_OCTETS, ASN_CONTEXT_SPECIFIC };

    status = AJ_ASN1DecodeElements(der, tags1, sizeof (tags1), &seq);
    if (AJ_OK != status) {
        return status;
    }
    status = AJ_ASN1DecodeElements(&seq, tags2, sizeof (tags2), &ver, &prv, 0, &alg);
    if (AJ_OK != status) {
        return status;
    }
    if ((1 != ver.size) || (1 != *ver.data)) {
        return AJ_ERR_INVALID;
    }
    if (KEY_ECC_PRV_SZ != prv.size) {
        return AJ_ERR_INVALID;
    }
    AJ_BigvalDecode(prv.data, key, KEY_ECC_SZ);

    return status;
}