OLD | NEW |
(Empty) | |
| 1 diff --git a/nss/lib/pk11wrap/pk11obj.c b/nss/lib/pk11wrap/pk11obj.c |
| 2 index 84268ab..7080294 100644 |
| 3 --- a/nss/lib/pk11wrap/pk11obj.c |
| 4 +++ b/nss/lib/pk11wrap/pk11obj.c |
| 5 @@ -914,17 +914,11 @@ PK11_Encrypt(PK11SymKey *symKey, |
| 6 return SECSuccess; |
| 7 } |
| 8 |
| 9 -/* |
| 10 - * Now SSL 2.0 uses raw RSA stuff. These next to functions *must* use |
| 11 - * RSA keys, or they'll fail. We do the checks up front. If anyone comes |
| 12 - * up with a meaning for rawdecrypt for any other public key operation, |
| 13 - * then we need to move this check into some of PK11_PubDecrypt callers, |
| 14 - * (namely SSL 2.0). |
| 15 - */ |
| 16 static SECStatus |
| 17 -pk11_PrivDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, |
| 18 - unsigned *outLen, unsigned int maxLen, unsigned char *enc, |
| 19 - unsigned encLen, CK_MECHANISM_PTR mech) |
| 20 +pk11_PrivDecryptRaw(SECKEYPrivateKey *key, |
| 21 + unsigned char *data, unsigned *outLen, unsigned int maxLen
, |
| 22 + const unsigned char *enc, unsigned encLen, |
| 23 + CK_MECHANISM_PTR mech) |
| 24 { |
| 25 PK11SlotInfo *slot = key->pkcs11Slot; |
| 26 CK_ULONG out = maxLen; |
| 27 @@ -960,11 +954,12 @@ pk11_PrivDecryptRaw(SECKEYPrivateKey *key, unsigned char *
data, |
| 28 * do C_Login with CKU_CONTEXT_SPECIFIC |
| 29 * between C_DecryptInit and C_Decrypt |
| 30 * ... But see note above about servers */ |
| 31 - if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock))
{ |
| 32 + if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) { |
| 33 PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE); |
| 34 } |
| 35 |
| 36 - crv = PK11_GETTAB(slot)->C_Decrypt(session,enc, encLen, data, &out); |
| 37 + crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen, |
| 38 + data, &out); |
| 39 if (haslock) PK11_ExitSlotMonitor(slot); |
| 40 pk11_CloseSession(slot,session,owner); |
| 41 *outLen = out; |
| 42 @@ -976,41 +971,37 @@ pk11_PrivDecryptRaw(SECKEYPrivateKey *key, unsigned char *
data, |
| 43 } |
| 44 |
| 45 SECStatus |
| 46 -PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, |
| 47 - unsigned *outLen, unsigned int maxLen, unsigned char *enc, |
| 48 - unsigned encLen) |
| 49 +PK11_PubDecryptRaw(SECKEYPrivateKey *key, |
| 50 + unsigned char *data, unsigned *outLen, unsigned int maxLen, |
| 51 + const unsigned char *enc, unsigned encLen) |
| 52 { |
| 53 CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 }; |
| 54 return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech); |
| 55 } |
| 56 |
| 57 SECStatus |
| 58 -PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, unsigned char *data, |
| 59 - unsigned *outLen, unsigned int maxLen, unsigned char *enc, |
| 60 - unsigned encLen) |
| 61 +PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, |
| 62 + unsigned char *data, unsigned *outLen, unsigned int maxLe
n, |
| 63 + const unsigned char *enc, unsigned encLen) |
| 64 { |
| 65 CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 }; |
| 66 return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech); |
| 67 } |
| 68 |
| 69 static SECStatus |
| 70 -pk11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc, |
| 71 - unsigned char *data, unsigned dataLen, |
| 72 - CK_MECHANISM_PTR mech, void *wincx) |
| 73 +pk11_PubEncryptRaw(SECKEYPublicKey *key, |
| 74 + unsigned char *out, unsigned int *outLen, |
| 75 + unsigned int maxLen, |
| 76 + const unsigned char *data, unsigned dataLen, |
| 77 + CK_MECHANISM_PTR mech, void *wincx) |
| 78 { |
| 79 PK11SlotInfo *slot; |
| 80 CK_OBJECT_HANDLE id; |
| 81 - CK_ULONG out; |
| 82 + CK_ULONG len = maxLen; |
| 83 PRBool owner = PR_TRUE; |
| 84 CK_SESSION_HANDLE session; |
| 85 CK_RV crv; |
| 86 |
| 87 - if (!key || key->keyType != rsaKey) { |
| 88 - PORT_SetError( SEC_ERROR_BAD_KEY ); |
| 89 - return SECFailure; |
| 90 - } |
| 91 - out = SECKEY_PublicKeyStrength(key); |
| 92 - |
| 93 slot = PK11_GetBestSlotWithAttributes(mech->mechanism,CKF_ENCRYPT,0,wincx); |
| 94 if (slot == NULL) { |
| 95 PORT_SetError( SEC_ERROR_NO_MODULE ); |
| 96 @@ -1035,10 +1026,12 @@ pk11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *
enc, |
| 97 PORT_SetError( PK11_MapError(crv) ); |
| 98 return SECFailure; |
| 99 } |
| 100 - crv = PK11_GETTAB(slot)->C_Encrypt(session,data,dataLen,enc,&out); |
| 101 + crv = PK11_GETTAB(slot)->C_Encrypt(session,(unsigned char *)data,dataLen, |
| 102 + out,&len); |
| 103 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 104 pk11_CloseSession(slot,session,owner); |
| 105 PK11_FreeSlot(slot); |
| 106 + *outLen = len; |
| 107 if (crv != CKR_OK) { |
| 108 PORT_SetError( PK11_MapError(crv) ); |
| 109 return SECFailure; |
| 110 @@ -1047,19 +1040,69 @@ pk11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *
enc, |
| 111 } |
| 112 |
| 113 SECStatus |
| 114 -PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc, |
| 115 - unsigned char *data, unsigned dataLen, void *wincx) |
| 116 +PK11_PubEncryptRaw(SECKEYPublicKey *key, |
| 117 + unsigned char *enc, |
| 118 + const unsigned char *data, unsigned dataLen, |
| 119 + void *wincx) |
| 120 { |
| 121 CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 }; |
| 122 - return pk11_PubEncryptRaw(key, enc, data, dataLen, &mech, wincx); |
| 123 + unsigned int outLen; |
| 124 + if (!key || key->keyType != rsaKey) { |
| 125 + PORT_SetError(SEC_ERROR_BAD_KEY); |
| 126 + return SECFailure; |
| 127 + } |
| 128 + outLen = SECKEY_PublicKeyStrength(key); |
| 129 + return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech, |
| 130 + wincx); |
| 131 } |
| 132 |
| 133 SECStatus |
| 134 -PK11_PubEncryptPKCS1(SECKEYPublicKey *key, unsigned char *enc, |
| 135 - unsigned char *data, unsigned dataLen, void *wincx) |
| 136 +PK11_PubEncryptPKCS1(SECKEYPublicKey *key, |
| 137 + unsigned char *enc, |
| 138 + const unsigned char *data, unsigned dataLen, |
| 139 + void *wincx) |
| 140 { |
| 141 CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 }; |
| 142 - return pk11_PubEncryptRaw(key, enc, data, dataLen, &mech, wincx); |
| 143 + unsigned int outLen; |
| 144 + if (!key || key->keyType != rsaKey) { |
| 145 + PORT_SetError(SEC_ERROR_BAD_KEY); |
| 146 + return SECFailure; |
| 147 + } |
| 148 + outLen = SECKEY_PublicKeyStrength(key); |
| 149 + return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech, |
| 150 + wincx); |
| 151 +} |
| 152 + |
| 153 +SECStatus |
| 154 +PK11_PrivDecrypt(SECKEYPrivateKey *key, |
| 155 + CK_MECHANISM_TYPE mechanism, SECItem *param, |
| 156 + unsigned char *out, unsigned int *outLen, |
| 157 + unsigned int maxLen, |
| 158 + const unsigned char *enc, unsigned encLen) |
| 159 +{ |
| 160 + CK_MECHANISM mech = { mechanism, NULL, 0 }; |
| 161 + if (param) { |
| 162 + mech.pParameter = param->data; |
| 163 + mech.ulParameterLen = param->len; |
| 164 + } |
| 165 + return pk11_PrivDecryptRaw(key, out, outLen, maxLen, enc, encLen, &mech); |
| 166 +} |
| 167 + |
| 168 +SECStatus |
| 169 +PK11_PubEncrypt(SECKEYPublicKey *key, |
| 170 + CK_MECHANISM_TYPE mechanism, SECItem *param, |
| 171 + unsigned char *out, unsigned int *outLen, |
| 172 + unsigned int maxLen, |
| 173 + const unsigned char *data, unsigned dataLen, |
| 174 + void *wincx) |
| 175 +{ |
| 176 + CK_MECHANISM mech = { mechanism, NULL, 0 }; |
| 177 + if (param) { |
| 178 + mech.pParameter = param->data; |
| 179 + mech.ulParameterLen = param->len; |
| 180 + } |
| 181 + return pk11_PubEncryptRaw(key, out, outLen, maxLen, data, dataLen, &mech, |
| 182 + wincx); |
| 183 } |
| 184 |
| 185 SECKEYPrivateKey * |
| 186 diff --git a/nss/lib/pk11wrap/pk11pub.h b/nss/lib/pk11wrap/pk11pub.h |
| 187 index 2f004b1..c3beef9 100644 |
| 188 --- a/nss/lib/pk11wrap/pk11pub.h |
| 189 +++ b/nss/lib/pk11wrap/pk11pub.h |
| 190 @@ -520,18 +520,38 @@ SECStatus PK11_Encrypt(PK11SymKey *symKey, |
| 191 const unsigned char *data, unsigned int dataLen); |
| 192 |
| 193 /* note: despite the name, this function takes a private key. */ |
| 194 -SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, |
| 195 - unsigned *outLen, unsigned int maxLen, unsigned char *enc, unsigned encLen); |
| 196 +SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key, |
| 197 + unsigned char *data, unsigned *outLen, |
| 198 + unsigned int maxLen, |
| 199 + const unsigned char *enc, unsigned encLen); |
| 200 #define PK11_PrivDecryptRaw PK11_PubDecryptRaw |
| 201 /* The encrypt function that complements the above decrypt function. */ |
| 202 -SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc, |
| 203 - unsigned char *data, unsigned dataLen, void *wincx); |
| 204 - |
| 205 -SECStatus PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, unsigned char *data, |
| 206 - unsigned *outLen, unsigned int maxLen, unsigned char *enc, unsigned encLen); |
| 207 +SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key, |
| 208 + unsigned char *enc, |
| 209 + const unsigned char *data, unsigned dataLen, |
| 210 + void *wincx); |
| 211 + |
| 212 +SECStatus PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, |
| 213 + unsigned char *data, unsigned *outLen, |
| 214 + unsigned int maxLen, |
| 215 + const unsigned char *enc, unsigned encLen); |
| 216 /* The encrypt function that complements the above decrypt function. */ |
| 217 -SECStatus PK11_PubEncryptPKCS1(SECKEYPublicKey *key, unsigned char *enc, |
| 218 - unsigned char *data, unsigned dataLen, void *wincx); |
| 219 +SECStatus PK11_PubEncryptPKCS1(SECKEYPublicKey *key, |
| 220 + unsigned char *enc, |
| 221 + const unsigned char *data, unsigned dataLen, |
| 222 + void *wincx); |
| 223 + |
| 224 +SECStatus PK11_PrivDecrypt(SECKEYPrivateKey *key, |
| 225 + CK_MECHANISM_TYPE mechanism, SECItem *param, |
| 226 + unsigned char *out, unsigned int *outLen, |
| 227 + unsigned int maxLen, |
| 228 + const unsigned char *enc, unsigned int encLen); |
| 229 +SECStatus PK11_PubEncrypt(SECKEYPublicKey *key, |
| 230 + CK_MECHANISM_TYPE mechanism, SECItem *param, |
| 231 + unsigned char *out, unsigned int *outLen, |
| 232 + unsigned int maxLen, |
| 233 + const unsigned char *data, unsigned int dataLen, |
| 234 + void *wincx); |
| 235 |
| 236 SECStatus PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, |
| 237 SECKEYPrivateKeyInfo *pki, SECItem *nickname, |
| 238 diff --git a/nss/lib/softoken/pkcs11.c b/nss/lib/softoken/pkcs11.c |
| 239 index da1e1b2..5a2b1e8 100644 |
| 240 --- a/nss/lib/softoken/pkcs11.c |
| 241 +++ b/nss/lib/softoken/pkcs11.c |
| 242 @@ -266,6 +266,8 @@ static const struct mechanismList mechanisms[] = { |
| 243 CKF_DUZ_IT_ALL}, PR_TRUE}, |
| 244 {CKM_RSA_PKCS_PSS, {RSA_MIN_MODULUS_BITS,CK_MAX, |
| 245 CKF_SN_VR}, PR_TRUE}, |
| 246 + {CKM_RSA_PKCS_OAEP, {RSA_MIN_MODULUS_BITS,CK_MAX, |
| 247 + CKF_EN_DE_WR_UN}, PR_TRUE}, |
| 248 #ifdef SFTK_RSA9796_SUPPORTED |
| 249 {CKM_RSA_9796, {RSA_MIN_MODULUS_BITS,CK_MAX, |
| 250 CKF_DUZ_IT_ALL}, PR_TRUE}, |
| 251 diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c |
| 252 index 472b71a..080dfda 100644 |
| 253 --- a/nss/lib/softoken/pkcs11c.c |
| 254 +++ b/nss/lib/softoken/pkcs11c.c |
| 255 @@ -302,6 +302,46 @@ GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech) |
| 256 } |
| 257 } |
| 258 |
| 259 +/* |
| 260 + * Returns true if "params" contains a valid set of PSS parameters |
| 261 + */ |
| 262 +static PRBool |
| 263 +sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params) |
| 264 +{ |
| 265 + if (!params) { |
| 266 + return PR_FALSE; |
| 267 + } |
| 268 + if (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL || |
| 269 + GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) { |
| 270 + return PR_FALSE; |
| 271 + } |
| 272 + return PR_TRUE; |
| 273 +} |
| 274 + |
| 275 +/* |
| 276 + * Returns true if "params" contains a valid set of OAEP parameters |
| 277 + */ |
| 278 +static PRBool |
| 279 +sftk_ValidateOaepParams(const CK_RSA_PKCS_OAEP_PARAMS *params) |
| 280 +{ |
| 281 + if (!params) { |
| 282 + return PR_FALSE; |
| 283 + } |
| 284 + /* The requirements of ulSourceLen/pSourceData come from PKCS #11, which |
| 285 + * state: |
| 286 + * If the parameter is empty, pSourceData must be NULL and |
| 287 + * ulSourceDataLen must be zero. |
| 288 + */ |
| 289 + if (params->source != CKZ_DATA_SPECIFIED || |
| 290 + (GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) || |
| 291 + (GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) || |
| 292 + (params->ulSourceDataLen == 0 && params->pSourceData != NULL) || |
| 293 + (params->ulSourceDataLen != 0 && params->pSourceData == NULL)) { |
| 294 + return PR_FALSE; |
| 295 + } |
| 296 + return PR_TRUE; |
| 297 +} |
| 298 + |
| 299 /* |
| 300 * return a context based on the SFTKContext type. |
| 301 */ |
| 302 @@ -588,11 +628,6 @@ sftk_RSAEncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned cha
r *output, |
| 303 hashAlg = GetHashTypeFromMechanism(info->params->hashAlg); |
| 304 maskHashAlg = GetHashTypeFromMechanism(info->params->mgf); |
| 305 |
| 306 - if (info->params->source != CKZ_DATA_SPECIFIED) { |
| 307 - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
| 308 - return SECFailure; |
| 309 - } |
| 310 - |
| 311 return RSA_EncryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg, |
| 312 (const unsigned char*)info->params->pSourceData, |
| 313 info->params->ulSourceDataLen, NULL, 0, |
| 314 @@ -617,11 +652,6 @@ sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned cha
r *output, |
| 315 hashAlg = GetHashTypeFromMechanism(info->params->hashAlg); |
| 316 maskHashAlg = GetHashTypeFromMechanism(info->params->mgf); |
| 317 |
| 318 - if (info->params->source != CKZ_DATA_SPECIFIED) { |
| 319 - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
| 320 - return SECFailure; |
| 321 - } |
| 322 - |
| 323 rv = RSA_DecryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg, |
| 324 (const unsigned char*)info->params->pSourceData, |
| 325 info->params->ulSourceDataLen, |
| 326 @@ -801,19 +831,18 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PT
R pMechanism, |
| 327 } |
| 328 context->destroy = sftk_Null; |
| 329 break; |
| 330 -/* XXX: Disabled until unit tests land. |
| 331 case CKM_RSA_PKCS_OAEP: |
| 332 if (key_type != CKK_RSA) { |
| 333 crv = CKR_KEY_TYPE_INCONSISTENT; |
| 334 break; |
| 335 } |
| 336 - context->multi = PR_FALSE; |
| 337 - context->rsa = PR_TRUE; |
| 338 - if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) { |
| 339 + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) || |
| 340 + !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS*)pMechanism->pPara
meter)) { |
| 341 crv = CKR_MECHANISM_PARAM_INVALID; |
| 342 break; |
| 343 } |
| 344 - /\* XXX: Need Parameter validation here *\/ |
| 345 + context->multi = PR_FALSE; |
| 346 + context->rsa = PR_TRUE; |
| 347 if (isEncrypt) { |
| 348 SFTKOAEPEncryptInfo *info = PORT_New(SFTKOAEPEncryptInfo); |
| 349 if (info == NULL) { |
| 350 @@ -849,7 +878,6 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR
pMechanism, |
| 351 } |
| 352 context->destroy = (SFTKDestroy) sftk_Space; |
| 353 break; |
| 354 -*/ |
| 355 case CKM_RC2_CBC_PAD: |
| 356 context->doPad = PR_TRUE; |
| 357 /* fall thru */ |
| 358 @@ -2506,7 +2534,8 @@ finish_rsa: |
| 359 break; |
| 360 } |
| 361 context->rsa = PR_TRUE; |
| 362 - if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { |
| 363 + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) || |
| 364 + !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS*)pMechanism->p
Parameter)) { |
| 365 crv = CKR_MECHANISM_PARAM_INVALID; |
| 366 break; |
| 367 } |
| 368 @@ -3143,7 +3172,8 @@ finish_rsa: |
| 369 break; |
| 370 } |
| 371 context->rsa = PR_TRUE; |
| 372 - if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { |
| 373 + if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) || |
| 374 + !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS*)pMechanism->p
Parameter)) { |
| 375 crv = CKR_MECHANISM_PARAM_INVALID; |
| 376 break; |
| 377 } |
OLD | NEW |