Beispiel #1
0
static int authcheck_sha1(aClient *cptr, anAuthStruct *as, char *para)
{
char buf[512];
int i, r;
char *saltstr, *hashstr;

	if (!para)
		return -1;
	r = parsepass(as->data, &saltstr, &hashstr);
	if (r)
	{
		/* New method with salt: b64(SHA1(SHA1(<pass>)+salt)) */
		char result1[MAXSALTLEN+20+1];
		char result2[20];
		char rsalt[MAXSALTLEN+1];
		int rsaltlen;
#ifndef _WIN32
		SHA_CTX hash;
#else
		HCRYPTPROV hProv;
		HCRYPTHASH hHash;
		DWORD size = 20;
#endif
		
		/* First, decode the salt to something real... */
		rsaltlen = b64_decode(saltstr, rsalt, sizeof(rsalt));
		if (rsaltlen <= 0)
			return -1;

#ifdef _WIN32
		if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
			return -1;
#endif
		
		/* Then hash the password (1st round)... */
#ifndef _WIN32
		SHA1_Init(&hash);
		SHA1_Update(&hash, para, strlen(para));
		SHA1_Final(result1, &hash);
#else
		if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
		if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL;
		if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL;
		CryptDestroyHash(hHash);
#endif
		/* Add salt to result */
		memcpy(result1+20, rsalt, rsaltlen); /* b64_decode already made sure bounds are ok */

		/* Then hash it all together again (2nd round)... */
#ifndef _WIN32
		SHA1_Init(&hash);
		SHA1_Update(&hash, result1, rsaltlen+20);
		SHA1_Final(result2, &hash);
#else
		if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
		if (!CryptHashData(hHash, result1, 20+rsaltlen, 0)) return NULL;
		if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL;
		CryptDestroyHash(hHash);
		CryptReleaseContext(hProv, 0);
#endif		
		/* Then base64 encode it all and we are done... */
		if ((i = b64_encode(result2, sizeof(result2), buf, sizeof(buf))))
		{
			if (!strcmp(buf, hashstr))
				return 2;
			else
				return -1;
		} else
			return -1;
	} else {
		/* OLD auth */
#ifndef _WIN32
		if ((i = b64_encode(SHA1(para, strlen(para), NULL), 20, buf, sizeof(buf))))
		{
			if (!strcmp(buf, as->data))
				return 2;
			else
				return -1;
		} else
			return -1;
#else
		HCRYPTPROV hProv;
		HCRYPTHASH hHash;
		char buf2[512];
		DWORD size = 512;
		if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
		     CRYPT_VERIFYCONTEXT))
			return -1;
		if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
			return -1;
		if (!CryptHashData(hHash, para, strlen(para), 0))
			return -1;
		if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0))
			return -1;
		CryptDestroyHash(hHash);
		CryptReleaseContext(hProv, 0);
		b64_encode(buf, 20, buf2, sizeof(buf2));
		if (!strcmp(buf2, as->data))
			return 2;
		else 
			return -1;
#endif
	}
}
Beispiel #2
0
static char *mkpass_sha1(char *para)
{
static char buf[128];
char result1[20+REALSALTLEN];
char result2[20];
char saltstr[REALSALTLEN]; /* b64 encoded printable string*/
char saltraw[RAWSALTLEN];  /* raw binary */
char xresult[64];
#ifndef _WIN32
SHA_CTX hash;
#else
HCRYPTPROV hProv;
HCRYPTHASH hHash;
DWORD size = 20;
#endif
int i;

	if (!para) return NULL;

	/* generate a random salt... */
	for (i=0; i < RAWSALTLEN; i++)
		saltraw[i] = getrandom8();

	i = b64_encode(saltraw, RAWSALTLEN, saltstr, REALSALTLEN);
	if (!i) return NULL;

#ifdef _WIN32
	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
		return NULL;
#endif

	/* b64(SHA1(SHA1(<pass>)+salt))
	 *         ^^^^^^^^^^^
	 *           step 1
	 *     ^^^^^^^^^^^^^^^^^^^^^
	 *     step 2
	 * ^^^^^^^^^^^^^^^^^^^^^^^^^^
	 * step 3
	 */

	/* STEP 1 */
#ifndef _WIN32
	SHA1_Init(&hash);
	SHA1_Update(&hash, para, strlen(para));
	SHA1_Final(result1, &hash);
#else
	if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
	if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL;
	if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL;
	CryptDestroyHash(hHash);
#endif
	/* STEP 2 */
	/* add salt to result */
	memcpy(result1+20, saltraw, RAWSALTLEN);
	/* Then hash it all together */
#ifndef _WIN32
	SHA1_Init(&hash);
	SHA1_Update(&hash, result1, RAWSALTLEN+20);
	SHA1_Final(result2, &hash);
#else
	if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL;
	if (!CryptHashData(hHash, result1, RAWSALTLEN+20, 0)) return NULL;
	if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL;
	CryptDestroyHash(hHash);
	CryptReleaseContext(hProv, 0);
#endif	
	/* STEP 3 */
	/* Then base64 encode it all together.. */
	i = b64_encode(result2, sizeof(result2), xresult, sizeof(xresult));
	if (!i) return NULL;

	/* Good.. now create the whole string:
	 * $<saltb64d>$<totalhashb64d>
	 */
	ircsprintf(buf, "$%s$%s", saltstr, xresult);
	return buf;
}
Beispiel #3
0
/**
 * Sets the data property
 *
 * @param data the data property
 *
 */
