PKI_MEM * PKI_MEM_get_decoded(PKI_MEM *mem, PKI_DATA_FORMAT format, int opts) { if (!mem || !mem->data) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return NULL; } // Let's check the available encodings switch (format) { case PKI_DATA_FORMAT_B64: return PKI_MEM_get_b64_decoded(mem, opts); break; case PKI_DATA_FORMAT_URL: return PKI_MEM_get_url_decoded(mem); break; default: // Unknown data format PKI_ERROR(PKI_ERR_DATA_FORMAT_UNKNOWN, NULL); } // If we reach here, it means no valid format was detected return NULL; }
/* * \brief Allocates and initializes a new PKI_HMAC by using a PKI_MEM to hold the secret key */ PKI_HMAC *PKI_HMAC_new_mem(PKI_MEM *key, PKI_DIGEST_ALG *digest, HSM *hsm) { PKI_HMAC *ret = NULL; if (!key || !key->data || key->size <= 0) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return NULL; } ret = PKI_HMAC_new_null(); if (!ret) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } if (PKI_HMAC_init(ret, key->data, key->size, digest, hsm) != PKI_OK) { PKI_HMAC_free(ret); return NULL; } return ret; }
int PKI_STACK_free_all (PKI_STACK * st) { // Input check if (!st) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); // Provides some debugging (helps with memory leaking) if (st->free == NULL) { // Provides some debugging (helps with memory leaking) PKI_ERROR(PKI_ERR_PARAM_NULL, "Can not free the stack because of missing memory-deallocation Function " "from Stack Initialization"); // Returns the error return PKI_ERR; } // Removes and frees all the nodes in the stack while (PKI_STACK_pop_free(st) == PKI_OK); // Let's free the PKI_STACK data structure's memory PKI_Free(st); // All Done. return PKI_OK; }
/*! * \brief Adds a new element to a PKI_STACK * It adds a general pointer to an already initialized PKI_STACK structure. * In case of success it returns the number of elements in the stack after * the new insertion. Otherwise it returns PKI_STACK_ERR. */ int PKI_STACK_push(PKI_STACK *st, void *obj) { PKI_STACK_NODE *n = NULL; if (st == NULL || obj == NULL) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return(PKI_STACK_ERR); } if((n = _PKI_STACK_NODE_new(obj)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return(PKI_STACK_ERR); } if (st->tail) { n->prev = st->tail; n->next = NULL; st->tail->next = n; st->tail = n; } else { st->tail = n; st->head = n; } st->elements++; return(st->elements); }
int PKI_X509_OCSP_RESP_copy_nonce ( PKI_X509_OCSP_RESP *resp, PKI_X509_OCSP_REQ *req ) { PKI_OCSP_RESP *r = NULL; if ( !resp || !resp->value || !req || !req->value ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; } r = resp->value; if (!r->bs) { PKI_log_err("Missing basic request in OCSP REQ value"); return PKI_ERR; } if(!OCSP_copy_nonce( r->bs, req->value )) { PKI_ERROR(PKI_ERR_OCSP_NONCE_COPY, NULL); return PKI_ERR; } return PKI_OK; }
PKI_MEM_STACK *URL_get_data_mysql ( const char *url_s, ssize_t size ) { PKI_MEM_STACK *ret = NULL; URL *url = NULL; if( !url_s ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); } if ((url = URL_new(url_s)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } if (url->proto != URI_PROTO_MYSQL) { PKI_log_debug("Wrong protocol for MySQL queries (%d)", URI_PROTO_MYSQL); URL_free(url); return NULL; } // Get the results ret = URL_get_data_mysql_url( url, size ); // Free the URL URL_free(url); // Return the results return ret; }
PKI_MEM * HSM_OPENSSL_sign(PKI_MEM *der, PKI_DIGEST_ALG *digest, PKI_X509_KEYPAIR *key) { EVP_MD_CTX *ctx = NULL; size_t out_size = 0; size_t ossl_ret = 0; PKI_MEM *out_mem = NULL; EVP_PKEY *pkey = NULL; if (!der || !der->data || !key || !key->value) { PKI_ERROR( PKI_ERR_PARAM_NULL, NULL); return NULL; } // Private Key pkey = key->value; // Get the Maximum size of a signature ossl_ret = out_size = (size_t) EVP_PKEY_size(pkey); // Initialize the return structure out_mem = PKI_MEM_new ((size_t)out_size); ctx = EVP_MD_CTX_new(); if (!out_mem || !ctx) { if (ctx) EVP_MD_CTX_free(ctx); if (out_mem) PKI_MEM_free(out_mem); PKI_ERROR( PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } EVP_MD_CTX_init(ctx); EVP_SignInit_ex(ctx, digest, NULL); EVP_SignUpdate (ctx, der->data, der->size); // Finalize the signature if (!EVP_SignFinal(ctx, out_mem->data, (unsigned int *) &ossl_ret, pkey)) { PKI_log_err("ERROR while finalizing signature (%s)", HSM_OPENSSL_get_errdesc(HSM_OPENSSL_get_errno(), NULL, 0)); PKI_MEM_free(out_mem); out_mem = NULL; } else out_mem->size = (size_t) ossl_ret; // Cleanup the context #if OPENSSL_VERSION_NUMBER <= 0x1010000f EVP_MD_CTX_cleanup(ctx); #else EVP_MD_CTX_reset(ctx); #endif EVP_MD_CTX_free(ctx); return out_mem; }
PKI_MEM *PKI_MEM_get_url_encoded(PKI_MEM *mem, int skipNewLines) { PKI_MEM *encoded = NULL; char enc_buf[1024]; int i = 0; int enc_idx = 0; if (!mem || !mem->data || (mem->size == 0)) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return NULL; } if ((encoded = PKI_MEM_new_null()) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } for( i = 0; i < mem->size; i++ ) { char *str = "=$&+,/:;=?@ <>#\%{}|\\^~[]\r\n`"; unsigned char tmp_d2 = 0; if (skipNewLines && (mem->data[i] == '\r' || mem->data[i] == '\n')) continue; tmp_d2 = mem->data[i]; if ((strchr( str, tmp_d2 ) != NULL ) || (tmp_d2 <= 31) || ( tmp_d2 >= 127 ) || (isgraph(tmp_d2) == 0)) { enc_idx += sprintf(&enc_buf[enc_idx], "%%%2.2x", tmp_d2 ); // PKI_MEM_add ( encoded, enc_buf, 3 ); } else { // PKI_MEM_add ( encoded, (char *) &(mem->data[i]), 1); enc_buf[enc_idx++] = mem->data[i]; } // Let's check if it is time to move the buffer contents into the // PKI_MEM. If so, let's transfer the content and reset the buffer // index if (enc_idx >= sizeof(enc_buf) - 4) { PKI_MEM_add(encoded, enc_buf, enc_idx); enc_idx = 0; } } // If there is something left in the buffer that needs to be added // we add it if (enc_idx > 0) PKI_MEM_add(encoded, enc_buf, enc_idx); // Let's now return the encoded PKI_MEM return encoded; }
char * PKI_HTTP_get_header_txt (const char * orig_data, const char * header) { char *tk = NULL, *pnt = NULL; char *ret = NULL; char *data = NULL; int found = 0; if( !orig_data || !header || !strlen(orig_data) || !strlen(header)) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return NULL; } if ((data = strdup(orig_data)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } for (tk = strtok_r ( data, "\r\n", &pnt ); tk; tk = strtok_r(NULL, "\r\n", &pnt)) { if ( tk == NULL ) break; if (strncmp_nocase(tk, header, (int) strlen(header)) == 0) { found = 1; break; } } if (!found) { PKI_Free ( data ); return NULL; } if ((pnt = strchr( tk, ':' )) == NULL) { PKI_Free ( data ); return NULL; } pnt++; while ((pnt != NULL ) && (*pnt == ' ' )) { pnt++; } if (pnt) ret = strdup( pnt ); PKI_Free ( data ); return ret; }
PKI_MEM *PKI_MEM_get_url_decoded(PKI_MEM *mem) { PKI_MEM *decoded = NULL; ssize_t data_size = 0; unsigned char *data = NULL; int i = 0; int enc_idx = 0; if(!mem || !mem->data || (mem->size == 0) ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return NULL; } // Let's allocate a big buffer - same size of the encoded one // is enough as URL encoding expands the size (decoded is smaller) if ((data = PKI_Malloc(mem->size)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // Let's do the decoding for( i = 0; i < mem->size; i++ ) { int p; unsigned char k; if (sscanf((const char *)&mem->data[i], "%%%2x", &p) > 0) { k = (unsigned char) p; data[enc_idx++] = k; i += 2; } else { data[enc_idx++] = mem->data[i]; } } // Allocates the new PKI_MEM for the decoding operations if((decoded = PKI_MEM_new_data(enc_idx, data)) == NULL) { PKI_Free(data); PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // Free the allocated memory PKI_Free(data); // Returns the newly allocated url-decoded PKI_MEM return decoded; }
PKI_OCSP_RESP *PKI_OCSP_RESP_new ( void ) { // Crypto Provider's specific data structures PKI_X509_OCSP_RESP_VALUE *r = NULL; OCSP_BASICRESP *bs = NULL; // Return container PKI_OCSP_RESP * ret = NULL; // Allocates the response object if ((r = OCSP_RESPONSE_new()) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // Sets the initial state to "Success" if (!(ASN1_ENUMERATED_set(r->responseStatus, PKI_X509_OCSP_RESP_STATUS_SUCCESSFUL))) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if (r) OCSP_RESPONSE_free (r); return NULL; } // Creates the basic response object if ((bs = OCSP_BASICRESP_new()) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if( r ) OCSP_RESPONSE_free ( r ); return ( NULL ); } // Let's now create the outer container if(( ret = (PKI_OCSP_RESP *) PKI_Malloc (sizeof(PKI_OCSP_RESP)))==NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if ( bs ) OCSP_BASICRESP_free ( bs ); if ( r ) OCSP_RESPONSE_free ( r ); return NULL; } // Transfer ownership of r and bs to the container ret->resp = r; ret->bs = bs; // Success - object created return ret; }
char * PKI_X509_KEYPAIR_get_parsed ( PKI_X509_KEYPAIR *pkey ) { if( !pkey || !pkey->value ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return ( NULL ); }; PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); return NULL; }
int PKI_MEM_decode(PKI_MEM *mem, PKI_DATA_FORMAT format, int opts) { PKI_MEM *decoded = NULL; if ((decoded = PKI_MEM_get_decoded(mem, format, opts)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return PKI_ERR_MEMORY_ALLOC; } // Clears the memory for the old PKI_MEM if (mem->data) PKI_Free(mem->data); // Transfer ownership of the data mem->data = decoded->data; mem->size = decoded->size; // Clears the encoded data container decoded->data = NULL; decoded->size = 0; // Free the newly-allocated (now empty) container PKI_MEM_free(decoded); // Returns success return PKI_OK; }
PKI_CONFIG_ELEMENT_STACK * PKI_CONFIG_get_element_children(PKI_CONFIG_ELEMENT *e) { PKI_CONFIG_ELEMENT_STACK *ret = NULL; PKI_CONFIG_ELEMENT *curr = NULL; if (!e) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); } if ((curr = e->children) == NULL) return NULL; if ((ret = PKI_STACK_CONFIG_ELEMENT_new()) == NULL) return NULL; while (curr) { if( curr->type != XML_ELEMENT_NODE ) continue; PKI_STACK_CONFIG_ELEMENT_push( ret, curr ); curr = curr->next; } return( ret ); }
STACK_OF(X509_REVOKED) *ocspd_build_crl_entries_list ( CA_LIST_ENTRY *ca, PKI_X509_CRL *crl ) { long rev_num = 0; STACK_OF(X509_REVOKED) *ret = NULL; PKI_X509_CRL_VALUE *crl_val = NULL; if ( !ca || !crl || !crl->value ) { return NULL; } crl_val = crl->value; ret = X509_CRL_get_REVOKED(crl_val); rev_num = sk_X509_REVOKED_num(ret); // if( ocspd_conf->verbose ) PKI_log( PKI_LOG_INFO, "INFO::CRL::%ld Entries [ %s ]", rev_num, ca->ca_id ); ca->crl_list = ret; ca->entries_num = (unsigned long) rev_num; if ((rev_num > -1 ) && (ca->crl_list == NULL)) { PKI_ERROR( PKI_ERR_MEMORY_ALLOC, NULL ); return NULL; } sk_X509_REVOKED_sort(ca->crl_list); return (ca->crl_list); }
int PKI_HMAC_update_mem(PKI_HMAC *hmac, PKI_MEM *data) { if (!hmac || !data || !data->data || data->size <= 0) return PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_HMAC_update(hmac, data->data, data->size); }
int PKI_STACK_pop_free ( PKI_STACK *st ) { void * data = NULL; // Input check if (!st || !st->free) { // Provides some debugging (helps with memory leaking) return PKI_ERROR(PKI_STACK_ERR, "Can not free the Popped Item because of missing memory-deallocation Function " "from Stack Initialization"); } // Gets the data or return 'PKI_ERR' to indicate there // are no more elements in the stack to pop if ((data = PKI_STACK_pop(st)) == NULL) return PKI_ERR; // If we retrieved the data, let's free its content if (data != NULL && st->free != NULL) { // Use the function pointer to free the memory (st->free)(data); } // All Done return PKI_OK; }
/*! \brief Returns the contents of the PKI_MEM in a string which is guaranteed * to carry all the contents of the original PKI_MEM and terminated (at * size + 1) with a NULL char. */ char * PKI_MEM_get_parsed(PKI_MEM *buf) { char *ret = NULL; if (!buf || !buf->data) return NULL; if (buf->size < 1) { ret = PKI_Malloc(1); *ret = '\x0'; return ret; } ret = PKI_Malloc(buf->size + 1); if (!ret) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } memcpy(ret, buf->data, buf->size); ret[buf->size] = '\x0'; return ret; }
PKI_X509_KEYPAIR *HSM_X509_KEYPAIR_new( PKI_KEYPARAMS *params, char *label, PKI_CRED *cred, HSM *hsm ) { PKI_X509_KEYPAIR *ret = NULL; URL *url = NULL; if( hsm && !url && (hsm->type == HSM_TYPE_PKCS11) ) { PKI_log_debug("PKI_X509_KEYPAIR_new()::Label is required when " "using HSM!"); return ( NULL ); } if ( label ) { if(( url = URL_new(label)) == NULL ) { PKI_ERROR(PKI_ERR_URI_PARSE, label); return ( NULL ); } }; ret = HSM_X509_KEYPAIR_new_url ( params, url, cred, hsm ); if( url ) URL_free( url ); return ( ret ); }
int PKI_X509_CRL_print_parsed(const PKI_X509_CRL *x, PKI_X509_DATA type, int fd){ const char *str = NULL; ssize_t rv = 0; if ( !x ) return ( PKI_ERR ); switch (type) { default: /* Not Recognized/Supported DATATYPE */ return ( PKI_ERR ); } if (str) { rv = write(fd, str, (size_t) strlen(str)); if (rv < strlen(str)) { PKI_ERROR(PKI_ERR_GENERAL, "Error writing bytes (%d vs %d)", rv, strlen(str)); return PKI_ERR; } } return PKI_OK; }
PKI_SCHEME_ID PKI_X509_KEYPAIR_VALUE_get_scheme ( PKI_X509_KEYPAIR_VALUE *pVal ) { PKI_SCHEME_ID ret = PKI_SCHEME_UNKNOWN; if ( !pVal ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return ret; }; switch(EVP_PKEY_type(pVal->type)) { case EVP_PKEY_DSA: ret = PKI_SCHEME_DSA; break; case EVP_PKEY_RSA: ret = PKI_SCHEME_RSA; break; #ifdef ENABLE_ECDSA case EVP_PKEY_EC: ret = PKI_SCHEME_ECDSA; break; #endif default: return ret; }; return ret; };
PKI_X509_OCSP_RESP *PKI_X509_OCSP_RESP_new ( void ) { PKI_X509_OCSP_RESP *ret = NULL; // Let's allocate the memory for the container if ((ret = PKI_X509_OCSP_RESP_new_null()) == NULL) return NULL; // If we have the create callback, let's allocate the // value for the object if (ret->cb && ret->cb->create) { ret->value = ret->cb->create(); // If the internal value creation failed, let's fail // all the way if (!ret->value) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); PKI_X509_OCSP_RESP_free(ret); return NULL; } } // Success - object created return ret; }
int PKI_MEM_grow( PKI_MEM *buf, size_t data_size ) { size_t new_size = 0; if (!buf) return PKI_ERR; if (buf->data == NULL) { buf->data = PKI_Malloc(data_size); if (!buf->data) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return (PKI_ERR); } buf->size = data_size; } else { new_size = buf->size + data_size; buf->data = realloc(buf->data, new_size); buf->size = new_size; } return ((int) buf->size); }
unsigned char * PKI_MEM_get_data( PKI_MEM *buf ) { if (!buf ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (PKI_ERR); }; return( buf->data ); }
size_t PKI_MEM_get_size( PKI_MEM *buf ) { if( !buf || !buf->data ) { if(!buf) PKI_ERROR(PKI_ERR_POINTER_NULL, NULL); return (0); }; return( buf->size ); }
PKI_X509_CERT *PKI_X509_CERT_dup(const PKI_X509_CERT *x) { if( !x ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return ( NULL ); }; return PKI_X509_dup ( x ); }
char * PKI_X509_CERT_get_parsed(const PKI_X509_CERT *x, PKI_X509_DATA type ) { char *ret = NULL; PKI_X509_KEYPAIR *k = NULL; const PKI_X509_KEYPAIR_VALUE *pkey = NULL; if( !x ) return (NULL); switch( type ) { case PKI_X509_DATA_SERIAL: ret = PKI_INTEGER_get_parsed((PKI_INTEGER *) PKI_X509_CERT_get_data(x, type)); break; case PKI_X509_DATA_SUBJECT: case PKI_X509_DATA_ISSUER: ret = PKI_X509_NAME_get_parsed((PKI_X509_NAME *) PKI_X509_CERT_get_data(x, type)); break; case PKI_X509_DATA_NOTBEFORE: case PKI_X509_DATA_NOTAFTER: ret = PKI_TIME_get_parsed((PKI_TIME *)PKI_X509_CERT_get_data(x, type)); break; case PKI_X509_DATA_ALGORITHM: ret = (char *) PKI_ALGOR_get_parsed((PKI_ALGOR *) PKI_X509_CERT_get_data(x,type)); break; case PKI_X509_DATA_PUBKEY: case PKI_X509_DATA_KEYPAIR_VALUE: if ((pkey = PKI_X509_CERT_get_data(x, type)) != NULL) { k = PKI_X509_new_dup_value(PKI_DATATYPE_X509_KEYPAIR, pkey, NULL); ret = PKI_X509_KEYPAIR_get_parsed( k ); PKI_X509_KEYPAIR_free(k); } break; case PKI_X509_DATA_KEYSIZE: PKI_ERROR(PKI_ERR_PARAM_TYPE, "Deprecated Cert Datatype"); break; case PKI_X509_DATA_CERT_TYPE: case PKI_X509_DATA_SIGNATURE: case PKI_X509_DATA_EXTENSIONS: default: /* Not Recognized/Supported DATATYPE */ return (NULL); } return (ret); }
int PKI_X509_OCSP_RESP_add ( PKI_X509_OCSP_RESP *resp, OCSP_CERTID *cid, PKI_OCSP_CERTSTATUS status, PKI_TIME *revokeTime, PKI_TIME *thisUpdate, PKI_TIME *nextUpdate, PKI_X509_CRL_REASON reason, PKI_X509_EXTENSION *invalidityDate ) { OCSP_SINGLERESP *single = NULL; PKI_TIME *myThisUpdate = NULL; PKI_OCSP_RESP *r = NULL; if ( !resp || !resp->value || !cid ) return ( PKI_ERR ); r = resp->value; if( !r->bs ) { // Creates the basic response object if ((r->bs = OCSP_BASICRESP_new()) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return PKI_ERR; } } if (thisUpdate == NULL ) { myThisUpdate = X509_gmtime_adj(NULL,0); } else { myThisUpdate = PKI_TIME_dup(thisUpdate); } if((single = OCSP_basic_add1_status(r->bs, cid, status, reason, revokeTime, myThisUpdate, nextUpdate))== NULL) { PKI_log_err ("Can not create basic entry!"); return ( PKI_ERR ); } if (myThisUpdate) PKI_TIME_free(myThisUpdate); if (invalidityDate) { if (!OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invalidityDate, 0, 0)) { PKI_log_err("Can not create extension entry for response!"); return PKI_ERR; } } return PKI_OK; }
char * PKI_CONFIG_get_element_name (PKI_CONFIG_ELEMENT *e) { if (!e) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); } return( (char *) e->name ); }
PKI_DSA_KEY * _pki_pkcs11_dsakey_new( PKI_KEYPARAMS *kp, URL *url, PKCS11_HANDLER *lib, void *driver ) { PKI_DSA_KEY *k = NULL; // unsigned char seed[20]; PKI_ERROR(PKI_ERR_NOT_IMPLEMENTED, NULL); return( k ); }