예제 #1
0
파일: crypto.c 프로젝트: agnov8/wolfssl
/* RSA Public key decode ASN.1 */
int CRYPT_RSA_PublicKeyDecode(CRYPT_RSA_CTX* rsa, const unsigned char* in,
                              unsigned int inSz)
{
    unsigned int idx = 0;
    (void)idx;

    if (rsa == NULL || in == NULL)
        return BAD_FUNC_ARG;

    return RsaPublicKeyDecode(in, &idx, (RsaKey*)rsa->holder, inSz);
}
예제 #2
0
파일: pkcs7.c 프로젝트: Coderz333/cyassl
/* create ASN.1 fomatted RecipientInfo structure, returns sequence size */
CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
                                     int keyEncAlgo, int blockKeySz,
                                     RNG* rng, byte* contentKeyPlain,
                                     byte* contentKeyEnc,
                                     int* keyEncSz, byte* out, word32 outSz)
{
    word32 idx = 0;
    int ret = 0, totalSz = 0;
    int verSz, issuerSz, snSz, keyEncAlgSz;
    int issuerSeqSz, recipSeqSz, issuerSerialSeqSz;
    int encKeyOctetStrSz;

    byte ver[MAX_VERSION_SZ];
    byte serial[MAX_SN_SZ];
    byte issuerSerialSeq[MAX_SEQ_SZ];
    byte recipSeq[MAX_SEQ_SZ];
    byte issuerSeq[MAX_SEQ_SZ];
    byte keyAlgArray[MAX_ALGO_SZ];
    byte encKeyOctetStr[MAX_OCTET_STR_SZ];

    RsaKey pubKey;
    DecodedCert decoded;

    InitDecodedCert(&decoded, (byte*)cert, certSz, 0);
    ret = ParseCert(&decoded, CA_TYPE, NO_VERIFY, 0);
    if (ret < 0) {
        FreeDecodedCert(&decoded);
        return ret;
    }

    /* version */
    verSz = SetMyVersion(0, ver, 0);

    /* IssuerAndSerialNumber */
    if (decoded.issuerRaw == NULL || decoded.issuerRawLen == 0) {
        CYASSL_MSG("DecodedCert lacks raw issuer pointer and length");
        FreeDecodedCert(&decoded);
        return -1;
    }
    issuerSz    = decoded.issuerRawLen;
    issuerSeqSz = SetSequence(issuerSz, issuerSeq);

    if (decoded.serial == NULL || decoded.serialSz == 0) {
        CYASSL_MSG("DecodedCert missing serial number");
        FreeDecodedCert(&decoded);
        return -1;
    }
    snSz = SetSerialNumber(decoded.serial, decoded.serialSz, serial);

    issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
                                    issuerSerialSeq);

    /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
    if (keyEncAlgo != RSAk)
        return ALGO_ID_E;

    keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
    if (keyEncAlgSz == 0)
        return BAD_FUNC_ARG;

    /* EncryptedKey */
    ret = InitRsaKey(&pubKey, 0);
    if (ret != 0) return ret;
    if (RsaPublicKeyDecode(decoded.publicKey, &idx, &pubKey,
                           decoded.pubKeySize) < 0) {
        CYASSL_MSG("ASN RSA key decode error");
        return PUBLIC_KEY_E;
    }

    *keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
                                 MAX_ENCRYPTED_KEY_SZ, &pubKey, rng);
    FreeRsaKey(&pubKey);
    if (*keyEncSz < 0) {
        CYASSL_MSG("RSA Public Encrypt failed");
        return *keyEncSz;
    }

    encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr);

    /* RecipientInfo */
    recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
                             issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz +
                             *keyEncSz, recipSeq);

    if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
        keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
        CYASSL_MSG("RecipientInfo output buffer too small");
        return BUFFER_E;
    }

    XMEMCPY(out + totalSz, recipSeq, recipSeqSz);
    totalSz += recipSeqSz;
    XMEMCPY(out + totalSz, ver, verSz);
    totalSz += verSz;
    XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz);
    totalSz += issuerSerialSeqSz;
    XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
    totalSz += issuerSeqSz;
    XMEMCPY(out + totalSz, decoded.issuerRaw, issuerSz);
    totalSz += issuerSz;
    XMEMCPY(out + totalSz, serial, snSz);
    totalSz += snSz;
    XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz);
    totalSz += keyEncAlgSz;
    XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz);
    totalSz += encKeyOctetStrSz;
    XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
    totalSz += *keyEncSz;

    FreeDecodedCert(&decoded);

    return totalSz;
}
예제 #3
0
파일: pkcs7.c 프로젝트: Coderz333/cyassl
/* Finds the certificates in the message and saves it. */
int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
{
    word32 idx, contentType;
    int length, version, ret;
    byte* content = NULL;
    byte* sig = NULL;
    byte* cert = NULL;
    byte* signedAttr = NULL;
    int contentSz = 0, sigSz = 0, certSz = 0, signedAttrSz = 0;

    (void)signedAttr;    /* not used yet, just set */
    (void)signedAttrSz;

    if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
        return BAD_FUNC_ARG;

    idx = 0;

    /* Get the contentInfo sequence */
    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* Get the contentInfo contentType */
    if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (contentType != SIGNED_DATA) {
        CYASSL_MSG("PKCS#7 input not of type SignedData");
        return PKCS7_OID_E;
    }

    /* get the ContentInfo content */
    if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
        return ASN_PARSE_E;

    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* Get the signedData sequence */
    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* Get the version */
    if (GetMyVersion(pkiMsg, &idx, &version) < 0)
        return ASN_PARSE_E;

    if (version != 1) {
        CYASSL_MSG("PKCS#7 signedData needs to be of version 1");
        return ASN_VERSION_E;
    }

    /* Get the set of DigestAlgorithmIdentifiers */
    if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* Skip the set. */
    idx += length;

    /* Get the inner ContentInfo sequence */
    if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* Get the inner ContentInfo contentType */
    if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (contentType != DATA) {
        CYASSL_MSG("PKCS#7 inner input not of type Data");
        return PKCS7_OID_E;
    }

    if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
        return ASN_PARSE_E;

    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (pkiMsg[idx++] != ASN_OCTET_STRING)
        return ASN_PARSE_E;

    if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    /* Save the inner data as the content. */
    if (length > 0) {
        /* Local pointer for calculating hashes later */
        pkcs7->content = content = &pkiMsg[idx];
        pkcs7->contentSz = contentSz = length;
        idx += length;
    }

    /* Get the implicit[0] set of certificates */
    if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
        idx++;
        if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        if (length > 0) {
            /* At this point, idx is at the first certificate in
             * a set of certificates. There may be more than one,
             * or none, or they may be a PKCS 6 extended
             * certificate. We want to save the first cert if it
             * is X.509. */

            word32 certIdx = idx;

            if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
                if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0)
                    return ASN_PARSE_E;

                cert = &pkiMsg[idx];
                certSz += (certIdx - idx);
            }
            PKCS7_InitWithCert(pkcs7, cert, certSz);
        }
        idx += length;
    }

    /* Get the implicit[1] set of crls */
    if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
        idx++;
        if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* Skip the set */
        idx += length;
    }

    /* Get the set of signerInfos */
    if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
        return ASN_PARSE_E;

    if (length > 0) {
        RsaKey key;
        word32 scratch = 0;
        int plainSz = 0;
        byte digest[MAX_SEQ_SZ+MAX_ALGO_SZ+MAX_OCTET_STR_SZ+SHA_DIGEST_SIZE];

        /* Get the sequence of the first signerInfo */
        if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* Get the version */
        if (GetMyVersion(pkiMsg, &idx, &version) < 0)
            return ASN_PARSE_E;

        if (version != 1) {
            CYASSL_MSG("PKCS#7 signerInfo needs to be of version 1");
            return ASN_VERSION_E;
        }

        /* Get the sequence of IssuerAndSerialNumber */
        if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* Skip it */
        idx += length;

        /* Get the sequence of digestAlgorithm */
        if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* Skip it */
        idx += length;

        /* Get the IMPLICIT[0] SET OF signedAttributes */
        if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
            idx++;

            if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
                return ASN_PARSE_E;

            /* save pointer and length */
            signedAttr = &pkiMsg[idx];
            signedAttrSz = length;

            idx += length;
        }

        /* Get the sequence of digestEncryptionAlgorithm */
        if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
            return ASN_PARSE_E;

        /* Skip it */
        idx += length;

        /* Get the signature */
        if (pkiMsg[idx] == ASN_OCTET_STRING) {
            idx++;

            if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
                return ASN_PARSE_E;

            /* save pointer and length */
            sig = &pkiMsg[idx];
            sigSz = length;

            idx += length;
        }

        XMEMSET(digest, 0, sizeof(digest));
        pkcs7->content = content;
        pkcs7->contentSz = contentSz;

        ret = InitRsaKey(&key, NULL);
        if (ret != 0) return ret;
        if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, &key,
                               pkcs7->publicKeySz) < 0) {
            CYASSL_MSG("ASN RSA key decode error");
            return PUBLIC_KEY_E;
        }
        plainSz = RsaSSL_Verify(sig, sigSz, digest, sizeof(digest), &key);
        FreeRsaKey(&key);
        if (plainSz < 0)
            return plainSz;
    }

    return 0;
}