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 + -
显示快捷键?