📄 ssl_utils.c
字号:
goto error; } globus_gsi_cred_handle_destroy(cred_handle); return_status = SSL_SUCCESS; error: if (bio != NULL) { BIO_free(bio); } return return_status;}intssl_proxy_delegation_sign(SSL_CREDENTIALS *creds, SSL_PROXY_RESTRICTIONS *restrictions, unsigned char *input_buffer, int input_buffer_length, unsigned char **output_buffer, int *output_buffer_length){ X509_REQ *request = NULL; X509 *proxy_certificate = NULL; int return_status = SSL_ERROR; BIO *bio = NULL; unsigned char number_of_certs; int index; globus_gsi_proxy_handle_t proxy_handle = NULL; globus_gsi_proxy_handle_attrs_t proxy_handle_attrs = NULL; globus_gsi_cred_handle_t cred_handle = NULL; globus_result_t local_result;#if defined(GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY) /* handle API changes */ globus_gsi_cert_utils_cert_type_t cert_type;#endif assert(creds != NULL); assert(creds->certificate); assert(creds->private_key); assert(input_buffer != NULL); assert(output_buffer != NULL); assert(output_buffer_length != NULL); my_init(); /* initialize cred_handle with our credential so we can use Globus GSI API */ local_result = globus_gsi_cred_handle_init(&cred_handle, NULL); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_handle_init() failed"); goto error; } local_result = globus_gsi_cred_set_cert(cred_handle, creds->certificate); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_set_cert() failed"); goto error; } local_result = globus_gsi_cred_set_key(cred_handle, creds->private_key); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_set_key() failed"); goto error; } local_result = globus_gsi_cred_set_cert_chain(cred_handle, creds->certificate_chain); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_set_cert_chain() failed"); goto error; } /* Set lifetime in proxy_handle_attrs for GT 2.2 compatibility. */ globus_gsi_proxy_handle_attrs_init(&proxy_handle_attrs);#if !defined(GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY) if (!restrictions || !restrictions->lifetime) { globus_gsi_proxy_handle_attrs_set_time_valid(proxy_handle_attrs, PROXY_DEFAULT_LIFETIME/60); } else if (restrictions->lifetime > 0) { globus_gsi_proxy_handle_attrs_set_time_valid(proxy_handle_attrs, restrictions->lifetime/60); }#endif /* proxy handle is the proxy we're going to sign */ local_result = globus_gsi_proxy_handle_init(&proxy_handle, proxy_handle_attrs); /* done with proxy_handle_attrs now */ globus_gsi_proxy_handle_attrs_destroy(proxy_handle_attrs); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_handle_init() failed"); goto error; }#if defined(GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY) /* what type of certificate do we have in the repository? */ local_result = globus_gsi_cert_utils_get_cert_type(creds->certificate, &cert_type); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cert_utils_get_cert_type() failed"); goto error; } /* if we don't have an RFC or GSI3 proxy in the repository, i.e., we have a GSI2 proxy or an EEC, then remove RFC/GSI3 proxy cert info from our proxy_handle so we take on the proxy type in the request */ if (GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY(cert_type) == 0) {#if defined(GLOBUS_GSI_CERT_UTILS_IS_RFC_PROXY) if (GLOBUS_GSI_CERT_UTILS_IS_RFC_PROXY(cert_type) == 0) {#endif local_result = globus_gsi_proxy_handle_set_proxy_cert_info(proxy_handle, NULL); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_handle_set_proxy_cert_info() " "failed"); goto error; }#if defined(GLOBUS_GSI_CERT_UTILS_IS_RFC_PROXY) }#endif }#endif /* get proxy request */ bio = BIO_new(BIO_s_mem()); if (bio == NULL) { verror_put_string("BIO_new() failed"); goto error; } if (BIO_write(bio, input_buffer, input_buffer_length) < 0) { verror_put_string("BIO_write() failed"); goto error; } local_result = globus_gsi_proxy_inquire_req(proxy_handle, bio); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_inquire_req() failed"); goto error; } BIO_free(bio); bio = NULL; /* Set lifetime and limited options on proxy before signing. */#if defined(GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY) if (GLOBUS_GSI_CERT_UTILS_IS_PROXY(cert_type)) { local_result = globus_gsi_proxy_handle_set_type(proxy_handle, cert_type); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_handle_set_type() failed"); goto error; } } if (restrictions && restrictions->limited_proxy) { globus_gsi_proxy_handle_get_type(proxy_handle, &cert_type); if (GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY(cert_type)) { globus_gsi_proxy_handle_set_type(proxy_handle, GLOBUS_GSI_CERT_UTILS_TYPE_GSI_3_LIMITED_PROXY);#if defined(GLOBUS_GSI_CERT_UTILS_IS_RFC_PROXY) } else if (GLOBUS_GSI_CERT_UTILS_IS_RFC_PROXY(cert_type)) { globus_gsi_proxy_handle_set_type(proxy_handle, GLOBUS_GSI_CERT_UTILS_TYPE_RFC_LIMITED_PROXY);#endif } else if (GLOBUS_GSI_CERT_UTILS_IS_GSI_2_PROXY(cert_type)) { globus_gsi_proxy_handle_set_type(proxy_handle, GLOBUS_GSI_CERT_UTILS_TYPE_GSI_2_LIMITED_PROXY); } else { verror_put_string("unknown proxy type for limited proxy"); goto error; } } if (!restrictions || !restrictions->lifetime) { globus_gsi_proxy_handle_set_time_valid(proxy_handle, PROXY_DEFAULT_LIFETIME/60); } else if (restrictions->lifetime > 0) { globus_gsi_proxy_handle_set_time_valid(proxy_handle, restrictions->lifetime/60); }#else if (restrictions && restrictions->limited_proxy) { globus_gsi_proxy_handle_set_is_limited(proxy_handle, 1); }#endif /* send number of certificates in reply for backward compatibility */ bio = BIO_new(BIO_s_mem()); if (bio == NULL) { verror_put_string("BIO_new() failed"); goto error; } number_of_certs = sk_num(creds->certificate_chain) + 2; if (BIO_write(bio, &number_of_certs, sizeof(number_of_certs)) == SSL_ERROR) { verror_put_string("Failed dumping proxy certificate to buffer (BIO_write() failed)"); ssl_error_to_verror(); goto error; } /* sign request and write out proxy certificate to bio */ local_result = globus_gsi_proxy_sign_req(proxy_handle, cred_handle, bio); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_sign_req() failed"); goto error; } /* then write out our signing certificate... */ if (i2d_X509_bio(bio, creds->certificate) == SSL_ERROR) { verror_put_string("Failed dumping proxy certificate to buffer (write of signing cert failed)"); ssl_error_to_verror(); goto error; } /* ...and any other certificates in the chain. */ for (index = 0; index < sk_num(creds->certificate_chain); index++) { X509 *cert; cert = (X509 *) sk_value(creds->certificate_chain, index); if (i2d_X509_bio(bio, cert) == SSL_ERROR) { verror_put_string("Failed dumping proxy certificate to buffer (write of cert chain failed)"); ssl_error_to_verror(); goto error; } } /* Now dump bio's contents to buffer */ if (bio_to_buffer(bio, output_buffer, output_buffer_length) == SSL_ERROR) { goto error; } /* Success */ return_status = SSL_SUCCESS; error: if (bio != NULL) { BIO_free(bio); } if (request != NULL) { X509_REQ_free(request); } if (proxy_certificate != NULL) { X509_free(proxy_certificate); } if (proxy_handle) { globus_gsi_proxy_handle_destroy(proxy_handle); } if (cred_handle) { globus_gsi_cred_handle_destroy(cred_handle); } return return_status;}voidssl_free_buffer(unsigned char *buffer){ if (buffer != NULL) { free(buffer); }}SSL_PROXY_RESTRICTIONS *ssl_proxy_restrictions_new(){ SSL_PROXY_RESTRICTIONS *restrictions = NULL; restrictions = malloc(sizeof(SSL_PROXY_RESTRICTIONS)); if (restrictions == NULL) { verror_put_string("malloc() failed"); verror_put_errno(errno); return NULL; } /* Set defaults */ restrictions->limited_proxy = 0; /* Not limited */ restrictions->lifetime = 0; /* 0 == default */ return restrictions;}voidssl_proxy_restrictions_destroy(SSL_PROXY_RESTRICTIONS *restrictions){ if (restrictions != NULL) { free(restrictions); }}intssl_proxy_restrictions_set_lifetime(SSL_PROXY_RESTRICTIONS *restrictions, const long lifetime){ int return_value = SSL_ERROR; /* Check arguments */ if (restrictions == NULL) { verror_put_errno(EINVAL); goto error; } if (lifetime < 0L) { verror_put_errno(EINVAL); goto error; } /* OK */ restrictions->lifetime = lifetime; return_value = SSL_SUCCESS; error: return return_value;}intssl_get_base_subject_file(const char *proxyfile, char **subject){ SSL_CREDENTIALS *creds = NULL; int return_value = -1; char path[MAXPATHLEN]; if (proxyfile == NULL) { char *user_cert = NULL; GLOBUS_GSI_SYSCONFIG_GET_PROXY_FILENAME(&user_cert, GLOBUS_PROXY_FILE_INPUT); if (user_cert == NULL) { GLOBUS_GSI_SYSCONFIG_GET_USER_CERT_FILENAME(&user_cert, NULL); if (user_cert == NULL) { verror_put_string("Unable to locate certificate to determine " "subject name."); goto error; } } strncpy(path, user_cert, sizeof(path)); free(user_cert); } else { strncpy(path, proxyfile, sizeof(path)); } creds = ssl_credentials_new(); if (ssl_certificate_load_from_file(creds, path) != SSL_SUCCESS) goto error; if (ssl_get_base_subject(creds, subject) != SSL_SUCCESS) goto error; return_value = 0; error: if (creds) ssl_credentials_destroy(creds); return return_value;}intssl_get_base_subject(SSL_CREDENTIALS *creds, char **subject){ char client[1024]; X509_NAME *client_subject = NULL; client_subject = X509_NAME_dup(X509_get_subject_name(creds->certificate)); if (client_subject == NULL) { return SSL_ERROR; }#if defined(GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY) /* gotta love API changes */ sk_unshift(creds->certificate_chain, (char *)creds->certificate); globus_gsi_cert_utils_get_base_name(client_subject, creds->certificate_chain); sk_shift(creds->certificate_chain);#else globus_gsi_cert_utils_get_base_name(client_subject);#endif X509_NAME_oneline(client_subject, client, sizeof(client)); *subject = strdup(client); X509_NAME_free(client_subject); return SSL_SUCCESS;}intssl_creds_to_buffer(SSL_CREDENTIALS *creds, unsigned char **buffer, int *buffer_length){ BIO *bio = NULL; if (creds_to_bio(creds, &bio) == SSL_ERROR) return SSL_ERROR; if (bio_to_buffer(bio, buffer, buffer_length) == SSL_ERROR) { BIO_free(bio); return SSL_ERROR; } BIO_free(bio); return SSL_SUCCESS;}intssl_creds_from_buffer(unsigned char *buffer, int buffer_length, SSL_CREDENTIALS **creds){ BIO *bio = NULL; bio = bio_from_buffer(buffer, buffer_length); if (bio == NULL) return SSL_ERROR; if (creds_from_bio(bio, creds) == SSL_ERROR) { BIO_free(bio); return SSL_ERROR; } BIO_free(bio); return SSL_SUCCESS;}intssl_sign(unsigned char *data, int length, SSL_CREDENTIALS *creds, unsigned char **signature, int *signature_len){ EVP_MD_CTX ctx; *signature = malloc(EVP_PKEY_size(creds->private_key)); if (*signature == NULL) { verror_put_string("malloc()"); verror_put_errno(errno); return SSL_ERROR; } EVP_SignInit(&ctx, EVP_sha1()); EVP_SignUpdate(&ctx, (void *)data, length); if (EVP_SignFinal(&ctx, *signature, (unsigned int *)signature_len, creds->private_key) != 1) { verror_put_string("Creating signature (EVP_SignFinal())"); ssl_error_to_verror(); free(*signature); EVP_MD_CTX_cleanup(&ctx); return SSL_ERROR; } EVP_MD_CTX_cleanup(&ctx); return SSL_SUCCESS;}intssl_verify(unsigned char *data, int length, SSL_CREDENTIALS *creds, unsigned char *signature, int signature_len){ EVP_MD_CTX ctx; EVP_PKEY *pubkey = NULL; EVP_VerifyInit(&ctx, EVP_sha1()); EVP_VerifyUpdate(&ctx, (void*) data, length); pubkey = X509_get_pubkey(creds->certificate); if (EVP_VerifyFinal(&ctx, signature, signature_len, pubkey) != 1 ) { verror_put_string("Verifying signature (EVP_VerifyFinal())"); ssl_error_to_verror(); EVP_MD_CTX_cleanup(&ctx); EVP_PKEY_free(pubkey); return SSL_ERROR; } EVP_MD_CTX_cleanup(&ctx); EVP_PKEY_free(pubkey); return SSL_SUCCESS;}/* Chain verifying is inspired by proxy_verify_chain() from GSI. */intssl_verify_gsi_chain(SSL_CREDENTIALS *chain){ int return_status = SSL_ERROR; int i,j; char *certdir = NULL; X509 *xcert = NULL; X509_LOOKUP *lookup = NULL; X509_STORE *cert_store = NULL; X509_STORE_CTX csc; SSL *ssl = NULL; SSL_CTX *sslContext = NULL; memset(&csc, 0, sizeof(csc)); cert_store=X509_STORE_new(); if (chain->certificate_chain != NULL) { for (i = 0; i < sk_X509_num(chain->certificate_chain); i++) { xcert = sk_X509_value(chain->certificate_chain, i); j = X509_STORE_add_cert(cert_store, xcert); if (!j) { if ((ERR_GET_REASON(ERR_peek_error()) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) { ERR_clear_error(); break; } else { verror_put_string("X509_STORE_add_cert()"); ssl_error_to_verror(); goto end; } } } } lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_hash_dir()); if (lookup == NULL) { verror_put_string("X509_STORE_add_lookup()"); ssl_error_to_verror(); goto end; } GLOBUS_GSI_SYSCONFIG_GET_CERT_DIR(&certdir); if (certdir == NULL) { verror_put_string("failed to find GSI CA cert directory"); ssl_error_to_verror(); goto end; } X509_LOOKUP_add_dir(lookup, certdir, X509_FILETYPE_PEM); X509_STORE_CTX_init(&csc, cert_store, chain->certificate, NULL); sslContext = SSL_CTX_new(SSLv3_server_method()); if (sslContext == NULL) { verror_put_string("Initializing SSL_CTX"); ssl_error_to_verror(); goto end; } SSL_CTX_set_purpose(sslContext, X509_PURPOSE_ANY); ssl = SSL_new(sslContext); if (ssl == NULL) { verror_put_string("Initializing SSL"); ssl_error_to_verror(); goto end; } /* override the check_issued with our version */ csc.check_issued = globus_gsi_callback_check_issued; X509_STORE_CTX_set_app_data(&csc, (void*)ssl); if(!X509_verify_cert(&csc)) { verror_put_string("X509_verify_cert() failed"); ssl_error_to_verror(); goto end; } return_status = SSL_SUCCESS;end: X509_STORE_CTX_cleanup(&csc); if (ssl) SSL_free(ssl); if (sslContext) SSL_CTX_free(sslContext); if (certdir) free(certdir); if (cert_store) X509_STORE_free(cert_store); return return_status;}intssl_get_times(const char *path, time_t *not_before, time_t *not_after){ FILE *cert_file = NULL; X509 *cert = NULL; assert(path != NULL); my_init(); cert_file = fopen(path, "r"); if (cert_file == NULL) { verror_put_string("Failure opening file \"%s\"", cert_file); verror_put_errno(errno); return -1; } if (not_before) *not_before = 0; if (not_after) *not_after = 0; while ((cert = PEM_read_X509(cert_file, NULL, PEM_NO_CALLBACK)) != NULL) { if (not_before) { time_t new_not_before; globus_gsi_cert_utils_make_time(X509_get_notBefore(cert), &new_not_before); if (*not_before == 0 || *not_before < new_not_before) { *not_before = new_not_before; } } if (not_after) { time_t new_not_after; globus_gsi_cert_utils_make_time(X509_get_notAfter(cert), &new_not_after); if (*not_after == 0 || *not_after > new_not_after) { *not_after = new_not_after; } } X509_free(cert); cert = NULL; } fclose(cert_file); ERR_clear_error(); /* clear EOF error */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -