static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { EC_KEY *ec_key = pkey->pkey.ec; void *pval = NULL; int ptype; unsigned char *penc = NULL, *p; int penclen; if (!eckey_param2type(&ptype, &pval, ec_key)) { ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); return 0; } penclen = i2o_ECPublicKey(ec_key, NULL); if (penclen <= 0) goto err; penc = OPENSSL_malloc(penclen); if (!penc) goto err; p = penc; penclen = i2o_ECPublicKey(ec_key, &p); if (penclen <= 0) goto err; if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc, penclen)) return 1; err: if (ptype == V_ASN1_OBJECT) ASN1_OBJECT_free(pval); else ASN1_STRING_free(pval); if (penc) OPENSSL_free(penc); return 0; }
static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; unsigned char *buf=NULL,*databuf,*sptr; int i,j,data_len,ret=0; int ptype = V_ASN1_UNDEF; DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); if (pk->save_parameters) { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; } data_len = BN_num_bytes(dsa->pub_key); databuf = OPENSSL_malloc(data_len); BN_bn2bin(dsa->pub_key,databuf); octet = ASN1_OCTET_STRING_new(); ASN1_STRING_set(octet,NULL,data_len); sptr = ASN1_STRING_data(octet); for (i=0,j=data_len-1; i< data_len;i++,j--) { sptr[i]=databuf[j]; } OPENSSL_free(databuf); ret = i2d_ASN1_OCTET_STRING(octet,&buf); ASN1_BIT_STRING_free(octet); if (ret <0) return 0; return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); }
static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; unsigned char *buf=NULL,*databuf,*sptr; int i,j,data_len,ret=0; const EC_POINT *pub_key; BIGNUM *X,*Y,*order; const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); if (pk->save_parameters) { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; } order = BN_new(); EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL); pub_key=EC_KEY_get0_public_key(ec); if (!pub_key) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); return 0; } X=BN_new(); Y=BN_new(); EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), pub_key,X,Y,NULL); data_len = 2*BN_num_bytes(order); BN_free(order); databuf = OPENSSL_malloc(data_len); memset(databuf,0,data_len); store_bignum(X,databuf+data_len/2,data_len/2); store_bignum(Y,databuf,data_len/2); BN_free(X); BN_free(Y); octet = ASN1_OCTET_STRING_new(); ASN1_STRING_set(octet,NULL,data_len); sptr=ASN1_STRING_data(octet); for (i=0,j=data_len-1;i<data_len;i++,j--) { sptr[i]=databuf[j]; } OPENSSL_free(databuf); ret = i2d_ASN1_OCTET_STRING(octet,&buf); ASN1_BIT_STRING_free(octet); if (ret <0) return 0; return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret); }
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; int ptype; unsigned char *penc = NULL; int penclen; ASN1_STRING *str = NULL; ASN1_INTEGER *pubint = NULL; ASN1_OBJECT *aobj; dsa = pkey->pkey.dsa; if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { str = ASN1_STRING_new(); if (str == NULL) { DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_DSAparams(dsa, &str->data); if (str->length <= 0) { DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; } else ptype = V_ASN1_UNDEF; pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL); if (pubint == NULL) { DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } penclen = i2d_ASN1_INTEGER(pubint, &penc); ASN1_INTEGER_free(pubint); if (penclen <= 0) { DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } aobj = OBJ_nid2obj(EVP_PKEY_DSA); if (aobj == NULL) goto err; if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen)) return 1; err: OPENSSL_free(penc); ASN1_STRING_free(str); return 0; }
static int dh_pub_encode (X509_PUBKEY * pk, const EVP_PKEY * pkey) { DH *dh; void *pval = NULL; int ptype; unsigned char *penc = NULL; int penclen; ASN1_STRING *str; ASN1_INTEGER *pub_key = NULL; dh = pkey->pkey.dh; str = ASN1_STRING_new (); str->length = i2d_DHparams (dh, &str->data); if (str->length <= 0) { DHerr (DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } pval = str; ptype = V_ASN1_SEQUENCE; pub_key = BN_to_ASN1_INTEGER (dh->pub_key, NULL); if (!pub_key) goto err; penclen = i2d_ASN1_INTEGER (pub_key, &penc); ASN1_INTEGER_free (pub_key); if (penclen <= 0) { DHerr (DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param (pk, OBJ_nid2obj (EVP_PKEY_DH), ptype, pval, penc, penclen)) return 1; err: if (penc) OPENSSL_free (penc); if (pval) ASN1_STRING_free (pval); return 0; }
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { unsigned char *penc = NULL; int penclen; penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); if (penclen <= 0) return 0; if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL, penc, penclen)) return 1; OPENSSL_free(penc); return 0; }
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { uint8_t *encoded; size_t encoded_len; if (!RSA_public_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) { return 0; } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL, encoded, encoded_len)) { OPENSSL_free(encoded); return 0; } return 1; }
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; void *pval = NULL; int ptype; unsigned char *penc = NULL; int penclen; dsa = pkey->pkey.dsa; if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { ASN1_STRING *str; str = ASN1_STRING_new(); if (str == NULL) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_DSAparams(dsa, &str->data); if (str->length <= 0) { DSAerror(ERR_R_MALLOC_FAILURE); ASN1_STRING_free(str); goto err; } pval = str; ptype = V_ASN1_SEQUENCE; } else ptype = V_ASN1_UNDEF; dsa->write_params = 0; penclen = i2d_DSAPublicKey(dsa, &penc); if (penclen <= 0) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, penc, penclen)) return 1; err: free(penc); ASN1_STRING_free(pval); return 0; }
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { uint8_t *encoded = NULL; int len; len = i2d_RSAPublicKey(pkey->pkey.rsa, &encoded); if (len <= 0) { return 0; } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL, encoded, len)) { OPENSSL_free(encoded); return 0; } return 1; }
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; ASN1_STRING *pval = NULL; uint8_t *penc = NULL; int penclen; dsa = pkey->pkey.dsa; dsa->write_params = 0; int ptype; if (dsa->p && dsa->q && dsa->g) { pval = ASN1_STRING_new(); if (!pval) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } pval->length = i2d_DSAparams(dsa, &pval->data); if (pval->length <= 0) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; } else { ptype = V_ASN1_UNDEF; } penclen = i2d_DSAPublicKey(dsa, &penc); if (penclen <= 0) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, penc, penclen)) { return 1; } err: OPENSSL_free(penc); ASN1_STRING_free(pval); return 0; }
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { unsigned char *penc = NULL; int penclen; ASN1_STRING *str; int strtype; if (!rsa_param_encode(pkey, &str, &strtype)) return 0; penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); if (penclen <= 0) return 0; if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), strtype, str, penc, penclen)) return 1; OPENSSL_free(penc); return 0; }
static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { EC_KEY *ec_key = pkey->pkey.ec; void *pval = NULL; int ptype; uint8_t *penc = NULL, *p; int penclen; if (!eckey_param2type(&ptype, &pval, ec_key)) { OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); return 0; } penclen = i2o_ECPublicKey(ec_key, NULL); if (penclen <= 0) { goto err; } penc = OPENSSL_malloc(penclen); if (!penc) { goto err; } p = penc; penclen = i2o_ECPublicKey(ec_key, &p); if (penclen <= 0) { goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc, penclen)) { return 1; } err: if (ptype == V_ASN1_OBJECT) { ASN1_OBJECT_free(pval); } else { ASN1_STRING_free(pval); } if (penc) { OPENSSL_free(penc); } return 0; }
static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { const ECX_KEY *ecxkey = pkey->pkey.ecx; unsigned char *penc; if (ecxkey == NULL) { ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY); return 0; } penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey)); if (penc == NULL) { ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE); return 0; } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) { OPENSSL_free(penc); ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE); return 0; } return 1; }
static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; ASN1_STRING *params = NULL; void *pval = NULL; unsigned char *buf = NULL, *sptr; int key_size, ret = 0; const EC_POINT *pub_key; BIGNUM *X = NULL, *Y = NULL; const GOST_KEY *ec = pk->pkey.gost; int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); if (pk->save_parameters) { params = encode_gost01_algor_params(pk); if (params == NULL) return 0; pval = params; ptype = V_ASN1_SEQUENCE; } key_size = GOST_KEY_get_size(ec); pub_key = GOST_KEY_get0_public_key(ec); if (pub_key == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); goto err; } octet = ASN1_OCTET_STRING_new(); if (octet == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); goto err; } ret = ASN1_STRING_set(octet, NULL, 2 * key_size); if (ret == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); goto err; } sptr = ASN1_STRING_data(octet); X = BN_new(); Y = BN_new(); if (X == NULL || Y == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); goto err; } if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), pub_key, X, Y, NULL) == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); goto err; } GOST_bn2le(X, sptr, key_size); GOST_bn2le(Y, sptr + key_size, key_size); BN_free(Y); BN_free(X); ret = i2d_ASN1_OCTET_STRING(octet, &buf); ASN1_BIT_STRING_free(octet); if (ret < 0) return 0; return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); err: BN_free(Y); BN_free(X); ASN1_BIT_STRING_free(octet); ASN1_STRING_free(params); return 0; }
/* returns newly allocated RDSSL_RKEY or NULL */ RDSSL_RKEY * rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len) { EVP_PKEY *epk = NULL; RDSSL_RKEY *lkey; int nid; #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) int ret; /* By some reason, Microsoft sets the OID of the Public RSA key to the oid for "MD5 with RSA Encryption" instead of "RSA Encryption" Kudos to Richard Levitte for the following (. intiutive .) lines of code that resets the OID and let's us extract the key. */ X509_PUBKEY *key = NULL; X509_ALGOR *algor = NULL; key = X509_get_X509_PUBKEY(cert); if (key == NULL) { error("Failed to get public key from certificate.\n"); return NULL; } ret = X509_PUBKEY_get0_param(NULL, NULL, 0, &algor, key); if (ret != 1) { error("Faild to get algorithm used for public key.\n"); return NULL; } nid = OBJ_obj2nid(algor->algorithm); if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption)) { DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n")); X509_PUBKEY_set0_param(key, OBJ_nid2obj(NID_rsaEncryption), 0, NULL, NULL, 0); } #else /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */ nid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm); if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption)) { DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n")); ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm); cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); } #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 || && defined(LIBRESSL_VERSION_NUMBER) */ epk = X509_get_pubkey(cert); if (NULL == epk) { error("Failed to extract public key from certificate\n"); return NULL; } lkey = RSAPublicKey_dup(EVP_PKEY_get1_RSA(epk)); EVP_PKEY_free(epk); *key_len = RSA_size(lkey); return lkey; }