seckey.c

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

C
1,652
字号
		    return spki;		}	    }	    break;	  case dsaKey:	    /* DER encode the params. */	    rv_item = SEC_ASN1EncodeItem(arena, &params, &pubk->u.dsa.params,					 SECKEY_PQGParamsTemplate);	    if (rv_item != NULL) {		rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,					   SEC_OID_ANSIX9_DSA_SIGNATURE,					   &params);		if (rv == SECSuccess) {		    /*		     * DER encode the public key into the subjectPublicKeyInfo.		     */		    rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,						 pubk,						 SECKEY_DSAPublicKeyTemplate);		    if (rv_item != NULL) {			/*			 * The stored value is supposed to be a BIT_STRING,			 * so convert the length.			 */			spki->subjectPublicKey.len <<= 3;			/*			 * We got a good one; return it.			 */			return spki;		    }		}	    }	    SECITEM_FreeItem(&params, PR_FALSE);	    break;	  case keaKey:	  case dhKey: /* later... */	  break;  	  case fortezzaKey:#ifdef notdef	    /* encode the DSS parameters (PQG) */	    rv = FortezzaBuildParams(&params,pubk);	    if (rv != SECSuccess) break;	    /* set the algorithm */	    rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,				       SEC_OID_MISSI_KEA_DSS, &params);	    PORT_Free(params.data);	    if (rv == SECSuccess) {		/*		 * Encode the public key into the subjectPublicKeyInfo.		 * Fortezza key material is not standard DER		 */		rv = FortezzaEncodeCertKey(arena,&spki->subjectPublicKey,pubk);		if (rv == SECSuccess) {		    /*		     * The stored value is supposed to be a BIT_STRING,		     * so convert the length.		     */		    spki->subjectPublicKey.len <<= 3;		    /*		     * We got a good one; return it.		     */		    return spki;		}	    }#endif	    break;	  default:	    break;	}    } else {	PORT_SetError(SEC_ERROR_NO_MEMORY);    }    PORT_FreeArena(arena, PR_FALSE);    return NULL;}voidSECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki){    if (spki && spki->arena) {	PORT_FreeArena(spki->arena, PR_FALSE);    }}/* * this only works for RSA keys... need to do something * similiar to CERT_ExtractPublicKey for other key times. */SECKEYPublicKey *SECKEY_DecodeDERPublicKey(SECItem *pubkder){    PRArenaPool *arena;    SECKEYPublicKey *pubk;    SECStatus rv;    arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	PORT_SetError (SEC_ERROR_NO_MEMORY);	return NULL;    }    pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));    if (pubk != NULL) {	pubk->arena = arena;	pubk->pkcs11Slot = NULL;	pubk->pkcs11ID = 0;	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate,				pubkder);	if (rv == SECSuccess)	    return pubk;	SECKEY_DestroyPublicKey (pubk);    } else {	PORT_SetError (SEC_ERROR_NO_MEMORY);    }    PORT_FreeArena (arena, PR_FALSE);    return NULL;}/* * Decode a base64 ascii encoded DER encoded public key. */SECKEYPublicKey *SECKEY_ConvertAndDecodePublicKey(char *pubkstr){    SECKEYPublicKey *pubk;    SECStatus rv;    SECItem der;    rv = ATOB_ConvertAsciiToItem (&der, pubkstr);    if (rv != SECSuccess)	return NULL;    pubk = SECKEY_DecodeDERPublicKey (&der);    PORT_Free (der.data);    return pubk;}CERTSubjectPublicKeyInfo *SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider){    PRArenaPool *arena;    CERTSubjectPublicKeyInfo *spki;    SECStatus rv;    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return NULL;    }    spki = (CERTSubjectPublicKeyInfo *)		PORT_ArenaZAlloc(arena, sizeof (CERTSubjectPublicKeyInfo));    if (spki != NULL) {	spki->arena = arena;	rv = SEC_ASN1DecodeItem(arena,spki,				CERT_SubjectPublicKeyInfoTemplate,spkider);	if (rv == SECSuccess)	    return spki;	SECKEY_DestroySubjectPublicKeyInfo(spki);    } else {	PORT_SetError(SEC_ERROR_NO_MEMORY);    }    PORT_FreeArena(arena, PR_FALSE);    return NULL;}/* * Decode a base64 ascii encoded DER encoded subject public key info. */CERTSubjectPublicKeyInfo *SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(char *spkistr){    CERTSubjectPublicKeyInfo *spki;    SECStatus rv;    SECItem der;    rv = ATOB_ConvertAsciiToItem(&der, spkistr);    if (rv != SECSuccess)	return NULL;    spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);    PORT_Free(der.data);    return spki;}/* * Decode a base64 ascii encoded DER encoded public key and challenge * Verify digital signature and make sure challenge matches */CERTSubjectPublicKeyInfo *SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,								void *wincx){    CERTSubjectPublicKeyInfo *spki = NULL;    CERTPublicKeyAndChallenge pkac;    SECStatus rv;    SECItem signedItem;    PRArenaPool *arena = NULL;    CERTSignedData sd;    SECItem sig;    SECKEYPublicKey *pubKey = NULL;    int len;        signedItem.data = NULL;        /* convert the base64 encoded data to binary */    rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr);    if (rv != SECSuccess) {	goto loser;    }    /* create an arena */    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	goto loser;    }    /* decode the outer wrapping of signed data */    PORT_Memset(&sd, 0, sizeof(CERTSignedData));    rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem );    if ( rv ) {	goto loser;    }    /* decode the public key and challenge wrapper */    PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge));    rv = SEC_ASN1DecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate, 			    &sd.data);    if ( rv ) {	goto loser;    }    /* decode the subject public key info */    spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki);    if ( spki == NULL ) {	goto loser;    }        /* get the public key */    pubKey = seckey_ExtractPublicKey(spki);    if ( pubKey == NULL ) {	goto loser;    }    /* check the signature */    sig = sd.signature;    DER_ConvertBitString(&sig);    rv = VFY_VerifyData(sd.data.data, sd.data.len, pubKey, &sig,			SECOID_GetAlgorithmTag(&(sd.signatureAlgorithm)), wincx);    if ( rv != SECSuccess ) {	goto loser;    }        /* check the challenge */    if ( challenge ) {	len = PORT_Strlen(challenge);	/* length is right */	if ( len != pkac.challenge.len ) {	    goto loser;	}	/* actual data is right */	if ( PORT_Memcmp(challenge, pkac.challenge.data, len) != 0 ) {	    goto loser;	}    }    goto done;loser:    /* make sure that we return null if we got an error */    if ( spki ) {	SECKEY_DestroySubjectPublicKeyInfo(spki);    }    spki = NULL;    done:    if ( signedItem.data ) {	PORT_Free(signedItem.data);    }    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }    if ( pubKey ) {	SECKEY_DestroyPublicKey(pubKey);    }        return spki;}voidSECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk,			     PRBool freeit){    PRArenaPool *poolp;    if(pvk != NULL) {	if(pvk->arena) {	    poolp = pvk->arena;	    /* zero structure since PORT_FreeArena does not support	     * this yet.	     */	    PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len);	    PORT_Memset((char *)pvk, 0, sizeof(*pvk));	    if(freeit == PR_TRUE) {		PORT_FreeArena(poolp, PR_TRUE);	    } else {		pvk->arena = poolp;	    }	} else {	    SECITEM_ZfreeItem(&pvk->version, PR_FALSE);	    SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE);	    SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE);	    PORT_Memset((char *)pvk, 0, sizeof(pvk));	    if(freeit == PR_TRUE) {		PORT_Free(pvk);	    }	}    }}voidSECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,				      PRBool freeit){    PRArenaPool *poolp;    if(epki != NULL) {	if(epki->arena) {	    poolp = epki->arena;	    /* zero structure since PORT_FreeArena does not support	     * this yet.	     */	    PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len);	    PORT_Memset((char *)epki, 0, sizeof(*epki));	    if(freeit == PR_TRUE) {		PORT_FreeArena(poolp, PR_TRUE);	    } else {		epki->arena = poolp;	    }	} else {	    SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE);	    SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE);	    PORT_Memset((char *)epki, 0, sizeof(epki));	    if(freeit == PR_TRUE) {		PORT_Free(epki);	    }	}    }}SECStatusSECKEY_CopyPrivateKeyInfo(PRArenaPool *poolp,			  SECKEYPrivateKeyInfo *to,			  SECKEYPrivateKeyInfo *from){    SECStatus rv = SECFailure;    if((to == NULL) || (from == NULL)) {	return SECFailure;    }    rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);    if(rv != SECSuccess) {	return SECFailure;    }    rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey);    if(rv != SECSuccess) {	return SECFailure;    }    rv = SECITEM_CopyItem(poolp, &to->version, &from->version);    return rv;}SECStatusSECKEY_CopyEncryptedPrivateKeyInfo(PRArenaPool *poolp, 				   SECKEYEncryptedPrivateKeyInfo *to,				   SECKEYEncryptedPrivateKeyInfo *from){    SECStatus rv = SECFailure;    if((to == NULL) || (from == NULL)) {	return SECFailure;    }    rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);    if(rv != SECSuccess) {	return SECFailure;    }    rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData);    return rv;}KeyTypeSECKEY_GetPrivateKeyType(SECKEYPrivateKey *privKey){   return privKey->keyType;}KeyTypeSECKEY_GetPublicKeyType(SECKEYPublicKey *pubKey){   return pubKey->keyType;}

⌨️ 快捷键说明

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