secalgid.c (4090B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "secoid.h" 6 #include "secder.h" /* XXX remove this when remove the DERTemplate */ 7 #include "secasn1.h" 8 #include "secitem.h" 9 #include "secerr.h" 10 #include "nsshash.h" 11 12 SECOidTag 13 SECOID_GetAlgorithmTag(const SECAlgorithmID *id) 14 { 15 if (id == NULL || id->algorithm.data == NULL) 16 return SEC_OID_UNKNOWN; 17 18 return SECOID_FindOIDTag(&(id->algorithm)); 19 } 20 21 static PRBool 22 secoid_IsRSAPKCS1(SECOidTag which) 23 { 24 switch (which) { 25 case SEC_OID_PKCS1_RSA_ENCRYPTION: 26 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: 27 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: 28 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: 29 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: 30 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: 31 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: 32 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: 33 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: 34 return PR_TRUE; 35 default: 36 break; 37 } 38 return PR_FALSE; 39 } 40 41 SECStatus 42 SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *id, SECOidTag which, 43 SECItem *params) 44 { 45 SECOidData *oiddata; 46 PRBool add_null_param; 47 48 oiddata = SECOID_FindOIDByTag(which); 49 if (!oiddata) { 50 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 51 return SECFailure; 52 } 53 54 if (SECITEM_CopyItem(arena, &id->algorithm, &oiddata->oid)) 55 return SECFailure; 56 57 if ((secoid_IsRSAPKCS1(which)) || 58 (HASH_GetHashTypeByOidTag(which) != HASH_AlgNULL)) { 59 add_null_param = PR_TRUE; 60 } else { 61 add_null_param = PR_FALSE; 62 } 63 64 if (params) { 65 /* 66 * I am specifically *not* enforcing the following assertion 67 * (by following it up with an error and a return of failure) 68 * because I do not want to introduce any change in the current 69 * behavior. But I do want for us to notice if the following is 70 * ever true, because I do not think it should be so and probably 71 * signifies an error/bug somewhere. 72 */ 73 PORT_Assert(!add_null_param || (params->len == 2 && params->data[0] == SEC_ASN1_NULL && params->data[1] == 0)); 74 if (SECITEM_CopyItem(arena, &id->parameters, params)) { 75 return SECFailure; 76 } 77 } else { 78 /* 79 * Again, this is not considered an error. But if we assume 80 * that nobody tries to set the parameters field themselves 81 * (but always uses this routine to do that), then we should 82 * not hit the following assertion. Unless they forgot to zero 83 * the structure, which could also be a bad (and wrong) thing. 84 */ 85 PORT_Assert(id->parameters.data == NULL); 86 87 if (add_null_param) { 88 (void)SECITEM_AllocItem(arena, &id->parameters, 2); 89 if (id->parameters.data == NULL) { 90 return SECFailure; 91 } 92 id->parameters.data[0] = SEC_ASN1_NULL; 93 id->parameters.data[1] = 0; 94 } 95 } 96 97 return SECSuccess; 98 } 99 100 SECStatus 101 SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *to, 102 const SECAlgorithmID *from) 103 { 104 SECStatus rv; 105 106 rv = SECITEM_CopyItem(arena, &to->algorithm, &from->algorithm); 107 if (rv) 108 return rv; 109 rv = SECITEM_CopyItem(arena, &to->parameters, &from->parameters); 110 return rv; 111 } 112 113 void 114 SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit) 115 { 116 SECITEM_ZfreeItem(&algid->parameters, PR_FALSE); 117 SECITEM_FreeItem(&algid->algorithm, PR_FALSE); 118 if (freeit == PR_TRUE) 119 PORT_Free(algid); 120 } 121 122 SECComparison 123 SECOID_CompareAlgorithmID(SECAlgorithmID *a, SECAlgorithmID *b) 124 { 125 SECComparison rv; 126 127 rv = SECITEM_CompareItem(&a->algorithm, &b->algorithm); 128 if (rv) 129 return rv; 130 rv = SECITEM_CompareItem(&a->parameters, &b->parameters); 131 return rv; 132 }