Beispiel #1
0
int send_message(std::string & type, std::string data, std::string&response_type, std::string& response_message, int sock, keyinfo & conn_info){

    //Construct message
    std::string message(type);
    if (type.length() != 0) {
        message.append("|");
        message.append(data);
    }

    //Send it and get response
    std::string response;
    int err = send_nonce(message, response, sock, conn_info);
    
    if (err != 0) {
        return err;
    }
    size_t sep_pos = response.find('|');
    if (sep_pos == response.npos ){
        return -1;
    }
    response_type = response.substr(0, sep_pos);
    response_message = response.substr(sep_pos+1, response.length() - sep_pos);
    return 0;
}
Beispiel #2
0
int main (int argc, char *argv[]){
	int sock, newsock;
	struct sockaddr_storage client_addr;
	socklen_t sin_size;
	char s[INET6_ADDRSTRLEN];
	RSA *decrypt, *sign;
        decrypt = NULL;
        sign    = NULL;

	int retval = SIBYL_SUCCESS;

        char *dir  = NULL;
        char *ip   = NULL;
        char *port = NULL;
        char *decr_namefile = NULL;
        char *sign_namefile = NULL;

        dir  = (char *)calloc(_POSIX_PATH_MAX + 1, sizeof(char));
        ip   = (char *)calloc(17 + 1, sizeof(char));
        port = (char *)calloc(10, sizeof(char));
        decr_namefile = (char *)calloc(_POSIX_PATH_MAX + 1, sizeof(char));
        sign_namefile = (char *)calloc(_POSIX_PATH_MAX + 1, sizeof(char));

        if(dir == NULL || ip == NULL || port == NULL ||
           decr_namefile == NULL || sign_namefile == NULL){
                D("Malloc");
                retval = SIBYL_OSERR;
                goto FREE;
        }

        strncpy(dir, SIBYL_DIR, _POSIX_PATH_MAX);
        strncpy(port, SIBYL_PORT, 9);
        strncpy(decr_namefile, SIBYL_DECR_KEY, _POSIX_PATH_MAX);
        strncpy(sign_namefile, SIBYL_SIGN_KEY, _POSIX_PATH_MAX);

	/* Read options */
	int c;
	while((c = getopt(argc, argv, SIBYL_SRV_OPTS)) != -1){
                if(optarg == NULL)
                        c = 'h';
		switch(c){
			case 'd':
                                strncpy(decr_namefile, 
                                        optarg,
                                        _POSIX_PATH_MAX);
				break;
			case 's':
                                strncpy(sign_namefile,
                                        optarg,
                                        _POSIX_PATH_MAX);
				break;
			case 'p':
                                strncpy(port,
                                        optarg,
                                        9);
				break;
			case 'i':
                                strncpy(ip,
                                        optarg,
                                        _POSIX_PATH_MAX);
				break;
			case 'D':
                                strncpy(dir,
                                        optarg,
                                        _POSIX_PATH_MAX);
				break;
			case 'h':
			default:
				printf("Usage: %s -d decrypt -s sign -i IP -p port -D dir\n"
				       "  -d decrypt: decrypt private key (default: decrypt)\n"
				       "  -s sign: sign private key (default: sign)\n"
				       "  -i IP: IP where the server will listen (default: localhost)\n"
				       "  -p port: port where the server will listen (default: 9999)\n"
				       "  -D dir: directory where the private keys are stored "
				       "(default: /etc/sibyl)\n"
				       "  -h: shows this help text\n", argv[0]);
				exit(1);
		}
	}

	/* Read private keys */
	retval = read_keys(&decrypt,
			   decr_namefile,
			   &sign,
			   sign_namefile,
			   dir);
	if(retval != SIBYL_SUCCESS)
                goto FREE;
        D("Private keys read");

	/* Start server */
	retval = start_server(&sock,
			      ip,
			      port);
	if(retval != SIBYL_SUCCESS){
                goto FREE;
	}
        D("Server started\n");

	while(1){
		/* Accept connection */
		sin_size = sizeof client_addr;
		newsock = accept(sock, 
                                 (struct sockaddr *)&client_addr, 
                                 &sin_size);
		if (newsock == -1){
			perror("server: accept");
			continue;
		}

		inet_ntop(client_addr.ss_family,
			  get_in_addr((struct sockaddr *)&client_addr), 
                          s, 
                          sizeof(s));
		D1("server: got connection from %s\n", s);

		if (!fork()){ // child process
			close(sock); // child doesn't need the listener
			char *strnonce = NULL;
			char *msg      = NULL;
                        char command   = 0;
			char *token[3] = {NULL,NULL,NULL};
			char *p1_data     = NULL;
                        char *p2_data     = NULL;
                        char *auth_result = NULL;

			/* Send the nonce */
			strnonce = (char *) calloc(32, sizeof(char));
                        if (strnonce == NULL){
                                D("Malloc");
                                retval = SIBYL_OSERR;
                                goto ENDCHILD;
                        }

			retval = send_nonce(newsock, strnonce);
			if (retval != SIBYL_SUCCESS){
                                goto ENDCHILD;
			}

			/* Receive the client's message and parse it */
			msg = (char *) calloc(SIBYL_MAX_MSG, sizeof(char));
			if(msg == NULL){
                                D("Malloc");
                                retval = SIBYL_OSERR;
                                goto ENDCHILD;
			}
			retval = receive_msg(msg,
					     newsock,
                                             &command,
					     token);
			if (retval != SIBYL_SUCCESS){
                                goto ENDCHILD;
			}

        		D1("Received: [%s]\n", msg);
                        D1("command: [%c]\n", command);
			D1("m : %s\n", token[0]);
			D1("p1 : %s\n", token[1]);
			D1("p2 : %s\n", token[2]);

                        /* 
                         * Now there are several actions depending on the command
                         * which is stored in command.
                         */

                        /* Just send the public keys */
                        if(command == '-'){
                                retval = send_public_keys(dir,
                                                          decr_namefile,
                                                          sign_namefile,
                                                          newsock);
                                goto ENDCHILD;
                        }
                        
                        /* Any other command requires decryption of p1 */
			/* Decrypt p1 (p1 = token[1]) */
                        /* p1_data always includes a trailing 0 */
                        p1_data = (char *)calloc(RSA_size(decrypt) + 1, 
                                                 sizeof(u_char));
                        if(p1_data == NULL){
                                D("Malloc strnonce");
                                retval = SIBYL_OSERR;
                                goto ENDCHILD;
                        }


                        D1("token[1]:{%s}\n", token[1]);
                        /* this is path */
                        char *resp = (char *)calloc(SIBYL_MAX_MSG,
                                                    sizeof(u_char));
                        memcpy(resp, token[1], strlen(token[1]));
			retval = decrypt_token(p1_data,
                                               command,
					       resp,
					       decrypt);
			if (retval != SIBYL_SUCCESS){
                                printf("Decryption error\n");
                                goto ENDCHILD;
			}

			D1("p1_data: %s\n", p1_data);

                        /* 
                         * If command != \000 then it is '0' <= command <='9'
                         * and translation is asked for.
                         */
                        D1("token[0]:{%s}\n", token[0]);
                        if(command != 0){
                                if(strncmp(strnonce, 
                                           token[0], 
                                           strlen(strnonce))){
                                        D("Wrong nonce");
                                        retval = SIBYL_NONCE_ERROR;
                                        goto ENDCHILD;
                                }
                                retval = translate_and_send(p1_data,
                                                            command,
                                                            decr_namefile,
                                                            dir,
                                                            newsock,
                                                            sign);
                                goto ENDCHILD;
                        }

			/* 
                         * Decrypt p2 (p2 = token[2]):
                         * only if command == verify
                         */
                        p2_data = (char *)calloc(RSA_size(decrypt) + 1, 
                                                 sizeof(u_char));
                        if(p2_data == NULL){
                                perror("Unable to allocate memory for p2_data");
                                retval = SIBYL_OSERR;
                                goto ENDCHILD;
                        }

			retval = decrypt_token(p2_data,
                                               command,
					       token[2],
					       decrypt);
			if (retval != SIBYL_SUCCESS){
                                goto ENDCHILD;
			}

			D1("p2_data: %s\n", p2_data);

			/* Is the password correct */
                        auth_result = calloc(1, sizeof(char));
			if(auth_result == NULL){
				D("Unable to allocate memory for auth_result");
                                retval = SIBYL_OSERR;
                                goto ENDCHILD;
			}
			retval = is_pwd_ok(p1_data,
					   p2_data,
					   auth_result,
					   strnonce);
			if (retval != SIBYL_SUCCESS){
                                goto ENDCHILD;
			}

			/* Send the response to the client */

			retval = send_response(&newsock,
					       token,
					       auth_result,
					       sign);
			if (retval != SIBYL_SUCCESS){
                                goto ENDCHILD;
			}

                ENDCHILD:
                        free(strnonce);
                        free(msg);
                        free(p1_data);
                        free(p2_data);
                        free(auth_result);

			/* Close socket */
			close(newsock);
                        retval = SIBYL_SUCCESS;
                        goto FREE;
		}
		close(newsock); // parent doesn't need this
	}

FREE:

        RSA_free(decrypt);
        RSA_free(sign);
        free(dir);
        free(ip);
        free(port);
        free(decr_namefile);
        free(sign_namefile);
	exit(retval);
}
Beispiel #3
0
void symbolic_attacker(int attacker_id, struct keypair* keypair)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               true == bad(attacker_id) &*&
               principal(attacker_id, ?count) &*&
               keypair(keypair, attacker_id, ?id, ?info, pub); @*/
  //@ ensures false;
{
  //@ retreive_proof_obligations();

  for (;;)
    /*@ invariant [f]world(pub, key_clsfy) &*&
                  proof_obligations(pub) &*&
                  principal(attacker_id, _) &*&
                  keypair(keypair, attacker_id, id, info, pub); @*/
  {
    struct network_status *net_stat = 0;
    int net_choise = random_int_();
    int port = random_int_();
    if (net_choise % 2 == 0)
      net_stat = network_bind_and_accept(port % 65536);
    else
      net_stat = network_connect("localhost", port % 65536);

    {
      int action = random_int_();
      int *counter;
      switch (action % 13)
      {
        case 0:
          //@ open [f]world(pub, key_clsfy);
          //@ assert [_]is_key_classifier(_, pub, key_clsfy);
          //@ retreive_public_invariant_constraints(key_clsfy);
          //@ duplicate_lemma_function_pointer_chunk(key_classifier);
          /*@ {
                lemma void public_key_classifier(cryptogram key, int p, int c,
                                                bool symmetric)
                  requires polarssl_proof_pred(pub, key_clsfy)() &*&
                          [_]polarssl_pub(pub)(key) &*&
                          symmetric ?
                            key == cg_symmetric_key(p, c)
                          :
                            key == cg_private_key(p, c);
                  ensures polarssl_proof_pred(pub, key_clsfy)() &*&
                          col || true == key_clsfy(p, c, symmetric);
                {
                  open [_]polarssl_pub(pub)(key);
                  item k;
                  if (symmetric)
                    k = symmetric_key_item(p, c);
                  else
                    k = private_key_item(p, c);
                  
                  open polarssl_proof_pred(pub, key_clsfy)();
                  assert is_key_classifier(?proof, pub, key_clsfy);
                  proof(k, p, c, symmetric);
                  close polarssl_proof_pred(pub, key_clsfy)();
                }
                produce_lemma_function_pointer_chunk(public_key_classifier) :
                  public_key_classifier(polarssl_pub(pub), key_clsfy,
                                        polarssl_proof_pred(pub, key_clsfy))
                                        (key__, p__, c__, sym__)
                  { call(); }
                  {duplicate_lemma_function_pointer_chunk(public_key_classifier);};
              }
          @*/
          //@ close polarssl_proof_pred(pub, key_clsfy)();
          attacker();
          //@ open polarssl_proof_pred(pub, key_clsfy)();
          //@ close [f]world(pub, key_clsfy);
          //@ leak public_invariant_constraints(_, _);
          //@ leak is_public_key_classifier(_, _, _, _);
          //@ leak is_key_classifier(_, _, _);
          break;
        case 1:
          // Anyone can publish arbitrary data items...
          send_data(net_stat);
          break;
        case 2:
          // Anyone can create pairs of public items...
          send_pair_composed(net_stat);
          break;
        case 3:
         // Anyone can deconstruct a public pair...
          send_pair_decomposed(net_stat);
          break;
        case 4:
          // Bad principals can publish generated nonce items...
          send_nonce(net_stat);
          break;
        case 5:
          // Bad principals can increment public nonces...
          increment_and_send_nonce(net_stat);
          break;
        case 6:
          // Bad principals can leak their keys...
          send_keys(net_stat, keypair);
          break;
        case 7:
          // Anyone can hmac public payload with public key
          send_hmac(net_stat, keypair);
          break;
        case 8:
          // Anyone can symmteric encrypt public payload with public key
          send_symmetric_encrypted(net_stat, keypair);
          break;
        case 9:
          // Anyone can symmteric decrypt message with public key
          send_symmetric_decrypted(net_stat, keypair);
          break;
        case 10:
          // Anyone can asymmteric encrypt public payload with public key
          send_asymmetric_encrypted(net_stat, keypair);
          break;
        case 11:
          // Anyone can asymmteric decrypt message with public key
          send_asymmetric_decrypted(net_stat, keypair);
          break;
        case 12:
          // Anyone can asymmteric sign public payload with public key
          send_asymmetric_signature(net_stat, keypair);
      }
    }
    network_disconnect(net_stat);
  }
  //@ leak proof_obligations(pub);
}