Beispiel #1
0
static int decode64(dearmour_arg_t *arg,ops_error_t **errors,
		    ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo)
{
	unsigned n;
	int n2;
	unsigned long l;
	int c;
	int ret;

	if(!(arg->buffered == 0))		// ASSERT(arg->buffered == 0);
	{
		OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly formed base64");
		return 0;
	}

	ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&l);
	if(ret < 0)
	{
		OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly formed base64");
		return 0;
	}

	if(n == 3)
	{
		if(c != '=')
		{
			OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated base64 (2)");
			return 0;
		}
		arg->buffered=2;
		arg->eof64=ops_true;
		l >>= 2;
	}
	else if(n == 2)
Beispiel #2
0
static ops_boolean_t error_writer(const unsigned char *src,
                                  unsigned length,
                                  ops_error_t **errors,
                                  ops_writer_info_t *winfo)
    {
    OPS_USED(src);
    OPS_USED(length);
    error_arg_t *arg=ops_writer_get_arg(winfo);
    arg->times_called++;
    CU_ASSERT(arg->times_called <= arg->count);
    if (arg->times_called == arg->count)
        {
        OPS_ERROR(errors, arg->code, arg->msg);
        return ops_false;
        }
    else
        {
        return ops_true;
        }
    }
Beispiel #3
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 #4
0
/* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */
static int parse_headers(dearmour_arg_t *arg,ops_error_t **errors,
			 ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo)
{
	int rtn=1;
	char *buf;
	unsigned nbuf;
	unsigned size;
	ops_boolean_t first=ops_true;
	//ops_parser_content_t content;

	buf=NULL;
	nbuf=size=0;

	for( ;  ; )
	{
		int c;

		if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0)
		{
			OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Unexpected EOF");
			rtn=-1;
			break;
		}

		if(c == '\n')
		{
			char *s;

			if(nbuf == 0)
				break;

			if(!(nbuf < size)) // ASSERT(nbuf < size);
			{
				OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Size error in armour header");
				return -1 ;
			}
			buf[nbuf]='\0';

			s=strchr(buf,':');
			if(!s)
				if(!first && !arg->allow_headers_without_gap)
				{
					// then we have seriously malformed armour
					OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No colon in armour header");
					rtn=-1;
					break;
				}
				else
				{
					if(first &&
							!(arg->allow_headers_without_gap || arg->allow_no_gap))
					{
						OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No colon in armour header (2)");
						// then we have a nasty armoured block with no
						// headers, not even a blank line.
						buf[nbuf]='\n';
						push_back(arg,(unsigned char *)buf,nbuf+1);
						rtn=-1;
						break;
					}
				}
			else
			{
				*s='\0';
				if(s[1] != ' ')
				{
					OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No space in armour header");
					rtn=-1;
					goto end;
				}
				if (!add_header(arg,buf,s+2))
				{
					OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Invalid header %s", buf);
					rtn=-1;
					goto end;
				}
				nbuf=0;
			}
			first=ops_false;
		}
		else
		{
			if(size <= nbuf+1)
			{
				size+=size+80;
				char *nbuf;
				nbuf=realloc(buf,size);
				if (nbuf == NULL)
				{
					free(buf);
                    buf = NULL ;
					rtn=-1;
					goto end;
				}
				buf = nbuf;
			}
			buf[nbuf++]=c;
		}
	}

end:
	free(buf);

	return rtn;
}
Beispiel #5
0
static int set_lastseen_headerline(dearmour_arg_t* arg, char* buf, ops_error_t **errors)
    {
    char* begin_msg="BEGIN PGP MESSAGE";
    char* begin_public="BEGIN PGP PUBLIC KEY BLOCK";
    char* begin_private="BEGIN PGP PRIVATE KEY BLOCK";
    char* begin_multi="BEGIN PGP MESSAGE, PART ";
    char* begin_sig="BEGIN PGP SIGNATURE";

    char* end_msg="END PGP MESSAGE";
    char* end_public="END PGP PUBLIC KEY BLOCK";
    char* end_private="END PGP PRIVATE KEY BLOCK";
    char* end_multi="END PGP MESSAGE, PART ";
    char* end_sig="END PGP SIGNATURE";

    char* begin_signed_msg="BEGIN PGP SIGNED MESSAGE";

    int prev=arg->lastseen;

    if (!strncmp(buf,begin_msg,strlen(begin_msg)))
        arg->lastseen=BEGIN_PGP_MESSAGE;
    else if (!strncmp(buf,begin_public,strlen(begin_public)))
        arg->lastseen=BEGIN_PGP_PUBLIC_KEY_BLOCK;
    else if (!strncmp(buf,begin_private,strlen(begin_private)))
        arg->lastseen=BEGIN_PGP_PRIVATE_KEY_BLOCK;
    else if (!strncmp(buf,begin_multi,strlen(begin_multi)))
        arg->lastseen=BEGIN_PGP_MULTI;
    else if (!strncmp(buf,begin_sig,strlen(begin_sig)))
        arg->lastseen=BEGIN_PGP_SIGNATURE;

    else if (!strncmp(buf,end_msg,strlen(end_msg)))
        arg->lastseen=END_PGP_MESSAGE;
    else if (!strncmp(buf,end_public,strlen(end_public)))
        arg->lastseen=END_PGP_PUBLIC_KEY_BLOCK;
    else if (!strncmp(buf,end_private,strlen(end_private)))
        arg->lastseen=END_PGP_PRIVATE_KEY_BLOCK;
    else if (!strncmp(buf,end_multi,strlen(end_multi)))
        arg->lastseen=END_PGP_MULTI;
    else if (!strncmp(buf,end_sig,strlen(end_sig)))
        arg->lastseen=END_PGP_SIGNATURE;

    else if (!strncmp(buf,begin_signed_msg,strlen(begin_signed_msg)))
        arg->lastseen=BEGIN_PGP_SIGNED_MESSAGE;

    else
        {
        OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unrecognised Header Line %s", buf);
        return 0;
        }

    if (debug)
        printf("set header: buf=%s, arg->lastseen=%d, prev=%d\n", buf, arg->lastseen, prev);

    switch (arg->lastseen) 
        {
    case NONE:
        OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unrecognised last seen Header Line %s", buf);
        break;

    case END_PGP_MESSAGE:
        if (prev!=BEGIN_PGP_MESSAGE)
            OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP MESSAGE, but not after BEGIN");
        break;

    case END_PGP_PUBLIC_KEY_BLOCK:
        if (prev!=BEGIN_PGP_PUBLIC_KEY_BLOCK)
            OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP PUBLIC KEY BLOCK, but not after BEGIN");
        break;

    case END_PGP_PRIVATE_KEY_BLOCK:
        if (prev!=BEGIN_PGP_PRIVATE_KEY_BLOCK)
            OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP PRIVATE KEY BLOCK, but not after BEGIN");
        break;

    case BEGIN_PGP_MULTI:
    case END_PGP_MULTI:
            OPS_ERROR(errors,OPS_E_R_UNSUPPORTED,"Multi-part messages are not yet supported");
        break;

    case END_PGP_SIGNATURE:
        if (prev!=BEGIN_PGP_SIGNATURE)
            OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP SIGNATURE, but not after BEGIN");
        break;

    case BEGIN_PGP_MESSAGE:
    case BEGIN_PGP_PUBLIC_KEY_BLOCK:
    case BEGIN_PGP_PRIVATE_KEY_BLOCK:
    case BEGIN_PGP_SIGNATURE:
    case BEGIN_PGP_SIGNED_MESSAGE:
        break;
        }

    return 1;
    }