Ejemplo n.º 1
1
Archivo: jws.c Proyecto: cisco/cjose
static bool _cjose_jws_verify_sig_ps(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;
    uint8_t *em = NULL;
    size_t em_len = 0;

    // ensure jwk is RSA
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // build digest using SHA-256/384/512 digest algorithm
    const EVP_MD *digest_alg = NULL;
    if (strcmp(alg, CJOSE_HDR_ALG_PS256) == 0)
        digest_alg = EVP_sha256();
    else if (strcmp(alg, CJOSE_HDR_ALG_PS384) == 0)
        digest_alg = EVP_sha384();
    else if (strcmp(alg, CJOSE_HDR_ALG_PS512) == 0)
        digest_alg = EVP_sha512();

    if (NULL == digest_alg)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // allocate buffer for encoded message
    em_len = RSA_size((RSA *)jwk->keydata);
    em = (uint8_t *)cjose_get_alloc()(em_len);
    if (NULL == em)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // decrypt signature
    if (RSA_public_decrypt(jws->sig_len, jws->sig, em, (RSA *)jwk->keydata, RSA_NO_PADDING) != em_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // verify decrypted signature data against PSS encoded digest
    if (RSA_verify_PKCS1_PSS((RSA *)jwk->keydata, jws->dig, digest_alg, em, -1) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ps_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_ps_cleanup:
    cjose_get_dealloc()(em);

    return retval;
}
Ejemplo n.º 2
0
int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
                           size_t max_out, const uint8_t *in, size_t in_len,
                           int padding) {
  const unsigned rsa_size = RSA_size(rsa);
  BIGNUM *f, *result;
  int ret = 0;
  int r = -1;
  uint8_t *buf = NULL;
  BN_CTX *ctx = NULL;

  if (max_out < rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
    return 0;
  }

  if (!check_modulus_and_exponent_sizes(rsa)) {
    return 0;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }

  BN_CTX_start(ctx);
  f = BN_CTX_get(ctx);
  result = BN_CTX_get(ctx);
  if (padding == RSA_NO_PADDING) {
    buf = out;
  } else {
    /* Allocate a temporary buffer to hold the padded plaintext. */
    buf = OPENSSL_malloc(rsa_size);
    if (buf == NULL) {
      OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }
  if (!f || !result) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (in_len != rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
    goto err;
  }

  if (BN_bin2bn(in, in_len, f) == NULL) {
    goto err;
  }

  if (BN_ucmp(f, rsa->n) >= 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
    goto err;
  }

  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
      goto err;
    }
  }

  if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
    goto err;
  }

  if (!BN_bn2bin_padded(buf, rsa_size, result)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  switch (padding) {
    case RSA_PKCS1_PADDING:
      r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size);
      break;
    case RSA_NO_PADDING:
      r = rsa_size;
      break;
    default:
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
      goto err;
  }

  if (r < 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
  } else {
    *out_len = r;
    ret = 1;
  }

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  if (padding != RSA_NO_PADDING && buf != NULL) {
    OPENSSL_cleanse(buf, rsa_size);
    OPENSSL_free(buf);
  }
  return ret;
}
Ejemplo n.º 3
0
void openssl_rsa_crypt()
{
	RSA *r;
	BIO *b;
	BIGNUM *bne;
	unsigned int len;
	int size, elen, dlen;
	unsigned char inputs[COMM_LEN] = "rsa crypt";
	unsigned char tmps[MAX1_LEN], outputs[MAX1_LEN];

	memset(tmps, 0, sizeof(tmps));
	memset(outputs, 0, sizeof(outputs));
	printf("\nRSA generate key:\n");
	bne = BN_new();
	BN_set_word(bne, RSA_3);
	r = RSA_new();
	RSA_generate_key_ex(r, MAX1_LEN, bne, NULL);
	RSA_print_fp(stdout, r, 11);
	b = BIO_new_file("/tmp/rsa.key", "w");
	i2d_RSAPrivateKey_bio(b, r);
	BIO_free(b);

	elen = RSA_private_encrypt(RSA_size(r) - 11,
							   inputs, outputs, r, RSA_PKCS1_PADDING);
	dlen = RSA_public_decrypt(elen, outputs, tmps, r, RSA_PKCS1_PADDING);
	if (elen <= 0 || dlen <= 0 || memcmp(inputs, tmps, RSA_size(r) - 11)) {
		printf("RSA_private_encrypt error!\n");
		RSA_free(r);
		return;
	}
	printf("RSA_private_encrypt(%s) = ", inputs);
	for (size = 0; size < elen; size++)
		printf("%02x", outputs[size]);
	printf("\n");

	memset(outputs, 0, sizeof(outputs));
	elen = RSA_public_encrypt(RSA_size(r) - 11,
							  inputs, outputs, r, RSA_PKCS1_PADDING);
	dlen = RSA_private_decrypt(elen, outputs, tmps, r, RSA_PKCS1_PADDING);
	if (elen <= 0 || dlen <= 0 || memcmp(inputs, tmps, RSA_size(r) - 11)) {
		printf("RSA_public_encrypt error!\n");
		RSA_free(r);
		return;
	}
	printf("RSA_public_encrypt(%s) = ", inputs);
	for (size = 0; size < elen; size++)
		printf("%02x", outputs[size]);
	printf("\n");

	memset(outputs, 0, sizeof(outputs));
	RSA_sign(NID_md5_sha1, inputs, 36, outputs, &len, r);
	printf("RSA_sign(%s) = ", inputs);
	for (size = 0; size < len; size++)
		printf("%02x", outputs[size]);
	printf("\n");

	memset(tmps, 0, sizeof(tmps));
	RSA_verify(NID_md5_sha1, inputs, 36, outputs, len, r);
	printf("RSA_verify(");
	for (size = 0; size < len; size++)
		printf("%02x", outputs[size]);
	printf(") = %s\n", inputs);

	RSA_free(r);
}
Ejemplo n.º 4
0
int bdd_do_select ( char *safe_trame )
{
    // Déclaration variable
    char* morceau = NULL ;          // Variable contenant chaque morceau de la trame (strtok_r)
    char* statut = NULL ;
    char* affectation = NULL ;
    char* groupes = NULL ;
    char* reference = NULL ;
    int cpt = 0 ;                   // Compteur
    MYSQL_RES* resultat_req ;       // Object MYSQL décrivant le résultat d'une requête
    MYSQL_ROW tuple ;               // Object MYSQL décrivant un tuple dans la liste résultat
    char* safe_tuple = NULL ;       // Permet d'appeler strtok_r sur le bon contenu.
    char* valeur = NULL ;
    char* politique = NULL ;
    int code_retour = 0 ;

    // On découpe les 4 éléments restant de notre trame
    for ( cpt = 0; cpt < 4; cpt++ )
    {
        // On découpe la trame en morceaux repérés via un "*"
        if ( ( morceau = strtok_r ( NULL, "*", &safe_trame ) ) == NULL )
        {
            perror ( "Erreur_bdd_do_select : information manquante " ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }

        // On vérifie que l'information est présente
        if ( strcmp ( morceau, "EOF") == 0 )
        {
            perror ( "Erreur_bdd_do_select : information manquante II" ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }
        else
        {
            // On affecte l'information
            switch ( cpt )
            {
                case ZERO :
                    statut = morceau ;
                    break ;

                case UN :
                    affectation = morceau ;
                    break ;

                case DEUX :
                    groupes = morceau ;
                    break ;

                case TROIS :
                    reference = morceau ;
                    break ;

                default :
                    perror ( "Erreur_do_select : overflow compteur cpt " ) ;
                    bdd_send_msg ( SELECT, "ERROR" ) ;
                    return ERRNO ;
                    break ;
            }
        }
    }

    // On récupère auprès de la BDD, la valeur associée à cette référence
    if ( bdd_do_request ( mysql_bdd, SELECT, reference, NULL, &resultat_req ) == ERRNO )
    {
        perror ( "Erreur_bdd_do_select : bad requete " ) ;
        mysql_free_result ( resultat_req ) ;
        bdd_send_msg ( SELECT, "ERROR" ) ;
        return ERRNO ;
    }

    // On récupère le tuple
    if ( ( tuple = mysql_fetch_row ( resultat_req ) ) ==  NULL )
    {
        perror ( "Erreur_bdd_do_select : bad tuple " ) ;
        mysql_free_result ( resultat_req ) ;
        bdd_send_msg ( SELECT, "ERROR" ) ;
        return ERRNO ;
    }

    // On déchiffre le tuple
    char* output = (char*) malloc ( RSA_size ( bdd_key ) * sizeof ( char ) ) ;
    memset ( output, '\0', RSA_size ( bdd_key ) ) ;
    if ( RSA_chiffrement ( (unsigned char*) tuple[0], (unsigned char*) output, DECHIFFREMENT ) != TRUE )
    {
        perror ( "Erreur_bdd_do_select : RSA_dechiffrement " ) ;
        free ( output ) ;
        mysql_free_result ( resultat_req ) ;
        bdd_send_msg ( SELECT, "ERROR" ) ;
        return ERRNO ;
    }

    // On récupère les 3 informations du tuple
    morceau = NULL ;
    for ( cpt = 0; cpt < 3; cpt++ )
    {
        // On découpe le tuple en morceaux repérés via un "*"
        if ( cpt == 0 )
            morceau = strtok_r ( output, "*", &safe_tuple ) ;
        else
            morceau = strtok_r ( NULL, "*", &safe_tuple ) ;

        // Vérification
        if ( morceau == NULL )
        {
            perror ( "Erreur_bdd_do_select : information manquante III " ) ;
            free ( output ) ;
            mysql_free_result ( resultat_req ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }

        // On affecte l'information
        switch ( cpt )
        {
            case ZERO :
                break ;

            case UN :
                valeur = morceau ;
                break ;

            case DEUX :
                politique = morceau ;
                break ;

            default :
                perror ( "Erreur_do_select : overflow compteur cpt " ) ;
                free ( output ) ;
                mysql_free_result ( resultat_req ) ;
                bdd_send_msg ( SELECT, "ERROR" ) ;
                return ERRNO ;
                break ;
        }
    }

    // On regarde les politique de partage de la ressource
    morceau = NULL ;
    safe_tuple = NULL ;
    for ( cpt = 0; cpt < 3; cpt++ )
    {
        // On découpe les politiques de partage en morceaux repérés via un "$"
        if ( cpt == 0 )
            morceau = strtok_r ( politique, "$", &safe_tuple ) ;
        else
            morceau = strtok_r ( NULL, "$", &safe_tuple ) ;
        if ( morceau == NULL )
        {
            perror ( "Erreur_bdd_do_select : information manquante IV " ) ;
            free ( output ) ;
            mysql_free_result ( resultat_req ) ;
            bdd_send_msg ( SELECT, "ERROR" ) ;
            return ERRNO ;
        }

        // On regarde d'abord si on est en accès interdit
        if ( strcmp ( morceau, "-" ) == 0 )
        {
            printf ( "Erreur_bdd_do_select : BAD-PERMISSION " ) ;
            free ( output ) ;
            mysql_free_result ( resultat_req ) ;
            bdd_send_msg ( SELECT, "BAD-PERMISSION" ) ;
            return FALSE ;
        }
        else if ( strcmp ( morceau, "+") != 0 ) // Puis si on n'est pas en accès total
        {
            // Alors on traite le cas par cas
            switch ( cpt )
            {
                case ZERO : // Statut
                    code_retour = bdd_verification_partage ( morceau, statut ) ;
                    break ;

                case UN :   // Affectation
                    code_retour = bdd_verification_partage ( morceau, affectation ) ;
                    break ;

                case DEUX : // Groupes
                    code_retour = bdd_verification_partage ( morceau, groupes ) ;
                    break ;

                default :
                    perror ( "Erreur_do_select : overflow compteur cpt " ) ;
                    free ( output ) ;
                    mysql_free_result ( resultat_req ) ;
                    bdd_send_msg ( SELECT, "ERROR" ) ;
                    return ERRNO ;
                    break ;
            }

            // On vérifie le code retour
            if ( code_retour == FALSE )
            {
                printf ( "Erreur_bdd_do_select : bad permission " ) ;
                free ( output ) ;
                mysql_free_result ( resultat_req ) ;
                bdd_send_msg ( SELECT, "BAD-PERMISSION" ) ;
                return FALSE ;
            }
            else if ( code_retour == ERRNO )
            {
                printf ( "Erreur_bdd_do_select : bdd_verification_partage " ) ;
                free ( output ) ;
                mysql_free_result ( resultat_req ) ;
                bdd_send_msg ( SELECT, "ERROR" ) ;
                return ERRNO ;
            }
        }
    }

    // Si on arrive ici c'est que la poltique de partage est respectée : on retourne la valeur
    int taille = strlen ( valeur ) + 10 ;
    char* reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*%s*EOF", SELECT, valeur ) ;
    res_send ( reponse ) ;

    // On free l'espace de résultat
    free ( output ) ;
    mysql_free_result ( resultat_req ) ;
    free ( reponse ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}
Ejemplo n.º 5
0
int bdd_do_request ( MYSQL* mysql_bdd, int action, char* reference, char* valeur, MYSQL_RES** resultat_req )
{
    // Initialisation
    char *requete = (char*) malloc ( TAILLE_REQUETE * sizeof ( char ) ) ;
    memset ( requete, '\0', TAILLE_REQUETE ) ;
    int return_value ;

    // On prépare la zone mémoire de sortie (chiffrement)
    int i = 0 ;
    int good = FALSE ;
    char* insertion = (char*) malloc ( RSA_size ( bdd_key ) * sizeof ( char ) ) ;
    memset ( insertion, '\0', RSA_size ( bdd_key ) ) ;

    // Chiffrement BDD
    if ( action == INSERT )
    {
        // On vérifie la taille du buffer d'entrée
        if ( strlen ( valeur ) <= ( TAILLE_MAX_UTILE - 1 ) )
        {
            // Tant que le chiffré n'est pas bon
            while ( good != TRUE )
            {
                // Ini
                memset ( insertion, '\0', RSA_size ( bdd_key ) ) ;

                // On chiffre
                if ( RSA_chiffrement ( (unsigned char*) valeur, (unsigned char*) insertion, CHIFFREMENT ) != TRUE )
                {
                    perror ( "Erreur_bdd_do_request : RSA_chiffrement " ) ;
                    free ( insertion ) ;
                    free ( requete ) ;
                    return ERRNO ;
                }

                // On suppose chiffré bon
                good = TRUE ;

                // On vérifie la non présence du caractère ", \ et \0
                for ( i = 0; i < TAILLE_MAX_RSA; i ++ )
                {
                    if ( ( (int) insertion[i] == APOSTROPHE ) || ( (int) insertion[i] == BACK_SLASH ) || ( (int) insertion[i] == ZERO_TERMINAL ) )
                        good = FALSE ;
                }
            }
        }
    }

    // On prépare la requête selon l'action à faire
    switch ( action )
    {
        case SELECT_ALL :
            sprintf ( requete, "select REF, VAL from %s;", TABLE ) ;
            break ;

        case SELECT :
            sprintf ( requete, "select VAL from %s where REF = \"%s\";", TABLE, reference ) ;
            break ;

        case INSERT :
            sprintf ( requete, "insert into %s (REF, VAL) values(\"%s\",\"%s\");", TABLE, reference, insertion ) ;
            break ;

        case DELETE :
            sprintf ( requete, "delete from %s where REF = \"%s\";", TABLE, reference ) ;
            break ;

        case DELETE_ALL :
            sprintf ( requete, "delete from %s;", TABLE ) ;
            break ;

        default :
            perror ( "Erreur_bdd_do_request : bad action " ) ;
            free ( requete ) ;
            free ( insertion ) ;
            return ERRNO ;
            break ;
    }

    // On réalise la requête
    if ( ( return_value = mysql_query ( mysql_bdd, requete ) ) != 0 )
    {
        fprintf ( stderr, "Erreur_bdd_do_request : mysql_query avec code action : %d \n", action ) ;
        fprintf ( stderr, "Erreur_bdd_do_request : mysql_query avec requete : %s \n", requete ) ;
        fprintf ( stderr, "Erreur_bdd_do_request : mysql_query avec retour : %d \n", return_value ) ;
        free ( requete ) ;
        free ( insertion ) ;
        return ERRNO ;
    }

    // Selon l'action réalisée, on récupère des résultats
    if ( ( action == SELECT_ALL ) || ( action == SELECT ) )
    {
        if ( ( *resultat_req = mysql_use_result ( mysql_bdd ) ) == NULL )
        {
            perror ( "Erreur_bdd_do_request : mysql_use_result " ) ;
            free ( requete ) ;
            free ( insertion ) ;
            return ERRNO ;
        }
    }

    // Free
    free ( requete ) ;
    free ( insertion ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}
Ejemplo n.º 6
0
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
int
ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], *sig;
	u_int slen, dlen, len;
	int ok, nid;
	Buffer b;

	if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
		pamsshagentauth_logerror("ssh_rsa_sign: no RSA key");
		return -1;
	}
	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		pamsshagentauth_logerror("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
		return -1;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	slen = RSA_size(key->rsa);
	sig = pamsshagentauth_xmalloc(slen);

	ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
	memset(digest, 'd', sizeof(digest));

	if (ok != 1) {
		int ecode = ERR_get_error();

		pamsshagentauth_logerror("ssh_rsa_sign: RSA_sign failed: %s",
		    ERR_error_string(ecode, NULL));
		pamsshagentauth_xfree(sig);
		return -1;
	}
	if (len < slen) {
		u_int diff = slen - len;
		pamsshagentauth_verbose("slen %u > len %u", slen, len);
		memmove(sig + diff, sig, len);
		memset(sig, 0, diff);
	} else if (len > slen) {
		pamsshagentauth_logerror("ssh_rsa_sign: slen %u slen2 %u", slen, len);
		pamsshagentauth_xfree(sig);
		return -1;
	}
	/* encode signature */
	pamsshagentauth_buffer_init(&b);
	pamsshagentauth_buffer_put_cstring(&b, "ssh-rsa");
	pamsshagentauth_buffer_put_string(&b, sig, slen);
	len = pamsshagentauth_buffer_len(&b);
	if (lenp != NULL)
		*lenp = len;
	if (sigp != NULL) {
		*sigp = pamsshagentauth_xmalloc(len);
		memcpy(*sigp, pamsshagentauth_buffer_ptr(&b), len);
	}
	pamsshagentauth_buffer_free(&b);
	memset(sig, 's', slen);
	pamsshagentauth_xfree(sig);

	return 0;
}
Ejemplo n.º 7
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;

}
Ejemplo n.º 8
0
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
                         size_t *siglen, const unsigned char *tbs,
                         size_t tbslen)
{
    int ret;
    RSA_PKEY_CTX *rctx = ctx->data;
    RSA *rsa = ctx->pkey->pkey.rsa;

    if (rctx->md) {
        if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
            RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH);
            return -1;
        }

        if (EVP_MD_type(rctx->md) == NID_mdc2) {
            unsigned int sltmp;
            if (rctx->pad_mode != RSA_PKCS1_PADDING)
                return -1;
            ret = RSA_sign_ASN1_OCTET_STRING(0,
                                             tbs, tbslen, sig, &sltmp, rsa);

            if (ret <= 0)
                return ret;
            ret = sltmp;
        } else if (rctx->pad_mode == RSA_X931_PADDING) {
            if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) {
                RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL);
                return -1;
            }
            if (!setup_tbuf(rctx, ctx)) {
                RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE);
                return -1;
            }
            memcpy(rctx->tbuf, tbs, tbslen);
            rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md));
            ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
                                      sig, rsa, RSA_X931_PADDING);
        } else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
            unsigned int sltmp;
            ret = RSA_sign(EVP_MD_type(rctx->md),
                           tbs, tbslen, sig, &sltmp, rsa);
            if (ret <= 0)
                return ret;
            ret = sltmp;
        } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
            if (!setup_tbuf(rctx, ctx))
                return -1;
            if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa,
                                                rctx->tbuf, tbs,
                                                rctx->md, rctx->mgf1md,
                                                rctx->saltlen))
                return -1;
            ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
                                      sig, rsa, RSA_NO_PADDING);
        } else {
            return -1;
        }
    } else {
        ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
                                  rctx->pad_mode);
    }
    if (ret < 0)
        return ret;
    *siglen = ret;
    return 1;
}
Ejemplo n.º 9
0
ssh_string ssh_encrypt_rsa1(ssh_session session, ssh_string data, ssh_public_key key) {
  ssh_string str = NULL;
  size_t len = string_len(data);
  size_t size = 0;
#ifdef HAVE_LIBGCRYPT
  const char *tmp = NULL;
  gcry_sexp_t ret_sexp;
  gcry_sexp_t data_sexp;

  if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))",
      len, string_data(data))) {
    ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
    return NULL;
  }
  if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) {
    gcry_sexp_release(data_sexp);
    ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
    return NULL;
  }

  gcry_sexp_release(data_sexp);

  data_sexp = gcry_sexp_find_token(ret_sexp, "a", 0);
  if (data_sexp == NULL) {
    ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
    gcry_sexp_release(ret_sexp);
    return NULL;
  }
  tmp = gcry_sexp_nth_data(data_sexp, 1, &size);
  if (*tmp == 0) {
    size--;
    tmp++;
  }

  str = string_new(size);
  if (str == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    gcry_sexp_release(data_sexp);
    gcry_sexp_release(ret_sexp);
    return NULL;
  }
  string_fill(str, tmp, size);

  gcry_sexp_release(data_sexp);
  gcry_sexp_release(ret_sexp);
