1 /* 2 * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/asn1t.h> 13 #include <openssl/x509.h> 14 #include <openssl/rand.h> 15 16 /* PKCS#5 password based encryption structure */ 17 18 ASN1_SEQUENCE(PBEPARAM) = { 19 ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING), 20 ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER) 21 } ASN1_SEQUENCE_END(PBEPARAM) 22 23 IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) 24 25 /* Set an algorithm identifier for a PKCS#5 PBE algorithm */ 26 27 int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter, 28 const unsigned char *salt, int saltlen, 29 OSSL_LIB_CTX *ctx) 30 { 31 PBEPARAM *pbe = NULL; 32 ASN1_STRING *pbe_str = NULL; 33 unsigned char *sstr = NULL; 34 35 pbe = PBEPARAM_new(); 36 if (pbe == NULL) { 37 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 38 goto err; 39 } 40 if (iter <= 0) 41 iter = PKCS5_DEFAULT_ITER; 42 if (!ASN1_INTEGER_set(pbe->iter, iter)) { 43 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 44 goto err; 45 } 46 if (!saltlen) 47 saltlen = PKCS5_SALT_LEN; 48 if (saltlen < 0) 49 goto err; 50 51 sstr = OPENSSL_malloc(saltlen); 52 if (sstr == NULL) { 53 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 54 goto err; 55 } 56 if (salt) 57 memcpy(sstr, salt, saltlen); 58 else if (RAND_bytes_ex(ctx, sstr, saltlen, 0) <= 0) 59 goto err; 60 61 ASN1_STRING_set0(pbe->salt, sstr, saltlen); 62 sstr = NULL; 63 64 if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { 65 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 66 goto err; 67 } 68 69 PBEPARAM_free(pbe); 70 pbe = NULL; 71 72 if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) 73 return 1; 74 75 err: 76 OPENSSL_free(sstr); 77 PBEPARAM_free(pbe); 78 ASN1_STRING_free(pbe_str); 79 return 0; 80 } 81 82 int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, 83 const unsigned char *salt, int saltlen) 84 { 85 return PKCS5_pbe_set0_algor_ex(algor, alg, iter, salt, saltlen, NULL); 86 } 87 88 /* Return an algorithm identifier for a PKCS#5 PBE algorithm */ 89 90 X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter, 91 const unsigned char *salt, int saltlen, 92 OSSL_LIB_CTX *ctx) 93 { 94 X509_ALGOR *ret; 95 ret = X509_ALGOR_new(); 96 if (ret == NULL) { 97 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 98 return NULL; 99 } 100 101 if (PKCS5_pbe_set0_algor_ex(ret, alg, iter, salt, saltlen, ctx)) 102 return ret; 103 104 X509_ALGOR_free(ret); 105 return NULL; 106 } 107 108 X509_ALGOR *PKCS5_pbe_set(int alg, int iter, 109 const unsigned char *salt, int saltlen) 110 { 111 return PKCS5_pbe_set_ex(alg, iter, salt, saltlen, NULL); 112 } 113 114