コード例 #1
0
ファイル: afflib.cpp プロジェクト: eaas-framework/xmount
/* af_open_with is the real open routine.
 * It opens a particular file with a particular vnode implementation.
 */
AFFILE *af_open_with(const char *url,int flags,int mode, struct af_vnode *v)
{
    /* Alloate the space for the AFFILE structure */
    AFFILE *af = (AFFILE *)calloc(sizeof(AFFILE),1);
    af_crypto_allocate(af);
#ifdef HAVE_PTHREAD
    pthread_rwlock_init(&af->rwlock);
    AF_WRLOCK(af);
#endif
    af->v	  = v;
    af->version   = 2;
    af->openflags = flags | O_BINARY;	// make sure that we ask for binray
    af->openmode  = mode;
    af->image_sectorsize = 512;		// default size
    af->error_reporter = warnx;
    af->badflag   = (unsigned char *)malloc(af->image_sectorsize);

    /* Decode URL */
    af_parse_url(url,&af->protocol,&af->hostname,&af->username,&af->password,
		 &af->port,&af->fname);

    /* A null passphrase is the same as no passphrase*/
    if(af->password && af->password[0]==0){
	free(af->password);
	af->password=0;
    }
    /* If no password was set and the AFFLIB_PASSPHRASE environment variable is set, use that */
    if(af->password==0 && getenv(AFFLIB_PASSPHRASE)){
	af->password = strdup(getenv(AFFLIB_PASSPHRASE));
    }
    /* If no password is set and its in a file, get it there */
    if(af->password==0 && getenv(AFFLIB_PASSPHRASE_FILE)){
	int fd = open(AFFLIB_PASSPHRASE_FILE,O_RDONLY,0);
	if(fd>0){
	    struct stat sb;
	    if(fstat(fd,&sb)==0){
		af->password = (char *)malloc(sb.st_size);
		int r = read(fd,af->password,sb.st_size);
		if(r!=sb.st_size){
		    free(af->password);
		    af->password=0;	// couldn't read it
		}
		close(fd);
	    }
	}
    }
    /* If no password is set and its in a file, get it there */
    if(af->password==0 && getenv(AFFLIB_PASSPHRASE_FD)){
	int fd = atoi(AFFLIB_PASSPHRASE_FD);
	af->password = (char *)malloc(1);
	int buflen = 0;
	int rlen = 0;
	char mybuf[1024];

	while((rlen=read(fd,mybuf,sizeof(mybuf)))>0){
	    af->password = (char *)realloc(af->password,buflen+rlen+1);
	    memcpy(af->password+buflen,mybuf,rlen);
	    buflen += rlen;
	    af->password[buflen] = '\000';
	}
    }
		
    /* TK: If no password was set and the AFFLIB_ASK_PASS is set, ask for a passphrase */

    /* Note things for hard files */
    af->exists    = (access(af->fname,R_OK) == 0);	// does the file exist?

    /* Right now just set up the cache by hand */
    const char *cache_pages = getenv(AFFLIB_CACHE_PAGES);
    if(cache_pages) af->num_pbufs = atoi(cache_pages);
    if(af->num_pbufs<1) af->num_pbufs = AFFLIB_CACHE_PAGES_DEFAULT; // default valuen

    af->pbcache   = (struct aff_pagebuf *)calloc(af->num_pbufs,sizeof(struct aff_pagebuf));
    if(af->pbcache==0){			// if can't allocate the full amount
	af->num_pbufs = 2;		// try a significantly smaller cache
	af->pbcache   = (struct aff_pagebuf *)calloc(af->num_pbufs,sizeof(struct aff_pagebuf));
    }

    if(flags & AF_HALF_OPEN) return af;	// for low-level tools

    /* Try opening it! */
    if((*af->v->open)(af)){ 
	strlcpy(af_error_str,af->error_str,sizeof(af_error_str)); // make a copy of the error string
	af_deallocate(af);
	return 0;
    }

    /* If there is no AFFKEY and the file is read-only, don't use a password */
    if(af->password && (af_get_seg(af,AF_AFFKEY,0,0,0)!=0) && ((af->openflags & O_ACCMODE)==O_RDONLY)){
	af_sanitize_password(af);
    }

    /* Set up the encryption if requested and if this support metadata */
    if(AF_SEALING_VNODE(af) && ((flags & AF_NO_CRYPTO)==0)){
	bool can_decrypt = false;
	if(af->password){
	    struct af_vnode_info vni;
	    memset(&vni,0,sizeof(vni));
	    if((*af->v->vstat)(af,&vni)==0 && vni.supports_metadata){
		int r = 0;
		if(af_get_seg(af,AF_AFFKEY,0,0,0)!=0){ // it does not have a password
		    r = af_establish_aes_passphrase(af,af->password);
		}
		if(r==0){
		    r = af_use_aes_passphrase(af,af->password);
		    if(r==0) {
			can_decrypt = true;
		    } else {
			(*af->error_reporter)("af_open: invalid passphrase: '%s'",af->password);
		    }
		}
		af_sanitize_password(af);
	    }
	}
	
	/* Try public key... */
	if(can_decrypt==false){
	    const char *kf = getenv(AFFLIB_DECRYPTING_PRIVATE_KEYFILE);
	    if(kf){
		af_set_unseal_keyfile(af,kf);
	    }
	}
    }
	
    af_read_sizes(af);		// set up the metadata
    if(af_trace) fprintf(af_trace,"af_open_with(%s,%o,%o,%s)\n",url,flags,mode,v->name);
    return af;
}
コード例 #2
0
ファイル: aftest.cpp プロジェクト: jonstewart/afflib
int aestest()
{
    unsigned char keyblock[32];
     
    /* Make a key; doesn't need to be a good key; make it 256 bits */
    for(int i=0;i<32;i++){
	keyblock[i] = i;
    }

    AFFILE *af = af_open("crypto.aff",O_CREAT|O_RDWR|O_TRUNC,0666);
    if(!af) err(1,"af_open");
    if(af_set_aes_key(af,keyblock,256)) err(1,"af_set_aes_key");
    af_set_pagesize(af,65536);

    /* Now, let's write some data of various sizes */

    u_char test[1024],buf[1024],rbuf[1024];
    size_t  buflen = sizeof(buf);
    make_test_seg(test,0);
    for(u_int len=0;len<=strlen((const char *)test);len++){
	if(af_update_seg(af,"page0",0,test,len)) err(1,"af_update_seg len=%d",len);
	
	/* Now try to read the segment */
	memset(buf,0,sizeof(buf));
	buflen = sizeof(buf);
	if(af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen)){
	    err(1,"Could not read encrypted segment with length %d.\n",len);
	}
	if(buflen!=len){
	    printf("size of returned segment = %zd ",buflen);
	    printf("(should be %d) \n",len);
	    exit(0);
	}
	if(memcmp(buf,test,len)!=0){
	    printf("does not match\n");
	    printf("  wanted: %s\n",test);
	    printf("  got: %s\n",buf);
	    exit(0);
	}
    }
    if(af_close(af)) err(1,"af_close");

    /* Now re-open the file, do not set the encryption key, and see if we can read it */
    int r;
    memset(buf,0,sizeof(buf));
    af = af_open("crypto.aff",O_RDONLY,0666);
    buflen = sizeof(buf);
    r = af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen);
    if(r!=-1) {
	errx(1,"Error; attempt to read segment 'encrypted' succeded. It should have failed.");
    }

    /* Try to read 'encrypted/aes' */
    r = af_get_seg(af,"encrypted/aes",0,(unsigned char *)buf,&buflen);
    if(memcmp(buf,test,buflen)==0){
	errx(1,"Error: segment encrypted/aes wasn't actually encrypted.");
    }
    af_close(af);
    
    /* Now set the correct encryption key and see if we can read it */
    af = af_open("crypto.aff",O_RDONLY,0666);
    if(af_set_aes_key(af,keyblock,256)) err(1,"af_set_aes_key");
    buflen = sizeof(buf);
    memset(buf,0,sizeof(buf));
    r = af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen);
    if(buflen != strlen((const char *)test)){
	errx(1,"Error: Could not read encrypted segment after re-opening file");
    }
    if(memcmp(buf,test,buflen)!=0) errx(1,"Error: Re-read of file produces wrong data.");
    printf("encrypted data read and decrypted: '%s'\n",buf);
    /* Try to read a segment that doesn't eixst */
    buflen = 0;
    if(af_get_seg(af,"encrypted2",0,0,&buflen)==0){
	errx(1,"Error: Attempt to get size of non-existant segment 'encrypted2' got %zd\n",buflen);
    }
    af_close(af);


    /* Now set the wrong encryption key and see if we can read it */
    memset(buf,0,sizeof(buf));
    af = af_open("crypto.aff",O_RDONLY,0666);
    keyblock[3] = 42;
    if(af_set_aes_key(af,keyblock,256)) err(1,"af_set_aes_key");
    buflen = sizeof(buf);
    r = af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen);
    if(memcmp(buf,test,buflen)==0) errx(1,"Error: Setting wrong key still produces correct data.");
    af_close(af);

    printf("Basic crypto checks. Now check passphrase....\n");

    /* Write the data with a passphrase and try to read it back */ 
    af = af_open("crypto_pass.aff",O_CREAT|O_RDWR|O_TRUNC,0666);
    if(!af) err(1,"af_open 3");
    af_set_pagesize(af,65536);
    if(af_establish_aes_passphrase(af,"yummy")) err(1,"af_establish_aes_passphrase");
    if(af_use_aes_passphrase(af,"yummy")) err(1,"af_use_aes_passphrase");
    if(af_update_seg(af,"page0",0,(const u_char *)test,strlen((const char *)test))) err(1,"af_update_seg failed at 3");
    if(af_close(af)) err(1,"af_close at 3");


    /* Now try to read it back */
    memset(rbuf,0,sizeof(rbuf));
    size_t rbuflen = sizeof(rbuf);
    af = af_open("crypto_pass.aff",O_RDONLY,0666);
    if(!af) err(1,"af_open 4");
    if(af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen)==0){
	errx(1,"af_get_seg should have failed and didn't");
    }
    if(af_use_aes_passphrase(af,"yummy")) err(1,"af_set_passphrase 2");
    rbuflen=sizeof(rbuf);
    if(af_get_seg(af,"page0",0,(unsigned char *)rbuf,&rbuflen)){
	errx(1,"af_get_seg failed");
    }
    if(rbuflen!=strlen((const char *)test)) errx(1,"Reading encrypted data returned wrong size");
    if(memcmp(rbuf,test,rbuflen)!=0) errx(1,"Error: wrong data");
    printf("encrypted data read with passphrase 'yummy': %s\n",rbuf);
    af_close(af);

    /* Try to change the passphrase */
    af = af_open("crypto_pass.aff",O_RDWR,0666);
    if(!af) err(1,"af_open 5");
    if(af_change_aes_passphrase(af,"yummy","dummy")) err(1,"could not change passphrase");
    af_close(af);

    /* Try to read with new passphrase */
    af = af_open("crypto_pass.aff",O_RDONLY,0666);
    if(!af) err(1,"af_open 5");
    memset(rbuf,0,sizeof(rbuf));
    rbuflen = sizeof(rbuf);
    if(af_use_aes_passphrase(af,"dummy")) err(1,"af_set_passphrase 2");
    rbuflen=sizeof(rbuf);
    if(af_get_seg(af,"page0",0,(unsigned char *)rbuf,&rbuflen)){
	errx(1,"af_get_seg failed");
    }
    if(rbuflen!=strlen((const char *)test)) errx(1,"Reading encrypted with new passphrase data returned wrong size");
    if(memcmp(rbuf,test,rbuflen)!=0) errx(1,"Error: wrong data");
    printf("encrypted data read with new passphrase 'dummy': %s\n",rbuf);
    af_close(af);
    exit(0);
    
    
    /* Now try to read with the wrong passphrase */
    af = af_open("crypto.aff",O_RDONLY,0666);
    if(af_use_aes_passphrase(af,"yummy2")) err(1,"af_set_passphrase 3");
    buflen=sizeof(buf);
    memset(buf,0,sizeof(buf));
    if(af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen)){
	printf("Couldn't get data with wrong passphrase (that's good)\n");
    }
    printf("data read with wrong passphrase: %s\n",buf);
    if(buflen>0 && memcmp(buf,test,buflen)==0){
	errx(1,"Error: data fetched with wrong passphrase was not scrambled.");
    }
    af_close(af);
    exit(0);
}