#elif defined HAVE_LIBCRYPTO
  size = RSA_size(key->rsa_pub);

  str = string_new(size);
  if (str == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return NULL;
  }

  if (RSA_public_encrypt(len, string_data(data), string_data(str), key->rsa_pub,
      RSA_PKCS1_PADDING) < 0) {
    string_free(str);
    return NULL;
  }
#endif

  return str;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
{
	/* Variabili e strutture standard per la gestione della connessione */
	int ret;
	int cl_sk;
	int cl_ret;
	struct sockaddr_in sv_addr;

	/* Passare, oltre a indirizzo IP e porta (del server), anche la password condivisa con il server */
	if(argc != 4) {
		cerr << "Errore: sintassi del comando errata" << endl;
		cout << "Digitare: ./client <indirizzo_IP> <porta> <password_condivisa>" << endl;
		exit(1);
	}

	SERVER_IP_ADD = argv[1];
	SERVER_PORT = atoi(argv[2]);
	CLIENT_PWD = argv[3];

	cout << endl;
	cout << "********* INIZIO FASE DI CONNESSIONE ********" << endl;

	int np = strlen(CLIENT_PWD); //Numero di caratteri che compongono la password

	if(np < 8) {
		cerr << "Errore: inserire una password di almeno 8 caratteri alfanumerici e/o caratteri speciali" << endl;	
		exit(1);
	}

	if(SERVER_PORT <= 1023) {
		cerr << "Porta <" << SERVER_PORT << "> non utilizzabile :: Well Known Port" << endl;
		return -1;
	}

	if(SERVER_PORT <= 65535 && SERVER_PORT >= 49152)
		cout << "Fare attenzione nella scelta della porta <" << SERVER_PORT << "> :: Dynamic and/or Private Port" << endl;

	/* Creazione del socket lato client */	
	cl_sk = socket(AF_INET, SOCK_STREAM, 0);
	if(cl_sk == -1) {
    		cerr << "Errore: funzione <socket> non eseguita correttamente sul client" << endl;
    		exit(0);
	}

	/* Inizializzazione struttura dati */
	bzero(&sv_addr, sizeof(struct sockaddr_in)); /* Azzera il contenuto della struttura */
	sv_addr.sin_family = AF_INET;
	sv_addr.sin_port = htons(SERVER_PORT);
	inet_pton(AF_INET, SERVER_IP_ADD, &sv_addr.sin_addr.s_addr); /* Converte l'indirizzo da stringa a valore numerico */
	
	cl_ret = connect(cl_sk, (struct sockaddr *)(&sv_addr), sizeof(struct sockaddr_in));
	if(cl_ret == -1) {
		cerr << "Errore: funzione <connect> non eseguita correttamente sul client" << endl;
    		exit(0);
	}
	
	cout << endl;
	cout << "\033[32mCONNESSIONE CLIENT-SERVER EFFETTUATA\033[0m" << endl;
	cout << "\033[32mIndirizzo IP server: " << SERVER_IP_ADD << "\033[0m" << endl;
	cout << "\033[32mPorta server: " << SERVER_PORT << "\033[0m" << endl;
	cout << "\033[32mDescrittore del soket lato client in ascolto: " << cl_sk << "\033[0m" << endl;	
	cout << endl;
	cout << "********** FINE FASE DI CONNESSIONE *********" << endl;
	cout << endl;
	cout << "---------------------------------------------" << endl;
	cout << endl; 
	cout << "****** INIZIO FASE DI SCAMBIO MESSAGGI ******" << endl;
	cout << endl;
	
	/* Setto l'identificatore del client e del server */
	CLIENT = 'C';		
	SERVER = 'S';

	/* Costrutisco il messaggio M1 */
	msg1 m1;		
	m1.client = CLIENT;
	m1.server = SERVER;

	/* Invio al server il messaggio M1 */
	int dim1 = sizeof(msg1);
	ret = send(cl_sk, &m1, dim1, 0);
	if(ret == -1) {
		cerr << "Errore: messaggio M1 non inviato correttamente" << endl;
		return -1;
	}

	cout << "\033[32m:: C -> S\033[0m" << endl;
	cout << "\033[34m:: Messaggio in chiaro M1 inviato al server\033[0m" << endl;
	cout << endl;

	/* Ricevo dal server il messaggio M2 */
	msg2 m2;
	int dim2 = sizeof(msg2);
	ret = recv(cl_sk, &m2, dim2, MSG_WAITALL);
	if(ret == -1) {
		cerr << "Errore: messaggio M2 non ricevuto correttamente" << endl;
		return -1;
	}

	/* Memorizzo il nounce ricevuto dal server */
	NOUNCE = m2.nounce;

	cout << "\033[32m:: S -> C\033[0m" << endl;
	cout << "\033[34m:: Messaggio in chiaro M2 ricevuto correttamente\033[0m" << endl;
	cout << endl;

	/* Setto la chiave pubblica con cui criptare M3 */
	FILE *pub = fopen(PUB_KEY, "r");
	RSA *pub_key = RSA_new();
	PEM_read_RSA_PUBKEY(pub, &pub_key, NULL, NULL);

	/* Converto il nounce in una stringa per poterlo inserire nel messaggio da cifrare */
	char tmp[50];
	int n; //Numero di caratteri che compongono il nounce
	n = sprintf(tmp, "%i", NOUNCE); //Converto il nounce in una stringa
	char nounce[n];
	strcpy(nounce, tmp);
	
	/* Genero le componenti della chiave di sessione in maniera random */
	int part1 = rand();
	char tmp1[50];
	int t1 = sprintf(tmp1, "%i", part1);
	char p1[t1];
	strcpy(p1, tmp1);

	int part2 = rand();
	char tmp2[50];
	int t2 = sprintf(tmp2, "%i", part2);
	char p2[t2];
	strcpy(p2, tmp2);

	int part3 = rand();
	char tmp3[50];
	int t3 = sprintf(tmp3, "%i", part3);
	char p3[t3];
	strcpy(p3, tmp3);
	
	/* Costruisco la chiave di sessione */
	int dim_ses = t1 + t2 + t3; //Numero di caratteri della chiave di sessione
	char *ses_key = (char*) malloc (dim_ses);
	bzero(ses_key, dim_ses);
	strcpy(ses_key, p1);
	strcat(ses_key, p2);
	strcat(ses_key, p3);

	/* Setto la chiave di sessione */
	BF_KEY kcs;
	BF_set_key(&kcs, dim_ses, (const unsigned char*)ses_key);	

	/* Costruisco il messaggio M3 da criptare e inviare al client */
	int sep3 = 4; //Numero di separatori da inserire nel messaggio M3
	int ids3 = 2; //Numero di identificatori da inserire nel messaggio M3
	int dim3 = ids3 + n + np + dim_ses + sep3;
	char *m3 = (char*) malloc(dim3 + 1);
	bzero(m3, dim3 + 1);
	strcpy(m3, "C");
	strcat(m3, " ");
	strcat(m3, "S");
	strcat(m3, " ");
	strcat(m3, nounce);
	strcat(m3, " ");
	strcat(m3, CLIENT_PWD);
	strcat(m3, " ");
	strcat(m3, ses_key);
	
	/* Cripto il messaggio M3 con la chiave pubblica */
	unsigned char *m3c = (unsigned char*) malloc(RSA_size(pub_key));
	bzero(m3c, RSA_size(pub_key));
	int nc; //Numero di byte restituiti dalla cifratura
	nc = RSA_public_encrypt(dim3, (unsigned char*)m3, m3c, pub_key, RSA_PKCS1_OAEP_PADDING);
	if(nc == -1) {
		cerr << "Errore: funzione <RSA_public_encrypt> sul messaggio M3 non effettuata con successo" << endl;
		exit(1);
	}
	if(nc == 0) {
		cerr << "Errore: messaggio M3 non criptato correttamente" << endl;
		exit(1);	
	}

	/* Invio al server la dimensione del messaggio cifrato */
	int dim3c = RSA_size(pub_key);
	ret = send(cl_sk, &dim3c, 4, 0);
	if(ret == -1) {
		cerr << "Errore: dimensione del messaggio cifrato M3 non inviata correttamente" << endl;
		return -1;
	}

	/* Invio al server il messaggio cifrato M3 */
	ret = send(cl_sk, m3c, dim3c, 0);
	if(ret == -1) {
		cerr << "Errore: messaggio cifrato M3 non inviato correttamente" << endl;
		return -1;
	}

	cout << "\033[32m:: C -> S\033[0m" << endl;
	cout << "\033[34m:: Messaggio cifrato M3 inviato al server\033[0m" << endl;
		cout << endl;	

	/* Ricevo dal server la dimensione il messaggio criptato M4 */
	int dim4c;	
	ret = recv(cl_sk, &dim4c, 4, MSG_WAITALL);
	if(ret == -1) {
		cerr << "Errore: dimensione del messaggio cifrato M4 non ricevuta correttamente" << endl;
		return -1;
	}

	/* Imposto la dimensione del messaggio criptato M4 */
	double b = 8.0; //Numero di byte -> dimensione del blocco cifrato
	int dim4cb = (int)ceil(dim4c / b) * 8;
	dim4cb++;
	
	/* Ricevo dal server il messaggio criptato M4 */
	unsigned char *m4c = (unsigned char*) malloc(dim4cb);
	bzero(m4c, dim4cb);
	ret = recv(cl_sk, m4c, dim4cb, MSG_WAITALL);
	if(ret == -1) {
		cerr << "Errore: dimensione del messaggio cifrato M4 non ricevuta correttamente" << endl;
		return -1;
	}

	cout << "\033[32m:: S -> C\033[0m" << endl;
	cout << "\033[34m:: Messaggio cifrato M4 ricevuto correttamente\033[0m" << endl;

	/* Decifro il messaggio criptato M4 */
	unsigned char *m4 = (unsigned char*) malloc(dim4c);
	bzero(m4, dim4c);
	int off = 0; //Offeset		
	for(int i = 0; i < (int)ceil(dim4c / b); i++) {
		BF_ecb_encrypt(m4c + off, &m4[off], &kcs, BF_DECRYPT);
		off+=b;
	}

	cout << "\t\033[31m:: Messaggio cifrato M4 decriptato correttamente\033[0m" << endl;

	/* Analizzo il messaggio decriptato M4 */
	char *s4 = strtok((char*)m4, " "); //Memorizzo l'id del server
	char *c4 = strtok(NULL, " "); //Memorizzo l'id del client
	char *p4 = strtok(NULL, " "); //Memorizzo la password

	/* Controllo che la password sia quella attesa */
	if(strcmp(p4, CLIENT_PWD) != 0) {
		cout << "La password non coincide con quella attesa" << endl;
		exit(0);		
	}
	else {
		cout << "\033[31m\t:: Controllo Password -> OK\033[0m" << endl;
	}

	cout << endl;
	cout << "******* FINE FASE DI SCAMBIO MESSAGGI *******" << endl;
	cout << endl;
	cout << "---------------------------------------------" << endl;
	cout << endl;

	/* Pulizia delle variabili inutilizzate per evitare warning */	
	strcpy(c4, "");
	strcpy(s4, "");
 
	cout << "************ INIZIO FASE DI TEST ************" << endl;
	cout << endl;

	/* Apertura del file per effettuare il test */
	fstream ft;
	ft.open(TEST, ios::in);
	if(!ft) {
		cerr << "Errore nell'apertura del file di test" << endl;
    		exit(0);
  	}
	 
	/* Memorizzo il file di test in una stringa */	
	char *test_tmp = (char*) malloc(MAX_FILE_LEN);
	bzero(test_tmp, MAX_FILE_LEN);
	char line[MAX_LINE_LEN];
	while(ft.getline(line, MAX_LINE_LEN)) {
		strcat(test_tmp, line);		
	}

	/* Alloco lo spazio effettivamente utilizzato dal file di test */
	int dimtest = strlen(test_tmp) + 1;
	char *test = (char*) malloc(dimtest+1);
	bzero(test, dimtest);
	strcpy(test,test_tmp);

	/* Invio al server la dimensione del messaggio in chiaro */
	ret = send(cl_sk, &dimtest, 4, 0);
	if(ret == -1) {
		cerr << "Errore: dimensione del messaggio di test in chiaro non inviata correttamente" << endl;
		return -1;
	}

	/* Imposto la dimensione del messaggio di test criptato */
	int dimtestc = (int)ceil(dimtest / b) * 8;
	dimtestc++;

	/* Cripto la stringa del file di test */
	unsigned char *testc = (unsigned char*) malloc(dimtestc);
	bzero(testc, dimtestc);	
	int offtest = 0;
	for(int j = 0; j < (int)ceil(dimtest / b); j++) {
		BF_ecb_encrypt((const unsigned char*)test + offtest, &testc[offtest], &kcs, BF_ENCRYPT);
		offtest += b;	
	}

	/* Invio al server la dimensione della stringa di test cifrata */
	ret = send(cl_sk, &dimtestc, 4, 0);
	if(ret == -1) {
		cerr << "Errore: dimensione del messaggio di test cifrato non inviata correttamente" << endl;
		return -1;
	}

	/* Invio al server la stringa di test cifrata */
	ret = send(cl_sk, testc, dimtestc, 0);
	if(ret == -1) {
		cerr << "Errore: messaggio di test cifrato non inviato correttamente" << endl;
		return -1;
	}

	cout << "\033[32m:: C -> S\033[0m" << endl;
	cout << "\033[34m:: Messaggio di test cifrato e inviato al server\033[0m" << endl;

	cout << endl;
	cout << "************* FINE FASE DI TEST *************" << endl;
	cout << endl;

	/* Libero la memoria */
	RSA_free(pub_key);
	fclose(pub);
	free(m3);
	free(m3c);
	free(ses_key);
	free(m4c);
	free(m4);
	free(test_tmp);
	free(test);
	free(testc);
	
	return 0;
}
Ejemplo n.º 11
0
/* Pre-processes and outputs RSA public key to standard out.
 */
