Example #1
0
int
olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  svl_crypto_ctx *ctx = NULL;
  CHECK(IS_LIST(params) && co_list_length(params) == 2, "Invalid params");
  
  size_t sid_len = co_str_len(co_list_element(params, 1));
  char *sid_str = _LIST_ELEMENT(params, 1);
  
  CHECK(sid_len == (2 * SID_SIZE) + 1 && str_is_subscriber_id(sid_str) == 1, "Invalid SID");
  
  ctx = svl_crypto_ctx_new();
  
  stowSid(ctx->sid, 0, sid_str);
  
  ctx->keyring_path = _LIST_ELEMENT(params, 0);
  ctx->keyring_len = co_str_len(co_list_element(params, 0)) - 1;
  CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
  
  CHECK(serval_init_keyring(ctx), "Failed to initialize Serval keyring");
  
  CMD_OUTPUT("key", co_bin8_create((char*)ctx->sas_private, crypto_sign_SECRETKEYBYTES, 0));
  
  return 1;
error:
  if (ctx)
    svl_crypto_ctx_free(ctx);
  return 0;
}
Example #2
0
int olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
  keyring_file *mdp_keyring = NULL;
  unsigned char *mdp_key = NULL;
  int mdp_key_len = 0;
  unsigned char packedSid[SID_SIZE] = {0};
  
  CHECK(IS_LIST(params) && co_list_length(params) == 2,"Invalid params");
  
  size_t sid_len = co_str_len(co_list_element(params,1));
  char *sid_str = _LIST_ELEMENT(params,1);
  
  CHECK(sid_len == 2*SID_SIZE + 1 && str_is_subscriber_id(sid_str) == 1,"Invalid SID");
  stowSid(packedSid,0,sid_str);
  
  CHECK(serval_init_keyring(packedSid,
		     SID_SIZE,
		     _LIST_ELEMENT(params,0),
		     co_str_len(co_list_element(params,0)),
		     &mdp_keyring,
		     &mdp_key,
		     &mdp_key_len), "Failed to initialize Serval keyring");
  
  CMD_OUTPUT("key",co_bin8_create((char*)mdp_key,mdp_key_len,0));
  
  return 1;
