Beispiel #1
0
/* Note that this skips CRs so implementations always see just
   straight LFs as line terminators */
static int process_dash_escaped(dearmour_arg_t *arg,ops_error_t **errors,
				ops_reader_info_t *rinfo,
				ops_parse_cb_info_t *cbinfo)
{
	ops_parser_content_t content;
	ops_parser_content_t content2;
	ops_signed_cleartext_body_t	*body=&content.content.signed_cleartext_body;
	ops_signed_cleartext_trailer_t *trailer
		=&content2.content.signed_cleartext_trailer;
	const char *hashstr;
	ops_hash_t *hash;
	int total;

	hash=malloc(sizeof *hash);
	hashstr=ops_find_header(&arg->headers,"Hash");
	if(hashstr)
	{
		ops_hash_algorithm_t alg;

		alg=ops_hash_algorithm_from_text(hashstr);

		if(!ops_is_hash_alg_supported(&alg))
		{
			free(hash);
			OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unsupported hash algorithm '%s'",hashstr);
			return -1;
		}
		if(alg == OPS_HASH_UNKNOWN)
		{
			free(hash);
			OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unknown hash algorithm '%s'",hashstr);
			return -1;
		}
		ops_hash_any(hash,alg);
	}
	else
		ops_hash_md5(hash);

	hash->init(hash);

	body->length=0;
	total=0;
	for( ; ; )
	{
		int c;
		unsigned count;

		if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0)
			return -1;
		if(arg->prev_nl && c == '-')
		{
			if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0)
				return -1;
			if(c != ' ')
			{
				/* then this had better be a trailer! */
				if(c != '-')
					OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad dash-escaping");
				for(count=2 ; count < 5 ; ++count)
				{
					if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0)
						return -1;
					if(c != '-')
						OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad dash-escaping (2)");
				}
				arg->state=AT_TRAILER_NAME;
				break;
			}
			/* otherwise we read the next character */
			if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0)
				return -1;
		}
		if(c == '\n' && body->length)
		{
			if(!(memchr(body->data+1,'\n',body->length-1) == NULL)) // ASSERT(memchr(body->data+1,'\n',body->length-1) == NULL);
			{
				fprintf(stderr,"no \\n in armoured file.") ;
				return -1 ;
			}
			if(body->data[0] == '\n')
				hash->add(hash,(unsigned char *)"\r",1);
			hash->add(hash,body->data,body->length);
			if (debug)
			{ fprintf(stderr,"Got body:\n%s\n",body->data); }
			CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content);
			body->length=0;
		}

		body->data[body->length++]=c;
		++total;
		if(body->length == sizeof body->data)
		{
			if (debug)
			{ fprintf(stderr,"Got body (2):\n%s\n",body->data); }
			CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content);
			body->length=0;
		}
	}

	if(!(body->data[0] == '\n'))	// ASSERT(body->data[0] == '\n');
	{
		fprintf(stderr,"Body should end with \\n\n"); 
		return -1 ;
	}
	if(!(body->length == 1))	// ASSERT(body->length == 1);
	{
		fprintf(stderr,"Body length error\n"); 
		return -1 ;
	}
	/* don't send that one character, because its part of the trailer. */

	trailer->hash=hash;
	CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2);

	return total;
}
Beispiel #2
0
int main(int argc,char **argv)
    {
    const char *keyfile;
    const char *plainfile;
    const char *user_id;
    const char *hashstr;
    const char *sigfile;
    ops_secret_key_t *skey;
    ops_create_signature_t *sig;
    ops_hash_algorithm_t alg;
    int fd;
    ops_create_info_t *info;
    unsigned char keyid[OPS_KEY_ID_SIZE];

    if(argc != 6)
	{
	fprintf(stderr,"%s <secret key file> <user_id> <hash> <plaintext file>"
		" <signature file>\n",argv[0]);
	exit(1);
	}

    keyfile=argv[1];
    user_id=argv[2];
    hashstr=argv[3];
    plainfile=argv[4];
    sigfile=argv[5];

    ops_init();

    skey=get_secret_key(keyfile);
    assert(skey);

    alg=ops_hash_algorithm_from_text(hashstr);
    if(alg == OPS_HASH_UNKNOWN)
	{
	fprintf(stderr,"Unkonwn hash algorithm: %s\n",hashstr);
	exit(2);
	}

    sig=ops_create_signature_new();
    ops_signature_start_cleartext_signature(sig,skey,alg,OPS_SIG_BINARY);

    fd=open(plainfile,O_RDONLY);
    if(fd < 0)
	{
	perror(plainfile);
	exit(3);
	}

    for( ; ; )
	{
	unsigned char buf[8192];
	int n;
	
	n=read(fd,buf,sizeof buf);
	if(!n)
	    break;
	if(n < 0)
	    {
	    perror(plainfile);
	    exit(4);
	    }
	ops_signature_add_data(sig,buf,n);
	}

    close(fd);

    ops_signature_add_creation_time(sig,time(NULL));

    ops_keyid(keyid,&skey->public_key);
    ops_signature_add_issuer_key_id(sig,keyid);

    ops_signature_hashed_subpackets_end(sig);

    fd=open(sigfile,O_CREAT|O_TRUNC|O_WRONLY,0666);
    if(fd < 0)
	{
	perror(sigfile);
	exit(5);
	}

    info=ops_create_info_new();
    ops_writer_set_fd(info,fd);

    ops_write_signature(sig,&skey->public_key,skey,info);

    ops_secret_key_free(skey);

    return 0;
    }