Main Page | Data Structures | File List | Data Fields | Globals

keystore_client.c

Go to the documentation of this file.
00001 
00009 /******************************************************************************
00010  *
00011  *      File:                   keystore_client.c
00012  *
00013  *      Function:               Secure Storage Keystore client API Library source
00014  *
00015  *      Author(s):              Giordano Scuderi and Nicola Dominante
00016  *
00017  *      Copyright:              Copyright (c) 2007 <Giordano Scuderi - gscuderi@unicosrl.it>
00018  *                                      All Rights Reserved.
00019  *
00020  *
00021  *      Notes:                  Redistributions of any form whatsoever must retain the following
00022  *                              acknowledgment:
00023  *                              "This product includes software developed by Giordano Scuderi
00024  *                              and Nicola Dominante for Unico SRL"
00025  *
00026  * ====================================================================
00027  * Copyright (c) Giordano Scuderi, Unico SRL.  All rights reserved.
00028  *
00029  * Redistribution and use in source and binary forms, with or without
00030  * modification, are permitted provided that the following conditions
00031  * are met:
00032  *
00033  * 1. Redistributions of source code must retain the above copyright
00034  *    notice, this list of conditions and the following disclaimer. 
00035  *
00036  * 2. Redistributions in binary form must reproduce the above copyright
00037  *    notice, this list of conditions and the following disclaimer in
00038  *    the documentation and/or other materials provided with the
00039  *    distribution.
00040  *
00041  * 3. All advertising materials mentioning features or use of this
00042  *    software must display the following acknowledgment:
00043  *    "This product includes software developed by Giordano Scuderi
00044  *    for Unico SRL"
00045  *
00046  * 4. The names "Secure Storage" must not be used to
00047  *    endorse or promote products derived from this software without
00048  *    prior written permission. For written permission, please contact
00049  *    gscuderi@unicosrl.it.
00050  *
00051  * 5. Products derived from this software may not be called "Secure Storage"
00052  *    nor may "Secure Storage" appear in their names without prior written
00053  *    permission of Giordano Scuderi (Unico SRL).
00054  *
00055  * 6. Redistributions of any form whatsoever must retain the following
00056  *    acknowledgment:
00057  *    "This product includes software developed by Giordano Scuderi
00058  *    for Unico SRL"
00059  *
00060  * THIS SOFTWARE IS PROVIDED BY UNICO SRL ``AS IS'' AND ANY
00061  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00062  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00063  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNICO SRL OR
00064  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00065  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00066  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00067  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00068  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00069  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00070  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00071  * OF THE POSSIBILITY OF SUCH DAMAGE.
00072  * ====================================================================
00073  *
00074  * "This product includes software developed by the OpenSSL Project
00075  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
00076  * 
00077  */
00078 
00079 #include <errno.h>
00080 #include <string.h>
00081 #include <netdb.h>
00083 #include "keystore_client.h"
00084 
00085 const char *ss_errlist[56] = {
00086         "Success",
00087         "Keystore: Wrong parameters number",                                                                                    // 1
00088         "Keystore: Error in saving data",                                                                                               // 2
00089         "Keystore: User not authorized",                                                                                                // 3
00090         "Keystore: Generic Error",                                                                                                              // 4
00091         "Keystore: Error reading key or iv",                                                                                    // 5
00092         "Keystore: Cannot delete the key",                                                                                              // 6
00093         "Keystore: A key for this LFN doesn't exist",                                                                   // 7
00094         "Keystore: A Key for this LFN just exists",                                                                             // 8
00095         "Invalid LFN specified",                                                                                                                // 9
00096         "Invalid VO specified",                                                                                                                 // 10
00097         "Invalid GUID specified",                                                                                                               // 11
00098         "Invalid SE specified",                                                                                                                 // 12
00099         "Invalid Source File specified",                                                                                                // 13
00100         "Invalid destination file specified",                                                                                   // 14
00101         "Invalid parameter specified",                                                                                                  // 15
00102         "File Exist",                                                                                                                                   // 16
00103         "No such file or directory",                                                                                                    // 17
00104         "No replica found",                                                                                                                             // 18
00105         "Permission denied",                                                                                                                    // 19
00106         "Illegal seek",                                                                                                                                 // 20
00107         "Invalid offset specified",                                                                                                             // 21
00108         "Invalid whence specified",                                                                                                             // 22
00109         "Source file name too long",                                                                                                    // 23
00110         "Destination file name too long",                                                                                               // 24
00111         "File name too long",                                                                                                                   // 25
00112         "Invalid SS_GRID_KEYSTORE_HOST environment variable",                                                   // 26
00113         "Invalid SS_GRID_KEYSTORE_DN environment variable",                                                             // 27
00114         "Invalid SS_LOCAL_KEYSTORE_HOST environment variable",                                                  // 28
00115         "Invalid SS_LOCAL_KEYSTORE_DN environment variable",                                                    // 29
00116         "Authentication with Keystore failed",                                                                                  // 30
00117         "Connection to the Keystore failed",                                                                                    // 31
00118         "Send data to keystore failed",                                                                                                 // 32
00119         "Receive data to keystore failed",                                                                                              // 33
00120         "Error when closing connection to the keystore",                                                                // 34
00121         "AES encryption initializing failed",                                                                                   // 35
00122         "The specified keystore host is unknown",                                                                               // 36
00123         "The requested keystore name is valid but does not have an IP address",                 // 37
00124         "A non-recoverable name server error occurred",                                                                 // 38
00125         "A temporary error occurred on an authoritative name server.Try again later",   // 39
00126         "No credentials found",                                                                                                                 // 40
00127         "No secure context has been established",                                                                               // 41
00128         "The referenced context could not be accessed",                                                                 // 42
00129         "The referenced context could not be deleted",                                                                  // 43
00130         "The context has already expired",                                                                                              // 44
00131         "The specified QOP is not supported by the mechanism",                                                  // 45
00132         "Generic error on wrapping message",                                                                                    // 46
00133         "Invalid token argument",                                                                                                               // 47
00134         "No token has been read",                                                                                                               // 48
00135         "Token too large",                                                                                                                              // 49
00136         "The token failed consistency checks",                                                                                  // 50
00137         "The MIC was incorrect",                                                                                                                // 51
00138         "The token is too old to check for duplication",                                                                // 52
00139         "The token has been verified out of sequence; a later token has already been received",                 // 53
00140         "The token has been verified out of sequence; an earlier expected token has not yet been received",     // 54
00141         "Generic error on unwrapping message",                                                                                  // 55
00142 };
00143 
00144 // \struct Used to represent client in keystore connection.
00145 struct ss_socket_client {       
00147         struct sockaddr_in peeraddr_in; 
00149         int sck;
00151         gss_ctx_id_t gss_context; 
00153         char* host;
00155         int port; 
00157         char* server_contact;
00162         int delegate_credentials;
00163 };
00164 
00165 extern int errno;
00166 
00167 static int get_keystore_env ( char **host, int *port, char **dn ) {
00168         
00169         char *ss_host_tmp = getenv(KEYSTORE_HOST);
00170         if ( ss_host_tmp == NULL ) { // SS_GRID_KEYSTORE_HOST not specified
00171                 errno = SS_ENOGRIDSSKEYSTOREENV;
00172                 return (-1);
00173         }
00174         char *ss_port = strrchr(ss_host_tmp, ':');
00175         if ( ss_port == NULL ) { // Port not specified on SS_GRID_KEYSTORE_HOST
00176                 errno = SS_ENOGRIDSSKEYSTOREENV;
00177                 return (-1);
00178         } else if ( strlen(ss_port) <= 1 ) { // Port not specified on SS_GRID_KEYSTORE_HOST
00179                 errno = SS_ENOGRIDSSKEYSTOREENV;
00180                 return (-1);
00181         }
00182         ss_port += 1;
00183         int keystore_port = atoi(ss_port);
00184         ss_port -= 1;
00185         if ( keystore_port <= 0 ) { // Invalid port specified on SS_GRID_KEYSTORE_HOST
00186                 errno = SS_ENOGRIDSSKEYSTOREENV;
00187                 return (-1);
00188         }
00189         size_t n = ss_port - ss_host_tmp;
00190         if ( n <= 0 ) { // Host not specified on SS_GRID_KEYSTORE_HOST
00191                 errno = SS_ENOGRIDSSKEYSTOREENV;
00192                 return (-1);
00193         }
00194 
00195         *host = (char*) malloc(n+1);
00196          memset(*host, '\0', n+1);      
00197          memcpy(*host,ss_host_tmp,n);
00198         *port = keystore_port;
00199         
00200         char *ss_dn = getenv(KEYSTORE_DN);
00201         if ( ss_dn == NULL ) { // Distinguished Name not specified on SS_GRID_KEYSTORE_DN
00202                 free(*host);
00203                 errno = SS_ENOGRIDSSKEYSTOREDNENV;
00204                 return (-1);
00205         }
00206         *dn = strdup (ss_dn);
00207         return 0;
00208 }
00209 
00210 
00211 /******************************************************************************
00212  * Send a gss token.
00213  * 
00214  ******************************************************************************/
00215 static int ss_send_token(void *arg, void *token, size_t token_length){
00216         
00217     size_t                      num_written = 0;
00218     ssize_t                     n_written;
00219     int                         fd = *( (int *) arg );
00220     unsigned char               token_length_buffer[4];
00221 
00222     if( token == NULL || (token_length <=0)) {         
00223         errno = SSKEYSTORE_INVALIDTOKEN;
00224         return (-1);
00225     }
00226 
00227     /* encode the token length in network byte order: 4 byte, big endian */
00228     token_length_buffer[0] = (unsigned char) ((token_length >> 24) & 0xff);
00229     token_length_buffer[1] = (unsigned char) ((token_length >> 16) & 0xff);
00230     token_length_buffer[2] = (unsigned char) ((token_length >>  8) & 0xff);
00231     token_length_buffer[3] = (unsigned char) ((token_length      ) & 0xff);
00232 
00233     /* send the token length */
00234     while(num_written < 4){
00235       n_written = send(fd, token_length_buffer + num_written, 4 - num_written,0);      
00236       if(n_written < 0){
00237           if(errno == EINTR)//Interrupted by SO,socket is not in error state
00238             continue;
00239           else
00240             return (-1);
00241       }else{
00242         num_written += n_written;
00243       }
00244     }
00245     
00246     /* send the token */
00247     num_written = 0;
00248     while(num_written < token_length){
00249        n_written = send(fd, ((u_char *)token) + num_written, token_length - num_written,0);       
00250        if(n_written < 0){
00251            if(errno == EINTR){//Interrupted by SO,socket is not in error state
00252                 continue;
00253            }else{
00254              return (-1);
00255            }
00256        }else{
00257          num_written += n_written;
00258        }
00259     }    
00260     return 0;
00261 }
00262 
00263 /******************************************************************************
00264  * Receive a gss token.
00265  * 
00266  ******************************************************************************/
00267 static int ss_get_token(void *arg, void **token, size_t *token_length){
00268         
00269     size_t                      num_read = 0;
00270     ssize_t                     n_read;
00271     int                         fd = *( (int *) arg );
00272     unsigned char               token_length_buffer[4];
00273 
00274     /* read the token length */
00275     while(num_read < 4){      
00276       n_read = recv(fd,token_length_buffer + num_read, 4 - num_read,0); 
00277       if(n_read < 0){
00278             if(errno == EINTR){//Interrupted by SO,socket is not in error state
00279                 continue;
00280             }else{
00281                 return (-1);
00282             }
00283       }else{
00284              if (n_read == 0){                  
00285                 errno = SSKEYSTORE_TOKENEOF;
00286                 return (-1);
00287              }else{
00288                 num_read += n_read;
00289              }
00290       }
00291     }    
00292     num_read = 0;
00293     
00294     /* decode the token length from network byte order: 4 byte, big endian */
00295     *token_length  = (((size_t) token_length_buffer[0]) << 24) & 0xffff;
00296     *token_length |= (((size_t) token_length_buffer[1]) << 16) & 0xffff;
00297     *token_length |= (((size_t) token_length_buffer[2]) <<  8) & 0xffff;
00298     *token_length |= (((size_t) token_length_buffer[3])      ) & 0xffff;
00299 
00300     if(*token_length > 1<<24){
00301         /* token too large */   
00302         errno = SSKEYSTORE_TOKENTOOLARGE;
00303         return (-1);
00304     }
00305 
00306     /* allocate space for the token */
00307     *((void **)token) = (void *) malloc(*token_length);
00308     if(*token == NULL){ 
00309         errno = ENOMEM;
00310         return (-1);
00311     }
00312 
00313     /* receive the token */
00314     num_read = 0;
00315     while(num_read < *token_length){
00316       n_read = recv(fd, ((u_char *) (*token)) + num_read,(*token_length) - num_read,0); 
00317       if(n_read < 0){
00318             if(errno == EINTR){//Interrupted by SO,socket is not in error state
00319                 continue;
00320             }else{
00321                 int errno_save = errno;
00322                 free(*token);
00323                 errno = errno_save;
00324                 return (-1);
00325             }
00326       }else{
00327             if(n_read == 0){
00328                 free(*token);
00329                 errno = SSKEYSTORE_TOKENEOF;
00330                 return (-1); 
00331             }
00332             num_read += n_read;
00333       }
00334     }
00335     return 0;
00336 }
00337 
00338 /******************************************************************************
00339  * Initialize GSI Authentication.
00340  * 
00341  ******************************************************************************/
00342 static int init_gsi_authentication(struct ss_socket_client *ssc){
00343         
00344         OM_uint32                   major_status = 0;
00345         OM_uint32                   minor_status = 0;
00346         gss_cred_id_t               credential = GSS_C_NO_CREDENTIAL;
00347         OM_uint32                   req_flags  = 0;
00348         OM_uint32                   ret_flags  = 0;
00349         int                         token_status = 0;
00350         gss_name_t                  targ_name;
00351         gss_buffer_desc             name_buffer;
00352         char                        service[1024];
00353         int                         status;
00354       
00355     /* acquire our credentials */
00356     major_status = globus_gss_assist_acquire_cred(&minor_status, GSS_C_BOTH, &credential);
00357 
00358     if(GSS_ERROR(major_status)!= 0) {   
00359         errno = SSKEYSTORE_NOCREDFOUND;
00360         return (-1);
00361     }    
00362     /* Request that remote peer authenticate tself */
00363     req_flags = GSS_C_MUTUAL_FLAG;   
00364     
00365     if(ssc-> delegate_credentials) req_flags |= GSS_C_DELEG_FLAG;    
00366     snprintf(service, sizeof(service), "host@%s", ssc->host);
00367 
00368     /* initialize the security context */
00369     /* credential has to be fill in beforehand */
00370     major_status = globus_gss_assist_init_sec_context(&minor_status, credential,&ssc->gss_context,
00371             (strlen(ssc-> server_contact)== 0) ? service : ssc-> server_contact,
00372              req_flags, &ret_flags, &token_status, ss_get_token,
00373              (void *) &ssc->sck, ss_send_token, (void *) &ssc->sck);
00374     
00375     gss_release_cred(&minor_status, &credential);
00376 
00377     if(GSS_ERROR(major_status) !=0 ) {
00378         errno = SSKEYSTORE_NOSECURECONTEXT;
00379         return (-1);     
00380     }
00381     else {      
00382         major_status = gss_inquire_context(&minor_status,ssc->gss_context,NULL,&targ_name, NULL,
00383                                          NULL, NULL, NULL, NULL);
00384      
00385         status = (major_status == GSS_S_COMPLETE);      
00386         major_status = gss_display_name(&minor_status, targ_name, &name_buffer, NULL);
00387         gss_release_name(&minor_status, &targ_name);
00388     }
00389     
00390     if (status == 0 && ssc->gss_context != GSS_C_NO_CONTEXT) {    
00391         gss_delete_sec_context(&minor_status, &ssc->gss_context, GSS_C_NO_BUFFER);
00392         errno = SSKEYSTORE_FAILEDINQUIRECONTEXT;
00393         return (-1);
00394    }
00395     return 0;
00396 }
00397 
00398 /******************************************************************************
00399  * Open connection.
00400  * 
00401  ******************************************************************************/
00402 static int socket_open(struct ss_socket_client *ssc){
00403   
00404   if((ssc->sck = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {     
00405         return (-1);
00406   }
00407   else {
00408     int value = 1;
00409     if (setsockopt(ssc->sck, SOL_SOCKET, SO_REUSEADDR, (void *) &value, sizeof(int)) < 0){      
00410         return (-1);
00411     }       
00412     if(connect(ssc->sck, (struct sockaddr*)&ssc->peeraddr_in,sizeof(struct sockaddr_in)) == -1) {       
00413         return (-1);
00414     }
00415   }  
00416   return 0;
00417 }
00418 
00419 /******************************************************************************
00420  * Close the connection.
00421  * 
00422  ******************************************************************************/
00423 static int socket_close(struct ss_socket_client *ssc){  
00424         //errno already set
00425         return (close(ssc->sck));
00426 }
00427 
00428 /******************************************************************************
00429  * Remove authentication and close the connection.
00430  * 
00431  ******************************************************************************/
00432 static int ss_close(struct ss_socket_client *ssc)
00433 {
00434   OM_uint32 minor_status = 0;
00435   int return_status = 0;
00436   int errno_save = 0;
00437   
00438   if (ssc-> gss_context != GSS_C_NO_CONTEXT) {
00439      gss_delete_sec_context(&minor_status, &ssc-> gss_context, GSS_C_NO_BUFFER);
00440      if (minor_status == GSS_S_FAILURE ){
00441         errno_save = SSKEYSTORE_FAILEDDELETECONTEXT;
00442         return_status = -1;             
00443      }else{
00444         ssc-> gss_context= GSS_C_NO_CONTEXT;
00445      }
00446   } 
00447   socket_close(ssc);
00448   if (ssc->server_contact != NULL){
00449         free(ssc->server_contact);
00450   }
00451   if (ssc-> host != NULL){
00452         free(ssc-> host);
00453   }
00454   free(ssc);
00455   errno = errno_save;
00456   return return_status;
00457 }
00458 
00459 
00460 /******************************************************************************
00461  * Open connection and make GSI authentication.
00462  * 
00463  ******************************************************************************/
00464 static int ss_open(char *host, int port, char *dn, struct ss_socket_client **client){
00465   
00466         struct ss_socket_client *ss_client; 
00467  
00468         //Create a new client
00469         ss_client = malloc(sizeof(struct ss_socket_client));    
00470         struct hostent *hp; 
00471         
00472         if ( ss_client == NULL) {
00473                 errno = ENOMEM;
00474                 return (-1);
00475         }       
00476         ss_client -> gss_context = GSS_C_NO_CONTEXT;
00477         memset ((char *) &ss_client->peeraddr_in, 0, sizeof(struct sockaddr_in));       
00478     
00479         if((hp = gethostbyname(host)) == NULL) {
00480                 free(ss_client);
00481                 switch (h_errno){
00482                         case HOST_NOT_FOUND :
00483                                 errno = SSKEYSTORE_HOSTNOTFOUND;
00484                                 break;
00485                         case NO_ADDRESS :
00486                                 errno = SSKEYSTORE_NODATAORADDR;
00487                                 break;  
00488                         case NO_RECOVERY :
00489                                 errno = SSKEYSTORE_NORECOVERY;
00490                                 break;  
00491                         case TRY_AGAIN :
00492                                 errno = SSKEYSTORE_TRY_AGAIN;
00493                                 break;
00494                         default :
00495                                 break;
00496                 }
00497                 return (-1);
00498         }
00499         else {      
00500               ss_client->peeraddr_in.sin_family = AF_INET;
00501               ss_client->peeraddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
00502               ss_client->peeraddr_in.sin_port = htons(port);          
00503         }
00504                 
00505         ss_client -> host = (char*) strdup(host);
00506         ss_client -> port = port;
00507         ss_client -> delegate_credentials = 1;          
00508         //Set DN
00509         ss_client-> server_contact = (char*) strdup(dn);
00510         
00511         //Open connection on socket
00512         int op;
00513         if ((op = socket_open(ss_client)) != 0){
00514                 int errno_save = errno;
00515                 ss_close(ss_client);
00516                 errno = errno_save;
00517                 return (-1);
00518         }
00519         //Authentication GSI
00520         int aut;
00521         if ((aut = init_gsi_authentication(ss_client)) != 0){                   
00522                 int errno_save = errno;
00523                 ss_close(ss_client);
00524                 errno = errno_save;
00525                 return (-1);
00526         }       
00527         *client = ss_client;
00528         return 0;
00529 }
00530 
00531 /******************************************************************************
00532  * Send a string value.
00533  * 
00534  ******************************************************************************/
00535 static int ss_send_string(struct ss_socket_client* ssc, const char* s){ 
00536   
00537   gss_buffer_desc  input_token;
00538   gss_buffer_desc  output_token;
00539   OM_uint32        maj_stat, min_stat;
00540   input_token.value = (void*)s;
00541   input_token.length = (strlen(s) + 1);
00542 
00543   if(ssc -> gss_context != GSS_C_NO_CONTEXT) {//dovrebbe essere piu corretto GSS_C_NO_CONTEXT rispetto a GSS_C_NO_CREDENTIAL   
00544     /* set this flag to 0 if you want to encrypt messages. set it to nonzero
00545        if only integrity protection is requested */     
00546     int conf_req_flag = 0;     
00547     maj_stat = gss_wrap (&min_stat,ssc -> gss_context,conf_req_flag, GSS_C_QOP_DEFAULT,
00548                          &input_token, NULL, &output_token);
00549      
00550     if (GSS_ERROR(maj_stat) != 0){
00551         switch (maj_stat){
00552                 case GSS_S_CONTEXT_EXPIRED :
00553                         errno = SSKEYSTORE_CONTEXTEXPIRED;
00554                         break;
00555                 case GSS_S_NO_CONTEXT :
00556                         errno = SSKEYSTORE_NOSECURECONTEXT;
00557                         break;  
00558                 case GSS_S_BAD_QOP :
00559                         errno = SSKEYSTORE_BADQOP;
00560                         break;  
00561                 case GSS_S_FAILURE :
00562                         errno = SSKEYSTORE_FAILEDWRAPMSG;
00563                         break;
00564                 default :
00565                         break;
00566         }       
00567         return (-1);
00568     }
00569     int result;
00570     if ((result = ss_send_token((void*) &ssc->sck, output_token.value, output_token.length)) != 0){             
00571         return (-1);
00572     }
00573      
00574     gss_release_buffer(&min_stat, &output_token);
00575   }else{
00576         errno = SSKEYSTORE_NOSECURECONTEXT;
00577         return (-1);    
00578   }     
00579   return 0;
00580 }
00581 
00582 /******************************************************************************
00583  * Send an int value.
00584  * 
00585  ******************************************************************************/
00586 static int ss_send_int(struct ss_socket_client* ssc, int i){    
00587   
00588   unsigned char int_buffer[4];
00589   gss_buffer_desc  input_token;
00590   gss_buffer_desc  output_token;
00591   OM_uint32        maj_stat, min_stat;
00592   input_token.value = (void*)int_buffer;
00593   input_token.length = 4;  
00594 
00595   if(ssc -> gss_context != GSS_C_NO_CONTEXT) {        
00596     int_buffer[0] = (unsigned char) ((i >> 24) & 0xff);
00597     int_buffer[1] = (unsigned char) ((i >> 16) & 0xff);
00598     int_buffer[2] = (unsigned char) ((i >>  8) & 0xff);
00599     int_buffer[3] = (unsigned char) ((i      ) & 0xff);
00600     
00601     /* set this flag to 0 if you want to encrypt messages. set it to nonzero
00602        if only integrity protection is requested */
00603     int conf_req_flag = 0;
00604 
00605     maj_stat = gss_wrap (&min_stat,ssc->gss_context,conf_req_flag,GSS_C_QOP_DEFAULT,&input_token,
00606         NULL,&output_token);
00607         
00608     if (GSS_ERROR(maj_stat) != 0){
00609         switch (maj_stat){
00610                 case GSS_S_CONTEXT_EXPIRED :
00611                         errno = SSKEYSTORE_CONTEXTEXPIRED;
00612                         break;
00613                 case GSS_S_NO_CONTEXT :
00614                         errno = SSKEYSTORE_NOSECURECONTEXT;
00615                         break;  
00616                 case GSS_S_BAD_QOP :
00617                         errno = SSKEYSTORE_BADQOP;
00618                         break;  
00619                 case GSS_S_FAILURE :
00620                         errno = SSKEYSTORE_FAILEDWRAPMSG;
00621                         break;
00622                 default :
00623                         break;
00624         }       
00625         return (-1);
00626     }
00627     int result;
00628     if ((result = ss_send_token((void*) &ssc->sck, output_token.value, output_token.length)) != 0){             
00629         return (-1);
00630     }
00631     
00632     gss_release_buffer(&min_stat, &output_token);
00633   }else{
00634         errno = SSKEYSTORE_NOSECURECONTEXT;
00635         return (-1);
00636   } 
00637   return 0;
00638 }
00639 
00640 /******************************************************************************
00641  * Receive a string value.
00642  * 
00643  ******************************************************************************/
00644 static int ss_receive_string(struct ss_socket_client* ssc,unsigned char* s){    
00645   OM_uint32 maj_stat, min_stat;
00646   gss_buffer_desc input_token;
00647   gss_buffer_desc output_token;
00648   int result;
00649   
00650   if(ssc->gss_context != GSS_C_NO_CONTEXT){
00651         if ((result = ss_get_token(&ssc->sck, &input_token.value, &input_token.length)) != 0){          
00652                 return (-1);
00653         }         
00654         maj_stat = gss_unwrap (&min_stat,ssc->gss_context, &input_token,&output_token, NULL, NULL);
00655         if (GSS_ERROR(maj_stat) != 0) { 
00656                 switch (maj_stat){
00657                         case GSS_S_DEFECTIVE_TOKEN :
00658                                 errno = SSKEYSTORE_DEFECTIVETOKEN;
00659                                 break;
00660                         case GSS_S_BAD_SIG :
00661                                 errno = SSKEYSTORE_BADSIG;
00662                                 break;
00663                         case GSS_S_DUPLICATE_TOKEN :
00664                                 errno = SSKEYSTORE_DUPLICATETOKEN;
00665                                 break;
00666                         case GSS_S_UNSEQ_TOKEN :
00667                                 errno = SSKEYSTORE_UNSEQTOKEN;
00668                                 break;
00669                         case GSS_S_GAP_TOKEN :
00670                                 errno = SSKEYSTORE_GAPTOKEN;
00671                                 break;  
00672                         case GSS_S_CONTEXT_EXPIRED :
00673                                 errno = SSKEYSTORE_CONTEXTEXPIRED;
00674                                 break;
00675                         case GSS_S_NO_CONTEXT :
00676                                 errno = SSKEYSTORE_NOSECURECONTEXT;
00677                                 break;                          
00678                         case GSS_S_FAILURE :
00679                                 errno = SSKEYSTORE_FAILEDUNWRAPMSG;
00680                                 break;
00681                         default :
00682                                 break;
00683                 }
00684                 return (-1);
00685         }       
00686         memcpy(s,output_token.value,output_token.length);  
00687         gss_release_buffer(&min_stat, &output_token);
00688         gss_release_buffer(&min_stat, &input_token);
00689   }else{
00690         errno = SSKEYSTORE_NOSECURECONTEXT;
00691         return (-1);    
00692   }
00693   return 0;
00694 }
00695 
00696 /******************************************************************************
00697  * Receive an int value.
00698  * 
00699  ******************************************************************************/
00700 static int ss_receive_int(struct ss_socket_client* ssc,int* i){ 
00701   unsigned char int_buffer[4];
00702   OM_uint32 maj_stat, min_stat;
00703   gss_buffer_desc input_token;
00704   gss_buffer_desc output_token;
00705 
00706   input_token.value = NULL;
00707 
00708   if(ssc->gss_context != GSS_C_NO_CONTEXT){
00709         if (ss_get_token(&ssc->sck, &input_token.value, &input_token.length) != 0){             
00710                 return (-1);
00711         }       
00712         maj_stat = gss_unwrap (&min_stat,ssc->gss_context,&input_token, &output_token, NULL, NULL);
00713         if (GSS_ERROR(maj_stat) != 0) { 
00714                 switch (maj_stat){
00715                         case GSS_S_DEFECTIVE_TOKEN :
00716                                 errno = SSKEYSTORE_DEFECTIVETOKEN;
00717                                 break;
00718                         case GSS_S_BAD_SIG :
00719                                 errno = SSKEYSTORE_BADSIG;
00720                                 break;
00721                         case GSS_S_DUPLICATE_TOKEN :
00722                                 errno = SSKEYSTORE_DUPLICATETOKEN;
00723                                 break;
00724                         case GSS_S_UNSEQ_TOKEN :
00725                                 errno = SSKEYSTORE_UNSEQTOKEN;
00726                                 break;
00727                         case GSS_S_GAP_TOKEN :
00728                                 errno = SSKEYSTORE_GAPTOKEN;
00729                                 break;  
00730                         case GSS_S_CONTEXT_EXPIRED :
00731                                 errno = SSKEYSTORE_CONTEXTEXPIRED;
00732                                 break;
00733                         case GSS_S_NO_CONTEXT :
00734                                 errno = SSKEYSTORE_NOSECURECONTEXT;
00735                                 break;                          
00736                         case GSS_S_FAILURE :
00737                                 errno = SSKEYSTORE_FAILEDUNWRAPMSG;
00738                                 break;
00739                         default :
00740                                 break;
00741                 }
00742                 return (-1);
00743         }       
00744         memcpy((char*)int_buffer, output_token.value, output_token.length);     
00745         *i  = (((unsigned int) int_buffer[0]) << 24) & 0xffff;
00746         *i |= (((unsigned int) int_buffer[1]) << 16) & 0xffff;
00747         *i |= (((unsigned int) int_buffer[2]) <<  8) & 0xffff;
00748         *i |= (((unsigned int) int_buffer[3])      ) & 0xffff;
00749          
00750         gss_release_buffer(&min_stat, &output_token);
00751         gss_release_buffer(&min_stat, &input_token);
00752   }else{
00753         errno = SSKEYSTORE_NOSECURECONTEXT;
00754         return (-1);
00755   }
00756   return 0;
00757 }
00758 
00759 /******************************************************************************
00760  * Send KEY and IV to keystore.
00761  * 
00762  ******************************************************************************/
00763 int ss_send_key ( const char *lfn, const unsigned char *key, const unsigned char *iv ) {
00764         
00765         int x;
00766         struct ss_socket_client *ss_client;     
00767         char *dn, *host;
00768         int port;
00769         if (get_keystore_env(&host, &port, &dn) != 0 ) {
00770                 return (-1);
00771         }
00772         if (ss_open(host,port,dn,&ss_client) != 0){
00773                 return (-1);
00774         }
00775         // Send KEY and IV to keystore
00776         // Build value to send to Keystore
00777         int param1_len = strlen(lfn);
00778         int param2_len = strlen(key);
00779         int param3_len = strlen(iv);
00780         int pack_length = ( sizeof(param_len) * 3 ) + sizeof(param_len) + param1_len + sizeof(param_len) + param2_len + sizeof(param_len) + param3_len;
00781         int numparam = 3;
00782         if (ss_send_int(ss_client,pack_length) != 0) {
00783                 int errno_save = errno;
00784                 ss_close(ss_client);
00785                 errno = errno_save;
00786                 return (-1);
00787         }
00788         if (ss_send_int(ss_client,SEND) != 0) {
00789                 int errno_save = errno;
00790                 ss_close(ss_client);
00791                 errno = errno_save;
00792                 return (-1);
00793         }
00794         if (ss_send_int(ss_client,numparam) != 0) {
00795                 int errno_save = errno;
00796                 ss_close(ss_client);
00797                 errno = errno_save;
00798                 return (-1);
00799         }
00800         const unsigned char* param_array[numparam];
00801         param_array[0] = lfn;
00802         param_array[1] = key;
00803         param_array[2] = iv;
00804         
00805         for ( x=0; x < numparam ; x++ ) {
00806                 int length = strlen(param_array[x]);
00807                 if (ss_send_int(ss_client,length) != 0) {
00808                         int errno_save = errno;
00809                         ss_close(ss_client);
00810                         errno = errno_save;
00811                         return (-1);
00812                 }
00813                 if (ss_send_string(ss_client,param_array[x]) != 0) {
00814                         int errno_save = errno;
00815                         ss_close(ss_client);
00816                         errno = errno_save;
00817                         return (-1);
00818                 }
00819         }       
00820         // Receive ack or error from Keystore
00821         int receive_length = 0;
00822         if(ss_receive_int(ss_client,&receive_length) != 0) {
00823                 int errno_save = errno;
00824                 ss_close(ss_client);
00825                 errno = errno_save;
00826                 return (-1);
00827         }
00828         int iterate = (receive_length / sizeof(int)) -1;
00829         int response[iterate];
00830         for (x=0; x < iterate; x++) {           
00831                 if(ss_receive_int(ss_client,&response[x]) != 0) {
00832                         int errno_save = errno;
00833                         ss_close(ss_client);
00834                         errno = errno_save;
00835                         return (-1);
00836                 }
00837         }
00838         ss_close(ss_client);    
00839         if (response[0] != 0){
00840                 errno = (response[0]+10000);
00841                 return (-1);
00842         }
00843         return 0;
00844 }
00845 
00846 /******************************************************************************
00847  * Get KEY and IV from keystore.
00848  * 
00849  ******************************************************************************/
00850 int ss_get_key  ( const char *lfn, unsigned char *key, unsigned char *iv ) {
00851                 
00852         struct ss_socket_client *ss_client;     
00853         char *dn, *host;
00854         int port;
00855         
00856         if (get_keystore_env(&host, &port, &dn) != 0 ) {
00857                 return (-1);
00858         }
00859         if (ss_open(host,port,dn,&ss_client) != 0){
00860                 return (-1);
00861         }
00862         // Build value to send to Keystore
00863         int param1_len = strlen(lfn);
00864         int pack_length = ( sizeof(param_len) * 3 ) + sizeof(param_len) + param1_len;
00865         int numparam = 1;
00866         const unsigned char* param_array[numparam];
00867         int x;
00868         
00869         if (ss_send_int(ss_client,pack_length) != 0) {
00870                 int errno_save = errno;
00871                 ss_close(ss_client);
00872                 errno = errno_save;
00873                 return (-1);
00874         }
00875         if (ss_send_int(ss_client,GET) != 0) {
00876                 int errno_save = errno;
00877                 ss_close(ss_client);
00878                 errno = errno_save;
00879                 return (-1);
00880         }
00881         if (ss_send_int(ss_client,numparam) != 0) {
00882                 int errno_save = errno;
00883                 ss_close(ss_client);
00884                 errno = errno_save;
00885                 return (-1);
00886         }
00887         param_array[0]=lfn;
00888         for ( x=0; x < numparam ; x++ ) {
00889                 int length = strlen(param_array[x]);
00890                 if (ss_send_int(ss_client,length) != 0) {
00891                         int errno_save = errno;
00892                         ss_close(ss_client);
00893                         errno = errno_save;
00894                         return (-1);
00895                 }
00896                 if (ss_send_string(ss_client,param_array[x]) != 0) {
00897                         int errno_save = errno;
00898                         ss_close(ss_client);
00899                         errno = errno_save;
00900                         return (-1);
00901                 }
00902         }
00903         // Read ack or error
00904         int receive_length = 0;
00905         if(ss_receive_int(ss_client,&receive_length) != 0) {
00906                 int errno_save = errno;
00907                 ss_close(ss_client);
00908                 errno = errno_save;
00909                 return (-1);
00910         }
00911         int response=0;
00912         if(ss_receive_int(ss_client,&response) != 0) {
00913                 int errno_save = errno;
00914                 ss_close(ss_client);
00915                 errno = errno_save;
00916                 return (-1);
00917         }       
00918         if ( response != 0 ) { // Return Keystore error
00919                 ss_close(ss_client);
00920                 errno = (response + 10000);
00921                 return (-1);
00922         }
00923         
00924         int numparam_resp;
00925         if(ss_receive_int(ss_client,&numparam_resp) != 0) {
00926                 int errno_save = errno;
00927                 ss_close(ss_client);
00928                 errno = errno_save;
00929                 return (-1);
00930         }
00931         int key_len=0;
00932         if(ss_receive_int(ss_client,&key_len) != 0) {
00933                 int errno_save = errno;
00934                 ss_close(ss_client);
00935                 errno = errno_save;
00936                 return (-1);
00937         }
00938         if(ss_receive_string(ss_client,key) != 0) {
00939                 int errno_save = errno;
00940                 ss_close(ss_client);
00941                 errno = errno_save;
00942                 return (-1);
00943         }
00944         int iv_len=0;
00945         if(ss_receive_int(ss_client,&iv_len) != 0) {
00946                 int errno_save = errno;
00947                 ss_close(ss_client);
00948                 errno = errno_save;
00949                 return (-1);
00950         }       
00951         if(ss_receive_string(ss_client,iv) != 0) {
00952                 int errno_save = errno;
00953                 ss_close(ss_client);
00954                 errno = errno_save;
00955                 return (-1);
00956         }
00957         ss_close(ss_client);    
00958         return 0;
00959 }
00960 
00961 
00962 /******************************************************************************
00963  * Delete KEY and IV from keystore.
00964  * 
00965  ******************************************************************************/
00966 int ss_delete_key ( const char *lfn ) {
00967         
00968         struct ss_socket_client *ss_client;     
00969         char *dn, *host;
00970         int port;
00971 
00972         if (get_keystore_env(&host, &port, &dn) != 0 ) {
00973                 return (-1);
00974         }
00975         if (ss_open(host,port,dn,&ss_client) != 0){
00976                 return (-1);
00977         }
00978         // Build value to send to Keystore
00979         int param1_len = strlen(lfn);
00980         int pack_length = ( sizeof(param_len) * 3 ) + sizeof(param_len) + param1_len;
00981         int numparam = 1;
00982         const unsigned char* param_array[numparam];
00983         int x;
00984         
00985         // Send LFN to keystore
00986         if (ss_send_int(ss_client,pack_length) != 0) {
00987                 int errno_save = errno;
00988                 ss_close(ss_client);
00989                 errno = errno_save;
00990                 return (-1);
00991         }
00992         if (ss_send_int(ss_client,DEL) != 0) {
00993                 int errno_save = errno;
00994                 ss_close(ss_client);
00995                 errno = errno_save;
00996                 return (-1);
00997         }
00998         if (ss_send_int(ss_client,numparam) != 0) {
00999                 int errno_save = errno;
01000                 ss_close(ss_client);
01001                 errno = errno_save;
01002                 return (-1);
01003         }
01004         param_array[0]=lfn;
01005         for ( x=0; x < numparam ; x++ ) {
01006                 int length = strlen(param_array[x]);
01007                 if (ss_send_int(ss_client,length) != 0) {
01008                         int errno_save = errno;
01009                         ss_close(ss_client);
01010                         errno = errno_save;
01011                         return (-1);
01012                 }
01013                 if (ss_send_string(ss_client,param_array[x]) != 0) {
01014                         int errno_save = errno;
01015                         ss_close(ss_client);
01016                         errno = errno_save;
01017                         return (-1);
01018                 }
01019         }       
01020         // Receive ack or error from Keystore
01021         int receive_length = 0;
01022         if(ss_receive_int(ss_client,&receive_length) != 0) {
01023                 int errno_save = errno;
01024                 ss_close(ss_client);
01025                 errno = errno_save;
01026                 return (-1);
01027         }
01028         int iterate = (receive_length / sizeof(int)) -1;
01029         int response[iterate];
01030         for (x=0; x < iterate; x++) {           
01031                 if(ss_receive_int(ss_client,&response[x]) != 0) {
01032                         int errno_save = errno;
01033                         ss_close(ss_client);
01034                         errno = errno_save;
01035                         return (-1);
01036                 }
01037         }       
01038         ss_close(ss_client);    
01039         if (response[0] != 0){
01040                 errno = (response[0]+10000);
01041                 return (-1);
01042         }
01043         return 0;
01044 }

Generated on Wed May 30 09:56:30 2007 for Secure Storage Service by doxygen 1.3.5