error:
  return 0;
}
Example #3
0
int createHlr(char *did,char *sid) {
  int i;
  int record_offset=0;

  /* Generate random SID */
  for(i=0;i<64;i++) sid[i]=hexdigit[random()&0xf]; sid[64]=0;
  if (debug>1) fprintf(stderr,"Creating new HLR entry with sid %s\n",sid);
  
  /* Find first free byte of HLR */
  findHlr(hlr,&record_offset,NULL,NULL);

  if (record_offset>=hlr_size)
    {
      /* No space */
      return setReason("No space in HLR for a new record");
    }
  else
    {
      /* We have found space, but is it enough? */
      int bytes=hlr_size-record_offset;
      if (bytes<1024) return setReason("<1KB space in HLR");
      
      /* Write shiny fresh new record.
	 32bit - record length 
	 32 bytes - SID
	 Total length = 4+32=36 bytes.
      */
      if (stowSid(hlr,record_offset+4,sid)) return setReason("Could not store SID in new HLR entry");
	
      /* Write length last of all to make entry valid */
      hlr[record_offset]=0;
      hlr[record_offset+1]=0;
      hlr[record_offset+2]=0;
      hlr[record_offset+3]=36;

      /* Store the DID */
      {
	unsigned char packeddid[DID_MAXSIZE];
	int pdidlen=0;
	stowDid(packeddid,&pdidlen,did);
	/* Work out reduced length of DID */
	for(pdidlen=1;pdidlen<DID_MAXSIZE;pdidlen++) if (packeddid[pdidlen-1]==0xff) break;
	hlrSetVariable(hlr,record_offset,VAR_DIDS,0x00,packeddid,pdidlen);
      }

      if (debug) fprintf(stderr,"Created new 36 byte HLR record for DID=[%s] @ 0x%x with SID=[%s]\n",
			 did,record_offset,sid);
      if (debug>2) dump("after HLR create",&hlr[0],256);
      return 0;
    }

  return setReason("Unreachable code turned out not to be");
}
Example #4
0
int packetSetSid(unsigned char *packet,int packet_maxlen,int *packet_len,char *sid)
{
  /* Convert and store hex formatted sid */
  int ofs=OFS_SIDDIDFIELD; /* where the DID/subscriber ID gets written */

  if (strlen(sid)!=64) {
    if (debug) fprintf(stderr,"Invalid SID: [%s] - should be 64 hex digits\n",sid);
    return setReason("SID must consist of 64 hex digits");
  }

  packet[ofs++]=0x01; /* SID */
  return stowSid(packet,ofs,sid);
}
Example #5
0
int cmd_serval_sign(const char *sid_str, 
	 const size_t sid_len,
	 const unsigned char *msg,
	 const size_t msg_len,
	 char *sig_str_buf,
	 const size_t sig_str_size,
	 const char *keyring_path,
	 const size_t keyring_len) {
  
  int ret = 0;
  unsigned char signed_msg[msg_len + SIGNATURE_BYTES];
  keyring_file *_keyring = NULL;
  unsigned char *key = NULL;
  unsigned char packedSid[SID_SIZE] = {0};
  
  CHECK(sig_str_size >= 2*SIGNATURE_BYTES + 1,"Signature buffer too small");
  
  if (sid_str) {
    CHECK_ERR(sid_len == 2*SID_SIZE && str_is_subscriber_id(sid_str) == 1,"Invalid SID");
    stowSid(packedSid,0,sid_str);
  }
  
  if (keyring_path) {
    CHECK_ERR(serval_init_keyring(sid_str ? packedSid : NULL,
                     sid_str ? SID_SIZE : 0,
		     keyring_path,
		     keyring_len,
		     &_keyring,
		     &key,
		     NULL), "Failed to initialize Serval keyring");
  } else {
    CHECK_ERR(serval_extract_sas(&key,NULL,keyring,packedSid),"Failed to fetch SAS key");
  }
  
  CHECK_ERR(serval_create_signature(key, msg, msg_len, signed_msg, SIGNATURE_BYTES + msg_len),"Failed to create signature");
  
  strncpy(sig_str_buf,alloca_tohex(signed_msg + msg_len,SIGNATURE_BYTES),2*SIGNATURE_BYTES);
  sig_str_buf[2*SIGNATURE_BYTES] = '\0';

  ret = 1;
error:
  if (_keyring) keyring_free(_keyring);
  return ret;
}
Example #6
0
int serval_verify_client(const char *sid_str,
	   const size_t sid_len,
	   const unsigned char *msg,
	   const size_t msg_len,
	   const char *sig,
	   const size_t sig_len,
 	   const char *keyring_path,
 	   const size_t keyring_len) {
  
  int verdict = 0;
  char sas_str[2*SAS_SIZE+1] = {0};
  unsigned char packedSid[SID_SIZE] = {0};
  
  CHECK(sid_len == 2*SID_SIZE,"Invalid SID length");
  CHECK(sig_len == 2*SIGNATURE_BYTES,"Invalid signature length");
  
  CHECK(str_is_subscriber_id(sid_str) != 0,"Invalid SID");
  stowSid(packedSid,0,sid_str);
  
  CHECK(serval_init_keyring(packedSid,
			 SID_SIZE,
			 keyring_path,
			 keyring_len,
			 &keyring,
			 NULL,
			 NULL), "Failed to initialize Serval keyring");
      
  struct subscriber *sub = find_subscriber(packedSid, SID_SIZE, 1); // get Serval identity described by given SID
  
  CHECK(sub,"Failed to fetch Serval subscriber");
  
  CHECK(keyring_send_sas_request_client(sub),"SAS request failed");
  
  CHECK(sub->sas_valid,"Could not validate the signing key!");
  CHECK(sub->sas_public[0],"Could not validate the signing key!");
  CHECK(tohex(sas_str,sub->sas_public,SAS_SIZE),"Failed to convert signing key");
  
  verdict = cmd_serval_verify(sas_str,2*SAS_SIZE,
			   msg,msg_len,sig,sig_len);
  
error:
  return verdict;
}
Example #7
0
static int load_directory_config(){
  if (!directory_service){
    const char *sid_hex = confValueGet("directory.service", NULL);
    if (!sid_hex)
      return 0;
    
    unsigned char sid[SID_SIZE];
    if (stowSid(sid, 0, sid_hex)==-1)
      return WHYF("Invalid directory server SID %s", sid_hex);
    
    directory_service = find_subscriber(sid, SID_SIZE, 1);
    if (!directory_service)
      return WHYF("Failed to create subscriber record");
    
    // used by tests
    INFOF("ADD DIRECTORY SERVICE %s", alloca_tohex_sid(directory_service->sid));
  }
  // always attempt to reload the address, may depend on DNS resolution
  return load_subscriber_address(directory_service);
}
Example #8
0
int serval_sign(const char *sid, 
	 const size_t sid_len,
	 const unsigned char *msg,
	 const size_t msg_len,
	 char *sig_buffer,
	 const size_t sig_size,
	 const char *keyringName,
	 const size_t keyring_len) {
  
  keyring_identity *new_ident;
  char keyringFile[1024];
  
  assert(msg_len);
  if (sid) assert(sid_len == 2*SID_SIZE);
  
  if (keyringName == NULL || keyring_len == 0) { 
    FORM_SERVAL_INSTANCE_PATH(keyringFile, "serval.keyring"); // if no keyring specified, use default keyring
  }
  else { // otherwise, use specified keyring (NOTE: if keyring does not exist, it will be created)
    strncpy(keyringFile,keyringName,keyring_len);
    keyringFile[keyring_len] = '\0';
  }
  
  keyring = keyring_open(keyringFile);
  keyring_enter_pin(keyring, KEYRING_PIN); // unlocks Serval keyring for using identities (also initializes global default identity my_subscriber)
  
  if (!sid) {
    //create new sid
    int c;
    for(c=0;c<keyring->context_count;c++) { // cycle through the keyring contexts until we find one with room for another identity
      new_ident = keyring_create_identity(keyring,keyring->contexts[c], KEYRING_PIN); // create new Serval identity
      if (new_ident)
	break;
    }
    if (!new_ident) {
      fprintf(stderr, "failed to create new SID\n");
      return 1;
    }
    if (keyring_commit(keyring)) { // need to commit keyring or else new identity won't be saved (needs root permissions)
      fprintf(stderr, "Failed to save new SID into keyring...make sure you are running as root!\n");
      return 1;
    }
    sid = alloca_tohex_sid(new_ident->subscriber->sid); // convert SID from binary to hex
  } else {
    if (!str_is_subscriber_id(sid)) {
      fprintf(stderr,"Invalid SID\n");
      return 1;
    }
  }
  
  unsigned char packedSid[SID_SIZE];
  stowSid(packedSid,0,sid);
  
  unsigned char *key=keyring_find_sas_private(keyring, packedSid, NULL); // get SAS key associated with our SID
  if (!key)
    return 1;
  
  unsigned char hash[crypto_hash_sha512_BYTES]; 
  unsigned long long sig_length = SIGNATURE_BYTES;
  crypto_hash_sha512(hash, msg, msg_len); // create sha512 hash of message, which will then be signed
  
  unsigned char signed_msg[msg_len + sig_length];
  memcpy(signed_msg,msg,msg_len);
  
  int ret = crypto_create_signature(key, hash, crypto_hash_sha512_BYTES, &signed_msg[msg_len], &sig_length); // create signature of message hash, append it to end of message
  
  if (!ret) { //success
    printf("%s\n", alloca_tohex(signed_msg + msg_len, sig_length));
    printf("%s\n",sid);
    if (sig_size > 0) {
      if (sig_size >= 2*sig_length + 1) {
        strncpy(sig_buffer,alloca_tohex(signed_msg + msg_len,sig_length),2*sig_length);
        sig_buffer[2*sig_length] = '\0';
      } else
	fprintf(stderr,"Insufficient signature buffer size\n");
    }
  }
  
  keyring_free(keyring);
  
  return ret;
}
Example #9
0
int
serval_crypto_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  CLEAR_ERR();
  
  svl_crypto_ctx *ctx = NULL;
  int list_len = co_list_length(params);
  int keypath = 0;
  
  CHECK_ERR(IS_LIST(params) && list_len >= 2, "Invalid params");
  
  if (!strncmp("--keyring=", co_obj_data_ptr(co_list_get_last(params)), 10)) {
    keypath = 1;
    --list_len;
  }
  
  ctx = svl_crypto_ctx_new();
  
  if (co_str_cmp_str(co_list_element(params, 0), "sign") == 0) {
    
    CHECK_ERR(list_len == 2 || list_len == 3, "Invalid arguments");
    
    if (list_len == 3) {
      char *sid_str = _LIST_ELEMENT(params, 1);
      size_t sid_len = co_str_len(co_list_element(params, 1)) - 1;
      CHECK_ERR(sid_len == (2 * SID_SIZE) && str_is_subscriber_id(sid_str) == 1,
		"Invalid SID");
      stowSid(ctx->sid, 0, sid_str);
      ctx->msg = (unsigned char*)_LIST_ELEMENT(params, 2);
      ctx->msg_len = co_str_len(co_list_element(params, 2)) - 1;
      if (keypath) {
	ctx->keyring_path = _LIST_ELEMENT(params, 3) + 10;
	ctx->keyring_len = co_str_len(co_list_element(params, 3)) - 11;
	CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
      }
    
    } else if (list_len == 2) {
      
      ctx->msg = (unsigned char*)_LIST_ELEMENT(params, 1);
      ctx->msg_len = co_str_len(co_list_element(params, 1)) - 1;
      if (keypath) {
	ctx->keyring_path = _LIST_ELEMENT(params, 2) + 10;
	ctx->keyring_len = co_str_len(co_list_element(params, 2)) - 11;
	CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
      }

    }
    CHECK_ERR(cmd_serval_sign(ctx), "Failed to create signature");
    
    // convert ctx->signature, ctx->sas_public, and ctx->sid to hex: 
    char sid_str[(2 * SID_SIZE) + 1] = {0};
    strncpy(sid_str, alloca_tohex(ctx->sid, SID_SIZE), 2 * SID_SIZE);
    char sas_str[(2 * crypto_sign_PUBLICKEYBYTES) + 1] = {0};
    strncpy(sas_str, alloca_tohex(ctx->sas_public, crypto_sign_PUBLICKEYBYTES), 2 * crypto_sign_PUBLICKEYBYTES);
    char sig_str[(2 * SIGNATURE_BYTES) + 1] = {0};
    strncpy(sig_str, alloca_tohex(ctx->signature, SIGNATURE_BYTES), 2 * SIGNATURE_BYTES);
    CMD_OUTPUT("SID", co_str8_create(sid_str, (2 * SID_SIZE) + 1, 0));
    CMD_OUTPUT("SAS", co_str8_create(sas_str, (2 * crypto_sign_PUBLICKEYBYTES) + 1, 0));
    CMD_OUTPUT("signature", co_str8_create(sig_str, (2 * SIGNATURE_BYTES) + 1, 0));
    
  } else if (co_str_cmp_str(co_list_element(params, 0), "verify") == 0) {
    
    CHECK_ERR(!keypath, "Keyring option not available for verification");
    CHECK_ERR(list_len == 4, "Invalid arguments");
    // convert SAS and signature from hex to bin
    CHECK_ERR(fromhexstr(ctx->signature, _LIST_ELEMENT(params, 2), SIGNATURE_BYTES) == 0, "Invalid signature");
    CHECK_ERR(fromhexstr(ctx->sas_public, _LIST_ELEMENT(params, 1), crypto_sign_PUBLICKEYBYTES) == 0, "Invalid SAS key");
    ctx->msg = (unsigned char*)_LIST_ELEMENT(params, 3);
    ctx->msg_len = co_str_len(co_list_element(params, 3)) - 1;

    int verdict = cmd_serval_verify(ctx);
    if (verdict == 1) {
      DEBUG("signature verified");
      CMD_OUTPUT("result", co_bool_create(true, 0));  // successfully verified
      CMD_OUTPUT("verified",co_str8_create("true",sizeof("true"),0));
    } else if (verdict == 0) {
      DEBUG("signature NOT verified");
      CMD_OUTPUT("result", co_bool_create(false, 0));
      CMD_OUTPUT("verified",co_str8_create("false",sizeof("false"),0));
    }
    
  }
  