void Authentication::setData(const char*data) {

    if (data == NULL) {
        // TBD
        return;
    }

    const char* type = this->getType();

    if (strcmp(type,AUTH_TYPE_BASIC) == 0) {
        char* clearData = NULL;

        if (encode) {
            unsigned long len = 0;
            len = strlen(data);
            char* tmp = stringdup(data);
            char* b64tmp2 = new char[(len/3+1)<<2];
            len = b64_encode(b64tmp2, tmp, len);
            char* b64tmp = new char[len + 1];
            memset(b64tmp, 0, len + 1);
            strncpy(b64tmp, b64tmp2, len);
            if (this->data) {
                delete [] this->data; this->data = NULL;
            }
            this->data = stringdup(b64tmp);

            clearData = new char[strlen(data) + 1];
            sprintf(clearData, data);

            if (b64tmp2) {
                delete [] b64tmp2; b64tmp2 = NULL;
            }
            if (b64tmp) {
                delete [] b64tmp; b64tmp = NULL;
            }
            if (tmp) {
                delete [] tmp; tmp = NULL;
            }

        } else {
            unsigned long len = 0;
            len = strlen(data);
            char* tmp = stringdup(data);
            char* b64tmp = new char[len];
            len = b64_decode(b64tmp, tmp);

            clearData = stringdup(b64tmp);
            if (this->data) {
                delete [] this->data; this->data = NULL;
            }
            //this->data = new char[strlen(clearData) + 1];
            //sprintf(this->data, clearData);
            this->data = stringdup(data);

            if (tmp) {
                delete [] tmp; tmp = NULL;
            }
            if (b64tmp) {
                delete [] b64tmp; b64tmp = NULL;
            }
        }

        unsigned int len = strlen(clearData);
        char* p1 = clearData;
        bool charFound = false;
        for (unsigned int k = 0; k < len; k++) {
            if (*p1 == 0) {
                break;
            }
            else if (*p1 == ':') {
                charFound = true;
                p1 = p1 + 1;
                break;
            }
            p1 = p1 + 1;
        }

        if (charFound == false) {
            this->setUsername(clearData);
            this->setPassword(NULL);
        } else {
            char* p2 = p1 - 1;
            *p2 = 0;
            if (strlen(clearData) > 0 ) {
                this->setUsername(clearData);
            } else {
                this->setUsername("");
            }
            if (strlen(p1) > 0) {
                this->setPassword(p1);
            } else {
                this->setPassword("");
            }

        }
        if (clearData) { delete [] clearData; clearData = NULL; }
    }

    if (strcmp(type, AUTH_TYPE_MD5) == 0) {
        if (meta->getFormat() == NULL) {
            this->setFormat(FORMAT_B64);
        }
        this->setUsername(data);
        this->data     = stringdup(data);
    }
}
Beispiel #4
0
static void test_1_00()
{
    XTESTS_TEST_INTEGER_EQUAL(0u, b64_encode(NULL, 0, NULL, 0));
}
Beispiel #5
0
/* This is needed as a separate function, otherwise we run out of stack!! */
static int execute_unittest()
{
    int             ints[1001];
    const size_t    n       =   rand() % (sizeof(ints) / sizeof(ints[0]));
    size_t          j;
    size_t          cch;
    size_t          cch2;
    char            *enc;
    size_t          cb;
    size_t          cb2;
    int             *dec;

    /* Randomise the array */
    for(j = 0; j < n; ++j)
    {
        ints[j] = rand();
    }

    /* Encode */
    cch     =   b64_encode(&ints[0], n * sizeof(int), NULL, 0);
    enc     =   (char*)alloca(cch);

    cch2    =   b64_encode(&ints[0], n * sizeof(int), enc, cch);

    if( 0 != n &&
        0 == cch)
    {
        fprintf(stderr, "Failed: b64_encode() returned 0\n");

        return 1;
    }
    else if(cch2 != cch)
    {
        fprintf(stderr, "Failed: b64_encode() returned different size to that reported in size determination\n");

        return 1;
    }

    /* Decode */
    cb      =   b64_decode(enc, cch, NULL, 0);
    dec     =   (int*)alloca(cb);

    cb2     =   b64_decode(enc, cch, dec, cb);

    if( 0 != n &&
        0 == cb)
    {
        fprintf(stderr, "Failed: b64_decode() returned 0\n");

        return 1;
    }
    else if(cb2 > cb)
    {
        fprintf(stderr, "Failed: b64_decode() returned different value than that reported in size determination\n");

        return 1;
    }

    if(cb < n * sizeof(int))
    {
        fprintf(stderr, "Failed: wrong size: encoded size: %ld; decoded size: %ld\n", (long)(n * sizeof(int)), (long)cb);

        return 1;
    }

    if(0 != memcmp(&ints[0], &dec[0], cb2))
    {
        fprintf(stderr, "Failed: decoded form different from original!\n");

        return 1;
    }

    return 0;
}
Beispiel #6
0
/* Prep and encrypt using Rijndael
*/
static int
_rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len)
{
    char           *plaintext;
    char           *b64ciphertext;
    unsigned char  *ciphertext;
    int             cipher_len;
    int             pt_len;
    int             zero_free_rv = FKO_SUCCESS;

    if(enc_key_len > RIJNDAEL_MAX_KEYSIZE)
        return(FKO_ERROR_INVALID_KEY_LEN);

    if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
        return(FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL);

    switch(ctx->digest_len)
    {
        case MD5_B64_LEN:
            break;
        case SHA1_B64_LEN:
            break;
        case SHA256_B64_LEN:
            break;
        case SHA384_B64_LEN:
            break;
        case SHA512_B64_LEN:
            break;
        default:
            return(FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL);
    }

    pt_len = ctx->encoded_msg_len + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2;

    /* Make a bucket big enough to hold the enc msg + digest (plaintext)
     * and populate it appropriately.
    */
    plaintext = calloc(1, pt_len);

    if(plaintext == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    pt_len = snprintf(plaintext, pt_len, "%s:%s", ctx->encoded_msg, ctx->digest);

    if(! is_valid_pt_msg_len(pt_len))
    {
        if(zero_free(plaintext, pt_len) == FKO_SUCCESS)
            return(FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL);
        else
            return(FKO_ERROR_ZERO_OUT_DATA);
    }

    /* Make a bucket for the encrypted version and populate it.
    */
    ciphertext = calloc(1, pt_len + 32); /* Plus padding for salt and Block */
    if(ciphertext == NULL)
    {
        if(zero_free(plaintext, pt_len) == FKO_SUCCESS)
            return(FKO_ERROR_MEMORY_ALLOCATION);
        else
            return(FKO_ERROR_ZERO_OUT_DATA);
    }

    cipher_len = rij_encrypt(
        (unsigned char*)plaintext, pt_len,
        (char*)enc_key, enc_key_len,
        ciphertext, ctx->encryption_mode
    );

    /* Now make a bucket for the base64-encoded version and populate it.
    */
    b64ciphertext = malloc(((cipher_len / 3) * 4) + 8);
    if(b64ciphertext == NULL)
    {
        if(zero_free((char *) ciphertext, pt_len+32) == FKO_SUCCESS
                && zero_free(plaintext, pt_len) == FKO_SUCCESS)
            return(FKO_ERROR_MEMORY_ALLOCATION);
        else
            return(FKO_ERROR_ZERO_OUT_DATA);
    }

    b64_encode(ciphertext, b64ciphertext, cipher_len);
    strip_b64_eq(b64ciphertext);

    if(ctx->encrypted_msg != NULL)
        zero_free_rv = zero_free(ctx->encrypted_msg,
                strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE));

    ctx->encrypted_msg     = strdup(b64ciphertext);
    ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE);

    /* Clean-up
    */
    if(zero_free(plaintext, pt_len) != FKO_SUCCESS)
        zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

    if(zero_free((char *) ciphertext, pt_len+32) != FKO_SUCCESS)
        zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

    if(zero_free(b64ciphertext, strnlen(b64ciphertext,
                    MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
        zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

    if(ctx->encrypted_msg == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
        return(FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL);

    return(zero_free_rv);
}
Beispiel #7
0
static int http_connect(URLContext *h, const char *path, const char *hoststr,
                        const char *auth)
{
    HTTPContext *s = h->priv_data;
    int post, err, ch;
    char line[1024], *q;


    /* send http header */
    post = h->flags & URL_WRONLY;

    snprintf(s->buffer, sizeof(s->buffer),
             "%s %s HTTP/1.0\r\n"
             "User-Agent: %s\r\n"
             "Accept: */*\r\n"
             "Host: %s\r\n"
             "Authorization: Basic %s\r\n"
             "\r\n",
             post ? "POST" : "GET",
             path,
             LIBAVFORMAT_IDENT,
             hoststr,
             b64_encode(auth));
    
    if (http_write(h, s->buffer, strlen(s->buffer)) < 0)
        return AVERROR_IO;
        
    /* init input buffer */
    s->buf_ptr = s->buffer;
    s->buf_end = s->buffer;
    s->line_count = 0;
    s->location[0] = '\0';
    if (post) {
        sleep(1);
        return 0;
    }
    
    /* wait for header */
    q = line;
    for(;;) {
        ch = http_getc(s);
        if (ch < 0)
            return AVERROR_IO;
        if (ch == '\n') {
            /* process line */
            if (q > line && q[-1] == '\r')
                q--;
            *q = '\0';
#ifdef DEBUG
            printf("header='%s'\n", line);
#endif
            err = process_line(s, line, s->line_count);
            if (err < 0)
                return err;
            if (err == 0)
                return 0;
            s->line_count++;
            q = line;
        } else {
            if ((q - line) < sizeof(line) - 1)
                *q++ = ch;
        }
    }
}
Beispiel #8
0
int main(void)
{
    /* Simple conversion using b64_encode() and b64_decode(). */

    /* Declare an array of bytes to use as the 'binary' blob to encode. */
    unsigned char   bytes[]  =   { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    /* Invoke b64_encode() to determine the maximum size of the encoded 
     * string, specifying the argument 0 for the destSize parameter.
     * 
     * Note: The value returned may be larger than the actual size 
     * required, but will never be smaller.
     */
    size_t  cch     =   b64_encode(&bytes[0], sizeof(bytes), NULL, 0);

    /* Using the length determined by the call to b64_encode(), create 
     * a buffer of sufficient size.
     */
    char    *enc    =   (char*)malloc(cch);
    size_t  cb;
    void    *dec;
    size_t  i;

    printf("Converting %u bytes:\n", (unsigned)NUM_ELEMENTS(bytes));
    for(i = 0; i != NUM_ELEMENTS(bytes); ++i)
    {
        printf(" %d", bytes[i]);
    }
    puts("");

    /* Perform the encoding. */
    cch = b64_encode(&bytes[0], sizeof(bytes), enc, cch);

    printf("Encoded form: [%.*s]\n", (int)cch, enc);

    /* Invoke b64_decode() to determine the maximum size of the decoded
     * blob, specifying the argument 0 for the destLen parameter.
     *
     * Note: The value returned may be larger than the actual size
     * required, but will never be smaller.
     */
    cb = b64_decode(enc, cch, NULL, 0);

    /* Using the length determined by the call to b64_decode(), create 
     * a buffer of sufficient size.
     */
    dec = malloc(cb);

    /* Perform the decoding. */
    cb = b64_decode(enc, cch, dec, cb);

    /* Verify that the decoding is exactly the same size and contents as 
     * the encoding.
     */
    assert(cb == sizeof(bytes));
    assert(0 == memcmp(&bytes[0], dec, sizeof(bytes)));

    /* Clean up */
    free(dec);
    free(enc);

    /* Placate the compiler's warnings. */
    ((void)cb);

    return EXIT_SUCCESS;
}
Beispiel #9
0
char *_generate_signature_for_parameters(HTTPParameter *first_parameter, HTTPConnection *http_connection) {
	int parameters_count = 0;
	HTTPParameter *current_parameter = first_parameter;
	while(current_parameter != NULL) {
		parameters_count++;
		current_parameter = (HTTPParameter *)current_parameter->next_parameter;
	}

	HTTPParameter http_parameters[parameters_count];
	int i = 0;

	current_parameter = first_parameter;
	while(current_parameter != NULL) {
		http_parameters[i] = *current_parameter;
		i++;
		current_parameter = (HTTPParameter *)current_parameter->next_parameter;
	}

	// sort parameters alphabetically
	qsort(http_parameters, parameters_count, sizeof(HTTPParameter), compare_parameters);

	char *signature_base_string = malloc(sizeof(char) * 500);

	for(i = 0; i < parameters_count; i++) {
		current_parameter = &(http_parameters[i]);
		if(current_parameter->type != HTTPParameterTypeAuthorizationHeader) {
			sprintf(signature_base_string, "%s%s=%s&", signature_base_string, current_parameter->key, current_parameter->value);
		}
	}

	signature_base_string[strlen(signature_base_string) - 1] = '\0'; // removes last '&'

	sprintf(signature_base_string, "%s&%s&%s", (http_connection->connection_method == HTTPConnectionMethodPOST ? "POST" : "GET"), _html_escape_string(http_connection->url), _html_escape_string(signature_base_string));

	unsigned char sha1_result[30];// = malloc(sizeof(char) * 32);
	char *key_string = malloc(sizeof(char) * 200);
	if(current_oauth_token) {
		sprintf(key_string, "%s&%s", OAUTH_CONSUMER_SECRET, current_oauth_token->oauth_token_secret);
	} else if(current_access_token) {
		sprintf(key_string, "%s&%s", OAUTH_CONSUMER_SECRET, current_access_token->access_token_secret);
	} else {
		sprintf(key_string, "%s&", OAUTH_CONSUMER_SECRET);
	}

	printf("signature_base_string: %s\n", signature_base_string);

	unsigned int md_len = 30;

	// result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL);
	int success = hmac_sha1(key_string, strlen(key_string), signature_base_string, strlen(signature_base_string), sha1_result);
	// int success = HMAC(EVP_sha1(), key_string, strlen(key_string), signature_base_string, strlen(signature_base_string), sha1_result, &md_len);

	// if(success != 0) {
	// 	printf(" Error generating oauth_signature (HMAC-SHA1). \n");
	// 	return NULL;
	// }

	free(key_string);
	free(signature_base_string);

	char *final_signature = malloc(sizeof(char) * 100);
	b64_encode(&sha1_result, final_signature);

	return final_signature;
}
Beispiel #10
0
/* Prep and encrypt using gpgme
*/
int
gpg_encrypt(fko_ctx_t ctx, char *enc_key)
{
    int             res;
    char           *plain;
    char           *b64cipher;
    unsigned char  *cipher = NULL;
    size_t          cipher_len;

    /* First make sure we have a recipient key set.
    */
    if(ctx->gpg_recipient == NULL)
        return(FKO_ERROR_MISSING_GPG_KEY_DATA);

    /* Make a bucket big enough to hold the enc msg + digest (plaintext)
     * and populate it appropriately.
    */
    plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2);
    if(plain == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    sprintf(plain, "%s:%s", ctx->encoded_msg, ctx->digest);

    res = gpgme_encrypt(ctx,
        (unsigned char*)plain, strlen(plain),
        enc_key, &cipher, &cipher_len
    );

    /* --DSS XXX: Better parsing of what went wrong would be nice :)
    */
    if(res != FKO_SUCCESS)
    {
        free(plain);

        if(cipher)
            free(cipher);

        return(res);
    }

    /* Now make a bucket for the base64-encoded version and populate it.
    */
    b64cipher = malloc(((cipher_len / 3) * 4) + 8);
    if(b64cipher == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    b64_encode(cipher, b64cipher, cipher_len);
    strip_b64_eq(b64cipher);

    ctx->encrypted_msg = strdup(b64cipher);

    /* Clean-up
    */
    free(plain);
    free(cipher);
    free(b64cipher);

    if(ctx->encrypted_msg == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    return(FKO_SUCCESS);
}
Beispiel #11
0
int sign_message(struct s3_message* mesg, const char* user, const char * key) {
	int sign_str_len = 0;
	char *sign_str;
	char date[1024];
	struct s3_header_object *amz;
	struct list *amz_headers;
	char digest[SHA1_DIGEST_LENGTH];
	char string[SHA1_DIGEST_LENGTH*2];
	int result;
	memset(digest, 0, SHA1_DIGEST_LENGTH);
	memset(string, 0, SHA1_DIGEST_LENGTH*2);

	switch(mesg->type) {
		case S3_MESG_GET: 
			sign_str_len += 4;
			break;
		case S3_MESG_POST: 
			sign_str_len += 5;
			break;
		case S3_MESG_PUT:
			sign_str_len += 4;
			break;
		case S3_MESG_DELETE:
			sign_str_len += 7;
			break;
		case S3_MESG_HEAD:
			sign_str_len += 5;
			break;
		case S3_MESG_COPY:
			sign_str_len += 4;
			break;
		default:
			return -1;
	}

	if(mesg->content_md5) sign_str_len += strlen(mesg->content_md5);
	sign_str_len += 1;
	if(mesg->content_type) sign_str_len += strlen(mesg->content_type);
	sign_str_len += 1;

	strftime(date, 1024, "%a, %d %b %Y %H:%M:%S %Z", gmtime(&mesg->date));
	sign_str_len += strlen(date) + 1;

	if(mesg->amz_headers) {	
		list_first_item(mesg->amz_headers);
		while( (amz = (struct s3_header_object *)list_next_item(mesg->amz_headers)) ) {
			if(amz->type < S3_HEADER_CUSTOM) continue;
			switch(amz->type) {
				case S3_HEADER_CUSTOM:
					if(!amz->custom_type) return -1;
					sign_str_len += strlen(amz->custom_type) + 1;
					break;
				default:
					sign_str_len += strlen(s3_get_header_string(amz->type, amz->custom_type)) + 1;
					break;
			}
			if(!amz->value) return -1;
			sign_str_len += strlen(amz->value) + 1;
		}
	}
	if(!mesg->bucket || !mesg->path) {
		return -1;
	}
	sign_str_len += 1 + strlen(mesg->bucket) + 1 + strlen(mesg->path) + 1;
	
	sign_str = malloc(sign_str_len);
	if(!sign_str) return -1;
	memset(sign_str, 0, sign_str_len);

	switch(mesg->type) {
		case S3_MESG_GET: 
			sprintf(sign_str, "GET\n");
			break;
		case S3_MESG_POST: 
			sprintf(sign_str, "POST\n");
			break;
		case S3_MESG_PUT:
			sprintf(sign_str, "PUT\n");
			break;
		case S3_MESG_DELETE:
			sprintf(sign_str, "DELETE\n");
			break;
		case S3_MESG_HEAD:
			sprintf(sign_str, "HEAD\n");
			break;
		case S3_MESG_COPY:
			sprintf(sign_str, "PUT\n");
			break;
	}

	if(mesg->content_md5) sprintf(sign_str, "%s%s\n", sign_str,mesg->content_md5);
			else sprintf(sign_str, "%s\n", sign_str);
	if(mesg->content_type) sprintf(sign_str, "%s%s\n", sign_str, mesg->content_type);
			else sprintf(sign_str, "%s\n", sign_str);
	sprintf(sign_str, "%s%s", sign_str, date);

	if(mesg->amz_headers) {
		amz_headers = list_sort(list_duplicate(mesg->amz_headers), &s3_header_object_comp);
		list_first_item(amz_headers);
		{	int c_type = -1;
			char* c_ctype = NULL;
			while( (amz = (struct s3_header_object *)list_next_item(amz_headers)) ) {
				if(amz->type < S3_HEADER_CUSTOM) continue;
				if(c_type != amz->type) {
					c_type = amz->type;
					c_ctype = amz->custom_type;
					sprintf(sign_str, "%s\n%s:%s", sign_str, s3_get_header_string(amz->type, amz->custom_type), amz->value);

				} else if(c_type == S3_HEADER_CUSTOM && strcmp(c_ctype, amz->custom_type)) {
					c_ctype = amz->custom_type;
					sprintf(sign_str, "%s\n%s:%s", sign_str, amz->custom_type, amz->value);
				} else {
					sprintf(sign_str, "%s,%s", sign_str, amz->value);
				}
			}
		}
		list_delete(amz_headers);
	}

	sprintf(sign_str, "%s\n/%s%s", sign_str, mesg->bucket, mesg->path);
	if((result = hmac_sha1(sign_str, strlen(sign_str), key, strlen(key), (unsigned char*)digest))) return result;

	hmac_sha1(sign_str, strlen(sign_str), key, strlen(key), (unsigned char*)digest);
	b64_encode(digest, SHA1_DIGEST_LENGTH, string, SHA1_DIGEST_LENGTH*2);

	sprintf(mesg->authorization, "AWS %s:%s", user, string);
	free(sign_str);
	return 0;
}
Beispiel #12
0
static void bookmark_save_one(FILE *fp, url_t *url)
{
  if (url == gvLocalUrl)
    fprintf(fp, "local");
  else if (url == gvDefaultUrl)
    fprintf(fp, "default");
  else
  {
    fprintf(fp, "machine %s://%s",
        url->protocol ? url->protocol : "ftp", url->hostname);
    if (url->port != -1)
      fprintf(fp, ":%d", url->port);
    if (url->alias)
    {
      char *a = xquote_chars(url->alias, "\'\"");
      fprintf(fp, " alias '%s'", a);
      free(a);
    }
  }

  if (url_isanon(url) && url->password &&
      strcmp(url->password, gvAnonPasswd) == 0)
    fprintf(fp, "\n  anonymous");
  else if (url->username)
  {
    fprintf(fp, "\n  login %s", url->username);
    if (url->password)
    {
      if (url_isanon(url))
        fprintf(fp, " password %s", url->password);
      else
      {
        char *cq = NULL;
        if (b64_encode(url->password, strlen(url->password), &cq) != -1)
        {
          fprintf(fp, " password [base64]%s", cq);
          free(cq);
        }
      }
    }
  }

  if (url->directory)
    fprintf(fp, " cwd '%s'", url->directory);

  if (url->protlevel)
    fprintf(fp, " prot %s", url->protlevel);

  if (url->mech)
  {
    char *mech_string = stringify_list(url->mech);
    if (mech_string)
    {
      fprintf(fp, " mech '%s'", mech_string);
      free(mech_string);
    }
  }

  if (url->pasvmode != -1)
    fprintf(fp, " passive %s", url->pasvmode ? "true" : "false");

  if (url->sftp_server)
    fprintf(fp, " sftp %s", url->sftp_server);

  if (url->noupdate)
    fprintf(fp, " noupdate");

  fprintf(fp, "\n\n");
}
Beispiel #13
0
static int sign(const char *msgfile)
{
	struct seckey skey;
	struct sig sig = {
		.pkalg = "Ed",
	};
	struct stat st;
	char buf[512];
	void *pubkey = buf;
	long mlen;
	void *m;
	int mfd;

	if (!get_base64_file(seckeyfile, &skey, sizeof(skey), buf, sizeof(buf)) ||
	    memcmp(skey.pkalg, "Ed", 2) != 0) {
		fprintf(stderr, "Failed to decode secret key\n");
		return 1;
	}

	if (skey.kdfrounds) {
		fprintf(stderr, "Password protected secret keys are not supported\n");
		return 1;
	}

	mfd = open(msgfile, O_RDONLY, 0);
	if (mfd < 0 || fstat(mfd, &st) < 0 ||
		(m = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, mfd, 0)) == MAP_FAILED) {
		if (mfd >= 0)
			close(mfd);
		perror("Cannot open message file");
		return 1;
	}
	mlen = st.st_size;

	memcpy(sig.fingerprint, skey.fingerprint, sizeof(sig.fingerprint));
	edsign_sec_to_pub(pubkey, skey.seckey);
	edsign_sign(sig.sig, pubkey, skey.seckey, m, mlen);
	munmap(m, mlen);
	close(mfd);

	if (b64_encode(&sig, sizeof(sig), buf, sizeof(buf)) < 0)
		return 1;

	write_file(sigfile, sig.fingerprint, "signed by key", buf);

	return 0;
}

static int fingerprint(void)
{
	struct seckey skey;
	struct pubkey pkey;
	struct sig sig;
	char buf[512];
	uint8_t *fp;

	if (seckeyfile &&
	    get_base64_file(seckeyfile, &skey, sizeof(skey), buf, sizeof(buf)))
		fp = skey.fingerprint;
	else if (pubkeyfile &&
	         get_base64_file(pubkeyfile, &pkey, sizeof(pkey), buf, sizeof(buf)))
		fp = pkey.fingerprint;
	else if (sigfile &&
	         get_base64_file(sigfile, &sig, sizeof(sig), buf, sizeof(buf)))
		fp = sig.fingerprint;
	else
		return 1;

	fprintf(stdout, "%"PRIx64"\n", fingerprint_u64(fp));
	return 0;
}

static int generate(void)
{
	struct seckey skey = {
		.pkalg = "Ed",
		.kdfalg = "BK",
		.kdfrounds = 0,
	};
	struct pubkey pkey = {
		.pkalg = "Ed",
	};
	struct sha512_state s;
	char buf[512];
	FILE *f;

	f = fopen("/dev/urandom", "r");
	if (!f ||
	    fread(skey.fingerprint, sizeof(skey.fingerprint), 1, f) != 1 ||
	    fread(skey.seckey, EDSIGN_SECRET_KEY_SIZE, 1, f) != 1 ||
	    fread(skey.salt, sizeof(skey.salt), 1, f) != 1) {
		fprintf(stderr, "Can't read data from /dev/urandom\n");
		return 1;
	}
	if (f)
		fclose(f);

	ed25519_prepare(skey.seckey);
	edsign_sec_to_pub(skey.seckey + 32, skey.seckey);

	sha512_init(&s);
	sha512_add(&s, skey.seckey, sizeof(skey.seckey));
	memcpy(skey.checksum, sha512_final_get(&s), sizeof(skey.checksum));

	if (b64_encode(&skey, sizeof(skey), buf, sizeof(buf)) < 0)
		return 1;

	write_file(seckeyfile, skey.fingerprint, "public key", buf);

	memcpy(pkey.fingerprint, skey.fingerprint, sizeof(pkey.fingerprint));
	memcpy(pkey.pubkey, skey.seckey + 32, sizeof(pkey.pubkey));

	if (b64_encode(&pkey, sizeof(pkey), buf, sizeof(buf)) < 0)
		return 1;

	write_file(pubkeyfile, pkey.fingerprint, "private key", buf);

	return 0;
}

static int usage(const char *cmd)
{
	fprintf(stderr,
		"Usage: %s <command> <options>\n"
		"Commands:\n"
		"  -V:			verify (needs at least -m and -p|-P)\n"
		"  -S:			sign (needs at least -m and -s)\n"
		"  -F:			print key fingerprint of public/secret key or signature\n"
		"  -G:			generate a new keypair\n"
		"Options:\n"
		"  -c <comment>: 	add comment to keys\n"
		"  -m <file>:		message file\n"
		"  -p <file>:		public key file (verify/fingerprint only)\n"
		"  -P <path>:		public key directory (verify only)\n"
		"  -q:			quiet (do not print verification result, use return code only)\n"
		"  -s <file>:		secret key file (sign/fingerprint only)\n"
		"  -x <file>:		signature file (defaults to <message file>.sig)\n"
		"\n",
		cmd);
	return 1;
}

static void set_cmd(const char *prog, int val)
{
	if (cmd != CMD_NONE)
		exit(usage(prog));

	cmd = val;
}

int main(int argc, char **argv)
{
	const char *msgfile = NULL;
	int ch;

	while ((ch = getopt(argc, argv, "FGSVc:m:P:p:qs:x:")) != -1) {
		switch (ch) {
		case 'V':
			set_cmd(argv[0], CMD_VERIFY);
			break;
		case 'S':
			set_cmd(argv[0], CMD_SIGN);
			break;
		case 'F':
			set_cmd(argv[0], CMD_FINGERPRINT);
			break;
		case 'G':
			set_cmd(argv[0], CMD_GENERATE);
			break;
		case 'c':
			comment = optarg;
			break;
		case 'm':
			msgfile = optarg;
			break;
		case 'P':
			pubkeydir = optarg;
			break;
		case 'p':
			pubkeyfile = optarg;
			break;
		case 's':
			seckeyfile = optarg;
			break;
		case 'x':
			sigfile = optarg;
			break;
		case 'q':
			quiet = true;
			break;
		default:
			return usage(argv[0]);
		}
	}

	if (!sigfile && msgfile) {
		char *buf = alloca(strlen(msgfile) + 5);

		if (!strcmp(msgfile, "-")) {
			fprintf(stderr, "Need signature file when reading message from stdin\n");
			return 1;
		}

		sprintf(buf, "%s.sig", msgfile);
		sigfile = buf;
	}

	switch (cmd) {
	case CMD_VERIFY:
		if ((!pubkeyfile && !pubkeydir) || !msgfile)
			return usage(argv[0]);
		return verify(msgfile);
	case CMD_SIGN:
		if (!seckeyfile || !msgfile || !sigfile)
			return usage(argv[0]);
		return sign(msgfile);
	case CMD_FINGERPRINT:
		if (!!seckeyfile + !!pubkeyfile + !!sigfile != 1) {
			fprintf(stderr, "Need one secret/public key or signature\n");
			return usage(argv[0]);
		}
		return fingerprint();
	case CMD_GENERATE:
		if (!seckeyfile || !pubkeyfile)
			return usage(argv[0]);
		return generate();
	default:
		return usage(argv[0]);
	}
}
static char * packStructure(char *serviceName, char *dest, char *trans_id, char *payload, char *contentType, unsigned int payload_len)
{           
    msgpack_sbuffer sbuf;
    msgpack_packer pk;  
    char* b64buffer =  NULL;
    size_t encodeSize = 0;
    char source[MAX_PARAMETERNAME_LEN/2] = {'\0'}; 
    int msg_type = 4;

    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, LMLite %s ENTER\n", __FUNCTION__ ));

    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, deviceMAC *********:%s\n",deviceMAC));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, serviceName :%s\n",serviceName));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, dest :%s\n",dest));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, transaction_id :%s\n",trans_id));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, contentType :%s\n",contentType));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, payload_len :%d\n",payload_len));

    snprintf(source, sizeof(source), "mac:%s/%s", deviceMAC, serviceName);

    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, Received DeviceMac from Atom side: %s\n",deviceMAC));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, Source derived is %s\n", source));
  
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, <======== Start of packStructure ======>\n"));
    
    // Start of msgpack encoding
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, -----------Start of msgpack encoding------------\n"));

    msgpack_sbuffer_init(&sbuf);
    msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
    msgpack_pack_map(&pk, WEBPA_MAP_SIZE);

    msgpack_pack_str(&pk, strlen(WEBPA_MSG_TYPE));
    msgpack_pack_str_body(&pk, WEBPA_MSG_TYPE,strlen(WEBPA_MSG_TYPE));
    msgpack_pack_int(&pk, msg_type);   
    
    msgpack_pack_str(&pk, strlen(WEBPA_SOURCE));
    msgpack_pack_str_body(&pk, WEBPA_SOURCE,strlen(WEBPA_SOURCE));
    msgpack_pack_str(&pk, strlen(source));
    msgpack_pack_str_body(&pk, source,strlen(source));
    
    msgpack_pack_str(&pk, strlen(WEBPA_DESTINATION));
    msgpack_pack_str_body(&pk, WEBPA_DESTINATION,strlen(WEBPA_DESTINATION));       
    msgpack_pack_str(&pk, strlen(dest));
    msgpack_pack_str_body(&pk, dest,strlen(dest));
    
    msgpack_pack_str(&pk, strlen(WEBPA_TRANSACTION_ID));
    msgpack_pack_str_body(&pk, WEBPA_TRANSACTION_ID,strlen(WEBPA_TRANSACTION_ID));
    msgpack_pack_str(&pk, strlen(trans_id));
    msgpack_pack_str_body(&pk, trans_id,strlen(trans_id));
     
    msgpack_pack_str(&pk, strlen(WEBPA_PAYLOAD));
    msgpack_pack_str_body(&pk, WEBPA_PAYLOAD,strlen(WEBPA_PAYLOAD));
       
    if(strcmp(contentType,"avro/binary") == 0)
    {
        CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, msg->payload binary\n"));
        msgpack_pack_bin(&pk, payload_len);
        msgpack_pack_bin_body(&pk, payload, payload_len);
    }
    else // string: "contentType :application/json"
    {
        CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, msg->payload string\n"));
        msgpack_pack_str(&pk, strlen(payload));
        msgpack_pack_str_body(&pk, payload,strlen(payload));
    }
  
    msgpack_pack_str(&pk, strlen(CONTENT_TYPE));
    msgpack_pack_str_body(&pk, CONTENT_TYPE,strlen(CONTENT_TYPE));
    msgpack_pack_str(&pk, strlen(contentType));
    msgpack_pack_str_body(&pk, contentType,strlen(contentType));
    
    /*if(consoleDebugEnable)
        fprintf(stderr, "RDK_LOG_DEBUG,msgpack encoded data contains %d bytes and data is : %s\n",(int)sbuf.size,sbuf.data);*/

    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,-----------End of msgpack encoding------------\n"));
    // End of msgpack encoding
    
    // Start of Base64 Encode
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,-----------Start of Base64 Encode ------------\n"));
    encodeSize = b64_get_encoded_buffer_size( sbuf.size );
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,encodeSize is %d\n", (int)encodeSize));
    b64buffer = malloc(encodeSize + 1); // one byte extra for terminating NULL byte
    b64_encode((const uint8_t *)sbuf.data, sbuf.size, (uint8_t *)b64buffer);
    b64buffer[encodeSize] = '\0' ;    
 
    
    /*if(consoleDebugEnable)
    {
    int i;
    fprintf(stderr, "RDK_LOG_DEBUG,\n\n b64 encoded data is : ");
    for(i = 0; i < encodeSize; i++)
        fprintf(stderr,"%c", b64buffer[i]);      

    fprintf(stderr,"\n\n");       
    }*/

    //CcspLMLiteTrace(("RDK_LOG_DEBUG,\nb64 encoded data length is %d\n",i));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,---------- End of Base64 Encode -------------\n"));
    // End of Base64 Encode
    
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,Destroying sbuf.....\n"));
    msgpack_sbuffer_destroy(&sbuf);
    
    //CcspLMLiteTrace(("RDK_LOG_DEBUG,Final Encoded data: %s\n",b64buffer));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,Final Encoded data length: %d\n",(int)strlen(b64buffer)));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,<======== End of packStructure ======>\n"));
    CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, LMLite %s EXIT\n", __FUNCTION__ ));

    return b64buffer;
}
Beispiel #15
0
    static rapidjson::Value* field2json(const Message *msg, const FieldDescriptor *field,
            rapidjson::Value::AllocatorType& allocator)
    {
        const Reflection *ref = msg->GetReflection();
        const bool repeated = field->is_repeated();

        size_t array_size = 0;
        if (repeated)
        {
            array_size = ref->FieldSize(*msg, field);
        }
        rapidjson::Value* json = NULL;
        if (repeated)
        {
            json = new rapidjson::Value(rapidjson::kArrayType);
        }
        switch (field->cpp_type())
        {
            case FieldDescriptor::CPPTYPE_DOUBLE:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        double value = ref->GetRepeatedDouble(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(ref->GetDouble(*msg, field));
                }
                break;
            case FieldDescriptor::CPPTYPE_FLOAT:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        float value = ref->GetRepeatedFloat(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(ref->GetFloat(*msg, field));
                }
                break;
            case FieldDescriptor::CPPTYPE_INT64:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        int64_t value = ref->GetRepeatedInt64(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(static_cast<int64_t>(ref->GetInt64(*msg, field)));
                }
                break;
            case FieldDescriptor::CPPTYPE_UINT64:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        uint64_t value = ref->GetRepeatedUInt64(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(static_cast<uint64_t>(ref->GetUInt64(*msg, field)));
                }
                break;
            case FieldDescriptor::CPPTYPE_INT32:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        int32_t value = ref->GetRepeatedInt32(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(ref->GetInt32(*msg, field));
                }
                break;
            case FieldDescriptor::CPPTYPE_UINT32:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        uint32_t value = ref->GetRepeatedUInt32(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(ref->GetUInt32(*msg, field));
                }
                break;
            case FieldDescriptor::CPPTYPE_BOOL:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        bool value = ref->GetRepeatedBool(*msg, field, i);
                        rapidjson::Value v(value);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(ref->GetBool(*msg, field));
                }
                break;
            case FieldDescriptor::CPPTYPE_STRING:
            {
                bool is_binary = field->type() == FieldDescriptor::TYPE_BYTES;
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        std::string value = ref->GetRepeatedString(*msg, field, i);
                        if (is_binary)
                        {
                            value = b64_encode(value);
                        }
                        rapidjson::Value v(value.c_str(), static_cast<rapidjson::SizeType>(value.size()), allocator);
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    std::string value = ref->GetString(*msg, field);
                    if (is_binary)
                    {
                        value = b64_encode(value);
                    }
                    json = new rapidjson::Value(value.c_str(), value.size(), allocator);
                }
                break;
            }
            case FieldDescriptor::CPPTYPE_MESSAGE:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        const Message *value = &(ref->GetRepeatedMessage(*msg, field, i));
                        rapidjson::Value* v = parse_msg(value, allocator);
                        json->PushBack(*v, allocator);
                        delete v;
                    }
                }
                else
                {
                    const Message *value = &(ref->GetMessage(*msg, field));
                    json = parse_msg(value, allocator);
                }
                break;
            case FieldDescriptor::CPPTYPE_ENUM:
                if (repeated)
                {
                    for (size_t i = 0; i != array_size; ++i)
                    {
                        const EnumValueDescriptor* value = ref->GetRepeatedEnum(*msg, field, i);
                        rapidjson::Value v(value->number());
                        json->PushBack(v, allocator);
                    }
                }
                else
                {
                    json = new rapidjson::Value(ref->GetEnum(*msg, field)->number());
                }
                break;
            default:
                break;
        }
        return json;
    }
