Exemple #1
0
int Element_FromBytes(Element & e, int type, unsigned char *data)
{
	string d = "";
	if(is_base64((unsigned char) data[0])) {
		string b64_encoded((char *) data);
		d = _base64_decode(b64_encoded);
	}
	else {
		return ELEMENT_INVALID_ARG;
	}

	if(type == ZR_t) {
		bn_read_bin(e.zr.z, (unsigned char *) d.c_str(), d.size());
	}
	else if(type == G1_t) {
		return g1_read_bin(e.g1.g, (unsigned char *) d.c_str(), d.size()); // x & y
	}
	else if(type == G2_t) {
		return g2_read_bin(e.g2.g, (unsigned char *) d.c_str(), d.size()); // x1, y1  & x2, y2
	}
	else if(type == GT_t) {
		return gt_read_bin(e.gt.g, (unsigned char *) d.c_str(), d.size()); // x1-6 && y1-6
	}

	return ELEMENT_INVALID_ARG;
}
Exemple #2
0
/**
 *  \brief  Decode Base64 encoded string to binary data
 *
 *  Decode Base64 encoded string \p in to binary data \p out
 *
 *  \param  in      Reference to a Base64 encoded string
 *  \param  in_sz   length of \p in in bytes (excluding the terminating \c NUL)
 *  \param  out     Pre-allocated buffer of size approx as \p in_sz
 *  \param  out_sz  Value-result argument initially containing the total
 *                  size of \p out in bytes.  On successful return it
 *                  holds the decoded buffer size.
 *
 *  \retval  0  on success
 *  \retval ~0  on failure
 */
int u_b64_decode (const char *in, size_t in_sz, uint8_t *out, size_t *out_sz)
{
    char buf[4];
    size_t i, len, pad, tot_sz = *out_sz;
    uint8_t *pout;

    dbg_return_if (in == NULL, ~0);
    dbg_return_if (in_sz == 0, ~0);
    dbg_return_if (out == NULL, ~0);
    dbg_return_if (out_sz == NULL, ~0);

    for (pout = out; in_sz; )
    {
        for (pad = 0, len = 0, i = 0; i < 4; ++i)
        {
            if (in_sz && in_sz-- > 0)   /* Avoid wrapping around in_sz. */
            {
                buf[i] = *in++;

                if (buf[i] == '=')
                    ++pad;
                else if (!is_base64(buf[i]))
                    return ~0;

                ++len;
            }
            else
                buf[i] = '\0';
        }

        if (len)
        {
            size_t nlen = 3 - pad;

            if (tot_sz >= nlen)
            {
                chunk_decode(buf, pout);
                tot_sz -= nlen; /* Take care of subtracting pad bytes. */
                pout += nlen;
            }
            else
                return ~0;  /* Not enough space. */
        }
    }

    *out_sz -= tot_sz;

    return 0;
}
Exemple #3
0
/* See if we need to add the "Salted__" string to the front of the
 * encrypted data.
*/
int
add_salted_str(fko_ctx_t ctx)
{
    char           *tbuf;

#if AFL_FUZZING
    ctx->added_salted_str = 1;
    return(FKO_SUCCESS);
#endif

    /* We only add the base64 encoded salt to data that is already base64
     * encoded
    */
    if(is_base64((unsigned char *)ctx->encrypted_msg,
            ctx->encrypted_msg_len) == 0)
        return(FKO_ERROR_INVALID_DATA_ENCODE_NOTBASE64);

    if(constant_runtime_cmp(ctx->encrypted_msg,
            B64_RIJNDAEL_SALT, B64_RIJNDAEL_SALT_STR_LEN) != 0)
    {
        /* We need to realloc space for the salt.
        */
        tbuf = realloc(ctx->encrypted_msg, ctx->encrypted_msg_len
                    + B64_RIJNDAEL_SALT_STR_LEN+1);
        if(tbuf == NULL)
            return(FKO_ERROR_MEMORY_ALLOCATION);

        memmove(tbuf+B64_RIJNDAEL_SALT_STR_LEN, tbuf, ctx->encrypted_msg_len);
	//Ìí¼ÓÑΡ£
        ctx->encrypted_msg = memcpy(tbuf,
                B64_RIJNDAEL_SALT, B64_RIJNDAEL_SALT_STR_LEN);

        /* Adjust the encoded msg len for added SALT value and Make sure we
         * are still a properly NULL-terminated string (Ubuntu was one system
         * for which this was an issue).
        */
        ctx->encrypted_msg_len += B64_RIJNDAEL_SALT_STR_LEN;
        tbuf[ctx->encrypted_msg_len] = '\0';

        ctx->added_salted_str = 1;
    }

    return(FKO_SUCCESS);
}
Exemple #4
0
/**
 * Count the number of valid base64 characters in the supplied input
 * buffer.
 * @desc this function counts the number of valid base64 characters,
 * skipping CR and LF characters. Invalid characters are treated as
 * end of buffer markers.
 *
 * \param inbuff the buffer to check.
 * \param inputlen the length of the input buffer.
 * \return the number of valid base64 characters.
 */