void output(RSA* key) {
  int i, nwords;
  const BIGNUM *key_n;
  BIGNUM *N = NULL;
  BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL;
  BIGNUM *B = NULL;
  BIGNUM *N0inv= NULL, *R = NULL, *RR = NULL, *RRTemp = NULL, *NnumBits = NULL;
  BIGNUM *n = NULL, *rr = NULL;
  BN_CTX *bn_ctx = BN_CTX_new();
  uint32_t n0invout;

  /* Output size of RSA key in 32-bit words */
  nwords = RSA_size(key) / 4;
  if (-1 == write(1, &nwords, sizeof(nwords)))
    goto failure;


  /* Initialize BIGNUMs */
  RSA_get0_key(key, &key_n, NULL, NULL);
  N = BN_dup(key_n);
  Big1 = BN_new();
  Big2 = BN_new();
  Big32 = BN_new();
  BigMinus1 = BN_new();
  N0inv= BN_new();
  R = BN_new();
  RR = BN_new();
  RRTemp = BN_new();
  NnumBits = BN_new();
  n = BN_new();
  rr = BN_new();


  BN_set_word(Big1, 1L);
  BN_set_word(Big2, 2L);
  BN_set_word(Big32, 32L);
  BN_sub(BigMinus1, Big1, Big2);

  B = BN_new();
  BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */

  /* Calculate and output N0inv = -1 / N[0] mod 2^32 */
  BN_mod_inverse(N0inv, N, B, bn_ctx);
  BN_sub(N0inv, B, N0inv);
  n0invout = BN_get_word(N0inv);
  if (-1 == write(1, &n0invout, sizeof(n0invout)))
    goto failure;

  /* Calculate R = 2^(# of key bits) */
  BN_set_word(NnumBits, BN_num_bits(N));
  BN_exp(R, Big2, NnumBits, bn_ctx);

  /* Calculate RR = R^2 mod N */
  BN_copy(RR, R);
  BN_mul(RRTemp, RR, R, bn_ctx);
  BN_mod(RR, RRTemp, N, bn_ctx);


  /* Write out modulus as little endian array of integers. */
  for (i = 0; i < nwords; ++i) {
    uint32_t nout;

    BN_mod(n, N, B, bn_ctx); /* n = N mod B */
    nout = BN_get_word(n);
    if (-1 == write(1, &nout, sizeof(nout)))
      goto failure;

    BN_rshift(N, N, 32); /*  N = N/B */
  }

  /* Write R^2 as little endian array of integers. */
  for (i = 0; i < nwords; ++i) {
    uint32_t rrout;

    BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */
    rrout = BN_get_word(rr);
    if (-1 == write(1, &rrout, sizeof(rrout)))
      goto failure;

    BN_rshift(RR, RR, 32); /* RR = RR/B */
  }

failure:
  /* Free BIGNUMs. */
  BN_free(N);
  BN_free(Big1);
  BN_free(Big2);
  BN_free(Big32);
  BN_free(BigMinus1);
  BN_free(N0inv);
  BN_free(R);
  BN_free(RRTemp);
  BN_free(NnumBits);
  BN_free(n);
  BN_free(rr);

}
Ejemplo n.º 12
0
static
int
__pkcs11h_openssl_rsa_enc (
	IN int flen,
	IN unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#else
static
int
__pkcs11h_openssl_rsa_enc (
	IN int flen,
	IN const unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#endif
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa);
	PKCS11H_BOOL session_locked = FALSE;
	CK_RV rv = CKR_FUNCTION_FAILED;
	size_t tlen;

	_PKCS11H_ASSERT (from!=NULL);
	_PKCS11H_ASSERT (to!=NULL);
	_PKCS11H_ASSERT (rsa!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_enc entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
		flen,
		from,
		to,
		(void *)rsa,
		padding
	);

	if (padding != RSA_PKCS1_PADDING) {
		rv = CKR_MECHANISM_INVALID;
		goto cleanup;
	}

	tlen = (size_t)RSA_size(rsa);

	if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) {
		goto cleanup;
	}
	session_locked = TRUE;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Performing signature"
	);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_RSA_PKCS,
			from,
			flen,
			to,
			&tlen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	rv = CKR_OK;

