Esempio n. 1
0
/*
 * Decode a string to a key. Return 0 on success.
 */
int
kn_decode_key(struct keynote_deckey *dc, char *key, int keytype)
{
    void *kk = NULL;
    X509 *px509Cert;
    EVP_PKEY *pPublicKey;
    unsigned char *ptr = NULL, *decoded = NULL;
    int encoding, internalencoding;
    long len = 0;

    keynote_errno = 0;
    if (keytype == KEYNOTE_PRIVATE_KEY)
      dc->dec_algorithm = keynote_get_private_key_algorithm(key, &encoding,
							    &internalencoding);
    else
      dc->dec_algorithm = keynote_get_key_algorithm(key, &encoding,
						    &internalencoding);
    if (dc->dec_algorithm == KEYNOTE_ALGORITHM_NONE)
    {
	if ((dc->dec_key = strdup(key)) == NULL) {
	    keynote_errno = ERROR_MEMORY;
	    return -1;
	}

	return 0;
    }

    key = strchr(key, ':'); /* Move forward, to the Encoding. We're guaranteed
			    * to have a ':' character, since this is a key */
    key++;

    /* Remove ASCII encoding */
    switch (encoding)
    {
	case ENCODING_NONE:
	    break;

	case ENCODING_HEX:
            len = strlen(key) / 2;
	    if (kn_decode_hex(key, (char **) &decoded) != 0)
	      return -1;
	    ptr = decoded;
	    break;

	case ENCODING_BASE64:
	    len = strlen(key);
	    if (len % 4)  /* Base64 encoding must be a multiple of 4 */
	    {
		keynote_errno = ERROR_SYNTAX;
		return -1;
	    }

	    len = 3 * (len / 4);
	    decoded = calloc(len, sizeof(unsigned char));
	    ptr = decoded;
	    if (decoded == NULL) {
		keynote_errno = ERROR_MEMORY;
		return -1;
	    }

	    if ((len = kn_decode_base64(key, decoded, len)) == -1)
	      return -1;
	    break;

	case ENCODING_NATIVE:
	    decoded = strdup(key);
	    if (decoded == NULL) {
		keynote_errno = ERROR_MEMORY;
		return -1;
	    }
	    len = strlen(key);
	    ptr = decoded;
	    break;

	default:
	    keynote_errno = ERROR_SYNTAX;
	    return -1;
    }

    /* DSA-HEX */
    if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) &&
	(internalencoding == INTERNAL_ENC_ASN1))
    {
	dc->dec_key = DSA_new();
	if (dc->dec_key == NULL) {
	    keynote_errno = ERROR_MEMORY;
	    return -1;
	}

	kk = dc->dec_key;
	if (keytype == KEYNOTE_PRIVATE_KEY)
	{
	    if (d2i_DSAPrivateKey((DSA **) &kk,(const unsigned char **) &decoded, len) == NULL) {
		free(ptr);
		DSA_free(kk);
		keynote_errno = ERROR_SYNTAX; /* Could be a memory error */
		return -1;
	    }
	}
	else
	{
	    if (d2i_DSAPublicKey((DSA **) &kk, (const unsigned char **) &decoded, len) == NULL) {
		free(ptr);
		DSA_free(kk);
		keynote_errno = ERROR_SYNTAX; /* Could be a memory error */
		return -1;
	    }
	}

	free(ptr);

	return 0;
    }

    /* RSA-PKCS1-HEX */
    if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) &&
        (internalencoding == INTERNAL_ENC_PKCS1))
    {
        dc->dec_key = RSA_new();
        if (dc->dec_key == NULL) {
            keynote_errno = ERROR_MEMORY;
            return -1;
        }

        kk = dc->dec_key;
        if (keytype == KEYNOTE_PRIVATE_KEY)
        {
            if (d2i_RSAPrivateKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) {
                free(ptr);
                RSA_free(kk);
                keynote_errno = ERROR_SYNTAX; /* Could be a memory error */
                return -1;
            }
	    if (RSA_blinding_on((RSA *) kk, NULL) != 1) {
                free(ptr);
                RSA_free(kk);
                keynote_errno = ERROR_MEMORY;
                return -1;
	    }		
        }
        else
        {
            if (d2i_RSAPublicKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) {
                free(ptr);
                RSA_free(kk);
                keynote_errno = ERROR_SYNTAX; /* Could be a memory error */
                return -1;
            }
        }

        free(ptr);

        return 0;
    }

    /* X509 Cert */
    if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_X509) &&
	(internalencoding == INTERNAL_ENC_ASN1) &&
	(keytype == KEYNOTE_PUBLIC_KEY))
    {
	if ((px509Cert = X509_new()) == NULL) {
	    free(ptr);
	    keynote_errno = ERROR_MEMORY;
	    return -1;
	}

	if(d2i_X509(&px509Cert, (const unsigned char **)&decoded, len) == NULL)
	{
	    free(ptr);
	    X509_free(px509Cert);
	    keynote_errno = ERROR_SYNTAX;
	    return -1;
	}

	if ((pPublicKey = X509_get_pubkey(px509Cert)) == NULL) {
	    free(ptr);
	    X509_free(px509Cert);
	    keynote_errno = ERROR_SYNTAX;
	    return -1;
	}

	/* RSA-specific */
	dc->dec_key = pPublicKey->pkey.rsa;

	free(ptr);
	return 0;
    }    

    /* BINARY keys */
    if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) &&
	(internalencoding == INTERNAL_ENC_NONE))
    {
	dc->dec_key = calloc(1, sizeof(struct keynote_binary));
	if (dc->dec_key == NULL)
	{
	    keynote_errno = ERROR_MEMORY;
	    return -1;
	}

	((struct keynote_binary *) dc->dec_key)->bn_key = decoded;
	((struct keynote_binary *) dc->dec_key)->bn_len = len;
	return RESULT_TRUE;
    }

    /* Add support for more algorithms here */

    free(ptr);

    /* This shouldn't ever be reached really */
    keynote_errno = ERROR_SYNTAX;
    return -1;
}
Esempio n. 2
0
/*
 * Verify the signature on an assertion; return SIGRESULT_TRUE is
 * success, SIGRESULT_FALSE otherwise.
 */