static uint32_t get_num_valid_characters( const uint8_t* inbuff, 
                                          size_t inputlen ) 
{
    uint32_t validCharCount=0;
    uint32_t idx=0;

    while ( idx < inputlen )
    {
        if ( is_base64( inbuff[idx] ) )
        {
            ++validCharCount;
            ++idx;
        }
        else if ( inbuff[idx] == '\r' || inbuff[idx] == '\n' ) 
        {
            ++idx;
        }
        else
        {
            break;
        }
    }
    return validCharCount;
}
Exemple #5
0
/* Validate and in some cases preprocess/reformat the SPA data.  Return an
 * error code value if there is any indication the data is not valid spa data.
*/
static int
preprocess_spa_data(const fko_srv_options_t *opts, spa_pkt_info_t *spa_pkt)
{

    char    *ndx = (char *)&(spa_pkt->packet_data);
    int      i, pkt_data_len = 0;

    pkt_data_len = spa_pkt->packet_data_len;

    /* At this point, we can reset the packet data length to 0.  This is our
     * indicator to the rest of the program that we do not have a current
     * spa packet to process (after this one that is).
    */
    spa_pkt->packet_data_len = 0;

    /* These two checks are already done in process_packet(), but this is a
     * defensive measure to run them again here
    */
    if(pkt_data_len < MIN_SPA_DATA_SIZE)
        return(SPA_MSG_BAD_DATA);

    if(pkt_data_len > MAX_SPA_PACKET_LEN)
        return(SPA_MSG_BAD_DATA);

    /* Ignore any SPA packets that contain the Rijndael or GnuPG prefixes
     * since an attacker might have tacked them on to a previously seen
     * SPA packet in an attempt to get past the replay check.  And, we're
     * no worse off since a legitimate SPA packet that happens to include
     * a prefix after the outer one is stripped off won't decrypt properly
     * anyway because libfko would not add a new one.
    */
    if(constant_runtime_cmp(ndx, B64_RIJNDAEL_SALT, B64_RIJNDAEL_SALT_STR_LEN) == 0)
        return(SPA_MSG_BAD_DATA);

    if(pkt_data_len > MIN_GNUPG_MSG_SIZE
            && constant_runtime_cmp(ndx, B64_GPG_PREFIX, B64_GPG_PREFIX_STR_LEN) == 0)
        return(SPA_MSG_BAD_DATA);

    /* Detect and parse out SPA data from an HTTP request. If the SPA data
     * starts with "GET /" and the user agent starts with "Fwknop", then
     * assume it is a SPA over HTTP request.
    */
    if(strncasecmp(opts->config[CONF_ENABLE_SPA_OVER_HTTP], "Y", 1) == 0
      && strncasecmp(ndx, "GET /", 5) == 0
      && strstr(ndx, "User-Agent: Fwknop") != NULL)
    {
        /* This looks like an HTTP request, so let's see if we are
         * configured to accept such request and if so, find the SPA
         * data.
        */

        /* Now extract, adjust (convert characters translated by the fwknop
         * client), and reset the SPA message itself.
        */
        strlcpy((char *)spa_pkt->packet_data, ndx+5, pkt_data_len);
        pkt_data_len -= 5;

        for(i=0; i<pkt_data_len; i++)
        {
            if(isspace(*ndx)) /* The first space marks the end of the req */
            {
                *ndx = '\0';
                break;
            }
            else if(*ndx == '-') /* Convert '-' to '+' */
                *ndx = '+';
            else if(*ndx == '_') /* Convert '_' to '/' */
                *ndx = '/';

            ndx++;
        }

        if(i < MIN_SPA_DATA_SIZE)
            return(SPA_MSG_BAD_DATA);

        spa_pkt->packet_data_len = pkt_data_len = i;
    }

    /* Require base64-encoded data
    */
    if(! is_base64(spa_pkt->packet_data, pkt_data_len))
        return(SPA_MSG_NOT_SPA_DATA);


    /* If we made it here, we have no reason to assume this is not SPA data.
     * The ultimate test will be whether the SPA data authenticates via an
     * HMAC anyway.
    */
    return(FKO_SUCCESS);
}
Exemple #6
0
int Element_FromBytes(Element &e, int type, unsigned char *data)
{
	if(type == ZR_t) {
		if(is_base64((unsigned char) data[0])) {
			string b64_encoded((char *) data);
			string s = _base64_decode(b64_encoded);
			int cnt = 0;
			Big b = Big(bytesToBig(s, &cnt));
			e = Element(b);
//			cout << "Element_FromBytes: " << e << endl;
			return TRUE;
		}
	}
	else if(type == G1_t) {
		if(is_base64((unsigned char) data[0])) {
			string b64_encoded((char *) data);
			string s = _base64_decode(b64_encoded);

			int cnt = 0;
			Big x, y;
			x = bytesToBig(s, &cnt);
			s = s.substr(cnt);
			y = bytesToBig(s, &cnt);
	//		cout << "point => (" << x << ", " << y << ")" << endl;
			G1 p;
			p.g.set(x, y);
			e = Element(p);
			//cout << "Element_FromBytes: " << e << endl;
			return TRUE;
		}
	}
#if ASYMMETRIC == 1
	else if(type == G2_t) {
		if(is_base64((unsigned char) data[0])) {
			string b64_encoded((char *) data);
			string s = _base64_decode(b64_encoded);
	//		cout << "original => " << s << endl;
			int cnt = 0;
			G2 p;
#if BUILD_MNT_CURVE == 1
			ZZn a[MNT_G2_SIZE];
			for(int i = 0; i < MNT_G2_SIZE; i++) {
				Big b = bytesToBig(s, &cnt);
				a[i] = ZZn( b ); // retrieve all six coordinates
				s = s.substr(cnt);
			}
			ZZn3 x (a[0], a[1], a[2]);
			ZZn3 y (a[3], a[4], a[5]);

			p.g.set(x, y);
#elif BUILD_BN_CURVE == 1
			Big a[BN_G2_SIZE];
			for(int i = 0; i < BN_G2_SIZE; i++) {
				a[i] = bytesToBig(s, &cnt);
				s = s.substr(cnt); // advance s ptr
			}

			ZZn2 x1(a[0], a[1]); // each zzn2 has a (x, y) coordinate of type Big
			ZZn2 y1(a[2], a[3]);
			p.g.set(x1, y1);
#endif
			e = Element(p);
			//cout << "Element_FromBytes: " << e << endl;
			return TRUE;
		}
	}
#endif
	else if(type == GT_t) {
		if(is_base64((unsigned char) data[0])) {
			string b64_encoded((char *) data);
			string s = _base64_decode(b64_encoded);
	//		cout << "original => " << s << endl;
			int cnt = 0;
			GT p;
#if BUILD_MNT_CURVE == 1
			Big a[MNT_GT_SIZE];
			for(int i = 0; i < MNT_GT_SIZE; i++) {
				a[i] = bytesToBig(s, &cnt);
				s = s.substr(cnt); // advance s ptr
			}

			ZZn2 x, y, z;
			x.set(a[0], a[1]);
			y.set(a[2], a[3]);
			z.set(a[4], a[5]);
			p.g.set(x, y, z);
#elif BUILD_BN_CURVE == 1
			Big a[BN_GT_SIZE];
			for(int i = 0; i < BN_GT_SIZE; i++) {
				a[i] = bytesToBig(s, &cnt);
				s = s.substr(cnt); // advance s ptr
			}
			ZZn2 x0, x1, y0, y1, z0, z1;
			x0.set(a[0], a[1]);
			x1.set(a[2], a[3]);
			y0.set(a[4], a[5]);
			y1.set(a[6], a[7]);
			z0.set(a[8], a[9]);
			z1.set(a[10], a[11]);

			ZZn4 x(x0, x1);
			ZZn4 y(y0, y1);
			ZZn4 z(z0, z1);
			p.g.set(x, y, z);
#elif BUILD_SS_CURVE == 1
			// must be symmetric
			Big a[SS_GT_SIZE];
			for(int i = 0; i < SS_GT_SIZE; i++) {
				a[i] = bytesToBig(s, &cnt);
				s = s.substr(cnt); // advance s ptr
			}
			p.g.set(a[0], a[1]);
#endif
			e = Element(p);
			//cout << "Element_FromBytes: " << e << endl;
			return TRUE;
		}
	}
	return 0;
}