示例#1
0
/*
 * Same as keynote_get_key_algorithm(), only verify that this is
 * a private key (just look at the prefix).
 */
static int
keynote_get_private_key_algorithm(char *key, int *encoding,
				  int *internalencoding)
{
    if (strncasecmp(KEYNOTE_PRIVATE_KEY_PREFIX, key, 
		    KEYNOTE_PRIVATE_KEY_PREFIX_LEN))
    {
	*internalencoding = INTERNAL_ENC_NONE;
	*encoding = ENCODING_NONE;
	return KEYNOTE_ALGORITHM_NONE;
    }

    return keynote_get_key_algorithm(key + KEYNOTE_PRIVATE_KEY_PREFIX_LEN,
				     encoding, internalencoding);
}
示例#2
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;
}
示例#3
0
void
keynote_keygen(int argc, char *argv[])
{
    int begin = KEY_PRINT_OFFSET, prlen = KEY_PRINT_LENGTH;
    char *foo, *privalgname, seed[SEED_LEN];
    int alg, enc, ienc, len = 0, counter;
    struct keynote_deckey dc;
    unsigned long h;
    DSA *dsa;
    RSA *rsa;
    FILE *fp;
    char *algname;

    if ((argc != 5) && (argc != 6) && (argc != 7))
    {
	keygenusage();
	exit(0);
    }

    /* Fix algorithm name */
    if (argv[1][strlen(argv[1]) - 1] != ':')
    {
	int len = strlen(argv[1]) + 2;

        fprintf(stderr, "Algorithm name [%s] should be terminated with a "
		"colon, fixing.\n", argv[1]);
	algname = (char *) calloc(len, sizeof(char));
	if (algname == (char *) NULL)
	{
	    perror("calloc()");
	    exit(1);
	}

	strlcpy(algname, argv[1], len);
	algname[strlen(algname)] = ':';
    }
    else
	algname = argv[1];

    if (argc > 5)
    {
	begin = atoi(argv[5]);
	if (begin <= -1)
	{
	    fprintf(stderr, "Erroneous value for print-offset parameter.\n");
	    exit(1);
	}
    }

    if (argc > 6)
    {
	prlen = atoi(argv[6]);
	if (prlen <= 0)
	{
	    fprintf(stderr, "Erroneous value for print-length parameter.\n");
	    exit(1);
	}
    }

    if (strlen(algname) + 2 > prlen)
    {
	fprintf(stderr, "Parameter ``print-length'' should be larger "
		"than the length of AlgorithmName (%lu)\n",
		(unsigned long) strlen(algname));
	exit(1);
    }

    alg = keynote_get_key_algorithm(algname, &enc, &ienc);
    len = atoi(argv[2]);

    if (len <= 0)
    {
	fprintf(stderr, "Invalid specified keysize %d\n", len);
	exit(1);
    }

    if ((alg == KEYNOTE_ALGORITHM_DSA) &&
	(ienc == INTERNAL_ENC_ASN1) &&
	((enc == ENCODING_HEX) || (enc == ENCODING_BASE64)))
    {
        RAND_bytes(seed, SEED_LEN);

	dsa = DSA_generate_parameters(len, seed, SEED_LEN, &counter, &h, NULL
				      , NULL);

	if (dsa == (DSA *) NULL)
	{
	    ERR_print_errors_fp(stderr);
	    exit(1);
	}

	if (DSA_generate_key(dsa) != 1)
	{
	    ERR_print_errors_fp(stderr);
	    exit(1);
	}

	dc.dec_algorithm = KEYNOTE_ALGORITHM_DSA;
	dc.dec_key = (void *) dsa;

	foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PUBLIC_KEY);
	if (foo == (char *) NULL)
	{
	    fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno);
	    exit(1);
	}

	if (!strcmp(argv[3], "-"))
	  fp = stdout;
	else
	{
	    fp = fopen(argv[3], "w");
	    if (fp == (FILE *) NULL)
	    {
		perror(argv[3]);
		exit(1);
	    }
	}

	print_key(fp, algname, foo, begin, prlen);
	free(foo);

	if (strcmp(argv[3], "-"))
	  fclose(fp);

	foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PRIVATE_KEY);
	if (foo == (char *) NULL)
	{
	    fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno);
	    exit(1);
	}

	if (!strcmp(argv[4], "-"))
	{
	    fp = stdout;
	    if (!strcmp(argv[3], "-"))
	      printf("===========================\n");
	}
	else
	{
	    fp = fopen(argv[4], "w");
	    if (fp == (FILE *) NULL)
	    {
		perror(argv[4]);
		exit(1);
	    }
	}

	len = strlen(KEYNOTE_PRIVATE_KEY_PREFIX) + strlen(foo) + 1;
	privalgname = (char *) calloc(len, sizeof(char));
	if (privalgname == (char *) NULL)
	{
	    perror("calloc()");
	    exit(1);
	}
	snprintf(privalgname, len, "%s%s", KEYNOTE_PRIVATE_KEY_PREFIX, algname);
	print_key(fp, privalgname, foo, begin, prlen);
	free(privalgname);
	free(foo);

	if (strcmp(argv[4], "-"))
	  fclose(fp);

	exit(0);
    }

    if ((alg == KEYNOTE_ALGORITHM_RSA) &&
	(ienc == INTERNAL_ENC_PKCS1) &&
	((enc == ENCODING_HEX) || (enc == ENCODING_BASE64)))
    {
	rsa = RSA_generate_key(len, DEFAULT_PUBLIC, NULL, NULL);

	if (rsa == (RSA *) NULL)
	{
	    ERR_print_errors_fp(stderr);
	    exit(1);
	}

	dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
	dc.dec_key = (void *) rsa;

	foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PUBLIC_KEY);
	if (foo == (char *) NULL)
	{
	    fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno);
	    exit(1);
	}

	if (!strcmp(argv[3], "-"))
	  fp = stdout;
	else
	{
	    fp = fopen(argv[3], "w");
	    if (fp == (FILE *) NULL)
	    {
		perror(argv[3]);
		exit(1);
	    }
	}

	print_key(fp, algname, foo, begin, prlen);
	free(foo);

	if (strcmp(argv[3], "-"))
	  fclose(fp);

	foo = kn_encode_key(&dc, ienc, enc, KEYNOTE_PRIVATE_KEY);
	if (foo == (char *) NULL)
	{
	    fprintf(stderr, "Error encoding key (errno %d)\n", keynote_errno);
	    exit(1);
	}

	if (!strcmp(argv[4], "-"))
	{
	    fp = stdout;
	    if (!strcmp(argv[3], "-"))
	      printf("===========================\n");
	}
	else
	{
	    fp = fopen(argv[4], "w");
	    if (fp == (FILE *) NULL)
	    {
		perror(argv[4]);
		exit(1);
	    }
	}

	len = strlen(KEYNOTE_PRIVATE_KEY_PREFIX) + strlen(foo) + 1;
	privalgname = (char *) calloc(len, sizeof(char));
	if (privalgname == (char *) NULL)
	{
	    perror("calloc()");
	    exit(1);
	}
	snprintf(privalgname, len, "%s%s", KEYNOTE_PRIVATE_KEY_PREFIX, algname);
	print_key(fp, privalgname, foo, begin, prlen);
	free(privalgname);
	free(foo);

	if (strcmp(argv[4], "-"))
	  fclose(fp);

	exit(0);
    }

    /* More algorithms here */

    fprintf(stderr, "Unknown/unsupported algorithm [%s]\n", algname);
    exit(1);
}