cleanup:

	if (session_locked) {
		pkcs11h_certificate_releaseSession (certificate);
		session_locked = FALSE;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_enc - return rv=%lu-'%s'",
		rv,
		pkcs11h_getMessage (rv)
	);

	return rv == CKR_OK ? (int)tlen : -1;
}
Ejemplo n.º 13
0
int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                              const unsigned char *EM, int sLen)
{
    int i;
    int ret = 0;
    int hLen, maskedDBLen, MSBits, emLen;
    const unsigned char *H;
    unsigned char *DB = NULL;
    EVP_MD_CTX ctx;
    unsigned char H_[EVP_MAX_MD_SIZE];
    EVP_MD_CTX_init(&ctx);

    if (mgf1Hash == NULL)
        mgf1Hash = Hash;

    hLen = EVP_MD_size(Hash);
    if (hLen < 0)
        goto err;
    /*-
     * Negative sLen has special meanings:
     *      -1      sLen == hLen
     *      -2      salt length is autorecovered from signature
     *      -N      reserved
     */
    if (sLen == -1)
        sLen = hLen;
    else if (sLen == -2)
        sLen = -2;
    else if (sLen < -2) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
        goto err;
    }

    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
    emLen = RSA_size(rsa);
    if (EM[0] & (0xFF << MSBits)) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
        goto err;
    }
    if (MSBits == 0) {
        EM++;
        emLen--;
    }
    if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
        goto err;
    }
    if (EM[emLen - 1] != 0xbc) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
        goto err;
    }
    maskedDBLen = emLen - hLen - 1;
    H = EM + maskedDBLen;
    DB = OPENSSL_malloc(maskedDBLen);
    if (!DB) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
        goto err;
    for (i = 0; i < maskedDBLen; i++)
        DB[i] ^= EM[i];
    if (MSBits)
        DB[0] &= 0xFF >> (8 - MSBits);
    for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
    if (DB[i++] != 0x1) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
        goto err;
    }
    if (sLen >= 0 && (maskedDBLen - i) != sLen) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
        goto err;
    }
    if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
        || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
        || !EVP_DigestUpdate(&ctx, mHash, hLen))
        goto err;
    if (maskedDBLen - i) {
        if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
            goto err;
    }
    if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
        goto err;
    if (sgx_memcmp(H_, H, hLen)) {
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
        ret = 0;
    } else
        ret = 1;

 err:
    if (DB)
        OPENSSL_free(DB);
    EVP_MD_CTX_cleanup(&ctx);

    return ret;

}
Ejemplo n.º 14
0
int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
                                   const unsigned char *mHash,
                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                                   int sLen)
{
    int i;
    int ret = 0;
    int hLen, maskedDBLen, MSBits, emLen;
    unsigned char *H, *salt = NULL, *p;
    EVP_MD_CTX ctx;

    if (mgf1Hash == NULL)
        mgf1Hash = Hash;

    hLen = EVP_MD_size(Hash);
    if (hLen < 0)
        goto err;
    /*-
     * Negative sLen has special meanings:
     *      -1      sLen == hLen
     *      -2      salt length is maximized
     *      -N      reserved
     */
    if (sLen == -1)
        sLen = hLen;
    else if (sLen == -2)
        sLen = -2;
    else if (sLen < -2) {
        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
        goto err;
    }

    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
    emLen = RSA_size(rsa);
    if (MSBits == 0) {
        *EM++ = 0;
        emLen--;
    }
    if (sLen == -2) {
        sLen = emLen - hLen - 2;
    } else if (emLen < (hLen + sLen + 2)) {
        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
        goto err;
    }
    if (sLen > 0) {
        salt = OPENSSL_malloc(sLen);
        if (!salt) {
            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
                   ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (RAND_bytes(salt, sLen) <= 0)
            goto err;
    }
    maskedDBLen = emLen - hLen - 1;
    H = EM + maskedDBLen;
    EVP_MD_CTX_init(&ctx);
    if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
        || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
        || !EVP_DigestUpdate(&ctx, mHash, hLen))
        goto err;
    if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
        goto err;
    if (!EVP_DigestFinal_ex(&ctx, H, NULL))
        goto err;
    EVP_MD_CTX_cleanup(&ctx);

    /* Generate dbMask in place then perform XOR on it */
    if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
        goto err;

    p = EM;

    /*
     * Initial PS XORs with all zeroes which is a NOP so just update pointer.
     * Note from a test above this value is guaranteed to be non-negative.
     */
    p += emLen - sLen - hLen - 2;
    *p++ ^= 0x1;
    if (sLen > 0) {
        for (i = 0; i < sLen; i++)
            *p++ ^= salt[i];
    }
    if (MSBits)
        EM[0] &= 0xFF >> (8 - MSBits);

    /* H is already in place so just set final 0xbc */

    EM[emLen - 1] = 0xbc;

    ret = 1;

 err:
    if (salt)
        OPENSSL_free(salt);

    return ret;

}
Ejemplo n.º 15
0
int fips_check_rsa(RSA *rsa)
    {
    int n, ret = 0;
    unsigned char tctext[256], *ctext = tctext;
    unsigned char tptext[256], *ptext = tptext;
    /* The longest we can have with PKCS#1 v1.5 padding and a 512 bit key,
     * namely 512/8-11-1 = 52 bytes */
    static const unsigned char original_ptext[] =
	"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
	"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
	"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
	"\x01\x23\x45\x67";

    if (RSA_size(rsa) > sizeof(tctext))
	{
	ctext = OPENSSL_malloc(RSA_size(rsa));
	ptext = OPENSSL_malloc(RSA_size(rsa));
	if (!ctext || !ptext)
		{
		ERR_print_errors_fp(OPENSSL_stderr());
		exit(1);
		}
	}
	

    /* this will fail for keys shorter than 512 bits */
    n=RSA_private_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,rsa,
			 RSA_PKCS1_PADDING);
    if(n < 0)
	{
	ERR_print_errors_fp(OPENSSL_stderr());
	exit(1);
	}
    if(!memcmp(ctext,original_ptext,n))
  	{
  	FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
 	goto error;
 	}
    n=RSA_public_decrypt(n,ctext,ptext,rsa,RSA_PKCS1_PADDING);
    if(n < 0)
	{
	ERR_print_errors_fp(OPENSSL_stderr());
	exit(1);
	}
    if(n != sizeof(original_ptext)-1 || memcmp(ptext,original_ptext,n))
	{
	FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
	goto error;
	}

    ret = 1;

    error:

    if (RSA_size(rsa) > sizeof(tctext))
	{
	OPENSSL_free(ctext);
	OPENSSL_free(ptext);
	}

    return ret;
    }
