Пример #1
0
Файл: asn1.c Проект: B-Rich/NUL
/*
	Get the BIT STRING key and plug into RSA structure.
*/
int32 getAsnRsaPubKey(psPool_t *pool, unsigned char **pp, uint32 len, 
					 psRsaKey_t *pubKey)
{
	unsigned char	*p = *pp;
	uint32			pubKeyLen, seqLen;
	int32			ignore_bits;
	memset(pubKey, 0x0, sizeof(psRsaKey_t));
	if (len < 1 || (*(p++) != ASN_BIT_STRING) ||
			getAsnLength(&p, len - 1, &pubKeyLen) < 0 ||
			(len - 1) < pubKeyLen) {
		psTraceCrypto("Initial parse error in getAsnRsaPubKey\n");
		return PS_PARSE_FAIL;
	}
	
	ignore_bits = *p++;
/*
	We assume this is always zero
*/
	psAssert(ignore_bits == 0);

	if (getAsnSequence(&p, pubKeyLen, &seqLen) < 0 ||
		getAsnBig(pool, &p, seqLen, &pubKey->N) < 0 ||
		getAsnBig(pool, &p, seqLen, &pubKey->e) < 0) {
		psTraceCrypto("Secondary parse error in getAsnRsaPubKey\n");
		return PS_PARSE_FAIL;
	}
	pubKey->size = pstm_unsigned_bin_size(&pubKey->N);
	*pp = p;
	return PS_SUCCESS;
}
Пример #2
0
Файл: asn1.c Проект: B-Rich/NUL
/*
	Implementation specific OID parser for suppported RSA algorithms
*/
int32 getAsnAlgorithmIdentifier(unsigned char **pp, uint32 len, int32 *oi,
				int32 isPubKey, int32 *paramLen)
{
	unsigned char   *p = *pp, *end;
	int32           plen;
	uint32			llen, arcLen;

	end = p + len;
	if (len < 1 || getAsnSequence(&p, len, &llen) < 0) {
		psTraceCrypto("getAsnAlgorithmIdentifier failed on inital parse\n");
		return PS_PARSE_FAIL;
	}
	if (end - p < 1) {
		psTraceCrypto("Malformed algorithmId\n");
		return PS_LIMIT_FAIL;
	}
	plen = end - p;
	if (*(p++) != ASN_OID || getAsnLength(&p, (uint32)(end - p), &arcLen) < 0
			|| llen < arcLen) {
		psTraceCrypto("Malformed algorithmId 2\n");
		return PS_PARSE_FAIL;
	}
	if (end - p < 2) {
		psTraceCrypto("Malformed algorithmId 3\n");
		return PS_LIMIT_FAIL;
	}
	if (isPubKey && (*p != 0x2a) && (*(p + 1) != 0x86)) {
/*
		Expecting DSA here if not RSA, but OID doesn't always match
*/
		psTraceCrypto("Unsupported algorithm identifier\n");
		return PS_UNSUPPORTED_FAIL;
	}
	*oi = 0;
	while (arcLen-- > 0) {
		*oi += (int32)*p;
		p++;
	}
/*
	Each of these cases might have a trailing NULL parameter.  Skip it
*/
	plen -= (end - p);
	*paramLen = llen - plen;
	if (*p != ASN_NULL) {
		*pp = p;
		return PS_SUCCESS;
	}
	if (end - p < 2) {
		psTraceCrypto("Malformed algorithmId 4\n");
		return PS_LIMIT_FAIL;
	}
	*paramLen -= 2;
	*pp = p + 2;
	return PS_SUCCESS;
}
Пример #3
0
/**
    Parse an RSA private key from a PKCS#1 byte stream.
    @see ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
 */
int32_t psRsaParsePkcs1PrivKey(psPool_t *pool,
    const unsigned char *p, psSize_t size,
    psRsaKey_t *key)
{
    RSA *rsa;

#  ifndef USE_D2I
    const unsigned char *end, *seq;
    int32_t version;
    psSize_t seqlen;
#  endif

#  ifdef USE_D2I
    if ((rsa = d2i_RSAPrivateKey(NULL, &p, size)) == NULL)
    {
        return PS_PARSE_FAIL;
    }
#  else
    if ((rsa = RSA_new()) == NULL)
    {
        return PS_MEM_FAIL;
    }
    end = p + size;
    if (getAsnSequence(&p, size, &seqlen) < 0)
    {
        RSA_free(rsa);
        goto L_FAIL;
    }
    seq = p;
    if (getAsnInteger(&p, (uint16_t) (end - p), &version) < 0 || version != 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->n) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->e) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->d) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->p) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->q) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->dmp1) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->dmq1) < 0 ||
        getBig(&p, (uint16_t) (end - p), &rsa->iqmp) < 0 ||
        (uint16_t) (p - seq) != seqlen)
    {

        RSA_free(rsa);
        goto L_FAIL;
    }
    rsa->version = version;
#  endif
    /* RSA_print_fp(stdout, rsa, 0); */
    *key = rsa;
    return PS_SUCCESS;
L_FAIL:
    psTraceIntCrypto("psRsaParsePkcs1PrivKey error on byte %d\n", p - (end - size));
    return PS_PARSE_FAIL;
}
Пример #4
0
/*
    Parse DER encoded asn.1 RSA public key out of a certificate stream.
    We reach here with 'pp' pointing to the byte after the algorithm identifier.
 */
int32_t psRsaParseAsnPubKey(psPool_t *pool,
    const unsigned char **pp, psSize_t len,
    psRsaKey_t *key, unsigned char sha1KeyHash[SHA1_HASH_SIZE])
{
# ifdef USE_SHA1
    psDigestContext_t dc;
# endif
    const unsigned char *p = *pp;
    RSA *rsa;
    psSize_t keylen;
# ifndef USE_D2I
    psSize_t seqlen;
# endif

    if (len < 1 || (*(p++) != ASN_BIT_STRING) ||
        getAsnLength(&p, len - 1, &keylen))
    {
        goto L_FAIL;
    }
    /* ignored bits field should be zero */
    if (*p++ != 0)
    {
        goto L_FAIL;
    }
    keylen--;
# ifdef USE_SHA1
    /* A public key hash is used in PKI tools (OCSP, Trusted CA indication).
        Standard RSA form - SHA-1 hash of the value of the BIT STRING
        subjectPublicKey [excluding the tag, length, and number of unused
        bits] */
    psSha1Init(&dc.sha1);
    psSha1Update(&dc.sha1, p, keylen);
    psSha1Final(&dc.sha1, sha1KeyHash);
# endif

# ifdef USE_D2I
    /* OpenSSL expects to parse after the ignored bits field */
    if ((rsa = d2i_RSAPublicKey(NULL, &p, keylen)) == NULL)
    {
        goto L_FAIL;
    }
# else
    /* We can manually create the structures as OpenSSL would */
    rsa = RSA_new();
    if (getAsnSequence(&p, keylen, &seqlen) < 0 ||
        getBig(&p, seqlen, &rsa->n) < 0 ||
        getBig(&p, seqlen, &rsa->e) < 0)
    {

        RSA_free(rsa);
        goto L_FAIL;
    }
# endif
    /* RSA_print_fp(stdout, rsa, 0); */
    *pp = p;
    *key = rsa;
    return PS_SUCCESS;
L_FAIL:
    psTraceIntCrypto("psRsaParseAsnPubKey error on byte %d\n", p - *pp);
    return PS_PARSE_FAIL;
}