WV_CencSingleSampleDecrypter::WV_CencSingleSampleDecrypter(std::string licenseURL, const uint8_t *pssh, size_t pssh_size)
  : AP4_CencSingleSampleDecrypter(0)
  , wv_adapter(0)
  , max_subsample_count_(0)
  , subsample_buffer_(0)
{
  uint8_t buf[1024];

  if (pssh_size > 256)
  {
    Log(SSD_HOST::LL_ERROR, "Init_data with length: %u seems not to be cenc init data!", pssh_size);
    return;
  }

  std::string strPath = host->GetDecrypterPath();
  if (strPath.empty())
  {
    Log(SSD_HOST::LL_ERROR, "Absolute path to widevine in settings expected");
    return;
  }
  strPath += WIDEVINECDMFILENAME;

  wv_adapter = new media::CdmAdapter("com.widevine.alpha", strPath.c_str(), media::CdmConfig());
  unsigned int buf_size = 32 + pssh_size;

  if (!wv_adapter->valid())
  {
    Log(SSD_HOST::LL_ERROR, "Unable to load widevine shared library (%s)", strPath.c_str());
    goto FAILURE;
  }

  // This will request a new session and initializes session_id and message members in cdm_adapter.
  // message will be used to create a license request in the step after CreateSession call.
  // Initialization data is the widevine cdm pssh code in google proto style found in mpd schemeIdUri
  static uint8_t proto[] = { 0x00, 0x00, 0x00, 0x63, 0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0xed, 0xef, 0x8b, 0xa9,
    0x79, 0xd6, 0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed, 0x00, 0x00, 0x00, 0x43 };

  memcpy(buf, proto, sizeof(proto));
  memcpy(&buf[32], pssh, pssh_size);

  wv_adapter->CreateSessionAndGenerateRequest(0, cdm::SessionType::kTemporary, cdm::InitDataType::kCenc, buf, buf_size);

  if (wv_adapter->SessionValid())
  {
    std::string license, challenge(b64_encode(wv_adapter->GetMessage(), wv_adapter->GetMessageSize(), true));
    challenge = "widevine2Challenge=" + challenge;
    challenge += "&includeHdcpTestKeyInLicense=true";

    // open the file
    void* file = host->CURLCreate(licenseURL.c_str());
    host->CURLAddOption(file, SSD_HOST::OPTION_PROTOCOL, "acceptencoding", "gzip");
    host->CURLAddOption(file, SSD_HOST::OPTION_PROTOCOL, "seekable", "0");
    host->CURLAddOption(file, SSD_HOST::OPTION_HEADER, "Content-Type", "application/x-www-form-urlencoded");

    size_t nbRead;
    std::string::size_type licStartPos, licEndPos;

    if (!host->CURLOpen(file, SSD_HOST::FILE_POST))
    {
      Log(SSD_HOST::LL_ERROR, "Failed to open CURL file");
      goto FAILURE;
    }

    if (size_t sz = host->WriteFile(file, challenge.c_str(), challenge.size()) != 200)
    {
      Log(SSD_HOST::LL_ERROR, "License server returned failure (%d)", static_cast<int>(sz));
      host->CloseFile(file);
      goto FAILURE;
    }

    // read the file
    while ((nbRead = host->ReadFile(file, buf, 1024)) > 0)
      license += std::string((const char*)buf,nbRead);

    host->CloseFile(file);

    if (nbRead != 0)
    {
      Log(SSD_HOST::LL_ERROR, "Could not read full license response");
      goto FAILURE;
    }

    licStartPos = license.find("\"license\":\"");
    if (licStartPos == std::string::npos)
    {
      Log(SSD_HOST::LL_ERROR, "License start position not found");
      goto FAILURE;
    }
    licStartPos += 11;
    licEndPos = license.find("\",", licStartPos);
    if (licEndPos == std::string::npos)
    {
      Log(SSD_HOST::LL_ERROR, "License end position not found");
      goto FAILURE;
    }

    buf_size = 1024;
    b64_decode(license.c_str() + licStartPos, licEndPos - licStartPos, buf, buf_size);
    wv_adapter->UpdateSession(buf, buf_size);

    if (!wv_adapter->KeyIdValid())
    {
      Log(SSD_HOST::LL_ERROR, "License update not successful");
      goto FAILURE;
    }
    // forbit auto delete for this object
    SetParentIsOwner(false);
    return;
  }
FAILURE:
  delete wv_adapter;
  wv_adapter = 0;
}
Beispiel #17
0
/* Prep and encrypt using gpgme
*/
static int
gpg_encrypt(fko_ctx_t ctx, const char *enc_key)
{
    int             res;
    char           *plain;
    int             pt_len, zero_free_rv = FKO_SUCCESS;
    char           *b64cipher;
    unsigned char  *cipher = NULL;
    size_t          cipher_len;
    char           *empty_key = "";

    if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
        return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL);

    switch(ctx->digest_len)
    {
        case MD5_B64_LEN:
            break;
        case SHA1_B64_LEN:
            break;
        case SHA256_B64_LEN:
            break;
        case SHA384_B64_LEN:
            break;
        case SHA512_B64_LEN:
            break;
        default:
            return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL);
    }

    /* First make sure we have a recipient key set.
    */
    if(ctx->gpg_recipient == NULL)
        return(FKO_ERROR_MISSING_GPG_KEY_DATA);

    pt_len = ctx->encoded_msg_len + ctx->digest_len + 2;

    /* Make a bucket big enough to hold the enc msg + digest (plaintext)
     * and populate it appropriately.
    */
    plain = malloc(ctx->encoded_msg_len + ctx->digest_len + 2);
    if(plain == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    pt_len = snprintf(plain, pt_len+1, "%s:%s", ctx->encoded_msg, ctx->digest);

    if(! is_valid_pt_msg_len(pt_len))
    {
        if(zero_free(plain, pt_len) == FKO_SUCCESS)
            return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL);
        else
            return(FKO_ERROR_ZERO_OUT_DATA);
    }

    if (enc_key != NULL)
    {
        res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len,
            enc_key, &cipher, &cipher_len
        );
    }
    else
    {
        res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len,
            empty_key, &cipher, &cipher_len
        );
    }

    /* --DSS XXX: Better parsing of what went wrong would be nice :)
    */
    if(res != FKO_SUCCESS)
    {
        zero_free_rv = zero_free(plain, pt_len);

        if(cipher != NULL)
            if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS)
                zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

        if(zero_free_rv == FKO_SUCCESS)
            return(res);
        else
            return(zero_free_rv);
    }

    /* Now make a bucket for the base64-encoded version and populate it.
    */
    b64cipher = malloc(((cipher_len / 3) * 4) + 8);
    if(b64cipher == NULL)
    {
        if(zero_free(plain, pt_len) != FKO_SUCCESS)
            zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

        if(cipher != NULL)
            if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS)
                zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

        if(zero_free_rv == FKO_SUCCESS)
            return(FKO_ERROR_MEMORY_ALLOCATION);
        else
            return(zero_free_rv);
    }

    b64_encode(cipher, b64cipher, cipher_len);
    strip_b64_eq(b64cipher);

    if(ctx->encrypted_msg != NULL)
        zero_free_rv = zero_free(ctx->encrypted_msg,
                strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE));

    ctx->encrypted_msg     = strdup(b64cipher);
    ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE);

    /* Clean-up
    */
    if(zero_free(plain, pt_len) != FKO_SUCCESS)
        zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

    if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS)
        zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

    if(zero_free(b64cipher, strnlen(b64cipher,
                    MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
        zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;

    if(ctx->encrypted_msg == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
        return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL);

    return(zero_free_rv);
}
Beispiel #18
0
int fko_set_spa_hmac(fko_ctx_t ctx,
    const char * const hmac_key, const int hmac_key_len)
{
    unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0};
    char *hmac_base64 = NULL;
    int   hmac_digest_str_len = 0;
    int   hmac_digest_len = 0;

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(hmac_key_len > MAX_DIGEST_BLOCK_LEN)
        return(FKO_ERROR_INVALID_HMAC_KEY_LEN);

    if(ctx->hmac_type == FKO_HMAC_MD5)
    {
        hmac_md5(ctx->encrypted_msg,
            ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);

        hmac_digest_len     = MD5_DIGEST_LEN;
        hmac_digest_str_len = MD5_DIGEST_STR_LEN;
    }
    else if(ctx->hmac_type == FKO_HMAC_SHA1)
    {
        hmac_sha1(ctx->encrypted_msg,
            ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);

        hmac_digest_len     = SHA1_DIGEST_LEN;
        hmac_digest_str_len = SHA1_DIGEST_STR_LEN;
    }
    else if(ctx->hmac_type == FKO_HMAC_SHA256)
    {
        hmac_sha256(ctx->encrypted_msg,
            ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);

        hmac_digest_len     = SHA256_DIGEST_LEN;
        hmac_digest_str_len = SHA256_DIGEST_STR_LEN;
    }
    else if(ctx->hmac_type == FKO_HMAC_SHA384)
    {
        hmac_sha384(ctx->encrypted_msg,
            ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);

        hmac_digest_len     = SHA384_DIGEST_LEN;
        hmac_digest_str_len = SHA384_DIGEST_STR_LEN;
    }
    else if(ctx->hmac_type == FKO_HMAC_SHA512)
    {
        hmac_sha512(ctx->encrypted_msg,
            ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);

        hmac_digest_len     = SHA512_DIGEST_LEN;
        hmac_digest_str_len = SHA512_DIGEST_STR_LEN;
    }

    hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1);
    if (hmac_base64 == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    b64_encode(hmac, hmac_base64, hmac_digest_len);
    strip_b64_eq(hmac_base64);

    if(ctx->msg_hmac != NULL)
        free(ctx->msg_hmac);

    ctx->msg_hmac     = strdup(hmac_base64);
    ctx->msg_hmac_len = strnlen(ctx->msg_hmac, hmac_digest_str_len);

    free(hmac_base64);

    switch(ctx->msg_hmac_len)
    {
        case MD5_B64_LEN:
            break;
        case SHA1_B64_LEN:
            break;
        case SHA256_B64_LEN:
            break;
        case SHA384_B64_LEN:
            break;
        case SHA512_B64_LEN:
            break;
        default:
            return(FKO_ERROR_INVALID_DATA);
    }

    return FKO_SUCCESS;
}
Beispiel #19
0
/* Provide an FKO wrapper around base64 encode/decode functions
*/
int
fko_base64_encode(unsigned char * const in, char * const out, int in_len)
{
    return b64_encode(in, out, in_len);
}