Ejemplo n.º 16
0
/* TODO : split this function in two so it becomes smaller */
SIGNATURE *signature_from_string(ssh_session session, ssh_string signature,
    ssh_public_key pubkey, int needed_type) {
  SIGNATURE *sign = NULL;
  ssh_buffer tmpbuf = NULL;
  ssh_string rs = NULL;
  ssh_string type_s = NULL;
  ssh_string e = NULL;
  char *type_c = NULL;
  int type;
  int len;
  int rsalen;
#ifdef HAVE_LIBGCRYPT
  gcry_sexp_t sig;
#elif defined HAVE_LIBCRYPTO
  DSA_SIG *sig = NULL;
  ssh_string r = NULL;
  ssh_string s = NULL;
#endif

  sign = malloc(sizeof(SIGNATURE));
  if (sign == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return NULL;
  }

  tmpbuf = buffer_new();
  if (tmpbuf == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    signature_free(sign);
    return NULL;
  }

  if (buffer_add_data(tmpbuf, string_data(signature), string_len(signature)) < 0) {
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }

  type_s = buffer_get_ssh_string(tmpbuf);
  if (type_s == NULL) {
    ssh_set_error(session, SSH_FATAL, "Invalid signature packet");
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }

  type_c = string_to_char(type_s);
  string_free(type_s);
  if (type_c == NULL) {
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }
  type = ssh_type_from_name(type_c);
  SAFE_FREE(type_c);

  if (needed_type != type) {
    ssh_set_error(session, SSH_FATAL, "Invalid signature type: %s",
        ssh_type_to_char(type));
    signature_free(sign);
    buffer_free(tmpbuf);
    return NULL;
  }

  switch(needed_type) {
    case TYPE_DSS:
      rs = buffer_get_ssh_string(tmpbuf);
      buffer_free(tmpbuf);

      /* 40 is the dual signature blob len. */
      if (rs == NULL || string_len(rs) != 40) {
        string_free(rs);
        signature_free(sign);
        return NULL;
      }

      /* we make use of strings (because we have all-made functions to convert
       * them to bignums (ou pas ;) */
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
            20 ,string_data(rs), 20,(unsigned char *)string_data(rs) + 20)) {
        string_free(rs);
        signature_free(sign);
        return NULL;
      }
#elif defined HAVE_LIBCRYPTO
      r = string_new(20);
      s = string_new(20);
      if (r == NULL || s == NULL) {
        string_free(r);
        string_free(s);
        string_free(rs);
        signature_free(sign);
        return NULL;
      }

      string_fill(r, string_data(rs), 20);
      string_fill(s, (char *)string_data(rs) + 20, 20);

      sig = DSA_SIG_new();
      if (sig == NULL) {
        string_free(r);
        string_free(s);
        string_free(rs);
        signature_free(sign);
        return NULL;
      }
      sig->r = make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
      sig->s = make_string_bn(s);
      string_free(r);
      string_free(s);

      if (sig->r == NULL || sig->s == NULL) {
        string_free(rs);
        DSA_SIG_free(sig);
        signature_free(sign);
        return NULL;
      }
#endif

#ifdef DEBUG_CRYPTO
      ssh_print_hexa("r", string_data(rs), 20);
      ssh_print_hexa("s", (const unsigned char *)string_data(rs) + 20, 20);
#endif
      string_free(rs);

      sign->type = TYPE_DSS;
      sign->dsa_sign = sig;

      return sign;
    case TYPE_RSA:
      e = buffer_get_ssh_string(tmpbuf);
      buffer_free(tmpbuf);
      if (e == NULL) {
        signature_free(sign);
        return NULL;
      }
      len = string_len(e);
#ifdef HAVE_LIBGCRYPT
      rsalen = (gcry_pk_get_nbits(pubkey->rsa_pub) + 7) / 8;
#elif defined HAVE_LIBCRYPTO
      rsalen = RSA_size(pubkey->rsa_pub);
#endif
      if (len > rsalen) {
        string_free(e);
        signature_free(sign);
        ssh_set_error(session, SSH_FATAL, "Signature too big! %d instead of %d",
            len, rsalen);
        return NULL;
      }

      if (len < rsalen) {
        ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d",
            len, rsalen);
      }
      sign->type = TYPE_RSA;
#ifdef HAVE_LIBGCRYPT
      if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
          string_len(e), string_data(e))) {
        signature_free(sign);
        string_free(e);
        return NULL;
      }

      sign->rsa_sign = sig;
#elif defined HAVE_LIBCRYPTO
      sign->rsa_sign = e;
#endif

#ifdef DEBUG_CRYPTO
      ssh_log(session, SSH_LOG_FUNCTIONS, "len e: %d", len);
      ssh_print_hexa("RSA signature", string_data(e), len);
#endif

#ifdef HAVE_LIBGCRYPT
      string_free(e);
#endif

      return sign;
    default:
      return NULL;
  }

  return NULL;
}
Ejemplo n.º 17
0
int
ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	Buffer b;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	char *ktype;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen, modlen;
	int rlen, ret, nid;

	if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
		pamsshagentauth_logerror("ssh_rsa_verify: no RSA key");
		return -1;
	}
	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
		pamsshagentauth_logerror("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
		    BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
		return -1;
	}
	pamsshagentauth_buffer_init(&b);
	pamsshagentauth_buffer_append(&b, signature, signaturelen);
	ktype = pamsshagentauth_buffer_get_string(&b, NULL);
	if (strcmp("ssh-rsa", ktype) != 0) {
		pamsshagentauth_logerror("ssh_rsa_verify: cannot handle type %s", ktype);
		pamsshagentauth_buffer_free(&b);
		pamsshagentauth_xfree(ktype);
		return -1;
	}
	pamsshagentauth_xfree(ktype);
	sigblob = pamsshagentauth_buffer_get_string(&b, &len);
	rlen = pamsshagentauth_buffer_len(&b);
	pamsshagentauth_buffer_free(&b);
	if (rlen != 0) {
		pamsshagentauth_logerror("ssh_rsa_verify: remaining bytes in signature %d", rlen);
		pamsshagentauth_xfree(sigblob);
		return -1;
	}
	/* RSA_verify expects a signature of RSA_size */
	modlen = RSA_size(key->rsa);
	if (len > modlen) {
		pamsshagentauth_logerror("ssh_rsa_verify: len %u > modlen %u", len, modlen);
		pamsshagentauth_xfree(sigblob);
		return -1;
	} else if (len < modlen) {
		u_int diff = modlen - len;
		pamsshagentauth_verbose("ssh_rsa_verify: add padding: modlen %u > len %u",
		    modlen, len);
		sigblob = pamsshagentauth_xrealloc(sigblob, 1, modlen);
		memmove(sigblob + diff, sigblob, len);
		memset(sigblob, 0, diff);
		len = modlen;
	}
	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		pamsshagentauth_logerror("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
		pamsshagentauth_xfree(sigblob);
		return -1;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
	memset(digest, 'd', sizeof(digest));
	memset(sigblob, 's', len);
	pamsshagentauth_xfree(sigblob);
	pamsshagentauth_verbose("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
	return ret;
}
Ejemplo n.º 18
0
int RSAKeyImpl::size() const
{
	return RSA_size(_pRSA);
}
Ejemplo n.º 19
0
int AuthenticateAgent(AgentConnection *conn, bool trust_key)
{
    char sendbuffer[CF_EXPANDSIZE], in[CF_BUFSIZE], *out, *decrypted_cchall;
    BIGNUM *nonce_challenge, *bn = NULL;
    unsigned char digest[EVP_MAX_MD_SIZE];
    int encrypted_len, nonce_len = 0, len, session_size;
    bool need_to_implicitly_trust_server;
    char enterprise_field = 'c';
    RSA *server_pubkey = NULL;

    if ((PUBKEY == NULL) || (PRIVKEY == NULL))
    {
        /* Try once more to load the keys, maybe the system is converging. */
        LoadSecretKeys();
        if ((PUBKEY == NULL) || (PRIVKEY == NULL))
        {
            char *pubkeyfile = PublicKeyFile(GetWorkDir());
            Log(LOG_LEVEL_ERR, "No public/private key pair found at: %s", pubkeyfile);
            free(pubkeyfile);
            return false;
        }
    }

    enterprise_field = CfEnterpriseOptions();
    session_size = CfSessionKeySize(enterprise_field);

/* Generate a random challenge to authenticate the server */

    nonce_challenge = BN_new();
    if (nonce_challenge == NULL)
    {
        Log(LOG_LEVEL_ERR, "Cannot allocate BIGNUM structure for server challenge");
        return false;
    }

    BN_rand(nonce_challenge, CF_NONCELEN, 0, 0);
    nonce_len = BN_bn2mpi(nonce_challenge, in);

    if (FIPS_MODE)
    {
        HashString(in, nonce_len, digest, CF_DEFAULT_DIGEST);
    }
    else
    {
        HashString(in, nonce_len, digest, HASH_METHOD_MD5);
    }

/* We assume that the server bound to the remote socket is the official one i.e. = root's */

    /* Ask the server to send us the public key if we don't have it. */
    if ((server_pubkey = HavePublicKeyByIP(conn->username, conn->remoteip)))
    {
        need_to_implicitly_trust_server = false;
        encrypted_len = RSA_size(server_pubkey);
    }
    else
    {
        need_to_implicitly_trust_server = true;
        encrypted_len = nonce_len;
    }

// Server pubkey is what we want to has as a unique ID

    snprintf(sendbuffer, sizeof(sendbuffer), "SAUTH %c %d %d %c",
             need_to_implicitly_trust_server ? 'n': 'y',
             encrypted_len, nonce_len, enterprise_field);

    out = xmalloc(encrypted_len);

    if (server_pubkey != NULL)
    {
        if (RSA_public_encrypt(nonce_len, in, out, server_pubkey, RSA_PKCS1_PADDING) <= 0)
        {
            Log(LOG_LEVEL_ERR,
                "Public encryption failed. (RSA_public_encrypt: %s)",
            CryptoLastErrorString());
            free(out);
            RSA_free(server_pubkey);
            return false;
        }

        memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, out, encrypted_len);
    }
    else
    {
        memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, in, nonce_len);
    }

/* proposition C1 - Send challenge / nonce */

    SendTransaction(conn->conn_info, sendbuffer, CF_RSA_PROTO_OFFSET + encrypted_len, CF_DONE);

    BN_free(bn);
    BN_free(nonce_challenge);
    free(out);

/*Send the public key - we don't know if server has it */
/* proposition C2 */

    memset(sendbuffer, 0, CF_EXPANDSIZE);
    len = BN_bn2mpi(PUBKEY->n, sendbuffer);
    SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE);        /* No need to encrypt the public key ... */

/* proposition C3 */
    memset(sendbuffer, 0, CF_EXPANDSIZE);
    len = BN_bn2mpi(PUBKEY->e, sendbuffer);
    SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE);

/* check reply about public key - server can break conn_info here */

/* proposition S1 */
    memset(in, 0, CF_BUFSIZE);

    if (ReceiveTransaction(conn->conn_info, in, NULL) == -1)
    {
        Log(LOG_LEVEL_ERR, "Protocol transaction broken off (1). (ReceiveTransaction: %s)", GetErrorStr());
        RSA_free(server_pubkey);
        return false;
    }

    if (BadProtoReply(in))
    {
        Log(LOG_LEVEL_ERR, "Bad protocol reply: %s", in);
        RSA_free(server_pubkey);
        return false;
    }

/* Get challenge response - should be CF_DEFAULT_DIGEST of challenge */

