예제 #1
0
static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx)
	{
	int ret = 1;
	/* Check again inside the lock - the macro's check is racey */
	if(rsa->blinding == NULL)
		ret = RSA_blinding_on(rsa, ctx);
	return ret;
	}
예제 #2
0
Key *
key_load_private_pem(int fd, int type, const char *passphrase,
                     char **commentp)
{
    FILE *fp;
    EVP_PKEY *pk = NULL;
    Key *prv = NULL;
    char *name = "<no key>";

    fp = fdopen(fd, "r");
    if (fp == NULL) {
        error("fdopen failed: %s", strerror(errno));
        close(fd);
        return NULL;
    }
    pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
    if (pk == NULL) {
        debug("PEM_read_PrivateKey failed");
        (void)ERR_get_error();
    } else if (pk->type == EVP_PKEY_RSA &&
               (type == KEY_UNSPEC||type==KEY_RSA)) {
        prv = key_new(KEY_UNSPEC);
        prv->rsa = EVP_PKEY_get1_RSA(pk);
        prv->type = KEY_RSA;
        name = "rsa w/o comment";
#ifdef DEBUG_PK
        RSA_print_fp(stderr, prv->rsa, 8);
#endif
        if (RSA_blinding_on(prv->rsa, NULL) != 1) {
            error("key_load_private_pem: RSA_blinding_on failed");
            key_free(prv);
            prv = NULL;
        }
    } else if (pk->type == EVP_PKEY_DSA &&
               (type == KEY_UNSPEC||type==KEY_DSA)) {
        prv = key_new(KEY_UNSPEC);
        prv->dsa = EVP_PKEY_get1_DSA(pk);
        prv->type = KEY_DSA;
        name = "dsa w/o comment";
#ifdef DEBUG_PK
        DSA_print_fp(stderr, prv->dsa, 8);
#endif
    } else {
        error("PEM_read_PrivateKey: mismatch or "
              "unknown EVP_PKEY save_type %d", pk->save_type);
    }
    fclose(fp);
    if (pk != NULL)
        EVP_PKEY_free(pk);
    if (prv != NULL && commentp)
        *commentp = xstrdup(name);
    debug("read PEM private key done: type %s",
          prv ? key_type(prv) : "<unknown>");
    return prv;
}
/* reusable init */
void RSASigner::signerInit(
	const Context 	&context,
	bool			isSigning)
{
	StLock<Mutex> _(gMutex());

	setIsSigning(isSigning);
	keyFromContext(context);
	
	/* optional padding attribute */
	uint32 padding;
	bool padPresent = context.getInt(CSSM_ATTRIBUTE_PADDING, padding);
	if(padPresent) {
		/* padding specified in context, convert to openssl style */
		switch(padding) {
			case CSSM_PADDING_NONE:
				mPadding = RSA_NO_PADDING;
				break;
			case CSSM_PADDING_PKCS1:
				mPadding = RSA_PKCS1_PADDING;
				break;
			default:
				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
		}
	}
	
	/* optional blinding attribute */
	uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING);
	if(blinding) {
		if(RSA_blinding_on(mRsaKey, NULL) <= 0) {
			/* actually no legit failures */
			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
		}
	}
	else {
		RSA_blinding_off(mRsaKey);
	}

	setInitFlag(true);
}
예제 #4
0
static int
sshkey_parse_private_pem(struct sshbuf *blob, int type, const char *passphrase,
    struct sshkey **keyp, char **commentp)
{
	EVP_PKEY *pk = NULL;
	struct sshkey *prv = NULL;
	char *name = "<no key>";
	BIO *bio = NULL;
	int r;

	*keyp = NULL;
	if (commentp != NULL)
		*commentp = NULL;

