seckey.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,652 行 · 第 1/4 页

C
1,652
字号
                        return SECFailure;        }    } else {        return SECFailure;  /* return failure if oid is NULL */      }    /* at this point the subject cert has no pqg parameters and the     * issuer cert has a DSA or fortezza public key.  Update the issuer's     * pqg parameters with a recursive call to this same function. */    rv = seckey_UpdateCertPQGChain(issuerCert, count);    if (rv != SECSuccess) return rv;    /* ensure issuer has pqg parameters */    issuerSpki=&issuerCert->subjectPublicKeyInfo;    if (issuerSpki->algorithm.parameters.len == 0) {        rv = SECFailure;     }    /* if update was successful and pqg params present, then copy the     * parameters to the subject cert's key. */    if (rv == SECSuccess) {        rv = SECITEM_CopyItem(subjectCert->arena,                              &subjectSpki->algorithm.parameters, 	   		      &issuerSpki->algorithm.parameters);    }    return rv;} SECStatusSECKEY_UpdateCertPQG(CERTCertificate * subjectCert){    return(seckey_UpdateCertPQGChain(subjectCert,0));}   /* Decode the PQG parameters.  The params could be stored in two * possible formats, the old fortezza-only wrapped format or * the standard DER encoded format.   Store the decoded parameters in an * old fortezza cert data structure */ SECStatusSECKEY_FortezzaDecodePQGtoOld(PRArenaPool *arena, SECKEYPublicKey *pubk,                              SECItem *params) {        SECStatus rv;	PQGDualParams dual_params;    if (params == NULL) return SECFailure;         if (params->data == NULL) return SECFailure;    /* Check if params use the standard format.     * The value 0xa1 will appear in the first byte of the parameter data     * if the PQG parameters are not using the standard format. This     * code should be changed to use a better method to detect non-standard     * parameters.    */    if ((params->data[0] != 0xa1) &&        (params->data[0] != 0xa0)) {            /* PQG params are in the standard format */	    /* Store DSA PQG parameters */            rv = SEC_ASN1DecodeItem(arena, &pubk->u.fortezza.params,                              SECKEY_PQGParamsTemplate,                              params);	    if (rv == SECSuccess) {	        /* Copy the DSA PQG parameters to the KEA PQG parameters. */	        rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime,                                      &pubk->u.fortezza.params.prime);                if (rv != SECSuccess) return rv;                rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime,                                      &pubk->u.fortezza.params.subPrime);                if (rv != SECSuccess) return rv;                rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base,                                      &pubk->u.fortezza.params.base);                if (rv != SECSuccess) return rv;            }    } else {	dual_params.CommParams.prime.len = 0;        dual_params.CommParams.subPrime.len = 0;	dual_params.CommParams.base.len = 0;	dual_params.DiffParams.DiffDSAParams.prime.len = 0;        dual_params.DiffParams.DiffDSAParams.subPrime.len = 0;	dual_params.DiffParams.DiffDSAParams.base.len = 0;        /* else the old fortezza-only wrapped format is used. */	if (params->data[0] == 0xa1) {            rv = SEC_ASN1DecodeItem(arena, &dual_params, 				SECKEY_FortezzaPreParamTemplate, params);	} else {            rv = SEC_ASN1DecodeItem(arena, &dual_params, 	   			    SECKEY_FortezzaAltPreParamTemplate, params);        }        if (rv < 0) return rv;	        if ( (dual_params.CommParams.prime.len > 0) &&             (dual_params.CommParams.subPrime.len > 0) &&              (dual_params.CommParams.base.len > 0) ) {            /* copy in common params */	    	    rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.prime,                                  &dual_params.CommParams.prime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.subPrime,                                  &dual_params.CommParams.subPrime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.base,                                  &dual_params.CommParams.base);	    /* Copy the DSA PQG parameters to the KEA PQG parameters. */	    rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime,                                  &pubk->u.fortezza.params.prime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime,                                  &pubk->u.fortezza.params.subPrime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base,                                  &pubk->u.fortezza.params.base);            if (rv != SECSuccess) return rv;        } else {	    /* else copy in different params */	    /* copy DSA PQG parameters */	    rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.prime,                                  &dual_params.DiffParams.DiffDSAParams.prime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.subPrime,                                  &dual_params.DiffParams.DiffDSAParams.subPrime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.base,                                  &dual_params.DiffParams.DiffDSAParams.base);	    /* copy KEA PQG parameters */	    rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime,                                  &dual_params.DiffParams.DiffKEAParams.prime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime,                                  &dual_params.DiffParams.DiffKEAParams.subPrime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base,                                  &dual_params.DiffParams.DiffKEAParams.base);        }           }    return rv;}/* Decode the DSA PQG parameters.  The params could be stored in two * possible formats, the old fortezza-only wrapped format or * the normal standard format.  Store the decoded parameters in * a V3 certificate data structure.  */ SECStatusSECKEY_DSADecodePQG(PRArenaPool *arena, SECKEYPublicKey *pubk, SECItem *params) {        SECStatus rv;	PQGDualParams dual_params;    if (params == NULL) return SECFailure;         if (params->data == NULL) return SECFailure;    /* Check if params use the standard format.     * The value 0xa1 will appear in the first byte of the parameter data     * if the PQG parameters are not using the standard format.  This     * code should be changed to use a better method to detect non-standard     * parameters.    */    if ((params->data[0] != 0xa1) &&        (params->data[0] != 0xa0)) {             /* PQG params are in the standard format */         rv = SEC_ASN1DecodeItem(arena, &pubk->u.dsa.params,                             SECKEY_PQGParamsTemplate,                             params);    } else {	dual_params.CommParams.prime.len = 0;        dual_params.CommParams.subPrime.len = 0;	dual_params.CommParams.base.len = 0;	dual_params.DiffParams.DiffDSAParams.prime.len = 0;        dual_params.DiffParams.DiffDSAParams.subPrime.len = 0;	dual_params.DiffParams.DiffDSAParams.base.len = 0;        /* else the old fortezza-only wrapped format is used. */        if (params->data[0] == 0xa1) {            rv = SEC_ASN1DecodeItem(arena, &dual_params, 				SECKEY_FortezzaPreParamTemplate, params);	} else {            rv = SEC_ASN1DecodeItem(arena, &dual_params, 	   			    SECKEY_FortezzaAltPreParamTemplate, params);        }        if (rv < 0) return rv;        if ( (dual_params.CommParams.prime.len > 0) &&             (dual_params.CommParams.subPrime.len > 0) &&              (dual_params.CommParams.base.len > 0) ) {            /* copy in common params */	    	    rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,                                  &dual_params.CommParams.prime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,                                  &dual_params.CommParams.subPrime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,                                  &dual_params.CommParams.base);        } else {	    /* else copy in different params */	    /* copy DSA PQG parameters */	    rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,                                  &dual_params.DiffParams.DiffDSAParams.prime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,                                  &dual_params.DiffParams.DiffDSAParams.subPrime);            if (rv != SECSuccess) return rv;            rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,                                  &dual_params.DiffParams.DiffDSAParams.base);        }    }    return rv;}/* Decodes the DER encoded fortezza public key and stores the results in a * structure of type SECKEYPublicKey. */SECStatusSECKEY_FortezzaDecodeCertKey(PRArenaPool *arena, SECKEYPublicKey *pubk,                             SECItem *rawkey, SECItem *params) {	unsigned char *rawptr = rawkey->data;	unsigned char *end = rawkey->data + rawkey->len;	unsigned char *clearptr;	/* first march down and decode the raw key data */	/* version */		pubk->u.fortezza.KEAversion = *rawptr++;	if (*rawptr++ != 0x01) {		return SECFailure;	}	/* KMID */	PORT_Memcpy(pubk->u.fortezza.KMID,rawptr,				sizeof(pubk->u.fortezza.KMID));	rawptr += sizeof(pubk->u.fortezza.KMID);	/* clearance (the string up to the first byte with the hi-bit on */	clearptr = rawptr;	while ((rawptr < end) && (*rawptr++ & 0x80));	if (rawptr >= end) { return SECFailure; }	pubk->u.fortezza.clearance.len = rawptr - clearptr;	pubk->u.fortezza.clearance.data = 		(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.clearance.len);	if (pubk->u.fortezza.clearance.data == NULL) {		return SECFailure;	}	PORT_Memcpy(pubk->u.fortezza.clearance.data,clearptr,					pubk->u.fortezza.clearance.len);	/* KEAPrivilege (the string up to the first byte with the hi-bit on */	clearptr = rawptr;	while ((rawptr < end) && (*rawptr++ & 0x80));	if (rawptr >= end) { return SECFailure; }	pubk->u.fortezza.KEApriviledge.len = rawptr - clearptr;	pubk->u.fortezza.KEApriviledge.data = 		(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.KEApriviledge.len);	if (pubk->u.fortezza.KEApriviledge.data == NULL) {		return SECFailure;	}	PORT_Memcpy(pubk->u.fortezza.KEApriviledge.data,clearptr,				pubk->u.fortezza.KEApriviledge.len);	/* now copy the key. The next to bytes are the key length, and the	 * key follows */	pubk->u.fortezza.KEAKey.len = (*rawptr << 8) | rawptr[1];	rawptr += 2;	if (rawptr+pubk->u.fortezza.KEAKey.len > end) { return SECFailure; }	pubk->u.fortezza.KEAKey.data = 			(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.KEAKey.len);	if (pubk->u.fortezza.KEAKey.data == NULL) {		return SECFailure;	}	PORT_Memcpy(pubk->u.fortezza.KEAKey.data,rawptr,					pubk->u.fortezza.KEAKey.len);	rawptr += pubk->u.fortezza.KEAKey.len;	/* shared key */	if (rawptr >= end) {	    pubk->u.fortezza.DSSKey.len = pubk->u.fortezza.KEAKey.len;	    /* this depends on the fact that we are going to get freed with an	     * ArenaFree call. We cannot free DSSKey and KEAKey separately */	    pubk->u.fortezza.DSSKey.data=					pubk->u.fortezza.KEAKey.data;	    pubk->u.fortezza.DSSpriviledge.len = 				pubk->u.fortezza.KEApriviledge.len;	    pubk->u.fortezza.DSSpriviledge.data =			pubk->u.fortezza.DSSpriviledge.data;	    goto done;	}			/* DSS Version is next */	pubk->u.fortezza.DSSversion = *rawptr++;	if (*rawptr++ != 2) {		return SECFailure;	}	/* DSSPrivilege (the string up to the first byte with the hi-bit on */	clearptr = rawptr;	while ((rawptr < end) && (*rawptr++ & 0x80));	if (rawptr >= end) { return SECFailure; }	pubk->u.fortezza.DSSpriviledge.len = rawptr - clearptr;	pubk->u.fortezza.DSSpriviledge.data = 		(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.DSSpriviledge.len);	if (pubk->u.fortezza.DSSpriviledge.data == NULL) {		return SECFailure;	}	PORT_Memcpy(pubk->u.fortezza.DSSpriviledge.data,clearptr,				pubk->u.fortezza.DSSpriviledge.len);	/* finally copy the DSS key. The next to bytes are the key length,	 *  and the key follows */	pubk->u.fortezza.DSSKey.len = (*rawptr << 8) | rawptr[1];	rawptr += 2;	if (rawptr+pubk->u.fortezza.DSSKey.len > end){ return SECFailure; }	pubk->u.fortezza.DSSKey.data = 			(unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.DSSKey.len);	if (pubk->u.fortezza.DSSKey.data == NULL) {		return SECFailure;	}	PORT_Memcpy(pubk->u.fortezza.DSSKey.data,rawptr,					pubk->u.fortezza.DSSKey.len);	/* ok, now we decode the parameters */done:        return SECKEY_FortezzaDecodePQGtoOld(arena, pubk, params);}/* Function used to determine what kind of cert we are dealing with. */KeyType CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki) {    int tag;    KeyType keyType;    tag = SECOID_GetAlgorithmTag(&spki->algorithm);    switch (tag) {      case SEC_OID_X500_RSA_ENCRYPTION:      case SEC_OID_PKCS1_RSA_ENCRYPTION:	keyType = rsaKey;	break;      case SEC_OID_ANSIX9_DSA_SIGNATURE:	keyType = dsaKey;	break;      case SEC_OID_MISSI_KEA_DSS_OLD:      case SEC_OID_MISSI_KEA_DSS:      case SEC_OID_MISSI_DSS_OLD:      case SEC_OID_MISSI_DSS:  	keyType = fortezzaKey;	break;      case SEC_OID_MISSI_KEA:      case SEC_OID_MISSI_ALT_KEA:	keyType = keaKey;	break;      case SEC_OID_X942_DIFFIE_HELMAN_KEY:	keyType = dhKey;      default:	keyType = nullKey;    }    return keyType;}static SECKEYPublicKey *seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki){    SECKEYPublicKey *pubk;    SECItem os;    SECStatus rv;    PRArenaPool *arena;    SECOidTag tag;    arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?