/* proposition S2 */
    memset(in, 0, CF_BUFSIZE);

    if (ReceiveTransaction(conn->conn_info, in, NULL) == -1)
    {
        Log(LOG_LEVEL_ERR, "Protocol transaction broken off (2). (ReceiveTransaction: %s)", GetErrorStr());
        RSA_free(server_pubkey);
        return false;
    }

    /* Check if challenge reply was correct */
    if ((HashesMatch(digest, in, CF_DEFAULT_DIGEST)) ||
        (HashesMatch(digest, in, HASH_METHOD_MD5)))  // Legacy
    {
        if (need_to_implicitly_trust_server == false)
        {
            /* The IP was found in lastseen. */
            Log(LOG_LEVEL_VERBOSE,
                ".....................[.h.a.i.l.].................................");
            Log(LOG_LEVEL_VERBOSE,
                "Strong authentication of server '%s' connection confirmed",
                conn->this_server);
        }
        else                                /* IP was not found in lastseen */
        {
            if (trust_key)
            {
                Log(LOG_LEVEL_VERBOSE,
                    "Trusting server identity, promise to accept key from '%s' = '%s'",
                    conn->this_server, conn->remoteip);
            }
            else
            {
                Log(LOG_LEVEL_ERR,
                    "Not authorized to trust public key of server '%s' (trustkey = false)",
                    conn->this_server);
                RSA_free(server_pubkey);
                return false;
            }
        }
    }
    else
    {
        Log(LOG_LEVEL_ERR, "Challenge response from server '%s/%s' was incorrect", conn->this_server,
             conn->remoteip);
        RSA_free(server_pubkey);
        return false;
    }

/* Receive counter challenge from server */

/* proposition S3 */
    memset(in, 0, CF_BUFSIZE);
    encrypted_len = ReceiveTransaction(conn->conn_info, in, NULL);

    if (encrypted_len <= 0)
    {
        Log(LOG_LEVEL_ERR, "Protocol transaction sent illegal cipher length");
        RSA_free(server_pubkey);
        return false;
    }

    decrypted_cchall = xmalloc(encrypted_len);

    if (RSA_private_decrypt(encrypted_len, in, decrypted_cchall, PRIVKEY, RSA_PKCS1_PADDING) <= 0)
    {
        Log(LOG_LEVEL_ERR,
            "Private decrypt failed, abandoning. (RSA_private_decrypt: %s)",
            CryptoLastErrorString());
        RSA_free(server_pubkey);
        return false;
    }

/* proposition C4 */
    if (FIPS_MODE)
    {
        HashString(decrypted_cchall, nonce_len, digest, CF_DEFAULT_DIGEST);
    }
    else
    {
        HashString(decrypted_cchall, nonce_len, digest, HASH_METHOD_MD5);
    }

    if (FIPS_MODE)
    {
        SendTransaction(conn->conn_info, digest, CF_DEFAULT_DIGEST_LEN, CF_DONE);
    }
    else
    {
        SendTransaction(conn->conn_info, digest, CF_MD5_LEN, CF_DONE);
    }

    free(decrypted_cchall);

/* If we don't have the server's public key, it will be sent */

    if (server_pubkey == NULL)
    {
        RSA *newkey = RSA_new();

        Log(LOG_LEVEL_VERBOSE, "Collecting public key from server!");

        /* proposition S4 - conditional */
        if ((len = ReceiveTransaction(conn->conn_info, in, NULL)) <= 0)
        {
            Log(LOG_LEVEL_ERR, "Protocol error in RSA authentation from IP '%s'", conn->this_server);
            return false;
        }

        if ((newkey->n = BN_mpi2bn(in, len, NULL)) == NULL)
        {
            Log(LOG_LEVEL_ERR,
                "Private key decrypt failed. (BN_mpi2bn: %s)",
                CryptoLastErrorString());
            RSA_free(newkey);
            return false;
        }

        /* proposition S5 - conditional */

        if ((len = ReceiveTransaction(conn->conn_info, in, NULL)) <= 0)
        {
            Log(LOG_LEVEL_INFO, "Protocol error in RSA authentation from IP '%s'",
                 conn->this_server);
            RSA_free(newkey);
            return false;
        }

        if ((newkey->e = BN_mpi2bn(in, len, NULL)) == NULL)
        {
            Log(LOG_LEVEL_ERR,
                "Public key decrypt failed. (BN_mpi2bn: %s)",
                CryptoLastErrorString());
            RSA_free(newkey);
            return false;
        }

        server_pubkey = RSAPublicKey_dup(newkey);
        RSA_free(newkey);
    }
    assert(server_pubkey != NULL);

