Exemple #1
0
void
svl_crypto_ctx_free(svl_crypto_ctx *ctx)
{
  if (!ctx)
    return;
  if (ctx->keyring_file && ctx->keyring_file != keyring)
    keyring_free(ctx->keyring_file);
  h_free(ctx);
}
Exemple #2
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;
}
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;
}
Exemple #4
0
/*
  Open keyring file, read BAM and create initial context using the 
  stored salt. */
keyring_file *keyring_open(char *file)
{
  /* Allocate structure */
  keyring_file *k=calloc(sizeof(keyring_file),1);
  if (!k) {
    WHY_perror("calloc");
    return NULL;
  }
  /* Open keyring file read-write if we can, else use it read-only */
  k->file=fopen(file,"r+");
  if (!k->file) k->file=fopen(file,"r");
  if (!k->file) k->file=fopen(file,"w+");
  if (!k->file) {
    WHY_perror("fopen");
    WHYF("Could not open keyring file %s", file);
    keyring_free(k);
    return NULL;
  }
  if (fseeko(k->file,0,SEEK_END)) {
    WHY_perror("fseeko");
    WHYF("Could not seek to end of keyring file %s", file);
    keyring_free(k);
    return NULL;
  }
  k->file_size=ftello(k->file);
  if (k->file_size<KEYRING_PAGE_SIZE) {
    /* Uninitialised, so write 2KB of zeroes, 
       followed by 2KB of random bytes as salt. */
    if (fseeko(k->file,0,SEEK_SET)) {
      WHY_perror("fseeko");
      WHYF("Could not seek to start of keyring file %s", file);
      keyring_free(k);
      return NULL;
    }
    unsigned char buffer[KEYRING_PAGE_SIZE];
    bzero(&buffer[0],KEYRING_BAM_BYTES);
    if (fwrite(&buffer[0],2048,1,k->file)!=1) {
      WHY_perror("fwrite");
      WHYF("Could not write empty bitmap in fresh keyring file %s", file);
      keyring_free(k);
      return NULL;
    }
    if (urandombytes(&buffer[0],KEYRING_PAGE_SIZE-KEYRING_BAM_BYTES)) {
      WHYF("Could not get random keyring salt to put in fresh keyring file %s", file);
      keyring_free(k);
      return NULL;
    }
    if (fwrite(&buffer[0],KEYRING_PAGE_SIZE-KEYRING_BAM_BYTES,1,k->file) != 1) {
      WHY_perror("fwrite");
      WHYF("Could not write keyring salt in fresh keyring file %s", file);
      keyring_free(k);
      return NULL;
    }
    k->file_size=KEYRING_PAGE_SIZE;
  }

  /* Read BAMs for each slab in the file */
  keyring_bam **b=&k->bam;
  off_t offset=0;
  while(offset<k->file_size) {
    /* Read bitmap from slab.
       Also, if offset is zero, read the salt */
    if (fseeko(k->file,offset,SEEK_SET)) {
      WHY_perror("fseeko");
      WHYF("Could not seek to BAM in keyring file %s", file);
      keyring_free(k);
      return NULL;
    }
    *b=calloc(sizeof(keyring_bam),1);
    if (!(*b)) {
      WHY_perror("calloc");
      WHYF("Could not allocate keyring_bam structure for key ring file %s", file);
      keyring_free(k);
      return NULL;
    }
    (*b)->file_offset=offset;
    /* Read bitmap */
    int r=fread(&(*b)->bitmap[0],KEYRING_BAM_BYTES,1,k->file);
    if (r!=1) {
      WHY_perror("fread");
      WHYF("Could not read BAM from keyring file %s", file);
      keyring_free(k);
      return NULL;
    }

    /* Read salt if this is the first bitmap block.
       We setup a context for this self-supplied key-ring salt.
       (other keyring salts may be provided later on, resulting in
       multiple contexts being loaded) */
    if (!offset) {     
      k->contexts[0]=calloc(sizeof(keyring_context),1);     
      if (!k->contexts[0]) {
	WHY_perror("calloc");
	WHYF("Could not allocate keyring_context for keyring file %s", file);
	keyring_free(k);
	return NULL;
      }
      k->contexts[0]->KeyRingPin=strdup(""); /* Implied empty PIN if none provided */
      k->contexts[0]->KeyRingSaltLen=KEYRING_PAGE_SIZE-KEYRING_BAM_BYTES;
      k->contexts[0]->KeyRingSalt=malloc(k->contexts[0]->KeyRingSaltLen);
      if (!k->contexts[0]->KeyRingSalt) {
	WHY_perror("malloc");
	WHYF("Could not allocate keyring_context->salt for keyring file %s", file);
	keyring_free(k);
	return NULL;
      }
      r=fread(&k->contexts[0]->KeyRingSalt[0],k->contexts[0]->KeyRingSaltLen,1,k->file);
      if (r!=1) {
	WHY_perror("fread");
	WHYF("Could not read salt from keyring file %s", file);
	keyring_free(k);
	return NULL;
      }
      k->context_count=1;
    }

    /* Skip to next slab, and find next bam pointer. */
    offset+=KEYRING_PAGE_SIZE*(KEYRING_BAM_BYTES<<3);
    b=&(*b)->next;
  }

  return k;
}