diff options
Diffstat (limited to 'security/nss/lib/util/secalgid.c')
-rw-r--r-- | security/nss/lib/util/secalgid.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/security/nss/lib/util/secalgid.c b/security/nss/lib/util/secalgid.c new file mode 100644 index 000000000..718bb03ea --- /dev/null +++ b/security/nss/lib/util/secalgid.c @@ -0,0 +1,129 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "secoid.h" +#include "secder.h" /* XXX remove this when remove the DERTemplate */ +#include "secasn1.h" +#include "secitem.h" +#include "secerr.h" + +SECOidTag +SECOID_GetAlgorithmTag(const SECAlgorithmID *id) +{ + if (id == NULL || id->algorithm.data == NULL) + return SEC_OID_UNKNOWN; + + return SECOID_FindOIDTag(&(id->algorithm)); +} + +SECStatus +SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *id, SECOidTag which, + SECItem *params) +{ + SECOidData *oiddata; + PRBool add_null_param; + + oiddata = SECOID_FindOIDByTag(which); + if (!oiddata) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } + + if (SECITEM_CopyItem(arena, &id->algorithm, &oiddata->oid)) + return SECFailure; + + switch (which) { + case SEC_OID_MD2: + case SEC_OID_MD4: + case SEC_OID_MD5: + case SEC_OID_SHA1: + case SEC_OID_SHA224: + case SEC_OID_SHA256: + case SEC_OID_SHA384: + case SEC_OID_SHA512: + case SEC_OID_PKCS1_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: + add_null_param = PR_TRUE; + break; + default: + add_null_param = PR_FALSE; + break; + } + + if (params) { + /* + * I am specifically *not* enforcing the following assertion + * (by following it up with an error and a return of failure) + * because I do not want to introduce any change in the current + * behavior. But I do want for us to notice if the following is + * ever true, because I do not think it should be so and probably + * signifies an error/bug somewhere. + */ + PORT_Assert(!add_null_param || (params->len == 2 && params->data[0] == SEC_ASN1_NULL && params->data[1] == 0)); + if (SECITEM_CopyItem(arena, &id->parameters, params)) { + return SECFailure; + } + } else { + /* + * Again, this is not considered an error. But if we assume + * that nobody tries to set the parameters field themselves + * (but always uses this routine to do that), then we should + * not hit the following assertion. Unless they forgot to zero + * the structure, which could also be a bad (and wrong) thing. + */ + PORT_Assert(id->parameters.data == NULL); + + if (add_null_param) { + (void)SECITEM_AllocItem(arena, &id->parameters, 2); + if (id->parameters.data == NULL) { + return SECFailure; + } + id->parameters.data[0] = SEC_ASN1_NULL; + id->parameters.data[1] = 0; + } + } + + return SECSuccess; +} + +SECStatus +SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *to, + const SECAlgorithmID *from) +{ + SECStatus rv; + + rv = SECITEM_CopyItem(arena, &to->algorithm, &from->algorithm); + if (rv) + return rv; + rv = SECITEM_CopyItem(arena, &to->parameters, &from->parameters); + return rv; +} + +void +SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit) +{ + SECITEM_FreeItem(&algid->parameters, PR_FALSE); + SECITEM_FreeItem(&algid->algorithm, PR_FALSE); + if (freeit == PR_TRUE) + PORT_Free(algid); +} + +SECComparison +SECOID_CompareAlgorithmID(SECAlgorithmID *a, SECAlgorithmID *b) +{ + SECComparison rv; + + rv = SECITEM_CompareItem(&a->algorithm, &b->algorithm); + if (rv) + return rv; + rv = SECITEM_CompareItem(&a->parameters, &b->parameters); + return rv; +} |