/* proposition C5 */

    if (!SetSessionKey(conn))
    {
        Log(LOG_LEVEL_ERR, "Unable to set session key");
        return false;
    }

    if (conn->session_key == NULL)
    {
        Log(LOG_LEVEL_ERR, "A random session key could not be established");
        RSA_free(server_pubkey);
        return false;
    }

    encrypted_len = RSA_size(server_pubkey);

    out = xmalloc(encrypted_len);

    if (RSA_public_encrypt(session_size, conn->session_key, out, server_pubkey, RSA_PKCS1_PADDING) <= 0)
    {
        Log(LOG_LEVEL_ERR,
            "Public encryption failed. (RSA_public_encrypt: %s)",
            CryptoLastErrorString());
        free(out);
        RSA_free(server_pubkey);
        return false;
    }

    SendTransaction(conn->conn_info, out, encrypted_len, CF_DONE);

    Key *key = KeyNew(server_pubkey, CF_DEFAULT_DIGEST);
    conn->conn_info->remote_key = key;

    Log(LOG_LEVEL_VERBOSE, "Public key identity of host '%s' is: %s",
        conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key));

    SavePublicKey(conn->username, KeyPrintableHash(conn->conn_info->remote_key), server_pubkey);

    unsigned int length = 0;
    LastSaw(conn->remoteip, KeyBinaryHash(conn->conn_info->remote_key, &length), LAST_SEEN_ROLE_CONNECT);

    free(out);

    return true;
}
Ejemplo n.º 20
0
int
RSA_verify(int type, const unsigned char *from, unsigned int flen,
	   unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
{
    if (rsa->meth->rsa_verify)
	return rsa->meth->rsa_verify(type, from, flen, sigbuf, siglen, rsa);

    if (rsa->meth->rsa_pub_dec) {
	const AlgorithmIdentifier *digest_alg;
	void *data;
	DigestInfo di;
	size_t size;
	int ret, ret2;

	data = malloc(RSA_size(rsa));
	if (data == NULL)
	    return -1;

	memset(&di, 0, sizeof(di));

	ret = rsa->meth->rsa_pub_dec(siglen, sigbuf, data, rsa, RSA_PKCS1_PADDING);
	if (ret <= 0) {
	    free(data);
	    return -2;
	}

	ret2 = decode_DigestInfo(data, ret, &di, &size);
	free(data);
	if (ret2 != 0)
	    return -3;
	if (ret != size) {
	    free_DigestInfo(&di);
	    return -4;
	}

	if (flen != di.digest.length || memcmp(di.digest.data, from, flen) != 0) {
	    free_DigestInfo(&di);
	    return -5;
	}

	if (type == NID_sha1) {
	    digest_alg = &_signature_sha1_data;
	} else if (type == NID_md5) {
	    digest_alg = &_signature_md5_data;
	} else if (type == NID_sha256) {
	    digest_alg = &_signature_sha256_data;
	} else {
	    free_DigestInfo(&di);
	    return -1;
	}
	
	ret = der_heim_oid_cmp(&digest_alg->algorithm,
			       &di.digestAlgorithm.algorithm);
	free_DigestInfo(&di);
	
	if (ret != 0)
	    return 0;
	return 1;
    }

    return 0;
}
Ejemplo n.º 21
0
int
rsautl_main(int argc, char **argv)
{
	ENGINE *e = NULL;
	BIO *in = NULL, *out = NULL;
	char *infile = NULL, *outfile = NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	char *keyfile = NULL;
	char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
	int keyform = FORMAT_PEM;
	char need_priv = 0, badarg = 0, rev = 0;
	char hexdump = 0, asn1parse = 0;
	X509 *x;
	EVP_PKEY *pkey = NULL;
	RSA *rsa = NULL;
	unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
	char *passargin = NULL, *passin = NULL;
	int rsa_inlen, rsa_outlen = 0;
	int keysize;

	int ret = 1;

	argc--;
	argv++;

	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();
	pad = RSA_PKCS1_PADDING;

	while (argc >= 1) {
		if (!strcmp(*argv, "-in")) {
			if (--argc < 1)
				badarg = 1;
			else
				infile = *(++argv);
		} else if (!strcmp(*argv, "-out")) {
			if (--argc < 1)
				badarg = 1;
			else
				outfile = *(++argv);
		} else if (!strcmp(*argv, "-inkey")) {
			if (--argc < 1)
				badarg = 1;
			else
				keyfile = *(++argv);
		} else if (!strcmp(*argv, "-passin")) {
			if (--argc < 1)
				badarg = 1;
			else
				passargin = *(++argv);
		} else if (strcmp(*argv, "-keyform") == 0) {
			if (--argc < 1)
				badarg = 1;
			else
				keyform = str2fmt(*(++argv));
#ifndef OPENSSL_NO_ENGINE
		} else if (!strcmp(*argv, "-engine")) {
			if (--argc < 1)
				badarg = 1;
			else
				engine = *(++argv);
#endif
		} else if (!strcmp(*argv, "-pubin")) {
			key_type = KEY_PUBKEY;
		} else if (!strcmp(*argv, "-certin")) {
			key_type = KEY_CERT;
		} else if (!strcmp(*argv, "-asn1parse"))
			asn1parse = 1;
		else if (!strcmp(*argv, "-hexdump"))
			hexdump = 1;
		else if (!strcmp(*argv, "-raw"))
			pad = RSA_NO_PADDING;
		else if (!strcmp(*argv, "-oaep"))
			pad = RSA_PKCS1_OAEP_PADDING;
		else if (!strcmp(*argv, "-ssl"))
			pad = RSA_SSLV23_PADDING;
		else if (!strcmp(*argv, "-pkcs"))
			pad = RSA_PKCS1_PADDING;
		else if (!strcmp(*argv, "-x931"))
			pad = RSA_X931_PADDING;
		else if (!strcmp(*argv, "-sign")) {
			rsa_mode = RSA_SIGN;
			need_priv = 1;
		} else if (!strcmp(*argv, "-verify"))
			rsa_mode = RSA_VERIFY;
		else if (!strcmp(*argv, "-rev"))
			rev = 1;
		else if (!strcmp(*argv, "-encrypt"))
			rsa_mode = RSA_ENCRYPT;
		else if (!strcmp(*argv, "-decrypt")) {
			rsa_mode = RSA_DECRYPT;
			need_priv = 1;
		} else
			badarg = 1;
		if (badarg) {
			usage();
			goto end;
		}
		argc--;
		argv++;
	}

	if (need_priv && (key_type != KEY_PRIVKEY)) {
		BIO_printf(bio_err, "A private key is needed for this operation\n");
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	e = setup_engine(bio_err, engine, 0);
#endif
	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}

	switch (key_type) {
	case KEY_PRIVKEY:
		pkey = load_key(bio_err, keyfile, keyform, 0,
		    passin, e, "Private Key");
		break;

	case KEY_PUBKEY:
		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
		    NULL, e, "Public Key");
		break;

	case KEY_CERT:
		x = load_cert(bio_err, keyfile, keyform,
		    NULL, e, "Certificate");
		if (x) {
			pkey = X509_get_pubkey(x);
			X509_free(x);
		}
		break;
	}

	if (!pkey) {
		return 1;
	}
	rsa = EVP_PKEY_get1_RSA(pkey);
	EVP_PKEY_free(pkey);

	if (!rsa) {
		BIO_printf(bio_err, "Error getting RSA key\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile) {
		if (!(in = BIO_new_file(infile, "rb"))) {
			BIO_printf(bio_err, "Error Reading Input File\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	} else
		in = BIO_new_fp(stdin, BIO_NOCLOSE);

	if (outfile) {
		if (!(out = BIO_new_file(outfile, "wb"))) {
			BIO_printf(bio_err, "Error Reading Output File\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	}

	keysize = RSA_size(rsa);

	rsa_in = reallocarray(NULL, keysize, 2);
	rsa_out = malloc(keysize);

	/* Read the input data */
	rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
	if (rsa_inlen <= 0) {
		BIO_printf(bio_err, "Error reading input Data\n");
		exit(1);
	}
	if (rev) {
		int i;
		unsigned char ctmp;
		for (i = 0; i < rsa_inlen / 2; i++) {
			ctmp = rsa_in[i];
			rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
			rsa_in[rsa_inlen - 1 - i] = ctmp;
		}
	}
	switch (rsa_mode) {

	case RSA_VERIFY:
		rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	case RSA_SIGN:
		rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	case RSA_ENCRYPT:
		rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	case RSA_DECRYPT:
		rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
		break;

	}

	if (rsa_outlen <= 0) {
		BIO_printf(bio_err, "RSA operation error\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	ret = 0;
	if (asn1parse) {
		if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
			ERR_print_errors(bio_err);
		}
	} else if (hexdump)
		BIO_dump(out, (char *) rsa_out, rsa_outlen);
	else
		BIO_write(out, rsa_out, rsa_outlen);

end:
	RSA_free(rsa);
	BIO_free(in);
	BIO_free_all(out);
	free(rsa_in);
	free(rsa_out);
	free(passin);

	return ret;
}
Ejemplo n.º 22
0
int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                   const uint8_t *in, size_t in_len, int padding) {
  if (rsa->n == NULL || rsa->e == NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
    return 0;
  }

  const unsigned rsa_size = RSA_size(rsa);
  BIGNUM *f, *result;

  if (max_out < rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
    return 0;
  }

  if (in_len != rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
    return 0;
  }

  if (!check_modulus_and_exponent_sizes(rsa)) {
    return 0;
  }

  BN_CTX *ctx = BN_CTX_new();
  if (ctx == NULL) {
    return 0;
  }

  int ret = 0;
  uint8_t *buf = NULL;

  BN_CTX_start(ctx);
  f = BN_CTX_get(ctx);
  result = BN_CTX_get(ctx);
  if (f == NULL || result == NULL) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (padding == RSA_NO_PADDING) {
    buf = out;
  } else {
    // Allocate a temporary buffer to hold the padded plaintext.
    buf = OPENSSL_malloc(rsa_size);
    if (buf == NULL) {
      OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  if (BN_bin2bn(in, in_len, f) == NULL) {
    goto err;
  }

  if (BN_ucmp(f, rsa->n) >= 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
    goto err;
  }

  if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) ||
      !BN_mod_exp_mont(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
    goto err;
  }

  if (!BN_bn2bin_padded(buf, rsa_size, result)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  switch (padding) {
    case RSA_PKCS1_PADDING:
      ret =
          RSA_padding_check_PKCS1_type_1(out, out_len, rsa_size, buf, rsa_size);
      break;
    case RSA_NO_PADDING:
      ret = 1;
      *out_len = rsa_size;
      break;
    default:
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
      goto err;
  }

  if (!ret) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
    goto err;
  }

err:
  BN_CTX_end(ctx);
  BN_CTX_free(ctx);
  if (buf != out) {
    OPENSSL_free(buf);
  }
  return ret;
}
Ejemplo n.º 23
0
int bdd_search_modele ( MYSQL_RES* resultat_req, Ref* modele )
{
    // Initialisation
    Ref reference ;
    int return_value ;
    int suite = TRUE ;
    MYSQL_ROW tuple ;
    char* user = NULL ;
    char* safe_tuple = NULL ;              // Permet d'appeler strtok_r sur le bon contenu.
    char* reponse = NULL ;
    int first = TRUE ;

    // Initialisation
    user = (char*) malloc ( TAILLE_HASH_NOM * sizeof ( char ) ) ;
    memset ( user, '\0', TAILLE_HASH_NOM ) ;

    // Initialisation
    char* output = (char*) malloc ( RSA_size ( bdd_key ) * sizeof ( char ) ) ;
    memset ( output, '\0', RSA_size ( bdd_key ) ) ;

    // Initialisation
    char* temporaire = (char*) malloc ( ( TAILLE_MAX_REF + TAILLE_HASH_NOM + 3 ) * nbr_tuples * sizeof ( char ) ) ;
    memset ( temporaire, '\0', ( TAILLE_MAX_REF + TAILLE_HASH_NOM + 3 ) * nbr_tuples ) ;

    // On parcourt chaque tuple
    while ( suite == TRUE )
    {
        // On récupère un tuple
        if ( ( tuple = mysql_fetch_row ( resultat_req ) ) ==  NULL )
            suite = FALSE ;

        // On le traite
        if ( suite == TRUE )
        {
            // On découpe la référence
            if ( ( return_value = ref_split ( tuple[0], &reference ) ) == ERRNO )
            {
                perror ( "Erreur_bdd_search_modele : ref_split " ) ;
                free ( user ) ;
                free ( output ) ;
                bdd_send_msg ( SEEK, "ERROR" ) ;
                return ERRNO ;
            }

            // On regarde si elle correspond à ce que l'on recherche
            if ( ( return_value = ref_cmp ( &reference, modele ) ) == ERRNO )
            {
                perror ( "Erreur_bdd_traitement_request : ref_cmp " ) ;
                free ( user ) ;
                free ( output ) ;
                bdd_send_msg ( SEEK, "ERROR" ) ;
                return ERRNO ;
            }
            else if ( return_value == TRUE )    // La référence nous intéresse
            {

                // On déchiffre le tuple
                memset ( output, '\0', RSA_size ( bdd_key ) ) ;
                if ( RSA_chiffrement ( (unsigned char*) tuple[1], (unsigned char*) output, DECHIFFREMENT ) != TRUE )
                {
                    perror ( "Erreur_bdd_serach_modele : RSA_dechiffrement " ) ;
                    free ( output ) ;
                    free ( user ) ;
                    bdd_send_msg ( SEEK, "ERROR" ) ;
                    return ERRNO ;
                }

                // On récupère le hash du nom associé
                memset ( user, '\0', TAILLE_HASH_NOM ) ;
                sprintf ( user, "%s", strtok_r ( output, "*", &safe_tuple ) ) ;

                // On ajoute la référence et le nom associé à la réponse
                if ( first == TRUE )
                {
                    sprintf ( temporaire, "%s;%s", tuple[0], user ) ;
                    first = FALSE ;
                }
                else if ( first == FALSE )
                    sprintf ( temporaire + strlen ( temporaire ), "*%s;%s", tuple[0], user ) ;
            }
        }
    }

    // On envoie la réponse
    int taille = strlen ( temporaire ) + 10 ;
    reponse = (char*) malloc ( taille * sizeof ( char ) ) ;
    memset ( reponse, '\0', taille ) ;
    sprintf ( reponse, "%d*%s*EOF", SEEK, temporaire ) ;
    res_send ( reponse ) ;

    // Free
    free ( output ) ;
    free ( user ) ;
    free ( temporaire ) ;
    free ( reponse ) ;

    // On indique que tout s'est bien déroulé
    return TRUE ;
}
Ejemplo n.º 24
0
int int_rsa_verify(int dtype, const unsigned char *m,
                   unsigned int m_len,
                   unsigned char *rm, size_t *prm_len,
                   const unsigned char *sigbuf, size_t siglen, RSA *rsa)
{
    int i, ret = 0, sigtype;
    unsigned char *s;
    X509_SIG *sig = NULL;

    if (siglen != (unsigned int)RSA_size(rsa)) {
        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
        return (0);
    }

    if ((dtype == NID_md5_sha1) && rm) {
        i = RSA_public_decrypt((int)siglen,
                               sigbuf, rm, rsa, RSA_PKCS1_PADDING);
        if (i <= 0)
            return 0;
        *prm_len = i;
        return 1;
    }

    s = OPENSSL_malloc((unsigned int)siglen);
    if (s == NULL) {
        RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) {
        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
        goto err;
    }
    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);

    if (i <= 0)
        goto err;
    /*
     * Oddball MDC2 case: signature can be OCTET STRING. check for correct
     * tag and length octets.
     */
    if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) {
        if (rm) {
            memcpy(rm, s + 2, 16);
            *prm_len = 16;
            ret = 1;
        } else if (memcmp(m, s + 2, 16)) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
        } else {
            ret = 1;
        }
    } else if (dtype == NID_md5_sha1) {
        /* Special case: SSL signature */
        if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
        else
            ret = 1;
    } else {
        const unsigned char *p = s;
        sig = d2i_X509_SIG(NULL, &p, (long)i);

        if (sig == NULL)
            goto err;

        /* Excess data can be used to create forgeries */
        if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }

        /*
         * Parameters to the signature algorithm can also be used to create
         * forgeries
         */
        if (sig->algor->parameter
            && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }

        sigtype = OBJ_obj2nid(sig->algor->algorithm);

#ifdef RSA_DEBUG
        /* put a backward compatibility flag in EAY */
        fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
                OBJ_nid2ln(dtype));
#endif
        if (sigtype != dtype) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
            goto err;
        }
        if (rm) {
            const EVP_MD *md;
            md = EVP_get_digestbynid(dtype);
            if (md && (EVP_MD_size(md) != sig->digest->length))
                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
            else {
                memcpy(rm, sig->digest->data, sig->digest->length);
                *prm_len = sig->digest->length;
                ret = 1;
            }
        } else if (((unsigned int)sig->digest->length != m_len) ||
                   (memcmp(m, sig->digest->data, m_len) != 0)) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
        } else
            ret = 1;
    }
 err:
    X509_SIG_free(sig);
    OPENSSL_clear_free(s, (unsigned int)siglen);
    return (ret);
}
Ejemplo n.º 25
0
int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                        const uint8_t *in, size_t in_len, int padding) {
  const unsigned rsa_size = RSA_size(rsa);
  int r = -1;
  uint8_t *buf = NULL;
  int ret = 0;

  if (max_out < rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
    return 0;
  }

  if (padding == RSA_NO_PADDING) {
    buf = out;
  } else {
    /* Allocate a temporary buffer to hold the padded plaintext. */
    buf = OPENSSL_malloc(rsa_size);
    if (buf == NULL) {
      OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  if (in_len != rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
    goto err;
  }

  if (!RSA_private_transform(rsa, buf, in, rsa_size)) {
    goto err;
  }

  switch (padding) {
    case RSA_PKCS1_PADDING:
      r = RSA_padding_check_PKCS1_type_2(out, rsa_size, buf, rsa_size);
      break;
    case RSA_PKCS1_OAEP_PADDING:
      /* Use the default parameters: SHA-1 for both hashes and no label. */
      r = RSA_padding_check_PKCS1_OAEP_mgf1(out, rsa_size, buf, rsa_size,
                                            NULL, 0, NULL, NULL);
      break;
    case RSA_NO_PADDING:
      r = rsa_size;
      break;
    default:
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
      goto err;
  }

  if (r < 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
  } else {
    *out_len = r;
    ret = 1;
  }

err:
  if (padding != RSA_NO_PADDING && buf != NULL) {
    OPENSSL_cleanse(buf, rsa_size);
    OPENSSL_free(buf);
  }

  return ret;
}
Ejemplo n.º 26
0
int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
             unsigned char *sigret, unsigned int *siglen, RSA *rsa)
{
    X509_SIG sig;
    ASN1_TYPE parameter;
    int i, j, ret = 1;
    unsigned char *p, *tmps = NULL;
    const unsigned char *s = NULL;
    X509_ALGOR algor;
    ASN1_OCTET_STRING digest;
    if (rsa->meth->rsa_sign) {
        return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
    }
    /* Special case: SSL signature, just check the length */
    if (type == NID_md5_sha1) {
        if (m_len != SSL_SIG_LENGTH) {
            RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
            return (0);
        }
        i = SSL_SIG_LENGTH;
        s = m;
    } else {
        sig.algor = &algor;
        sig.algor->algorithm = OBJ_nid2obj(type);
        if (sig.algor->algorithm == NULL) {
            RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
            return (0);
        }
        if (OBJ_length(sig.algor->algorithm) == 0) {
            RSAerr(RSA_F_RSA_SIGN,
                   RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
            return (0);
        }
        parameter.type = V_ASN1_NULL;
        parameter.value.ptr = NULL;
        sig.algor->parameter = &parameter;

        sig.digest = &digest;
        sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
        sig.digest->length = m_len;

        i = i2d_X509_SIG(&sig, NULL);
    }
    j = RSA_size(rsa);
    if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
        RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
        return (0);
    }
    if (type != NID_md5_sha1) {
        tmps = OPENSSL_malloc((unsigned int)j + 1);
        if (tmps == NULL) {
            RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);
            return (0);
        }
        p = tmps;
        i2d_X509_SIG(&sig, &p);
        s = tmps;
    }
    i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
    if (i <= 0)
        ret = 0;
    else
        *siglen = i;

    if (type != NID_md5_sha1)
        OPENSSL_clear_free(tmps, (unsigned int)j + 1);
    return (ret);
}
Ejemplo n.º 27
0
int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                        const uint8_t *in, size_t in_len, int padding) {
  const unsigned rsa_size = RSA_size(rsa);
  BIGNUM *f, *result;
  uint8_t *buf = NULL;
  BN_CTX *ctx = NULL;
  int i, ret = 0;

  if (max_out < rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
    return 0;
  }

  if (!check_modulus_and_exponent_sizes(rsa)) {
    return 0;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }

  BN_CTX_start(ctx);
  f = BN_CTX_get(ctx);
  result = BN_CTX_get(ctx);
  buf = OPENSSL_malloc(rsa_size);
  if (!f || !result || !buf) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  switch (padding) {
    case RSA_PKCS1_PADDING:
      i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len);
      break;
    case RSA_PKCS1_OAEP_PADDING:
      /* Use the default parameters: SHA-1 for both hashes and no label. */
      i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len,
                                          NULL, 0, NULL, NULL);
      break;
    case RSA_NO_PADDING:
      i = RSA_padding_add_none(buf, rsa_size, in, in_len);
      break;
    default:
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
      goto err;
  }

  if (i <= 0) {
    goto err;
  }

  if (BN_bin2bn(buf, rsa_size, f) == NULL) {
    goto err;
  }

  if (BN_ucmp(f, rsa->n) >= 0) {
    /* usually the padding functions would catch this */
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
    goto err;
  }

  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
      goto err;
    }
  }

  if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
    goto err;
  }

  /* put in leading 0 bytes if the number is less than the length of the
   * modulus */
  if (!BN_bn2bin_padded(out, rsa_size, result)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  *out_len = rsa_size;
  ret = 1;

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  if (buf != NULL) {
    OPENSSL_cleanse(buf, rsa_size);
    OPENSSL_free(buf);
  }

  return ret;
}
Ejemplo n.º 28
0
int main(int argc, char **argv) {
	if(argc != 5)
		usageError();
	
	struct addrinfo hints, *res, *p;
	int sock, gai;
	FILE *s;

	memset(&hints, 0, sizeof(hints));
	hints.ai_socktype = SOCK_STREAM;    // use tcp socket
	hints.ai_family   = PF_UNSPEC;      // use ipv4 or ipv6
	hints.ai_flags    = AI_ADDRCONFIG;  // use ipv6 if we have interface

	printf("Connecting to %s:%s ...\n", argv[3], argv[4]);

	if(0 != (gai = getaddrinfo(argv[3], argv[4], &hints, &res))) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai));
		exit(EXIT_FAILURE);
	}
	
	/* as no domain was specified, use both (v4/v6) and check which connects properly */
	for(p = res; p != NULL; p = p->ai_next) {
		sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if(0 == connect(sock, p->ai_addr, p->ai_addrlen)) 
			break;

	}
	if(NULL == p) {
		perror("socket");
		exit(EXIT_FAILURE);
	}