error:
  INS_ERROR();
  if (ctx)
    svl_crypto_ctx_free(ctx);
  return 1;
}
Example #10
0
int findHlr(unsigned char *hlr,int *ofs,char *sid,char *did)
{
  unsigned int record_length;
  int match=0;
  int records_searched=0;
  int pid_len=0;
  unsigned char packed_id[40];

  if ((*ofs)>=hlr_size) return 0;

  if (debug>1) fprintf(stderr,"Searching for HLR record sid=[%s]/did=[%s]\n",sid?sid:"NULL",did?did:"NULL");
  
  if (did&&did[0]) {
    /* Make packed version of DID so that we can compare faster with the DIDs in the HLR */
    if (stowDid(packed_id,&pid_len,did)) return setReason("DID appears to be invalid");
    /* Find significant length of packed DID */
    for(pid_len=0;pid_len<DID_MAXSIZE;pid_len++) if ((packed_id[pid_len]&0x0f)==0x0f) { pid_len++; break; }
    if (debug>1) dump("Searching for DID records that match",packed_id,pid_len);
  }

  if (sid&&sid[0]) {
    /* Make packed version of SID for fast comparison */
    if (stowSid(packed_id,pid_len,sid)) return setReason("SID appears to be invalid");
    pid_len=SID_SIZE;
  }

  while(!match)
    {
      /* Get length of this record */
      record_length =hlr[(*ofs)+3]<<0;
      record_length|=hlr[(*ofs)+2]<<8;
      record_length|=hlr[(*ofs)+1]<<16;
      record_length|=hlr[(*ofs)+0]<<24;
      
      if (!record_length) return 0;

      if (debug>1) fprintf(stderr,"Considering HLR entry @ 0x%x\n",*ofs);
  
      records_searched++;
  
      if (sid&&sid[0]) {
	/* Lookup by SID, so just see if it matches */
	if (!bcompare(packed_id,&hlr[(*ofs)+4],SID_SIZE)) {
	  if (debug>1) fprintf(stderr,"Found requested SID at address 0x%x.\n",*ofs);
	  match=1;
	}
      }
      if (did&&did[0]) {
	/* Lookup by did, so see if there are any matching DID entries for this subscriber */
	int rofs=(*ofs);
	struct hlrentry_handle *h=openhlrentry(hlr,rofs);
	while(h)
	  {
	    /* Search through variables for matching DIDs */
	    if (debug>2) {
	      fprintf(stderr,"Considering variable 0x%02x, instance %d.\n",
		      h->var_id,h->var_instance);
	      dump("variable value",h->value,h->value_len);
	    }
	    if (h->var_id==VAR_DIDS) { /* DID entry  */
	      if (debug>2) fprintf(stderr,"Checking DID against record DID\n");
	      if (!bcompare(packed_id,h->value,pid_len)) {		
		if (debug>1) fprintf(stderr,"Found matching DID in HLR record #%d\n",records_searched);
		match=1;
		break;
	      }
	    }
	    else
	      {
		if (debug>2) fprintf(stderr,"Skipping non-DID variable while searching for DID.\n");
	      }		
	    h=hlrentrygetent(h);
	  }
      }
  
      /* For each match ... */
      if (match) 
	{
	  if (debug>1) fprintf(stderr,"Returning HLR entry @ 0x%x\n",*ofs);
	  return 1;
	}
  
      /* Consider next record */
      (*ofs)+=record_length;

      if ((*ofs)>=hlr_size) return 0;
    }

  return 0;
}