int
keynote_sigverify_assertion(struct assertion *as)
{
    int hashtype, enc, intenc, alg = KEYNOTE_ALGORITHM_NONE, hashlen = 0;
    unsigned char *sig, *decoded = NULL, *ptr;
    unsigned char res2[20];
    SHA_CTX shscontext;
    MD5_CTX md5context;
    int len = 0;
    DSA *dsa;
    RSA *rsa;
    if (as->as_signature == NULL ||
	as->as_startofsignature == NULL ||
	as->as_allbutsignature == NULL ||
	as->as_allbutsignature - as->as_startofsignature <= 0)
      return SIGRESULT_FALSE;

    alg = keynote_get_sig_algorithm(as->as_signature, &hashtype, &enc,
				    &intenc);
    if (alg == KEYNOTE_ALGORITHM_NONE)
      return SIGRESULT_FALSE;

    /* Check for matching algorithms */
    if ((alg != as->as_signeralgorithm) &&
	!((alg == KEYNOTE_ALGORITHM_RSA) &&
	  (as->as_signeralgorithm == KEYNOTE_ALGORITHM_X509)) &&
	!((alg == KEYNOTE_ALGORITHM_X509) &&
	  (as->as_signeralgorithm == KEYNOTE_ALGORITHM_RSA)))
      return SIGRESULT_FALSE;

    sig = strchr(as->as_signature, ':');   /* Move forward to the Encoding. We
					   * are guaranteed to have a ':'
					   * character, since this is a valid
					   * signature */
    sig++;

    switch (hashtype)
    {
	case KEYNOTE_HASH_SHA1:
	    hashlen = 20;
	    memset(res2, 0, hashlen);
	    SHA1_Init(&shscontext);
	    SHA1_Update(&shscontext, as->as_startofsignature,
			as->as_allbutsignature - as->as_startofsignature);
	    SHA1_Update(&shscontext, as->as_signature, 
			(char *) sig - as->as_signature);
	    SHA1_Final(res2, &shscontext);
	    break;
	    
	case KEYNOTE_HASH_MD5:
	    hashlen = 16;
	    memset(res2, 0, hashlen);
	    MD5_Init(&md5context);
	    MD5_Update(&md5context, as->as_startofsignature,
		       as->as_allbutsignature - as->as_startofsignature);
	    MD5_Update(&md5context, as->as_signature,
		       (char *) sig - as->as_signature);
	    MD5_Final(res2, &md5context);
	    break;

	case KEYNOTE_HASH_NONE:
	    break;
    }

    /* Remove ASCII encoding */
    switch (enc)
    {
	case ENCODING_NONE:
	    ptr = NULL;
	    break;

	case ENCODING_HEX:
	    len = strlen(sig) / 2;
	    if (kn_decode_hex(sig, (char **) &decoded) != 0)
	      return -1;
	    ptr = decoded;
	    break;

	case ENCODING_BASE64:
	    len = strlen(sig);
	    if (len % 4)  /* Base64 encoding must be a multiple of 4 */
	    {
		keynote_errno = ERROR_SYNTAX;
		return -1;
	    }

	    len = 3 * (len / 4);
	    decoded = calloc(len, sizeof(unsigned char));
	    ptr = decoded;
	    if (decoded == NULL) {
		keynote_errno = ERROR_MEMORY;
		return -1;
	    }

	    len = kn_decode_base64(sig, decoded, len);
	    if ((len == -1) || (len == 0) || (len == 1))
	      return -1;
	    break;

	case ENCODING_NATIVE:
	    
	    if ((decoded = strdup(sig)) == NULL) {
		keynote_errno = ERROR_MEMORY;
		return -1;
	    }
	    len = strlen(sig);
	    ptr = decoded;
	    break;

	default:
	    keynote_errno = ERROR_SYNTAX;
	    return -1;
    }

    /* DSA */
    if ((alg == KEYNOTE_ALGORITHM_DSA) && (intenc == INTERNAL_ENC_ASN1))
    {
	dsa = (DSA *) as->as_authorizer;
	if (DSA_verify(0, res2, hashlen, decoded, len, dsa) == 1) {
	    free(ptr);
	    return SIGRESULT_TRUE;
	}
    }
    else /* RSA */
      if ((alg == KEYNOTE_ALGORITHM_RSA) && (intenc == INTERNAL_ENC_PKCS1))
      {
          rsa = (RSA *) as->as_authorizer;
          if (RSA_verify_ASN1_OCTET_STRING(RSA_PKCS1_PADDING, res2, hashlen,
					   decoded, len, rsa) == 1) {
              free(ptr);
              return SIGRESULT_TRUE;
          }
      }
      else
	if ((alg == KEYNOTE_ALGORITHM_X509) && (intenc == INTERNAL_ENC_ASN1))
	{
	    /* RSA-specific */
	    rsa = (RSA *) as->as_authorizer;
	    if (RSA_verify(NID_shaWithRSAEncryption, res2, hashlen, decoded,
			   len, rsa) == 1) {
		free(ptr);
		return SIGRESULT_TRUE;
	    }
	}
    
    /* Handle more algorithms here */
    
    free(ptr);

    return SIGRESULT_FALSE;
}
Esempio n. 3
0
/*
 * add_variable -- add variable to current session
 *
 *	if all OK returns 0, otherwise it returns a 
 *	negative number that tells you where it got
 *	lost.
 */