#ifdef DEBUG
	printf("Domain: %d; Type: %d; Protocol: %d\n", p->ai_family, p->ai_socktype, p->ai_protocol);
#endif
	
	/* open network stream for conveniente read/write */
	if(NULL == (s = fdopen(sock, "a+"))) {
		perror("fdopen");
		exit(EXIT_FAILURE);
	}
	
	printf("Connection established\n");

	/* init crypto */
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	FILE *privKey, *pubKey;
	RSA *rsaPrivKey = NULL;
	RSA *rsaPubKey = NULL;
	int encSize, decSize, encSizeToServer;

	/* open and read client private key */
	if(NULL == (privKey = fopen(argv[1], "r"))) {
		perror("fopen");
		exit(EXIT_FAILURE);
	}
	if(NULL == (rsaPrivKey = PEM_read_RSAPrivateKey(privKey,NULL, NULL, CLIENTPASSPHRASE))) {
		fprintf(stderr, "PEM_read_RSAPrivateKey: %s\n", ERR_error_string(ERR_get_error(), NULL));
		exit(EXIT_FAILURE);
	}
	encSize = RSA_size(rsaPrivKey);
	decSize = RSA_size(rsaPrivKey) - RSA_PKCS1_OAEP_PADDING_SIZE;

	unsigned char decChallenge[decSize];
	unsigned char encChallenge[encSize];

	/* get the encrypted challenge from server */
	fread(encChallenge, encSize, 1, s);
#ifdef DEBUG
	printf("encrypted Challenge received:\n");
	dump(encChallenge, encSize);
#endif

	/* decrypted challenge from server */
	if(0 == RSA_private_decrypt(encSize, encChallenge, decChallenge, rsaPrivKey, RSA_PKCS1_OAEP_PADDING)) {
		fprintf(stderr, "RSA_public_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
		exit(EXIT_FAILURE);
	}
	unsigned char challenge[decSize];	
	memcpy(challenge, decChallenge, decSize);   // save the decrypted challenge for later
	
	/* encrypting answer to server */
	/* open server public Key */
	if(NULL == (pubKey = fopen(argv[2], "r"))) {
		perror("fopen");
		exit(EXIT_FAILURE);
	}
	if(NULL == (rsaPubKey = PEM_read_RSA_PUBKEY(pubKey, NULL, NULL, NULL))) {
		perror("PEM_read_RSA_PUBKEY");
		exit(EXIT_FAILURE);
	}
	encSizeToServer = RSA_size(rsaPubKey);
	unsigned char encChallengeToServer[encSizeToServer];

	/* encrypt the (decrypted) challenge again, now with server's publickey */
	if(-1 == RSA_public_encrypt(decSize, decChallenge, encChallengeToServer, rsaPubKey, RSA_PKCS1_OAEP_PADDING)) {
		fprintf(stderr, "RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
		exit(EXIT_FAILURE);
	}
#ifdef DEBUG
	printf("plaintext Challenge received:\n");
	dump(decChallenge, decSize);
	printf("encrypted Challenge to Server:\n");
	dump(encChallengeToServer, encSizeToServer);
#endif

	/* send encrypted challenge to server */
	fwrite(encChallengeToServer, encSizeToServer,1, s);

	/*-----------------------------------------------------------------------------
	 *  Challenge Response finished
	 *	    Attention: there is no (client) verification if chall/resp has successfully finished
	 *      in case of failure, client will get stuck...
	 *	
	 *	continuing with AES	
	 *	    IV  consisting of 1/2 of the Challenge
	 *      KEY consisting of the other half 
	 *-----------------------------------------------------------------------------*/

	EVP_CIPHER_CTX cctx;
	EVP_CIPHER_CTX_init(&cctx);
	int keylen = decSize/2;
	unsigned char key[keylen];
	unsigned char iv[keylen];
	memcpy(key, challenge, keylen); 
	memcpy(iv, challenge+keylen, keylen);
	
	/* init AES decrypt context */
	if(0 == EVP_CipherInit_ex(&cctx, EVP_aes_256_ofb(), NULL, key, iv, 0)){
		perror("EVP_CipherInit_ex");
		exit(EXIT_FAILURE);
	}
	unsigned char *decBuf = (unsigned char*) malloc(AESBUFFSIZE);
	unsigned char *encBuf = (unsigned char*) malloc(AESBUFFSIZE);
	
	/* get the "Hello from server!" message */
	fread(encBuf, AESBUFFSIZE, 1, s);
	printf("Authentication successfull\n");
	int bufLen = AESBUFFSIZE;

	/* decrypt the message */
	if(0 == EVP_CipherUpdate(&cctx, decBuf, &bufLen, encBuf, bufLen)) {
		EVP_CIPHER_CTX_cleanup(&cctx);
		perror("EVP_CipherUpdate");
		exit(EXIT_FAILURE);
	}
	EVP_CIPHER_CTX_cleanup(&cctx);

	printf("Received AES message: %s\n", decBuf);

	/* init AES encrypt context */
	bufLen = AESBUFFSIZE;	
	if(0 == EVP_CipherInit_ex(&cctx, EVP_aes_256_ofb(), NULL, key, iv, 1)){
		perror("EVP_CipherInit_ex");
		exit(EXIT_FAILURE);
	}
	/* restore all buffers */
	bufLen = AESBUFFSIZE;	
	decBuf = (unsigned char*) malloc(AESBUFFSIZE);
	encBuf = (unsigned char*) malloc(AESBUFFSIZE);

	/* encrypt and send the client -> server message */
	decBuf = (unsigned char*) "Hello from client.";
	if(0 == EVP_CipherUpdate(&cctx, encBuf, &bufLen, decBuf, bufLen)) {
		EVP_CIPHER_CTX_cleanup(&cctx);
		perror("EVP_CipherUpdate");
		exit(EXIT_FAILURE);
	}
	printf("Send AES message: %s\n", decBuf);
	fwrite(encBuf, bufLen, 1, s);

	/* sending/receiving could continue here */


	/* cleanup */
	EVP_CIPHER_CTX_cleanup(&cctx);
	fclose(s);
	freeaddrinfo(res);

	printf("Connection closed.\n");

	return 0;
}
Ejemplo n.º 29
0
static int int_rsa_size(const EVP_PKEY *pkey) {
  return RSA_size(pkey->pkey.rsa);
}
Ejemplo n.º 30
0
Archivo: jws.c Proyecto: cisco/cjose
static bool _cjose_jws_build_sig_rs(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    // ensure jwk is private RSA
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    RSA *rsa = (RSA *)jwk->keydata;
    BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
    _cjose_jwk_rsa_get(rsa, &rsa_n, &rsa_e, &rsa_d);
    if (!rsa || !rsa_e || !rsa_n || !rsa_d)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // allocate buffer for signature
    jws->sig_len = RSA_size((RSA *)jwk->keydata);
    jws->sig = (uint8_t *)cjose_get_alloc()(jws->sig_len);
    if (NULL == jws->sig)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return false;
    }

    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // build digest using SHA-256/384/512 digest algorithm
    int digest_alg = -1;
    if (strcmp(alg, CJOSE_HDR_ALG_RS256) == 0)
        digest_alg = NID_sha256;
    else if (strcmp(alg, CJOSE_HDR_ALG_RS384) == 0)
        digest_alg = NID_sha384;
    else if (strcmp(alg, CJOSE_HDR_ALG_RS512) == 0)
        digest_alg = NID_sha512;
    if (-1 == digest_alg)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        return false;
    }

    unsigned int siglen;
    if (RSA_sign(digest_alg, jws->dig, jws->dig_len, jws->sig, &siglen, (RSA *)jwk->keydata) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        return false;
    }
    jws->sig_len = siglen;

    // base64url encode signed digest
    if (!cjose_base64url_encode((const uint8_t *)jws->sig, jws->sig_len, &jws->sig_b64u, &jws->sig_b64u_len, err))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        return false;
    }

    return true;
}