	if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
		return SSH_ERR_ALLOC_FAIL;
	if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
	    (int)sshbuf_len(blob)) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	
	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
	    (char *)passphrase)) == NULL) {
		r = SSH_ERR_KEY_WRONG_PASSPHRASE;
		goto out;
	}
	if (pk->type == EVP_PKEY_RSA &&
	    (type == KEY_UNSPEC || type == KEY_RSA)) {
		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		prv->rsa = EVP_PKEY_get1_RSA(pk);
		prv->type = KEY_RSA;
		name = "rsa w/o comment";
#ifdef DEBUG_PK
		RSA_print_fp(stderr, prv->rsa, 8);
#endif
		if (RSA_blinding_on(prv->rsa, NULL) != 1) {
			r = SSH_ERR_LIBCRYPTO_ERROR;
			goto out;
		}
	} else if (pk->type == EVP_PKEY_DSA &&
	    (type == KEY_UNSPEC || type == KEY_DSA)) {
		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		prv->dsa = EVP_PKEY_get1_DSA(pk);
		prv->type = KEY_DSA;
		name = "dsa w/o comment";
#ifdef DEBUG_PK
		DSA_print_fp(stderr, prv->dsa, 8);
#endif
	} else if (pk->type == EVP_PKEY_EC &&
	    (type == KEY_UNSPEC || type == KEY_ECDSA)) {
		if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
		prv->type = KEY_ECDSA;
		prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
		if (prv->ecdsa_nid == -1 ||
		    sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
		    sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
		    EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
		    sshkey_ec_validate_private(prv->ecdsa) != 0) {
			r = SSH_ERR_INVALID_FORMAT;
			goto out;
		}
		name = "ecdsa w/o comment";
#ifdef DEBUG_PK
		if (prv != NULL && prv->ecdsa != NULL)
			sshkey_dump_ec_key(prv->ecdsa);
#endif
	} else {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if (commentp != NULL &&
	    (*commentp = strdup(name)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	r = 0;
	*keyp = prv;
	prv = NULL;
 out:
	BIO_free(bio);
	if (pk != NULL)
		EVP_PKEY_free(pk);
	if (prv != NULL)
		sshkey_free(prv);
	return r;
}
예제 #5
0
static int
sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase,
    struct sshkey **keyp, char **commentp)
{
	int r;
	u_int16_t check1, check2;
	u_int8_t cipher_type;
	struct sshbuf *decrypted = NULL, *copy = NULL;
	u_char *cp;
	char *comment = NULL;
	struct sshcipher_ctx ciphercontext;
	const struct sshcipher *cipher;
	struct sshkey *prv = NULL;

	*keyp = NULL;
	if (commentp != NULL)
		*commentp = NULL;

	/* Check that it is at least big enough to contain the ID string. */
	if (sshbuf_len(blob) < sizeof(authfile_id_string))
		return SSH_ERR_INVALID_FORMAT;

	/*
	 * Make sure it begins with the id string.  Consume the id string
	 * from the buffer.
	 */
	if (memcmp(sshbuf_ptr(blob), authfile_id_string,
	    sizeof(authfile_id_string)) != 0)
		return SSH_ERR_INVALID_FORMAT;

	if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((copy = sshbuf_fromb(blob)) == NULL ||
	    (decrypted = sshbuf_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshbuf_consume(copy, sizeof(authfile_id_string))) != 0)
		goto out;

	/* Read cipher type. */
	if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 ||
	    (r = sshbuf_get_u32(copy, NULL)) != 0)	/* reserved */
		goto out;

	/* Read the public key and comment from the buffer. */
	if ((r = sshbuf_get_u32(copy, NULL)) != 0 ||	/* key bits */
	    (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||
	    (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||
	    (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)
		goto out;

	/* Check that it is a supported cipher. */
	cipher = cipher_by_number(cipher_type);
	if (cipher == NULL) {
		r = SSH_ERR_KEY_UNKNOWN_CIPHER;
		goto out;
	}
	/* Initialize space for decrypted data. */
	if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0)
		goto out;

	/* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
	if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
	    CIPHER_DECRYPT)) != 0)
		goto out;
	if ((r = cipher_crypt(&ciphercontext, cp,
	    sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) {
		cipher_cleanup(&ciphercontext);
		goto out;
	}
	if ((r = cipher_cleanup(&ciphercontext)) != 0)
		goto out;

	if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 ||
	    (r = sshbuf_get_u16(decrypted, &check2)) != 0)
		goto out;
	if (check1 != check2) {
		r = SSH_ERR_KEY_WRONG_PASSPHRASE;
		goto out;
	}

	/* Read the rest of the private key. */
	if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||
	    (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||
	    (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||
	    (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)
		goto out;

	/* calculate p-1 and q-1 */
	if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
		goto out;

	/* enable blinding */
	if (RSA_blinding_on(prv->rsa, NULL) != 1) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	r = 0;
	*keyp = prv;
	prv = NULL;
	if (commentp != NULL) {
		*commentp = comment;
		comment = NULL;
	}
 out:
	bzero(&ciphercontext, sizeof(ciphercontext));
	if (comment != NULL)
		free(comment);
	if (prv != NULL)
		sshkey_free(prv);
	if (copy != NULL)
		sshbuf_free(copy);
	if (decrypted != NULL)
		sshbuf_free(decrypted);
	return r;
}
예제 #6
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;
}
예제 #7
0
int check_validity_of_cert(
    const char *cFile, const unsigned char *md5_md, unsigned char *sfileMsg,
    const int sfsize, const char* caPath
) {
    int retval = 0;
    X509 *cert;
    X509_STORE *store;
    X509_LOOKUP *lookup;
    X509_STORE_CTX *ctx = 0;
    EVP_PKEY *pubKey;
    BIO *bio;

    bio = BIO_new(BIO_s_file());
    BIO_read_filename(bio, cFile);
    if (NULL == (cert = PEM_read_bio_X509(bio, NULL, 0, NULL))) {
	    BIO_vfree(bio);
	    return 0;
    }
    // verify certificate
    store = X509_STORE_new();
    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
    X509_LOOKUP_add_dir(lookup, (char *)caPath, X509_FILETYPE_PEM);
    if ((ctx = X509_STORE_CTX_new()) != 0) {
        if (X509_STORE_CTX_init(ctx, store, cert, 0) == 1)
            retval = X509_verify_cert(ctx);
        X509_STORE_CTX_free(ctx);
    }
    X509_STORE_free(store);
    
    if (retval != 1) {
        fprintf(stderr,"ERROR: Cannot verify certificate ('%s')\n", cFile);
        return 0;
    }        
    pubKey = X509_get_pubkey(cert);
    if (!pubKey) {
        X509_free(cert);
        BIO_vfree(bio);
        return 0;
    }
    if (pubKey->type == EVP_PKEY_RSA) {
        BN_CTX *c = BN_CTX_new();
        if (!c) {
	        X509_free(cert);
	        EVP_PKEY_free(pubKey);
	        BIO_vfree(bio);
	        return 0;
	    }
	    if (!RSA_blinding_on(pubKey->pkey.rsa, c)) {
	        X509_free(cert);
	        EVP_PKEY_free(pubKey);
	        BIO_vfree(bio);
	        BN_CTX_free(c);
	        return 0;
	    }
	    retval = RSA_verify(NID_md5, md5_md, MD5_DIGEST_LENGTH, sfileMsg, sfsize, pubKey->pkey.rsa);
	    RSA_blinding_off(pubKey->pkey.rsa);
	    BN_CTX_free(c);
    }
    if (pubKey->type == EVP_PKEY_DSA) {
        fprintf(stderr, "ERROR: DSA keys are not supported.\n");
        return 0;
    }
    EVP_PKEY_free(pubKey);
    X509_free(cert);
    BIO_vfree(bio);
    return retval;
}
예제 #8
0
/* called by CSPFullPluginSession */
void RSA_CryptContext::init(const Context &context, bool encoding /*= true*/)
{
	StLock<Mutex> _(gMutex());
	
	if(mInitFlag && !opStarted()) {
		/* reusing - e.g. query followed by encrypt */
		return;
	}

	/* optional mode to use alternate key class (e.g., decrypt with public key) */
	CSSM_KEYCLASS  keyClass;
    switch (context.getInt(CSSM_ATTRIBUTE_MODE)) {
        case CSSM_ALGMODE_PUBLIC_KEY:
			keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
            break;
        case CSSM_ALGMODE_PRIVATE_KEY:
			keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
            break;
        case CSSM_ALGMODE_NONE:	
			/* default, not present in context: infer from op type */
			keyClass = encoding ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY;
			break;
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE);
	}
	
	/* fetch key from context */
	if(mRsaKey == NULL) {
		assert(!opStarted());
		CSSM_DATA label = {0, NULL};
		mRsaKey = contextToRsaKey(context,
			session(),
			keyClass,
			encoding ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
			mAllocdRsaKey,
			label);
		if(label.Data) {
			mLabel.copy(label);
			mOaep = true;
			free(label.Data);
		}
	}
	else {
		assert(opStarted());	
	}

	unsigned cipherBlockSize = RSA_size(mRsaKey);
	unsigned plainBlockSize;

	/* padding - not present means value zero, CSSM_PADDING_NONE */
	uint32 padding = context.getInt(CSSM_ATTRIBUTE_PADDING);
	switch(padding) {
		case CSSM_PADDING_NONE:
			mPadding = RSA_NO_PADDING;
			plainBlockSize = cipherBlockSize;
			break;
		case CSSM_PADDING_PKCS1:
			mPadding = RSA_PKCS1_PADDING;
			plainBlockSize = cipherBlockSize - 11;
			break;
		case CSSM_PADDING_APPLE_SSLv2:
			rsaCryptDebug("RSA_CryptContext::init using CSSM_PADDING_APPLE_SSLv2");
			mPadding = RSA_SSLV23_PADDING;
			plainBlockSize = cipherBlockSize - 11;
			break;
		default:
			rsaCryptDebug("RSA_CryptContext::init bad padding (0x%x)",
				(unsigned)padding);
			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
	}
	
	/* optional blinding attribute */
	uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING);
	if(blinding) {
		if(RSA_blinding_on(mRsaKey, NULL) <= 0) {
			/* actually no legit failures */
			CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
		}
	}
	else {
		RSA_blinding_off(mRsaKey);
	}

	/* finally, have BlockCryptor set up its stuff. */
	setup(encoding ? plainBlockSize  : cipherBlockSize, // blockSizeIn
		  encoding ? cipherBlockSize : plainBlockSize,	// blockSizeOut
		  false,										// pkcs5Pad
		  false,										// needsFinal
		  BCM_ECB,
		  NULL);											// IV
	mInitFlag = true;

}
예제 #9
0
// Signing functions
bool OSSLRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
		   ByteString& signature, const AsymMech::Type mechanism,
		   const void* param /* = NULL */, const size_t paramLen /* = 0 */)
{
	if (mechanism == AsymMech::RSA_PKCS)
	{
		// Separate implementation for RSA PKCS #1 signing without hash computation

		// Check if the private key is the right type
		if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
		{
			ERROR_MSG("Invalid key type supplied");

			return false;
		}

		// In case of PKCS #1 signing the length of the input data may not exceed 40% of the
		// modulus size
		OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;

		size_t allowedLen = osslKey->getN().size() - 11;

		if (dataToSign.size() > allowedLen)
		{
			ERROR_MSG("Data to sign exceeds maximum for PKCS #1 signature");

			return false;
		}

		// Perform the signature operation
		signature.resize(osslKey->getN().size());

		RSA* rsa = osslKey->getOSSLKey();

		if (!RSA_blinding_on(rsa, NULL))
		{
			ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");

			return false;
		}

		int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_PKCS1_PADDING);

		RSA_blinding_off(rsa);

		if (sigLen == -1)
		{
			ERROR_MSG("An error occurred while performing a PKCS #1 signature");

			return false;
		}

		signature.resize(sigLen);

		return true;
	}
	else if (mechanism == AsymMech::RSA)
	{
		// Separate implementation for raw RSA signing

		// Check if the private key is the right type
		if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
		{
			ERROR_MSG("Invalid key type supplied");

			return false;
		}

		// In case of raw RSA, the length of the input data must match the length of the modulus
		OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;

		if (dataToSign.size() != osslKey->getN().size())
		{
			ERROR_MSG("Size of data to sign does not match the modulus size");

			return false;
		}

		// Perform the signature operation
		signature.resize(osslKey->getN().size());

		RSA* rsa = osslKey->getOSSLKey();

		if (!RSA_blinding_on(rsa, NULL))
		{
			ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");

			return false;
		}

		int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_NO_PADDING);

		RSA_blinding_off(rsa);

		if (sigLen == -1)
		{
			ERROR_MSG("An error occurred while performing a raw RSA signature");

			return false;
		}

		signature.resize(sigLen);

		return true;
	}
	else
	{
		// Call default implementation
		return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
	}
}
예제 #10
0
static Key *
key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
                      char **commentp)
{
    int i, check1, check2, cipher_type;
    off_t len;
    Buffer buffer, decrypted;
    u_char *cp;
    CipherContext ciphercontext;
    Cipher *cipher;
    Key *prv = NULL;
    struct stat st;

    if (fstat(fd, &st) < 0) {
        error("fstat for key file %.200s failed: %.100s",
              filename, strerror(errno));
        close(fd);
        return NULL;
    }
    len = st.st_size;

    buffer_init(&buffer);
    cp = buffer_append_space(&buffer, len);

    if (read(fd, cp, (size_t) len) != (size_t) len) {
        debug("Read from key file %.200s failed: %.100s", filename,
              strerror(errno));
        buffer_free(&buffer);
        close(fd);
        return NULL;
    }

    /* Check that it is at least big enough to contain the ID string. */
    if (len < sizeof(authfile_id_string)) {
        debug3("Not a RSA1 key file %.200s.", filename);
        buffer_free(&buffer);
        close(fd);
        return NULL;
    }
    /*
     * Make sure it begins with the id string.  Consume the id string
     * from the buffer.
     */
    for (i = 0; i < sizeof(authfile_id_string); i++)
        if (buffer_get_char(&buffer) != authfile_id_string[i]) {
            debug3("Not a RSA1 key file %.200s.", filename);
            buffer_free(&buffer);
            close(fd);
            return NULL;
        }

    /* Read cipher type. */
    cipher_type = buffer_get_char(&buffer);
    (void) buffer_get_int(&buffer);	/* Reserved data. */

    /* Read the public key from the buffer. */
    (void) buffer_get_int(&buffer);
    prv = key_new_private(KEY_RSA1);

    buffer_get_bignum(&buffer, prv->rsa->n);
    buffer_get_bignum(&buffer, prv->rsa->e);
    if (commentp)
        *commentp = buffer_get_string(&buffer, NULL);
    else
        xfree(buffer_get_string(&buffer, NULL));

    /* Check that it is a supported cipher. */
    cipher = cipher_by_number(cipher_type);
    if (cipher == NULL) {
        debug("Unsupported cipher %d used in key file %.200s.",
              cipher_type, filename);
        buffer_free(&buffer);
        goto fail;
    }
    /* Initialize space for decrypted data. */
    buffer_init(&decrypted);
    cp = buffer_append_space(&decrypted, buffer_len(&buffer));

    /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
    cipher_set_key_string(&ciphercontext, cipher, passphrase,
                          CIPHER_DECRYPT);
    cipher_crypt(&ciphercontext, cp,
                 buffer_ptr(&buffer), buffer_len(&buffer));
    cipher_cleanup(&ciphercontext);
    memset(&ciphercontext, 0, sizeof(ciphercontext));
    buffer_free(&buffer);

    check1 = buffer_get_char(&decrypted);
    check2 = buffer_get_char(&decrypted);
    if (check1 != buffer_get_char(&decrypted) ||
            check2 != buffer_get_char(&decrypted)) {
        if (strcmp(passphrase, "") != 0)
            debug("Bad passphrase supplied for key file %.200s.",
                  filename);
        /* Bad passphrase. */
        buffer_free(&decrypted);
        goto fail;
    }
    /* Read the rest of the private key. */
    buffer_get_bignum(&decrypted, prv->rsa->d);
    buffer_get_bignum(&decrypted, prv->rsa->iqmp);		/* u */
    /* in SSL and SSH v1 p and q are exchanged */
    buffer_get_bignum(&decrypted, prv->rsa->q);		/* p */
    buffer_get_bignum(&decrypted, prv->rsa->p);		/* q */

    /* calculate p-1 and q-1 */
    rsa_generate_additional_parameters(prv->rsa);

    buffer_free(&decrypted);

    /* enable blinding */
    if (RSA_blinding_on(prv->rsa, NULL) != 1) {
        error("key_load_private_rsa1: RSA_blinding_on failed");
        goto fail;
    }
    close(fd);
    return prv;

fail:
    if (commentp)
        xfree(*commentp);
    close(fd);
    key_free(prv);
    return NULL;
}
예제 #11
0
파일: pki_evp.cpp 프로젝트: J-Javan/xca
EVP_PKEY *pki_evp::decryptKey() const
{
	unsigned char *p;
	const unsigned char *p1;
	int outl, decsize;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	unsigned char ckey[EVP_MAX_KEY_LENGTH];

	EVP_PKEY *tmpkey;
	EVP_CIPHER_CTX ctx;
	const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
	char ownPassBuf[MAX_PASS_LENGTH] = "";

	if (isPubKey()) {
		unsigned char *q;
		outl = i2d_PUBKEY(key, NULL);
		p = q = (unsigned char *)OPENSSL_malloc(outl);
		check_oom(q);
		i2d_PUBKEY(key, &p);
		p = q;
		tmpkey = d2i_PUBKEY(NULL, (const unsigned char**)&p, outl);
		OPENSSL_free(q);
		return tmpkey;
	}
	/* This key has its own password */
	if (ownPass == ptPrivate) {
		int ret;
		pass_info pi(XCA_TITLE, qApp->translate("MainWindow",
			"Please enter the password to decrypt the private key: '%1'").arg(getIntName()));
		ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &pi);
		if (ret < 0)
			throw errorEx(tr("Password input aborted"), class_name);
	} else if (ownPass == ptBogus) { // BOGUS pass
		ownPassBuf[0] = '\0';
	} else {
		memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH);
		//printf("Orig password: '******' len:%d\n", passwd, strlen(passwd));
		while (md5passwd(ownPassBuf) != passHash &&
			sha512passwd(ownPassBuf, passHash) != passHash)
		{
			int ret;
			//printf("Passhash= '%s', new hash= '%s', passwd= '%s'\n",
				//CCHAR(passHash), CCHAR(md5passwd(ownPassBuf)), ownPassBuf);
			pass_info p(XCA_TITLE, tr("Please enter the database password for decrypting the key '%1'").arg(getIntName()));
			ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &p);
			if (ret < 0)
				throw errorEx(tr("Password input aborted"), class_name);
		}
	}
	//printf("Using decrypt Pass: %s\n", ownPassBuf);
	p = (unsigned char *)OPENSSL_malloc(encKey.count());
	check_oom(p);
	pki_openssl_error();
	p1 = p;
	memset(iv, 0, EVP_MAX_IV_LENGTH);

	memcpy(iv, encKey.constData(), 8); /* recover the iv */
	/* generate the key */
	EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)ownPassBuf,
		strlen(ownPassBuf), 1, ckey,NULL);
	/* we use sha1 as message digest,
	 * because an md5 version of the password is
	 * stored in the database...
	 */
	EVP_CIPHER_CTX_init(&ctx);
	EVP_DecryptInit(&ctx, cipher, ckey, iv);
	EVP_DecryptUpdate(&ctx, p , &outl,
		(const unsigned char*)encKey.constData() +8, encKey.count() -8);

	decsize = outl;
	EVP_DecryptFinal(&ctx, p + decsize , &outl);
	decsize += outl;
	//printf("Decrypt decsize=%d, encKey_len=%d\n", decsize, encKey_len);
	pki_openssl_error();
	tmpkey = d2i_PrivateKey(key->type, NULL, &p1, decsize);
	pki_openssl_error();
	OPENSSL_free(p);
	EVP_CIPHER_CTX_cleanup(&ctx);
	pki_openssl_error();
	if (EVP_PKEY_type(tmpkey->type) == EVP_PKEY_RSA)
		RSA_blinding_on(tmpkey->pkey.rsa, NULL);
	return tmpkey;
}
예제 #12
0
static int RSA_eay_private_decrypt(int flen, unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM f,ret;
	int j,num=0,r= -1;
	unsigned char *p;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	BN_init(&f);
	BN_init(&ret);
	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;

	num=BN_num_bytes(rsa->n);

	if ((buf=(unsigned char *)Malloc(num)) == NULL)
		{
		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	/* This check was for equality but PGP does evil things
	 * and chops off the top '0' bytes */
	if (flen > num)
		{
		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
		goto err;
		}

	/* make data into a big number */
	if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;

	if ((rsa->flags & RSA_FLAG_BLINDING) && (RSA_get_thread_blinding_ptr(rsa) == NULL))
		RSA_blinding_on(rsa,ctx);
	if (rsa->flags & RSA_FLAG_BLINDING)
		if (!BN_BLINDING_convert(&f,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err;

	/* do the decrypt */
	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
		((rsa->p != NULL) &&
		(rsa->q != NULL) &&
		(rsa->dmp1 != NULL) &&
		(rsa->dmq1 != NULL) &&
		(rsa->iqmp != NULL)) )
		{ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
	else
		{
		if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
			goto err;
		}

	if (rsa->flags & RSA_FLAG_BLINDING)
		if (!BN_BLINDING_invert(&ret,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err;

	p=buf;
	j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
		break;
#ifndef	_OPENSSL_APPLE_CDSA_
#ifndef NO_SHA
        case RSA_PKCS1_OAEP_PADDING:
	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
                break;
#endif
#endif
 	case RSA_SSLV23_PADDING:
		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
		break;
	case RSA_NO_PADDING:
		r=RSA_padding_check_none(to,num,buf,j,num);
		break;
	default:
		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (r < 0)
		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);

err:
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_clear_free(&f);
	BN_clear_free(&ret);
	if (buf != NULL)
		{
		memset(buf,0,num);
		Free(buf);
		}
	return(r);
	}
예제 #13
0
static int RSA_eay_private_encrypt(int flen, unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM f,ret;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	BN_init(&f);
	BN_init(&ret);

	if ((ctx=BN_CTX_new()) == NULL) goto err;
	num=BN_num_bytes(rsa->n);
	if ((buf=(unsigned char *)Malloc(num)) == NULL)
		{
		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	case RSA_SSLV23_PADDING:
	default:
		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,&f) == NULL) goto err;

	if ((rsa->flags & RSA_FLAG_BLINDING) && (RSA_get_thread_blinding_ptr(rsa) == NULL))
		RSA_blinding_on(rsa,ctx);
	if (rsa->flags & RSA_FLAG_BLINDING)
		if (!BN_BLINDING_convert(&f,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err;

	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
		((rsa->p != NULL) &&
		(rsa->q != NULL) &&
		(rsa->dmp1 != NULL) &&
		(rsa->dmq1 != NULL) &&
		(rsa->iqmp != NULL)) )
		{ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
	else
		{
		if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
		}

	if (rsa->flags & RSA_FLAG_BLINDING)
		if (!BN_BLINDING_invert(&ret,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(&ret);
	i=BN_bn2bin(&ret,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_clear_free(&ret);
	BN_clear_free(&f);
	if (buf != NULL)
		{
		memset(buf,0,num);
		Free(buf);
		}
	return(r);
	}
예제 #14
0
파일: ike_auth.c 프로젝트: ebichu/dd-wrt
/* Encrypt the HASH into a SIG type.  */
static int
rsa_sig_encode_hash (struct message *msg)
{
  struct exchange *exchange = msg->exchange;
  struct ipsec_exch *ie = exchange->data;
  size_t hashsize = ie->hash->hashsize;
  struct cert_handler *handler;
  char header[80];
  int initiator = exchange->initiator;
  u_int8_t *buf, *data, *buf2;
  u_int32_t datalen;
  u_int8_t *id;
  size_t id_len;
  int idtype;
  void *sent_key;

  id = initiator ? exchange->id_i : exchange->id_r;
  id_len = initiator ? exchange->id_i_len : exchange->id_r_len;

  /* We may have been provided these by the kernel */
  buf = (u_int8_t *)conf_get_str (exchange->name, "Credentials");
  if (buf
      && (idtype = conf_get_num (exchange->name, "Credential_Type", -1) != -1))
    {
      exchange->sent_certtype = idtype;
      handler = cert_get (idtype);
      if (!handler)
	{
	  log_print ("rsa_sig_encode_hash: cert_get (%d) failed", idtype);
	  return -1;
	}

      exchange->sent_cert = handler->cert_from_printable ((char *)buf);
      if (!exchange->sent_cert)
	{
	  log_print ("rsa_sig_encode_hash: failed to retrieve certificate");
	  return -1;
	}

      handler->cert_serialize (exchange->sent_cert, &data, &datalen);
      if (!data)
	{
	  log_print ("rsa_sig_encode_hash: cert serialization failed");
	  return -1;
	}

      goto aftercert; /* Skip all the certificate discovery */
    }

  /* XXX This needs to be configurable.  */
  idtype = ISAKMP_CERTENC_KEYNOTE;

  /* Find a certificate with subjectAltName = id.  */
  handler = cert_get (idtype);
  if (!handler)
    {
      idtype = ISAKMP_CERTENC_X509_SIG;
      handler = cert_get (idtype);
      if (!handler)
	{
	  log_print ("rsa_sig_encode_hash: cert_get(%d) failed", idtype);
	  return -1;
	}
    }

  if (handler->cert_obtain (id, id_len, 0, &data, &datalen) == 0)
    {
      if (idtype == ISAKMP_CERTENC_KEYNOTE)
	{
	  idtype = ISAKMP_CERTENC_X509_SIG;
	  handler = cert_get (idtype);
	  if (!handler)
	    {
	      log_print ("rsa_sig_encode_hash: cert_get(%d) failed", idtype);
	      return -1;
	    }

	  if (handler->cert_obtain (id, id_len, 0, &data, &datalen) == 0)
	    {
	      LOG_DBG ((LOG_MISC, 10,
			"rsa_sig_encode_hash: no certificate to send"));
	      goto skipcert;
	    }
	}
      else
	{
	  LOG_DBG ((LOG_MISC, 10,
		    "rsa_sig_encode_hash: no certificate to send"));
	  goto skipcert;
	}
    }

  /* Let's store the certificate we are going to use */
  exchange->sent_certtype = idtype;
  exchange->sent_cert = handler->cert_get (data, datalen);
  if (!exchange->sent_cert)
    {
      free (data);
      log_print ("rsa_sig_encode_hash: failed to get certificate from wire "
		 "encoding");
      return -1;
    }

 aftercert:

  buf = realloc (data, ISAKMP_CERT_SZ + datalen);
  if (!buf)
    {
      log_error ("rsa_sig_encode_hash: realloc (%p, %d) failed", data,
		 ISAKMP_CERT_SZ + datalen);
      free (data);
      return -1;
    }
  memmove (buf + ISAKMP_CERT_SZ, buf, datalen);
  SET_ISAKMP_CERT_ENCODING (buf, idtype);
  if (message_add_payload (msg, ISAKMP_PAYLOAD_CERT, buf,
			   ISAKMP_CERT_SZ + datalen, 1))
    {
      free (buf);
      return -1;
    }

 skipcert:

  /* Again, we may have these from the kernel */
  buf = (u_int8_t *)conf_get_str (exchange->name, "PKAuthentication");
  if (buf)
    {
      key_from_printable (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, (char *)buf,
			  &data, &datalen);
      if (!data || datalen == -1)
	{
	  log_print ("rsa_sig_encode_hash: badly formatted RSA private key");
	  return 0;
	}

      sent_key = key_internalize (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, data,
				  datalen);
      if (!sent_key)
	{
	  log_print ("rsa_sig_encode_hash: bad RSA private key from dynamic "
		     "SA acquisition subsystem");
	  return 0;
	}
#if defined (USE_PRIVSEP)
      {
	/* With USE_PRIVSEP, the sent_key should be a key number. */
	void *key = sent_key;
	sent_key = monitor_RSA_upload_key (key);
      }
#endif
    }
  else /* Try through the regular means.  */
    {
      switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ])
	{
	case IPSEC_ID_IPV4_ADDR:
	case IPSEC_ID_IPV6_ADDR:
	  util_ntoa ((char **)&buf2,
		     id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ] == IPSEC_ID_IPV4_ADDR
		     ? AF_INET : AF_INET6,
		     id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
	  if (!buf2)
	    return 0;
	  break;

	case IPSEC_ID_FQDN:
	case IPSEC_ID_USER_FQDN:
	  buf2 = calloc (id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
			 sizeof (char));
	  if (!buf2)
	    {
	      log_print ("rsa_sig_encode_hash: malloc (%lu) failed",
			 (unsigned long)id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1);
	      return 0;
	    }
	  memcpy (buf2, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
		  id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
	  break;

	  /* XXX Support more ID types?  */
	default:
	  buf2 = 0;
	  return 0;
	}

#if defined (USE_PRIVSEP)
      sent_key = monitor_RSA_get_private_key (exchange->name, (char *)buf2);
#else
      sent_key = ike_auth_get_key (IKE_AUTH_RSA_SIG, exchange->name,
				   (char *)buf2, 0);
#endif
      free (buf2);

      /* Did we find a key?  */
      if (!sent_key)
	{
	  log_print ("rsa_sig_encode_hash: could not get private key");
	  return -1;
	}
    }

#if !defined (USE_PRIVSEP)
  /* Enable RSA blinding.  */
  if (RSA_blinding_on (sent_key, NULL) != 1)
    {
      log_error ("rsa_sig_encode_hash: RSA_blinding_on () failed.");
      return -1;
    }
#endif

  /* XXX hashsize is not necessarily prf->blocksize.  */
  buf = malloc (hashsize);
  if (!buf)
    {
      log_error ("rsa_sig_encode_hash: malloc (%lu) failed",
	(unsigned long)hashsize);
      return -1;
    }

  if (ike_auth_hash (exchange, buf) == -1)
    {
      free (buf);
      return -1;
    }

  snprintf (header, sizeof header, "rsa_sig_encode_hash: HASH_%c",
	    initiator ? 'I' : 'R');
  LOG_DBG_BUF ((LOG_MISC, 80, header, buf, hashsize));

#if !defined (USE_PRIVSEP)
  data = malloc (RSA_size (sent_key));
  if (!data)
    {
      log_error ("rsa_sig_encode_hash: malloc (%d) failed",
		 RSA_size (sent_key));
      return -1;
    }

  datalen = RSA_private_encrypt (hashsize, buf, data, sent_key,
				 RSA_PKCS1_PADDING);
#else
  datalen = monitor_RSA_private_encrypt (hashsize, buf, &data, sent_key,
					 RSA_PKCS1_PADDING);
#endif /* USE_PRIVSEP */
  if (datalen == -1)
    {
      log_print ("rsa_sig_encode_hash: RSA_private_encrypt () failed");
      if (data)
	free (data);
      free (buf);
      monitor_RSA_free (sent_key);
      return -1;
    }

  free (buf);

  buf = realloc (data, ISAKMP_SIG_SZ + datalen);
  if (!buf)
    {
      log_error ("rsa_sig_encode_hash: realloc (%p, %d) failed", data,
		 ISAKMP_SIG_SZ + datalen);
      free (data);
      return -1;
    }
  memmove (buf + ISAKMP_SIG_SZ, buf, datalen);

  snprintf (header, sizeof header, "rsa_sig_encode_hash: SIG_%c",
	    initiator ? 'I' : 'R');
  LOG_DBG_BUF ((LOG_MISC, 80, header, buf + ISAKMP_SIG_DATA_OFF, datalen));
  if (message_add_payload (msg, ISAKMP_PAYLOAD_SIG, buf,
			   ISAKMP_SIG_SZ + datalen, 1))
    {
      free (buf);
      return -1;
    }
  return 0;
}
예제 #15
0
파일: key.c 프로젝트: pakls/teraterm-ttssh2
Key *key_private_deserialize(buffer_t *blob)
{
	int success = 0;
	char *type_name = NULL;
	Key *k = NULL;
	unsigned int pklen, sklen;
	int type;

	type_name = buffer_get_string_msg(blob, NULL);
	if (type_name == NULL)
		goto error;
	type = get_keytype_from_name(type_name);

	k = key_new_private(type);

	switch (type) {
		case KEY_RSA:
			buffer_get_bignum2_msg(blob, k->rsa->n);
			buffer_get_bignum2_msg(blob, k->rsa->e);
			buffer_get_bignum2_msg(blob, k->rsa->d);
			buffer_get_bignum2_msg(blob, k->rsa->iqmp);
			buffer_get_bignum2_msg(blob, k->rsa->p);
			buffer_get_bignum2_msg(blob, k->rsa->q);

			/* Generate additional parameters */
			rsa_generate_additional_parameters(k->rsa);
			break;

		case KEY_DSA:
			buffer_get_bignum2_msg(blob, k->dsa->p);
			buffer_get_bignum2_msg(blob, k->dsa->q);
			buffer_get_bignum2_msg(blob, k->dsa->g);
			buffer_get_bignum2_msg(blob, k->dsa->pub_key);
			buffer_get_bignum2_msg(blob, k->dsa->priv_key);
			break;

		case KEY_ECDSA256:
		case KEY_ECDSA384:
		case KEY_ECDSA521:
			{
			int success = 0;
			unsigned int nid;
			char *curve = NULL;
			ssh_keytype skt;
			BIGNUM *exponent = NULL;
			EC_POINT *q = NULL;

			nid = keytype_to_cipher_nid(type);
			curve = buffer_get_string_msg(blob, NULL);
			skt = key_curve_name_to_keytype(curve);
			if (nid != keytype_to_cipher_nid(skt))
				goto ecdsa_error;

			k->ecdsa = EC_KEY_new_by_curve_name(nid);
			if (k->ecdsa == NULL)
				goto ecdsa_error;

			q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
			if (q == NULL)
				goto ecdsa_error;

			if ((exponent = BN_new()) == NULL)
				goto ecdsa_error;
			buffer_get_ecpoint_msg(blob,
				EC_KEY_get0_group(k->ecdsa), q);
			buffer_get_bignum2_msg(blob, exponent);
			if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
				goto ecdsa_error;
			if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
				goto ecdsa_error;
			if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
				EC_KEY_get0_public_key(k->ecdsa)) != 0)
				goto ecdsa_error;
			if (key_ec_validate_private(k->ecdsa) != 0)
				goto ecdsa_error;

			success = 1;

ecdsa_error:
			free(curve);
			if (exponent)
				BN_clear_free(exponent);
			if (q)
				EC_POINT_free(q);
			if (success == 0)
				goto error;
			}
			break;

		case KEY_ED25519:
			k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
			k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
			if (pklen != ED25519_PK_SZ) 
				goto error;
			if (sklen != ED25519_SK_SZ)
				goto error;
			break;

		default:
			goto error;
			break;
	}

	/* enable blinding */
	switch (k->type) {
		case KEY_RSA1:
		case KEY_RSA:
			if (RSA_blinding_on(k->rsa, NULL) != 1) 
				goto error;
			break;
	}

	success = 1;

error:
	free(type_name);

	if (success == 0) {
		key_free(k);
		k = NULL;
	}

	return (k);
}
예제 #16
0
bool OSSLRSA::signFinal(ByteString& signature)
{
	// Save necessary state before calling super class signFinal
	OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey;
	AsymMech::Type mechanism = currentMechanism;

	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	ByteString firstHash, secondHash;

	bool bFirstResult = pCurrentHash->hashFinal(firstHash);
	bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;

	delete pCurrentHash;
	pCurrentHash = NULL;

	if (pSecondHash != NULL)
	{
		delete pSecondHash;

		pSecondHash = NULL;
	}

	if (!bFirstResult || !bSecondResult)
	{
		return false;
	}

	ByteString digest = firstHash + secondHash;

	// Resize the data block for the signature to the modulus size of the key
	signature.resize(pk->getN().size());

	// Determine the signature NID type
	int type = 0;
	bool isPSS = false;
	const EVP_MD* hash = NULL;

	switch (mechanism)
	{
		case AsymMech::RSA_MD5_PKCS:
			type = NID_md5;
			break;
		case AsymMech::RSA_SHA1_PKCS:
			type = NID_sha1;
			break;
		case AsymMech::RSA_SHA224_PKCS:
			type = NID_sha224;
			break;
		case AsymMech::RSA_SHA256_PKCS:
			type = NID_sha256;
			break;
		case AsymMech::RSA_SHA384_PKCS:
			type = NID_sha384;
			break;
		case AsymMech::RSA_SHA512_PKCS:
			type = NID_sha512;
			break;
		case AsymMech::RSA_SHA1_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha1();
			break;
		case AsymMech::RSA_SHA224_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha224();
			break;
		case AsymMech::RSA_SHA256_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha256();
			break;
		case AsymMech::RSA_SHA384_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha384();
			break;
		case AsymMech::RSA_SHA512_PKCS_PSS:
			isPSS = true;
			hash = EVP_sha512();
			break;
		case AsymMech::RSA_SSL:
			type = NID_md5_sha1;
			break;
		default:
			break;
	}

	// Perform the signature operation
	unsigned int sigLen = signature.size();

	RSA* rsa = pk->getOSSLKey();

	if (!RSA_blinding_on(rsa, NULL))
	{
		ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key");

		return false;
	}

	bool rv;

	if (isPSS)
	{
		ByteString em;
		em.resize(pk->getN().size());

		rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0],
						hash, sLen) == 1);
		if (!rv)
		{
			ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error());
		}
		else
		{
			int result = RSA_private_encrypt(em.size(), &em[0], &signature[0],
							 pk->getOSSLKey(), RSA_NO_PADDING);
			if (result >= 0)
			{
				sigLen = result;
				rv = true;
			}
			else
			{
				rv = false;
				ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error());
			}
		}
	}
	else
	{
		rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0],
			       &sigLen, pk->getOSSLKey()) == 1);
	}

	RSA_blinding_off(rsa);

	signature.resize(sigLen);

	return rv;
}
예제 #17
0
		inline void rsa_key::enable_blinding(BN_CTX* ctx) const
		{
			error::throw_error_if_not(RSA_blinding_on(ptr().get(), ctx) != 0);
		}