int add_variables(int sessionid, char *pbuf)
{
	char *vp;
	char *dec_p;	// decoded array
	struct vp_offer *ofp;
	int n_vars;	// retrieved number of variable, value pairs
	int e_vars;	// estimated number according to buffer size
			// (includes __END__ pair, so
			// its one item bigger than the actual number
	int rval;

	while (*pbuf == ' ' || *pbuf == '\n' || *pbuf == '\t')
		pbuf++;

	if ((rval = kn_decode_hex(pbuf, &dec_p)) < 0) {
		fprintf(stderr, "add_variables: kn_decode_hex(%d), "
		    "returned %d, error %d.\n",  strlen(pbuf), rval, keynote_errno);
		fprintf(stderr, "buffer: <<<%s>>>\n", pbuf);
		return(-1);
	}
	if (dec_p == NULL) {
		fprintf(stderr, "process_offer: kn_decode_hex returned NULL ???\n");
		return(-2);
	}

	if ((e_vars =  strlen(pbuf)/2) % sizeof(struct vp_offer) != 0)
		fprintf(stderr, "warning: len (%d) not a multiple of vp_offer"
		    "(%d)\n\tbuf = <<%s>>\n", e_vars, sizeof(struct vp_offer), dec_p);
	e_vars = e_vars/sizeof(struct vp_offer);        // est. number of variables

	for (ofp = (struct vp_offer *)dec_p, n_vars = 0;
	    strncmp(ENDOFLIST, ofp->o_nam,  strlen(ENDOFLIST)) != 0; ofp++, n_vars++) {
		if (n_vars >= e_vars) {
			fprintf(stderr, "process_offer: too many variables\n");
			break;
		}
		printf("\t%s = \"%s\"\n", ofp->o_nam, ofp->o_val);
		if (kn_add_action(sessionid, ofp->o_nam, ofp->o_val, 0) == -1)
		{
			switch (keynote_errno)
			{
			    case ERROR_SYNTAX:
				fprintf(stderr, "Invalid name action attribute name "
					"[%s]\n", ofp->o_nam);
				break;

			    case ERROR_MEMORY:
				fprintf(stderr, "Out of mem adding action attribute "
					"[%s = \"%s\"]\n", ofp->o_nam, ofp->o_val);
				break;

			    case ERROR_NOTFOUND:
				fprintf(stderr, "Session %d not found while "
				    "addiing action " "attribute [%s = \"%s\"]\n",
				    sessionid, ofp->o_nam, ofp->o_val);
				break;

			    default:
				fprintf(stderr, "Can't happen error %d while adding"
				    "action attribute [%s = \"%s\"]\n",
				    keynote_errno, ofp->o_nam, ofp->o_val);
				break;
			}
			return(-4);
		}
	}
	return(0);
}