📄 ssl_utils.c
字号:
error = ERR_peek_error(); reason = ERR_GET_REASON(error); /* If this is a bad password, return a better error message */ if (reason == EVP_R_BAD_DECRYPT || reason == EVP_R_NO_SIGN_FUNCTION_CONFIGURED) { verror_put_string("Bad password"); } else { verror_put_string("Error reading private key %s", path); ssl_error_to_verror(); } goto error; } if (creds->private_key != NULL) { EVP_PKEY_free(creds->private_key); } creds->private_key = key; /* Success */ return_status = SSL_SUCCESS; error: if (key_file != NULL) { fclose(key_file); } _ssl_pass_phrase = NULL; return return_status;}intssl_private_key_is_encrypted(const char *path){ FILE *key_file = NULL; EVP_PKEY *key = NULL; int return_status = -1; my_init(); key_file = fopen(path, "r"); if (key_file == NULL) { verror_put_string("Error opening key file %s", path); verror_put_errno(errno); goto cleanup; /* error */ } _ssl_pass_phrase = NULL; ERR_clear_error(); if (PEM_read_PrivateKey(key_file, &(key), my_pass_phrase_callback, NULL) == NULL) { unsigned long error, reason; error = ERR_peek_error(); reason = ERR_GET_REASON(error); if (reason == EVP_R_BAD_DECRYPT || reason == EVP_R_NO_SIGN_FUNCTION_CONFIGURED) { return_status = 1; /* key is encrypted */ goto cleanup; } else { verror_put_string("Error reading private key %s", path); ssl_error_to_verror(); goto cleanup; /* error */ } } return_status = 0; /* key unencrypted */ cleanup: if (key_file) fclose(key_file); if (key) EVP_PKEY_free(key); ERR_clear_error(); return return_status; /* key unencrypted */}intssl_proxy_from_pem(SSL_CREDENTIALS *creds, const unsigned char *buffer, int buffer_len, const char *pass_phrase){ BIO *bio = NULL; X509 *cert = NULL; EVP_PKEY *key = NULL; STACK *cert_chain = NULL; int return_status = SSL_ERROR; assert(creds != NULL); assert(buffer != NULL); my_init(); /* * Put pass phrase where the callback function can find it. */ _ssl_pass_phrase = pass_phrase; bio = bio_from_buffer(buffer, buffer_len); if (bio == NULL) { goto error; } /* * Proxy file contains proxy certificate followed by proxy * private key, followed by the certificate chain. */ /* Read proxy certificate */ if (PEM_read_bio_X509(bio, &cert, PEM_NO_CALLBACK) == NULL) { verror_put_string("Error parsing proxy certificate"); ssl_error_to_verror(); goto error; } /* Read proxy private key */ if (PEM_read_bio_PrivateKey(bio, &(key), PEM_CALLBACK(my_pass_phrase_callback)) == NULL) { unsigned long error, reason; error = ERR_peek_error(); reason = ERR_GET_REASON(error); /* If this is a bad password, return a better error message */ if (ERR_GET_REASON(error) == EVP_R_BAD_DECRYPT || reason == EVP_R_NO_SIGN_FUNCTION_CONFIGURED) { verror_put_string("Bad password"); } else { verror_put_string("Error parsing private key"); ssl_error_to_verror(); } goto error; } /* Ok, now read the certificate chain */ /* Create empty stack */ cert_chain = sk_new_null(); while (1) { X509 *certificate = NULL; if (PEM_read_bio_X509(bio, &certificate, PEM_NO_CALLBACK) == NULL) { /* * If we just can't find a start line then we've reached EOF. */ if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) { /* Just EOF, clear error and break out of loop */ ERR_clear_error(); break; } /* Actual error */ verror_put_string("Error parsing certificate chain from proxy"); ssl_error_to_verror(); goto error; } /* Add to chain */ if (sk_insert(cert_chain, (char *) certificate, sk_num(cert_chain)) == SSL_ERROR) { verror_put_string("Error parsing certificate chain from proxy"); ssl_error_to_verror(); goto error; } } /* while(1) */ /* * Ok, everything has been successfully read, now store it into * creds, removing any existing contents. */ ssl_credentials_free_contents(creds); creds->private_key = key; creds->certificate = cert; creds->certificate_chain = cert_chain; /* Success */ return_status = SSL_SUCCESS; error: if (return_status == SSL_ERROR) { /* * On error, clean up any key, cert or chain. On success * we don't want to do this as they are part of the creds. */ if (cert != NULL) { X509_free(cert); } if (key != NULL) { EVP_PKEY_free(key); } if (cert_chain) { ssl_cert_chain_free(cert_chain); } } if (bio != NULL) { BIO_free(bio); } return return_status;} intssl_proxy_load_from_file(SSL_CREDENTIALS *creds, const char *path, const char *pass_phrase){ unsigned char *buffer = NULL; int buffer_len; int return_status = SSL_ERROR; assert(creds != NULL); assert(path != NULL); my_init(); /* Read the whole contents of the given file */ if (buffer_from_file(path, &buffer, &buffer_len) == -1) { goto error; } if (ssl_proxy_from_pem(creds, buffer, buffer_len, pass_phrase) == SSL_ERROR) { verror_prepend_string("Error reading proxy from %s", path); goto error; } /* Success */ return_status = SSL_SUCCESS; error: if (buffer != NULL) { free(buffer); } return return_status;}intssl_proxy_to_pem(SSL_CREDENTIALS *creds, unsigned char **pbuffer, int *pbuffer_len, const char *pass_phrase){ BIO *bio = NULL; const EVP_CIPHER *cipher; int pass_phrase_len; int cert_chain_index; int return_status = SSL_ERROR; assert(creds != NULL); assert(pbuffer != NULL); assert(pbuffer_len != NULL); my_init(); bio = BIO_new(BIO_s_mem()); if (bio == NULL) { verror_put_string("Failed creating memory BIO"); ssl_error_to_verror(); goto error; } /* * Write out proxy certificate, followed by proxy private key and * then followed by the cert chain. */ if (creds->certificate == NULL) { verror_put_string("Malformed proxy credentials (No certificate)"); goto error; } if (PEM_write_bio_X509(bio, creds->certificate) == SSL_ERROR) { verror_put_string("Error packing proxy certificate"); ssl_error_to_verror(); goto error; } if (creds->private_key == NULL) { verror_put_string("Malformed proxy credentials (No private key)"); goto error; } if (pass_phrase == NULL) { /* No encryption */ cipher = NULL; pass_phrase_len = 0; } else { /* Encrypt with pass phrase */ /* XXX This is my best guess at a cipher */ cipher = EVP_des_ede3_cbc(); pass_phrase_len = strlen(pass_phrase); } if (PEM_write_bio_PrivateKey(bio, creds->private_key, cipher, (unsigned char *) pass_phrase, pass_phrase_len, PEM_NO_CALLBACK) == SSL_ERROR) { verror_put_string("Error packing private key"); ssl_error_to_verror(); goto error; } if (creds->certificate_chain != NULL) { for (cert_chain_index = 0; cert_chain_index < sk_num(creds->certificate_chain); cert_chain_index++) { X509 *cert; cert = (X509 *) sk_value(creds->certificate_chain, cert_chain_index); if (PEM_write_bio_X509(bio, cert) == SSL_ERROR) { verror_put_string("Error packing certificate chain"); ssl_error_to_verror(); goto error; } } } /* OK, bio is filled, now dump to buffer */ if (bio_to_buffer(bio, pbuffer, pbuffer_len) == SSL_ERROR) { goto error; } /* Success */ return_status = SSL_SUCCESS; error: if (bio != NULL) { BIO_free(bio); } return return_status;} intssl_proxy_store_to_file(SSL_CREDENTIALS *proxy_creds, const char *path, const char *pass_phrase){ int fd = -1; int open_flags; int return_status = SSL_ERROR; unsigned char *buffer = NULL; int buffer_len; mode_t file_mode = 0; assert(proxy_creds != NULL); assert(path != NULL); my_init(); /* * Use open to open the file so we can make sure it doesn't already * exist. */ open_flags = O_CREAT | O_EXCL | O_WRONLY; file_mode = S_IRUSR | S_IWUSR; /* 0600 */ fd = open(path, open_flags, file_mode); if (fd == -1) { verror_put_string("Error creating %s", path); verror_put_errno(errno); goto error; } /* * Dump proxy to buffer */ if (ssl_proxy_to_pem(proxy_creds, &buffer, &buffer_len, pass_phrase) == SSL_ERROR) { goto error; } if (write(fd, buffer, buffer_len) == -1) { verror_put_errno(errno); verror_put_string("Error writing proxy to %s", path); goto error; } /* Success */ return_status = SSL_SUCCESS; error: if (buffer != NULL) { free(buffer); } if (fd != -1) { close(fd); if (return_status == SSL_ERROR) { /* Remove any file we created */ ssl_proxy_file_destroy(path); } } return return_status;} SSL_CREDENTIALS *ssl_credentials_new(){ SSL_CREDENTIALS *creds = NULL; my_init(); creds = malloc(sizeof(*creds)); if (creds == NULL) { verror_put_errno(errno); goto error; } creds->certificate = NULL; creds->private_key = NULL; creds->certificate_chain = NULL; error: return creds;}intssl_proxy_delegation_init(SSL_CREDENTIALS **new_creds, unsigned char **buffer, int *buffer_length, int requested_bits, void (*callback)(int,int,void *)){ int return_status = SSL_ERROR; globus_result_t local_result; globus_gsi_proxy_handle_attrs_t proxy_handle_attrs = NULL; BIO *bio = NULL;#if defined(GLOBUS_GSI_CERT_UTILS_IS_GSI_3_PROXY) char *GT_PROXY_MODE = NULL;#endif my_init(); assert(new_creds != NULL); assert(buffer != NULL); assert(buffer_length != NULL); *new_creds = ssl_credentials_new(); globus_gsi_proxy_handle_attrs_init(&proxy_handle_attrs); globus_gsi_proxy_handle_attrs_set_keybits(proxy_handle_attrs, MYPROXY_DEFAULT_KEYBITS); local_result = globus_gsi_proxy_handle_init(&(*new_creds)->proxy_req, 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) GT_PROXY_MODE = getenv("GT_PROXY_MODE"); if (GT_PROXY_MODE && strcmp(GT_PROXY_MODE, "old") == 0) { local_result = globus_gsi_proxy_handle_set_type((*new_creds)->proxy_req, GLOBUS_GSI_CERT_UTILS_TYPE_GSI_2_PROXY); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_handle_set_type() failed"); goto error; } }#endif bio = BIO_new(BIO_s_mem()); if (bio == NULL) { verror_put_string("BIO_new() failed"); goto error; } local_result = globus_gsi_proxy_create_req((*new_creds)->proxy_req, bio); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_create_req() failed"); goto error; } if (bio_to_buffer(bio, buffer, buffer_length) == SSL_ERROR) { verror_put_string("bio_to_buffer() failed"); goto error; } /* Success */ return_status = SSL_SUCCESS; error: if (bio) { BIO_free(bio); } return return_status;}intssl_proxy_delegation_finalize(SSL_CREDENTIALS *creds, unsigned char *buffer, int buffer_length){ BIO *bio = NULL; int return_status = SSL_ERROR; unsigned char number_of_certs; globus_result_t local_result; globus_gsi_cred_handle_t cred_handle; assert(creds != NULL); assert(buffer != NULL); /* Transfer the buffer to a bio */ bio = bio_from_buffer(buffer, buffer_length); if (bio == NULL) { verror_put_string("Failed unpacking proxy certificate from buffer"); goto error; } /* * Buffer contains: * -a bytes containing the number of certificates. * -the proxy certificate * -the certificate chain */ /* Read number of certificates for backward compatibility */ if (BIO_read(bio, &number_of_certs, sizeof(number_of_certs)) == SSL_ERROR) { verror_put_string("Failed unpacking proxy certificate from buffer (reading number of certificates)"); ssl_error_to_verror(); goto error; } if (number_of_certs == 0) { verror_put_string("Failed unpacking proxy certificate from buffer (number of certificates == 0)"); ssl_error_to_verror(); goto error; } /* read the proxy certificate and certificate chain */ local_result = globus_gsi_proxy_assemble_cred(creds->proxy_req, &cred_handle, bio); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_proxy_assemble_cred() failed"); goto error; } /* don't need the proxy_req anymore */ globus_gsi_proxy_handle_destroy(creds->proxy_req); /* pull out what we need from the cred_handle */ local_result = globus_gsi_cred_get_cert(cred_handle, &creds->certificate); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_get_cert() failed"); goto error; } local_result = globus_gsi_cred_get_key(cred_handle, &creds->private_key); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_get_key() failed"); goto error; } local_result = globus_gsi_cred_get_cert_chain(cred_handle, &creds->certificate_chain); if (local_result != GLOBUS_SUCCESS) { verror_put_string("globus_gsi_cred_get_cert_chain() failed");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -