int signRequest(char* pemRequest, int days, char* pemCAKey, char* pemCaCert,  int certType, char *url, char* result)  {

  BIO* bioReq = BIO_new_mem_buf(pemRequest, -1);
  BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1);

  BIO* bioCert = BIO_new_mem_buf(pemCaCert, -1);
  X509* caCert = PEM_read_bio_X509(bioCert, NULL, NULL, NULL);

  int err = 0;

  X509_REQ *req=NULL;
  if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL);
  if (!caKey) {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  X509* cert = X509_new();
  EVP_PKEY* reqPub;
  if(!(err =  X509_set_version(cert, 2)))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  //redo all the certificate details, because OpenSSL wants us to work hard
  X509_set_issuer_name(cert, X509_get_subject_name(caCert));

  ASN1_UTCTIME *s=ASN1_UTCTIME_new();

  // Jira-issue: WP-37
  // This is temp solution for putting pzp validity 5 minutes before current time
  // If there is a small clock difference between machines, it results in cert_not_yet_valid
  // It does set GMT time but is relevant to machine time.
  // A better solution would be to have ntp server contacted to get a proper time.
  if(certType == 2) {
    X509_gmtime_adj(s, long(0-300));
  }
  else {
    X509_gmtime_adj(s, long(0));
  }
  // End of WP-37
  X509_set_notBefore(cert, s);

  X509_gmtime_adj(s, (long)60*60*24*days);
  X509_set_notAfter(cert, s);

  ASN1_UTCTIME_free(s);

  X509_set_subject_name(cert, X509_REQ_get_subject_name(req));
  reqPub = X509_REQ_get_pubkey(req);
  X509_set_pubkey(cert,reqPub);
  EVP_PKEY_free(reqPub);

  //create a serial number at random
  ASN1_INTEGER* serial = getRandomSN();
  X509_set_serialNumber(cert, serial);

  X509_EXTENSION *ex;
  X509V3_CTX ctx;
  X509V3_set_ctx_nodb(&ctx);
  X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);

  char *str = (char*)malloc(strlen("caIssuers;") + strlen(url) + 1);
  if (str == NULL) {
    return -10;
  }
  strcpy(str, "caIssuers;");
  strcat(str, url);

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_info_access, (char*)str))) {
    free(str);
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }
  free(str);
  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }
  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_issuer_alt_name, (char*)"issuer:copy"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if( certType == 1) {
    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  } else if( certType == 2) {
    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  }

  if (!(err = X509_sign(cert,caKey,EVP_sha1())))
  {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return err;
  }

  BIO *mem = BIO_new(BIO_s_mem());
  PEM_write_bio_X509(mem,cert);

  BUF_MEM *bptr;
  BIO_get_mem_ptr(mem, &bptr);
  BIO_read(mem, result, bptr->length);

  BIO_free(mem);
  BIO_free(bioReq);
  BIO_free(bioCert);
  BIO_free(bioCAKey);

  return 0;
}
int selfSignRequest(char* pemRequest, int days, char* pemCAKey, int certType, char *url, char* result)  {
  BIO* bioReq = BIO_new_mem_buf(pemRequest, -1);
  BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1);

  int err = 0;

  X509_REQ *req=NULL;
  if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -5;
  }

  EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL);
  if (!caKey) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -6;
  }

  X509* cert = X509_new();
  EVP_PKEY* reqPub;

  //redo all the certificate details, because OpenSSL wants us to work hard
  if(!(err =  X509_set_version(cert, 2)))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  if(!(err = X509_set_issuer_name(cert, X509_REQ_get_subject_name(req))))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  ASN1_UTCTIME *s=ASN1_UTCTIME_new();
  // Jira-issue: WP-37
  // This is temp solution for putting pzp validity 5 minutes before current time
  // If there is a small clock difference between machines, it results in cert_not_yet_valid
  // It does set GMT time but is relevant to machine time.
  // A better solution would be to have ntp server contacted to get proper time.
  if(certType == 2) {
    X509_gmtime_adj(s, long(0-300));
  }
  else {
    X509_gmtime_adj(s, long(0));
  }
  // End of WP-37
  X509_set_notBefore(cert, s);

  X509_gmtime_adj(s, (long)60*60*24*days);
  X509_set_notAfter(cert, s);

  ASN1_UTCTIME_free(s);

  if(!(err = X509_set_subject_name(cert, X509_REQ_get_subject_name(req)))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  if (!(reqPub = X509_REQ_get_pubkey(req))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -7;
  }
  err = X509_set_pubkey(cert,reqPub);
  EVP_PKEY_free(reqPub);
  if (!err) {
    return err; // an error occurred, this is terrible style.
  }

  //create a serial number at random
  ASN1_INTEGER* serial = getRandomSN();
  X509_set_serialNumber(cert, serial);

  // V3 extensions
  X509_EXTENSION *ex;
  X509V3_CTX ctx;
  X509V3_set_ctx_nodb(&ctx);
  X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if( certType == 0) {
    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:TRUE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_key_usage, (char*)"critical, keyCertSign, digitalSignature, cRLSign"))) { /* critical, keyCertSign,cRLSign, nonRepudiation,*/
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_ext_key_usage, (char*)"critical, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_inhibit_any_policy, (char*)"0"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_crl_distribution_points, (char*)url))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  }

  if (!(err = X509_sign(cert,caKey,EVP_sha1()))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  BIO *mem = BIO_new(BIO_s_mem());
  PEM_write_bio_X509(mem,cert);

  BUF_MEM *bptr;
  BIO_get_mem_ptr(mem, &bptr);
  BIO_read(mem, result, bptr->length);

  BIO_free(mem);
  BIO_free(bioReq);
  BIO_free(bioCAKey);
  return 0;

}
static gboolean
SetCertSerialNumber(X509 *cert)                  // IN
{
   BIGNUM *btmp = NULL;
   ASN1_INTEGER *sno;
   gboolean ret = FALSE;
   gchar *err = NULL;

   sno = ASN1_INTEGER_new();
   if (!sno) {
      Error("Failed to allocate an ASN1 integer.\n");
      goto exit;
   }

   btmp = BN_new();
   if (!btmp) {
      Error("Failed to allocate a BIGNUM structure.\n");
      goto exit;
   }

   if (!BN_rand(btmp, 64, 0, 0)) {
      Error("Failed to generate random number: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   if (!BN_to_ASN1_INTEGER(btmp, sno)) {
      Error("Failed to convert from BIGNUM to ASN1_INTEGER: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   if (!X509_set_serialNumber(cert, sno)) {
      Error("Failed to set the certificate serial number: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   ret = TRUE;

exit:
   BN_free(btmp);
   ASN1_INTEGER_free(sno);
   g_free(err);

   return ret;
}
Exemple #4
0
/* Taken from openssl certmodule.c */
static int certificate_set_serial(X509 *x)
{
        ASN1_INTEGER *sno = ASN1_INTEGER_new();
        BIGNUM *bn = NULL;
        int rv = 0;
        
        bn = BN_new();
        
        if (!bn) {
                ASN1_INTEGER_free(sno);
                return 0;
        }
        
        if (BN_pseudo_rand(bn, SERIAL_RAND_BITS, 0, 0) == 1 &&
            (sno = BN_to_ASN1_INTEGER(bn, sno)) != NULL &&
            X509_set_serialNumber(x, sno) == 1)
                rv = 1;
        
        BN_free(bn);
        ASN1_INTEGER_free(sno);
        
        return rv;
}
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int ret=1;
	X509_REQ *req=NULL;
	X509 *x=NULL,*xca=NULL;
	ASN1_OBJECT *objtmp;
	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
	ASN1_INTEGER *sno = NULL;
	int i,num,badops=0;
	BIO *out=NULL;
	BIO *STDout=NULL;
	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
	int informat,outformat,keyformat,CAformat,CAkeyformat;
	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
	char *CAkeyfile=NULL,*CAserial=NULL;
	char *alias=NULL;
	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
	int next_serial=0;
	int subject_hash=0,issuer_hash=0,ocspid=0;
#ifndef OPENSSL_NO_MD5
	int subject_hash_old=0,issuer_hash_old=0;
#endif
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
	int ocsp_uri=0;
	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
	int C=0;
	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
	int pprint = 0;
	const char **pp;
	X509_STORE *ctx=NULL;
	X509_REQ *rq=NULL;
	int fingerprint=0;
	char buf[256];
	const EVP_MD *md_alg,*digest=NULL;
	CONF *extconf = NULL;
	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
	int need_rand = 0;
	int checkend=0,checkoffset=0;
	unsigned long nmflag = 0, certflag = 0;
#ifndef OPENSSL_NO_ENGINE
	char *engine=NULL;
#endif

	reqfile=0;

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;
	keyformat=FORMAT_PEM;
	CAformat=FORMAT_PEM;
	CAkeyformat=FORMAT_PEM;

	ctx=X509_STORE_new();
	if (ctx == NULL) goto end;
	X509_STORE_set_verify_cb(ctx,callb);

	argc--;
	argv++;
	num=0;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			keyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-req") == 0)
			{
			reqfile=1;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAform") == 0)
			{
			if (--argc < 1) goto bad;
			CAformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-CAkeyform") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-sigopt") == 0)
			{
			if (--argc < 1)
				goto bad;
			if (!sigopts)
				sigopts = sk_OPENSSL_STRING_new_null();
			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
				goto bad;
			}
		else if (strcmp(*argv,"-days") == 0)
			{
			if (--argc < 1) goto bad;
			days=atoi(*(++argv));
			if (days == 0)
				{
				BIO_printf(STDout,"bad number of days\n");
				goto bad;
				}
			}
		else if (strcmp(*argv,"-passin") == 0)
			{
			if (--argc < 1) goto bad;
			passargin= *(++argv);
			}
		else if (strcmp(*argv,"-extfile") == 0)
			{
			if (--argc < 1) goto bad;
			extfile= *(++argv);
			}
		else if (strcmp(*argv,"-extensions") == 0)
			{
			if (--argc < 1) goto bad;
			extsect= *(++argv);
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-signkey") == 0)
			{
			if (--argc < 1) goto bad;
			keyfile= *(++argv);
			sign_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CA") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			CA_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAkey") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyfile= *(++argv);
			}
		else if (strcmp(*argv,"-CAserial") == 0)
			{
			if (--argc < 1) goto bad;
			CAserial= *(++argv);
			}
		else if (strcmp(*argv,"-set_serial") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
				goto bad;
			}
		else if (strcmp(*argv,"-addtrust") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid trust object value %s\n", *argv);
				goto bad;
				}
			if (!trust) trust = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(trust, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-addreject") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid reject object value %s\n", *argv);
				goto bad;
				}
			if (!reject) reject = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(reject, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-setalias") == 0)
			{
			if (--argc < 1) goto bad;
			alias= *(++argv);
			trustout = 1;
			}
		else if (strcmp(*argv,"-certopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
			}
		else if (strcmp(*argv,"-nameopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if (strcmp(*argv,"-C") == 0)
			C= ++num;
		else if (strcmp(*argv,"-email") == 0)
			email= ++num;
		else if (strcmp(*argv,"-ocsp_uri") == 0)
			ocsp_uri= ++num;
		else if (strcmp(*argv,"-serial") == 0)
			serial= ++num;
		else if (strcmp(*argv,"-next_serial") == 0)
			next_serial= ++num;
		else if (strcmp(*argv,"-modulus") == 0)
			modulus= ++num;
		else if (strcmp(*argv,"-pubkey") == 0)
			pubkey= ++num;
		else if (strcmp(*argv,"-x509toreq") == 0)
			x509req= ++num;
		else if (strcmp(*argv,"-text") == 0)
			text= ++num;
		else if (strcmp(*argv,"-hash") == 0
			|| strcmp(*argv,"-subject_hash") == 0)
			subject_hash= ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv,"-subject_hash_old") == 0)
			subject_hash_old= ++num;
#endif
		else if (strcmp(*argv,"-issuer_hash") == 0)
			issuer_hash= ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv,"-issuer_hash_old") == 0)
			issuer_hash_old= ++num;
#endif
		else if (strcmp(*argv,"-subject") == 0)
			subject= ++num;
		else if (strcmp(*argv,"-issuer") == 0)
			issuer= ++num;
		else if (strcmp(*argv,"-fingerprint") == 0)
			fingerprint= ++num;
		else if (strcmp(*argv,"-dates") == 0)
			{
			startdate= ++num;
			enddate= ++num;
			}
		else if (strcmp(*argv,"-purpose") == 0)
			pprint= ++num;
		else if (strcmp(*argv,"-startdate") == 0)
			startdate= ++num;
		else if (strcmp(*argv,"-enddate") == 0)
			enddate= ++num;
		else if (strcmp(*argv,"-checkend") == 0)
			{
			if (--argc < 1) goto bad;
			checkoffset=atoi(*(++argv));
			checkend=1;
			}
		else if (strcmp(*argv,"-noout") == 0)
			noout= ++num;
		else if (strcmp(*argv,"-trustout") == 0)
			trustout= 1;
		else if (strcmp(*argv,"-clrtrust") == 0)
			clrtrust= ++num;
		else if (strcmp(*argv,"-clrreject") == 0)
			clrreject= ++num;
		else if (strcmp(*argv,"-alias") == 0)
			aliasout= ++num;
		else if (strcmp(*argv,"-CAcreateserial") == 0)
			CA_createserial= ++num;
		else if (strcmp(*argv,"-clrext") == 0)
			clrext = 1;
#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
		else if (strcmp(*argv,"-crlext") == 0)
			{
			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
			clrext = 1;
			}
#endif
		else if (strcmp(*argv,"-ocspid") == 0)
			ocspid= ++num;
		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
			{
			/* ok */
			digest=md_alg;
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		for (pp=x509_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine, 0);
#endif

	if (need_rand)
		app_RAND_load_file(NULL, bio_err, 0);

	ERR_load_crypto_strings();

	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}

	if (!X509_STORE_set_default_paths(ctx))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
		{ CAkeyfile=CAfile; }
	else if ((CA_flag) && (CAkeyfile == NULL))
		{
		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
		goto end;
		}

	if (extfile)
		{
		long errorline = -1;
		X509V3_CTX ctx2;
		extconf = NCONF_new(NULL);
		if (!NCONF_load(extconf, extfile,&errorline))
			{
			if (errorline <= 0)
				BIO_printf(bio_err,
					"error loading the config file '%s'\n",
								extfile);
                	else
                        	BIO_printf(bio_err,
				       "error on line %ld of config file '%s'\n"
							,errorline,extfile);
			goto end;
			}
		if (!extsect)
			{
			extsect = NCONF_get_string(extconf, "default", "extensions");
			if (!extsect)
				{
				ERR_clear_error();
				extsect = "default";
				}
			}
		X509V3_set_ctx_test(&ctx2);
		X509V3_set_nconf(&ctx2, extconf);
		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
			{
			BIO_printf(bio_err,
				"Error Loading extension section %s\n",
								 extsect);
			ERR_print_errors(bio_err);
			goto end;
			}
		}


	if (reqfile)
		{
		EVP_PKEY *pkey;
		BIO *in;

		if (!sign_flag && !CA_flag)
			{
			BIO_printf(bio_err,"We need a private key to sign with\n");
			goto end;
			}
		in=BIO_new(BIO_s_file());
		if (in == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (infile == NULL)
			BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
		else
			{
			if (BIO_read_filename(in,infile) <= 0)
				{
				perror(infile);
				BIO_free(in);
				goto end;
				}
			}
		req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
		BIO_free(in);

		if (req == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (	(req->req_info == NULL) ||
			(req->req_info->pubkey == NULL) ||
			(req->req_info->pubkey->public_key == NULL) ||
			(req->req_info->pubkey->public_key->data == NULL))
			{
			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
			BIO_printf(bio_err,"It does not contain a public key\n");
			goto end;
			}
		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
	                {
	                BIO_printf(bio_err,"error unpacking public key\n");
	                goto end;
	                }
		i=X509_REQ_verify(req,pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			{
			BIO_printf(bio_err,"Signature verification error\n");
			ERR_print_errors(bio_err);
			goto end;
			}
	        if (i == 0)
			{
			BIO_printf(bio_err,"Signature did not match the certificate request\n");
			goto end;
			}
		else
			BIO_printf(bio_err,"Signature ok\n");

		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);

		if ((x=X509_new()) == NULL) goto end;

		if (sno == NULL)
			{
			sno = ASN1_INTEGER_new();
			if (!sno || !rand_serial(NULL, sno))
				goto end;
			if (!X509_set_serialNumber(x, sno)) 
				goto end;
			ASN1_INTEGER_free(sno);
			sno = NULL;
			}
		else if (!X509_set_serialNumber(x, sno)) 
			goto end;

		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;

		X509_gmtime_adj(X509_get_notBefore(x),0);
	        X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);

		pkey = X509_REQ_get_pubkey(req);
		X509_set_pubkey(x,pkey);
		EVP_PKEY_free(pkey);
		}
	else
		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");

	if (x == NULL) goto end;
	if (CA_flag)
		{
		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
		if (xca == NULL) goto end;
		}

	if (!noout || text || next_serial)
		{
		OBJ_create("2.99999.3",
			"SET.ex3","SET x509v3 extension 3");

		out=BIO_new(BIO_s_file());
		if (out == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		if (outfile == NULL)
			{
			BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			out = BIO_push(tmpbio, out);
			}
#endif
			}
		else
			{
			if (BIO_write_filename(out,outfile) <= 0)
				{
				perror(outfile);
				goto end;
				}
			}
		}

	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);

	if (clrtrust) X509_trust_clear(x);
	if (clrreject) X509_reject_clear(x);

	if (trust)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(trust, i);
			X509_add1_trust_object(x, objtmp);
			}
		}

	if (reject)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(reject, i);
			X509_add1_reject_object(x, objtmp);
			}
		}

	if (num)
		{
		for (i=1; i<=num; i++)
			{
			if (issuer == i)
				{
				print_name(STDout, "issuer= ",
					X509_get_issuer_name(x), nmflag);
				}
			else if (subject == i) 
				{
				print_name(STDout, "subject= ",
					X509_get_subject_name(x), nmflag);
				}
			else if (serial == i)
				{
				BIO_printf(STDout,"serial=");
				i2a_ASN1_INTEGER(STDout,
					X509_get_serialNumber(x));
				BIO_printf(STDout,"\n");
				}
			else if (next_serial == i)
				{
				BIGNUM *bnser;
				ASN1_INTEGER *ser;
				ser = X509_get_serialNumber(x);
				bnser = ASN1_INTEGER_to_BN(ser, NULL);
				if (!bnser)
					goto end;
				if (!BN_add_word(bnser, 1))
					goto end;
				ser = BN_to_ASN1_INTEGER(bnser, NULL);
				if (!ser)
					goto end;
				BN_free(bnser);
				i2a_ASN1_INTEGER(out, ser);
				ASN1_INTEGER_free(ser);
				BIO_puts(out, "\n");
				}
			else if ((email == i) || (ocsp_uri == i))
				{
				int j;
				STACK_OF(OPENSSL_STRING) *emlst;
				if (email == i)
					emlst = X509_get1_email(x);
				else
					emlst = X509_get1_ocsp(x);
				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
					BIO_printf(STDout, "%s\n",
						   sk_OPENSSL_STRING_value(emlst, j));
				X509_email_free(emlst);
				}
			else if (aliasout == i)
				{
				unsigned char *alstr;
				alstr = X509_alias_get0(x, NULL);
				if (alstr) BIO_printf(STDout,"%s\n", alstr);
				else BIO_puts(STDout,"<No Alias>\n");
				}
			else if (subject_hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
				}
#ifndef OPENSSL_NO_MD5
			else if (subject_hash_old == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
				}
#endif
			else if (issuer_hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
				}
#ifndef OPENSSL_NO_MD5
			else if (issuer_hash_old == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
				}
#endif
			else if (pprint == i)
				{
				X509_PURPOSE *ptmp;
				int j;
				BIO_printf(STDout, "Certificate purposes:\n");
				for (j = 0; j < X509_PURPOSE_get_count(); j++)
					{
					ptmp = X509_PURPOSE_get0(j);
					purpose_print(STDout, x, ptmp);
					}
				}
			else
				if (modulus == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Modulus=unavailable\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				BIO_printf(STDout,"Modulus=");
#ifndef OPENSSL_NO_RSA
				if (pkey->type == EVP_PKEY_RSA)
					BN_print(STDout,pkey->pkey.rsa->n);
				else
#endif
#ifndef OPENSSL_NO_DSA
				if (pkey->type == EVP_PKEY_DSA)
					BN_print(STDout,pkey->pkey.dsa->pub_key);
				else
#endif
					BIO_printf(STDout,"Wrong Algorithm type");
				BIO_printf(STDout,"\n");
				EVP_PKEY_free(pkey);
				}
			else
				if (pubkey == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Error getting public key\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				PEM_write_bio_PUBKEY(STDout, pkey);
				EVP_PKEY_free(pkey);
				}
			else
				if (C == i)
				{
				unsigned char *d;
				char *m;
				int y,z;

				X509_NAME_oneline(X509_get_subject_name(x),
					buf,sizeof buf);
				BIO_printf(STDout,"/* subject:%s */\n",buf);
				m=X509_NAME_oneline(
					X509_get_issuer_name(x),buf,
					sizeof buf);
				BIO_printf(STDout,"/* issuer :%s */\n",buf);

				z=i2d_X509(x,NULL);
				m=OPENSSL_malloc(z);

				d=(unsigned char *)m;
				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509(x,&d);
				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				OPENSSL_free(m);
				}
			else if (text == i)
				{
				X509_print_ex(out,x,nmflag, certflag);
				}
			else if (startdate == i)
				{
				BIO_puts(STDout,"notBefore=");
				ASN1_TIME_print(STDout,X509_get_notBefore(x));
				BIO_puts(STDout,"\n");
				}
			else if (enddate == i)
				{
				BIO_puts(STDout,"notAfter=");
				ASN1_TIME_print(STDout,X509_get_notAfter(x));
				BIO_puts(STDout,"\n");
				}
			else if (fingerprint == i)
				{
				int j;
				unsigned int n;
				unsigned char md[EVP_MAX_MD_SIZE];
				const EVP_MD *fdig = digest;

				if (!fdig)
					fdig = EVP_sha1();

				if (!X509_digest(x,fdig,md,&n))
					{
					BIO_printf(bio_err,"out of memory\n");
					goto end;
					}
				BIO_printf(STDout,"%s Fingerprint=",
						OBJ_nid2sn(EVP_MD_type(fdig)));
				for (j=0; j<(int)n; j++)
					{
					BIO_printf(STDout,"%02X%c",md[j],
						(j+1 == (int)n)
						?'\n':':');
					}
				}

			/* should be in the library */
			else if ((sign_flag == i) && (x509req == 0))
				{
				BIO_printf(bio_err,"Getting Private key\n");
				if (Upkey == NULL)
					{
					Upkey=load_key(bio_err,
						keyfile, keyformat, 0,
						passin, e, "Private key");
					if (Upkey == NULL) goto end;
					}

				assert(need_rand);
				if (!sign(x,Upkey,days,clrext,digest,
						 extconf, extsect)) goto end;
				}
			else if (CA_flag == i)
				{
				BIO_printf(bio_err,"Getting CA Private Key\n");
				if (CAkeyfile != NULL)
					{
					CApkey=load_key(bio_err,
						CAkeyfile, CAkeyformat,
						0, passin, e,
						"CA Private Key");
					if (CApkey == NULL) goto end;
					}
				
				assert(need_rand);
				if (!x509_certify(ctx,CAfile,digest,x,xca,
					CApkey, sigopts,
					CAserial,CA_createserial,days, clrext,
					extconf, extsect, sno))
					goto end;
				}
			else if (x509req == i)
				{
				EVP_PKEY *pk;

				BIO_printf(bio_err,"Getting request Private Key\n");
				if (keyfile == NULL)
					{
					BIO_printf(bio_err,"no request key file specified\n");
					goto end;
					}
				else
					{
					pk=load_key(bio_err,
						keyfile, keyformat, 0,
						passin, e, "request key");
					if (pk == NULL) goto end;
					}

				BIO_printf(bio_err,"Generating certificate request\n");

				rq=X509_to_X509_REQ(x,pk,digest);
				EVP_PKEY_free(pk);
				if (rq == NULL)
					{
					ERR_print_errors(bio_err);
					goto end;
					}
				if (!noout)
					{
					X509_REQ_print(out,rq);
					PEM_write_bio_X509_REQ(out,rq);
					}
				noout=1;
				}
			else if (ocspid == i)
				{
				X509_ocspid_print(out, x);
				}
			}
		}

	if (checkend)
		{
		time_t tcheck=time(NULL) + checkoffset;

		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
			{
			BIO_printf(out,"Certificate will expire\n");
			ret=1;
			}
		else
			{
			BIO_printf(out,"Certificate will not expire\n");
			ret=0;
			}
		goto end;
		}

	if (noout)
		{
		ret=0;
		goto end;
		}

	if 	(outformat == FORMAT_ASN1)
		i=i2d_X509_bio(out,x);
	else if (outformat == FORMAT_PEM)
		{
		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
		else i=PEM_write_bio_X509(out,x);
		}
	else if (outformat == FORMAT_NETSCAPE)
		{
		NETSCAPE_X509 nx;
		ASN1_OCTET_STRING hdr;

		hdr.data=(unsigned char *)NETSCAPE_CERT_HDR;
		hdr.length=strlen(NETSCAPE_CERT_HDR);
		nx.header= &hdr;
		nx.cert=x;

		i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx);
		}
	else	{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i)
		{
		BIO_printf(bio_err,"unable to write certificate\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
	OBJ_cleanup();
	NCONF_free(extconf);
	BIO_free_all(out);
	BIO_free_all(STDout);
	X509_STORE_free(ctx);
	X509_REQ_free(req);
	X509_free(x);
	X509_free(xca);
	EVP_PKEY_free(Upkey);
	EVP_PKEY_free(CApkey);
	if (sigopts)
		sk_OPENSSL_STRING_free(sigopts);
	X509_REQ_free(rq);
	ASN1_INTEGER_free(sno);
	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
	if (passin) OPENSSL_free(passin);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Exemple #6
0
int x509_main(int argc, char **argv)
{
    ASN1_INTEGER *sno = NULL;
    ASN1_OBJECT *objtmp;
    BIO *out = NULL;
    CONF *extconf = NULL;
    EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL;
    STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
    X509 *x = NULL, *xca = NULL;
    X509_REQ *req = NULL, *rq = NULL;
    X509_STORE *ctx = NULL;
    const EVP_MD *digest = NULL;
    char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL;
    char *checkhost = NULL, *checkemail = NULL, *checkip = NULL;
    char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
    char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
    char buf[256], *prog;
    int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
    int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
    int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
    int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
    int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
    int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0;
    int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0;
    int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
    int checkoffset = 0, enddate = 0;
    unsigned long nmflag = 0, certflag = 0;
    OPTION_CHOICE o;
    ENGINE *e = NULL;
#ifndef OPENSSL_NO_MD5
    int subject_hash_old = 0, issuer_hash_old = 0;
#endif

    ctx = X509_STORE_new();
    if (ctx == NULL)
        goto end;
    X509_STORE_set_verify_cb(ctx, callb);

    prog = opt_init(argc, argv, x509_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(x509_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
                goto opthelp;
            break;
        case OPT_CAFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat))
                goto opthelp;
            break;
        case OPT_CAKEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAkeyformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_REQ:
            reqfile = need_rand = 1;
            break;

        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
        case OPT_FORCE_VERSION:
            force_version = atoi(opt_arg()) - 1;
            break;
#endif
        case OPT_DAYS:
            days = atoi(opt_arg());
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_EXTFILE:
            extfile = opt_arg();
            break;
        case OPT_EXTENSIONS:
            extsect = opt_arg();
            break;
        case OPT_SIGNKEY:
            keyfile = opt_arg();
            sign_flag = ++num;
            need_rand = 1;
            break;
        case OPT_CA:
            CAfile = opt_arg();
            CA_flag = ++num;
            need_rand = 1;
            break;
        case OPT_CAKEY:
            CAkeyfile = opt_arg();
            break;
        case OPT_CASERIAL:
            CAserial = opt_arg();
            break;
        case OPT_SET_SERIAL:
            if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL)
                goto opthelp;
            break;
        case OPT_FORCE_PUBKEY:
            fkeyfile = opt_arg();
            break;
        case OPT_ADDTRUST:
            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
                BIO_printf(bio_err,
                           "%s: Invalid trust object value %s\n",
                           prog, opt_arg());
                goto opthelp;
            }
            if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL)
                goto end;
            sk_ASN1_OBJECT_push(trust, objtmp);
            trustout = 1;
            break;
        case OPT_ADDREJECT:
            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
                BIO_printf(bio_err,
                           "%s: Invalid reject object value %s\n",
                           prog, opt_arg());
                goto opthelp;
            }
            if (reject == NULL
                && (reject = sk_ASN1_OBJECT_new_null()) == NULL)
                goto end;
            sk_ASN1_OBJECT_push(reject, objtmp);
            trustout = 1;
            break;
        case OPT_SETALIAS:
            alias = opt_arg();
            trustout = 1;
            break;
        case OPT_CERTOPT:
            if (!set_cert_ex(&certflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_NAMEOPT:
            if (!set_name_ex(&nmflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_C:
            C = ++num;
            break;
        case OPT_EMAIL:
            email = ++num;
            break;
        case OPT_OCSP_URI:
            ocsp_uri = ++num;
            break;
        case OPT_SERIAL:
            serial = ++num;
            break;
        case OPT_NEXT_SERIAL:
            next_serial = ++num;
            break;
        case OPT_MODULUS:
            modulus = ++num;
            break;
        case OPT_PUBKEY:
            pubkey = ++num;
            break;
        case OPT_X509TOREQ:
            x509req = ++num;
            break;
        case OPT_TEXT:
            text = ++num;
            break;
        case OPT_SUBJECT:
            subject = ++num;
            break;
        case OPT_ISSUER:
            issuer = ++num;
            break;
        case OPT_FINGERPRINT:
            fingerprint = ++num;
            break;
        case OPT_HASH:
            subject_hash = ++num;
            break;
        case OPT_ISSUER_HASH:
            issuer_hash = ++num;
            break;
        case OPT_PURPOSE:
            pprint = ++num;
            break;
        case OPT_STARTDATE:
            startdate = ++num;
            break;
        case OPT_ENDDATE:
            enddate = ++num;
            break;
        case OPT_NOOUT:
            noout = ++num;
            break;
        case OPT_NOCERT:
            nocert = 1;
            break;
        case OPT_TRUSTOUT:
            trustout = 1;
            break;
        case OPT_CLRTRUST:
            clrtrust = ++num;
            break;
        case OPT_CLRREJECT:
            clrreject = ++num;
            break;
        case OPT_ALIAS:
            aliasout = ++num;
            break;
        case OPT_CACREATESERIAL:
            CA_createserial = ++num;
            break;
        case OPT_CLREXT:
            clrext = 1;
            break;
        case OPT_OCSPID:
            ocspid = ++num;
            break;
        case OPT_BADSIG:
            badsig = 1;
            break;
#ifndef OPENSSL_NO_MD5
        case OPT_SUBJECT_HASH_OLD:
            subject_hash_old = ++num;
            break;
        case OPT_ISSUER_HASH_OLD:
            issuer_hash_old = ++num;
            break;
#endif
        case OPT_DATES:
            startdate = ++num;
            enddate = ++num;
            break;
        case OPT_CHECKEND:
            checkoffset = atoi(opt_arg());
            checkend = 1;
            break;
        case OPT_CHECKHOST:
            checkhost = opt_arg();
            break;
        case OPT_CHECKEMAIL:
            checkemail = opt_arg();
            break;
        case OPT_CHECKIP:
            checkip = opt_arg();
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &digest))
                goto opthelp;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (argc != 0) {
        BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]);
        goto opthelp;
    }

    out = bio_open_default(outfile, "w");
    if (out == NULL)
        goto end;

    if (need_rand)
        app_RAND_load_file(NULL, 0);

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (!X509_STORE_set_default_paths(ctx)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (fkeyfile) {
        fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
        if (fkey == NULL)
            goto end;
    }

    if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
        CAkeyfile = CAfile;
    } else if ((CA_flag) && (CAkeyfile == NULL)) {
        BIO_printf(bio_err,
                   "need to specify a CAkey if using the CA command\n");
        goto end;
    }

    if (extfile) {
        long errorline = -1;
        X509V3_CTX ctx2;
        extconf = NCONF_new(NULL);
        if (!NCONF_load(extconf, extfile, &errorline)) {
            if (errorline <= 0)
                BIO_printf(bio_err,
                           "error loading the config file '%s'\n", extfile);
            else
                BIO_printf(bio_err,
                           "error on line %ld of config file '%s'\n",
                           errorline, extfile);
            goto end;
        }
        if (!extsect) {
            extsect = NCONF_get_string(extconf, "default", "extensions");
            if (!extsect) {
                ERR_clear_error();
                extsect = "default";
            }
        }
        X509V3_set_ctx_test(&ctx2);
        X509V3_set_nconf(&ctx2, extconf);
        if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
            BIO_printf(bio_err,
                       "Error Loading extension section %s\n", extsect);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (reqfile) {
        EVP_PKEY *pkey;
        BIO *in;

        if (!sign_flag && !CA_flag) {
            BIO_printf(bio_err, "We need a private key to sign with\n");
            goto end;
        }
        in = bio_open_default(infile, "r");
        if (in == NULL)
            goto end;
        req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
        BIO_free(in);

        if (req == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }

        if ((req->req_info == NULL) ||
            (req->req_info->pubkey == NULL) ||
            (req->req_info->pubkey->public_key == NULL) ||
            (req->req_info->pubkey->public_key->data == NULL)) {
            BIO_printf(bio_err,
                       "The certificate request appears to corrupted\n");
            BIO_printf(bio_err, "It does not contain a public key\n");
            goto end;
        }
        if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
            BIO_printf(bio_err, "error unpacking public key\n");
            goto end;
        }
        i = X509_REQ_verify(req, pkey);
        EVP_PKEY_free(pkey);
        if (i < 0) {
            BIO_printf(bio_err, "Signature verification error\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (i == 0) {
            BIO_printf(bio_err,
                       "Signature did not match the certificate request\n");
            goto end;
        } else
            BIO_printf(bio_err, "Signature ok\n");

        print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
                   nmflag);

        if ((x = X509_new()) == NULL)
            goto end;

        if (sno == NULL) {
            sno = ASN1_INTEGER_new();
            if (!sno || !rand_serial(NULL, sno))
                goto end;
            if (!X509_set_serialNumber(x, sno))
                goto end;
            ASN1_INTEGER_free(sno);
            sno = NULL;
        } else if (!X509_set_serialNumber(x, sno))
            goto end;

        if (!X509_set_issuer_name(x, req->req_info->subject))
            goto end;
        if (!X509_set_subject_name(x, req->req_info->subject))
            goto end;

        X509_gmtime_adj(X509_get_notBefore(x), 0);
        X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
        if (fkey)
            X509_set_pubkey(x, fkey);
        else {
            pkey = X509_REQ_get_pubkey(req);
            X509_set_pubkey(x, pkey);
            EVP_PKEY_free(pkey);
        }
    } else
        x = load_cert(infile, informat, NULL, e, "Certificate");

    if (x == NULL)
        goto end;
    if (CA_flag) {
        xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate");
        if (xca == NULL)
            goto end;
    }

    if (!noout || text || next_serial) {
        OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");

    }

    if (alias)
        X509_alias_set1(x, (unsigned char *)alias, -1);

    if (clrtrust)
        X509_trust_clear(x);
    if (clrreject)
        X509_reject_clear(x);

    if (trust) {
        for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
            objtmp = sk_ASN1_OBJECT_value(trust, i);
            X509_add1_trust_object(x, objtmp);
        }
    }

    if (reject) {
        for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
            objtmp = sk_ASN1_OBJECT_value(reject, i);
            X509_add1_reject_object(x, objtmp);
        }
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag);
            } else if (subject == i) {
                print_name(out, "subject= ",
                           X509_get_subject_name(x), nmflag);
            } else if (serial == i) {
                BIO_printf(out, "serial=");
                i2a_ASN1_INTEGER(out, X509_get_serialNumber(x));
                BIO_printf(out, "\n");
            } else if (next_serial == i) {
                BIGNUM *bnser;
                ASN1_INTEGER *ser;
                ser = X509_get_serialNumber(x);
                bnser = ASN1_INTEGER_to_BN(ser, NULL);
                if (!bnser)
                    goto end;
                if (!BN_add_word(bnser, 1))
                    goto end;
                ser = BN_to_ASN1_INTEGER(bnser, NULL);
                if (!ser)
                    goto end;
                BN_free(bnser);
                i2a_ASN1_INTEGER(out, ser);
                ASN1_INTEGER_free(ser);
                BIO_puts(out, "\n");
            } else if ((email == i) || (ocsp_uri == i)) {
                int j;
                STACK_OF(OPENSSL_STRING) *emlst;
                if (email == i)
                    emlst = X509_get1_email(x);
                else
                    emlst = X509_get1_ocsp(x);
                for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
                    BIO_printf(out, "%s\n",
                               sk_OPENSSL_STRING_value(emlst, j));
                X509_email_free(emlst);
            } else if (aliasout == i) {
                unsigned char *alstr;
                alstr = X509_alias_get0(x, NULL);
                if (alstr)
                    BIO_printf(out, "%s\n", alstr);
                else
                    BIO_puts(out, "<No Alias>\n");
            } else if (subject_hash == i) {
                BIO_printf(out, "%08lx\n", X509_subject_name_hash(x));
            }
#ifndef OPENSSL_NO_MD5
            else if (subject_hash_old == i) {
                BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x));
            }
#endif
            else if (issuer_hash == i) {
                BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x));
            }
#ifndef OPENSSL_NO_MD5
            else if (issuer_hash_old == i) {
                BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x));
            }
#endif
            else if (pprint == i) {
                X509_PURPOSE *ptmp;
                int j;
                BIO_printf(out, "Certificate purposes:\n");
                for (j = 0; j < X509_PURPOSE_get_count(); j++) {
                    ptmp = X509_PURPOSE_get0(j);
                    purpose_print(out, x, ptmp);
                }
            } else if (modulus == i) {
                EVP_PKEY *pkey;

                pkey = X509_get_pubkey(x);
                if (pkey == NULL) {
                    BIO_printf(bio_err, "Modulus=unavailable\n");
                    ERR_print_errors(bio_err);
                    goto end;
                }
                BIO_printf(out, "Modulus=");
#ifndef OPENSSL_NO_RSA
                if (pkey->type == EVP_PKEY_RSA)
                    BN_print(out, pkey->pkey.rsa->n);
                else
#endif
#ifndef OPENSSL_NO_DSA
                if (pkey->type == EVP_PKEY_DSA)
                    BN_print(out, pkey->pkey.dsa->pub_key);
                else
#endif
                    BIO_printf(out, "Wrong Algorithm type");
                BIO_printf(out, "\n");
                EVP_PKEY_free(pkey);
            } else if (pubkey == i) {
                EVP_PKEY *pkey;

                pkey = X509_get_pubkey(x);
                if (pkey == NULL) {
                    BIO_printf(bio_err, "Error getting public key\n");
                    ERR_print_errors(bio_err);
                    goto end;
                }
                PEM_write_bio_PUBKEY(out, pkey);
                EVP_PKEY_free(pkey);
            } else if (C == i) {
                unsigned char *d;
                char *m;
                int len;

                X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
                BIO_printf(out, "/*\n"
                                " * Subject: %s\n", buf);

                m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf);
                BIO_printf(out, " * Issuer:  %s\n"
                                " */\n", buf);

                len = i2d_X509(x, NULL);
                m = app_malloc(len, "x509 name buffer");
                d = (unsigned char *)m;
                len = i2d_X509_NAME(X509_get_subject_name(x), &d);
                print_array(out, "the_subject_name", len, (unsigned char *)m);
                d = (unsigned char *)m;
                len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
                print_array(out, "the_public_key", len, (unsigned char *)m);
                d = (unsigned char *)m;
                len = i2d_X509(x, &d);
                print_array(out, "the_certificate", len, (unsigned char *)m);
                OPENSSL_free(m);
            } else if (text == i) {
                X509_print_ex(out, x, nmflag, certflag);
            } else if (startdate == i) {
                BIO_puts(out, "notBefore=");
                ASN1_TIME_print(out, X509_get_notBefore(x));
                BIO_puts(out, "\n");
            } else if (enddate == i) {
                BIO_puts(out, "notAfter=");
                ASN1_TIME_print(out, X509_get_notAfter(x));
                BIO_puts(out, "\n");
            } else if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];
                const EVP_MD *fdig = digest;

                if (!fdig)
                    fdig = EVP_sha1();

                if (!X509_digest(x, fdig, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(fdig)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }

            /* should be in the library */
            else if ((sign_flag == i) && (x509req == 0)) {
                BIO_printf(bio_err, "Getting Private key\n");
                if (Upkey == NULL) {
                    Upkey = load_key(keyfile, keyformat, 0,
                                     passin, e, "Private key");
                    if (Upkey == NULL)
                        goto end;
                }

                assert(need_rand);
                if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
                    goto end;
            } else if (CA_flag == i) {
                BIO_printf(bio_err, "Getting CA Private Key\n");
                if (CAkeyfile != NULL) {
                    CApkey = load_key(CAkeyfile, CAkeyformat,
                                      0, passin, e, "CA Private Key");
                    if (CApkey == NULL)
                        goto end;
                }

                assert(need_rand);
                if (!x509_certify(ctx, CAfile, digest, x, xca,
                                  CApkey, sigopts,
                                  CAserial, CA_createserial, days, clrext,
                                  extconf, extsect, sno, reqfile))
                    goto end;
            } else if (x509req == i) {
                EVP_PKEY *pk;

                BIO_printf(bio_err, "Getting request Private Key\n");
                if (keyfile == NULL) {
                    BIO_printf(bio_err, "no request key file specified\n");
                    goto end;
                } else {
                    pk = load_key(keyfile, keyformat, 0,
                                  passin, e, "request key");
                    if (pk == NULL)
                        goto end;
                }

                BIO_printf(bio_err, "Generating certificate request\n");

                rq = X509_to_X509_REQ(x, pk, digest);
                EVP_PKEY_free(pk);
                if (rq == NULL) {
                    ERR_print_errors(bio_err);
                    goto end;
                }
                if (!noout) {
                    X509_REQ_print(out, rq);
                    PEM_write_bio_X509_REQ(out, rq);
                }
                noout = 1;
            } else if (ocspid == i) {
                X509_ocspid_print(out, x);
            }
        }
    }

    if (checkend) {
        time_t tcheck = time(NULL) + checkoffset;

        if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
            BIO_printf(out, "Certificate will expire\n");
            ret = 1;
        } else {
            BIO_printf(out, "Certificate will not expire\n");
            ret = 0;
        }
        goto end;
    }

    print_cert_checks(out, x, checkhost, checkemail, checkip);

    if (noout || nocert) {
        ret = 0;
        goto end;
    }

    if (badsig)
        x->signature->data[x->signature->length - 1] ^= 0x1;

    if (outformat == FORMAT_ASN1)
        i = i2d_X509_bio(out, x);
    else if (outformat == FORMAT_PEM) {
        if (trustout)
            i = PEM_write_bio_X509_AUX(out, x);
        else
            i = PEM_write_bio_X509(out, x);
    } else if (outformat == FORMAT_NETSCAPE) {
        NETSCAPE_X509 nx;
        ASN1_OCTET_STRING hdr;

        hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
        hdr.length = strlen(NETSCAPE_CERT_HDR);
        nx.header = &hdr;
        nx.cert = x;

        i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
    } else {
        BIO_printf(bio_err, "bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err, "unable to write certificate\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    if (need_rand)
        app_RAND_write_file(NULL);
    OBJ_cleanup();
    NCONF_free(extconf);
    BIO_free_all(out);
    X509_STORE_free(ctx);
    X509_REQ_free(req);
    X509_free(x);
    X509_free(xca);
    EVP_PKEY_free(Upkey);
    EVP_PKEY_free(CApkey);
    EVP_PKEY_free(fkey);
    sk_OPENSSL_STRING_free(sigopts);
    X509_REQ_free(rq);
    ASN1_INTEGER_free(sno);
    sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
    sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
    OPENSSL_free(passin);
    return (ret);
}
Exemple #7
0
static ERL_NIF_TERM x509_make_cert_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  int expiry, serial;
  ASN1_INTEGER *asn1serial = NULL;
  BIGNUM *bn_rsa_genkey=NULL;
  BIO *bio_signing_private=NULL, *bio_issuer_cert = NULL, *bio_newcert_public = NULL;
  BIO *bio_x509=NULL;
  char *issuer_cert_pem=NULL;
  X509 *pX509 = NULL;
  X509 *pIssuerX509 = NULL;
  X509_NAME *pX509Name = NULL;
  X509_NAME *pIssuerName = NULL;
  x509_subject_entry *subject_entries;
  int num_subject_entries;
  int iret = 0;
  RSA *rsa=NULL;
  unsigned long f4=RSA_F4;
  unsigned args_len=-1;
  char *signing_keys[2], *cert_keys[2];
  ERL_NIF_TERM tail, *arg_terms=NULL;
  int idx;
  ERL_NIF_TERM ret, x509term;
  int x509len;
  unsigned char *x509data;

  EVP_PKEY *evp_signing_private = EVP_PKEY_new();
  EVP_PKEY *evp_newcert_public_key = EVP_PKEY_new();
  /* set RSA key gen type */
  bn_rsa_genkey = BN_new();
  BN_set_word(bn_rsa_genkey, f4);

  //
  // 1. stick subject of CA cert into NewCert
  // 2. stick public key of NewKeypair into NewCert
  // 3. sign NewCert with CA keypair

  /* Should be 6 elements in the list of X509 parameters.  We'll check each */
  if(!enif_get_list_length(env, argv[0], &args_len) || args_len != 6 ||
     NULL == (arg_terms = (ERL_NIF_TERM*)malloc(args_len * sizeof(ERL_NIF_TERM)))) return enif_make_badarg(env);
  
  enif_get_list_cell(env, argv[0], &arg_terms[0], &tail);
  for(idx=1; idx<args_len; idx++){
    if(!enif_get_list_cell(env, tail, &arg_terms[idx], &tail)){
      free(arg_terms);
      return enif_make_badarg(env);
    }
  }
  
  idx=0;
  /* get the signing private key */
  x509_parse_keypair(env, "signing_key", arg_terms[idx++], signing_keys);

  /* get the issuer cert */
  x509_parse_issuer_cert(env, arg_terms[idx++], &issuer_cert_pem);

  /* get the soon-to-be cert's public key */
  x509_parse_keypair(env, "newcert_public_key", arg_terms[idx++], cert_keys);

  /* get the subject */
  x509_parse_subject(env, arg_terms[idx++], &num_subject_entries, &subject_entries);

  /* get the serial number */
  x509_parse_int_tuple(env, arg_terms[idx++], "serial", &serial);

  /* get the expiry */
  x509_parse_int_tuple(env, arg_terms[idx++], "expiry", &expiry);

  /* work the OpenSSL cert creation magic */
  if ((bio_signing_private = BIO_new_mem_buf(signing_keys[1], -1))
      && (rsa = PEM_read_bio_RSAPrivateKey(bio_signing_private, NULL, NULL, NULL))
      && (iret = EVP_PKEY_assign_RSA(evp_signing_private, rsa))
              
      && (bio_newcert_public = BIO_new_mem_buf(cert_keys[0], -1))
      && (evp_newcert_public_key = PEM_read_bio_PUBKEY(bio_newcert_public, NULL, NULL, NULL))
              
      && (bio_issuer_cert = BIO_new_mem_buf(issuer_cert_pem, -1))
      && (pIssuerX509 = PEM_read_bio_X509(bio_issuer_cert, NULL, NULL, NULL))
      && (pX509 = X509_new())) {
    /* if we've managed to generate a key and allocate structure memory,
       set X509 fields */
    asn1serial = ASN1_INTEGER_new();
    X509_set_version(pX509, 2); /* cert_helper uses '3' here */
    ASN1_INTEGER_set(asn1serial, serial);
    X509_set_serialNumber(pX509, asn1serial);
    X509_gmtime_adj(X509_get_notBefore(pX509),0);
    X509_gmtime_adj(X509_get_notAfter(pX509),(long)60*60*24*expiry);
    X509_set_pubkey(pX509, evp_newcert_public_key);
    pX509Name = X509_get_subject_name(pX509);
    
    while(--num_subject_entries >= 0){
      X509_NAME_add_entry_by_txt(pX509Name, (subject_entries[num_subject_entries]).name,
                                 MBSTRING_ASC, (unsigned char*)(subject_entries[num_subject_entries]).value, -1, -1, 0);
    }
    
    pIssuerName = X509_get_issuer_name(pIssuerX509);
    X509_set_issuer_name(pX509, pIssuerName);
    X509_sign(pX509, evp_signing_private, digest);
    
    bio_x509 = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(bio_x509, pX509);
    
    x509len = BIO_get_mem_data(bio_x509, &x509data);
    memcpy(enif_make_new_binary(env, x509len, &x509term), x509data, x509len);
    ret = enif_make_tuple2(env, atom_x509_cert, x509term);
  }
    
 done:
  if(arg_terms) free(arg_terms);
  free_keys(signing_keys);
  free_keys(cert_keys);
  free_subject_entries(num_subject_entries, subject_entries);
  if(pX509) X509_free(pX509);
  if(pIssuerX509) X509_free(pIssuerX509);
  if(issuer_cert_pem) free(issuer_cert_pem);
  if(bio_issuer_cert) { BIO_set_close(bio_issuer_cert, BIO_NOCLOSE); BIO_free_all(bio_issuer_cert); }
  if(bio_signing_private) { BIO_set_close(bio_signing_private, BIO_NOCLOSE); BIO_free_all(bio_signing_private); }
  if(bio_newcert_public) { BIO_set_close(bio_newcert_public, BIO_NOCLOSE); BIO_free_all(bio_newcert_public); }
  if(bio_x509) BIO_free_all(bio_x509);
  if(asn1serial) ASN1_INTEGER_free(asn1serial);
  if(bn_rsa_genkey) BN_free(bn_rsa_genkey);
  if(rsa) RSA_free(rsa);

  return ret;
}
Exemple #8
0
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) {

  long *aLong = NULL;
  PKI_TIME *aTime = NULL;
  PKI_INTEGER *aInt = NULL;
  PKI_X509_NAME *aName = NULL;
  PKI_X509_KEYPAIR_VALUE *aKey = NULL;

  int ret = 0;

  LIBPKI_X509_CERT *xVal = NULL;
  LIBPKI_X509_ALGOR *alg = NULL;
  // PKI_X509_CERT_VALUE *xVal = NULL;

  if ( !x || !x->value || !data || x->type != PKI_DATATYPE_X509_CERT) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return (PKI_ERR);
  }

  // xVal = PKI_X509_get_value( x );
  xVal = x->value;

  switch( type ) {

    case PKI_X509_DATA_VERSION:
      aLong = (long *) data;
      ret = X509_set_version( xVal, *aLong );
      break;

    case PKI_X509_DATA_SERIAL:
      aInt = (PKI_INTEGER *) data;
      ret = X509_set_serialNumber( xVal, aInt);
      break;

    case PKI_X509_DATA_SUBJECT:
      aName = (PKI_X509_NAME *) data;
      ret = X509_set_subject_name( xVal, aName );
      break;

    case PKI_X509_DATA_ISSUER:
      aName = (PKI_X509_NAME *) data;
      ret = X509_set_issuer_name( xVal, aName );
      break;

    case PKI_X509_DATA_NOTBEFORE:
      aTime = (PKI_TIME *) data;
      ret = X509_set_notBefore( xVal, aTime );
      break;

    case PKI_X509_DATA_NOTAFTER:
      aTime = (PKI_TIME *) data;
      ret = X509_set_notAfter( xVal, aTime );
      break;

    case PKI_X509_DATA_KEYPAIR_VALUE:
      aKey = data;
      ret = X509_set_pubkey( xVal, aKey);
      break;

    case PKI_X509_DATA_ALGORITHM:
    case PKI_X509_DATA_SIGNATURE_ALG1:
      alg = data;
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      if (xVal->cert_info != NULL)
        xVal->cert_info->signature = alg;
#else
      // Transfer Ownership
      xVal->cert_info.signature.algorithm = alg->algorithm;
      xVal->cert_info.signature.parameter = alg->parameter;

      // Remove the transfered data
      alg->algorithm = NULL;
      alg->parameter = NULL;

      // Free memory
      X509_ALGOR_free((X509_ALGOR *)data);
      data = NULL;

#endif
	// Ok
	ret = 1;
      break;

    case PKI_X509_DATA_SIGNATURE_ALG2:
      // if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg);
      alg = data;
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
      xVal->sig_alg = alg;
#else
      // Transfer Ownership
      xVal->sig_alg.algorithm = alg->algorithm;
      xVal->sig_alg.parameter = alg->parameter;

      // Remove the transfered data
      alg->algorithm = NULL;
      alg->parameter = NULL;

      // Free memory
      X509_ALGOR_free((X509_ALGOR *)alg);
      data = NULL;

      // Ok
      ret = 1;

#endif
      break;

    default:
      /* Not Recognized/Supported DATATYPE */
      ret = 0;
      break;
  }

  if (!ret) return PKI_ERR;

  return PKI_OK;

}
Exemple #9
0
PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT    * ca_cert, 
                                   const PKI_X509_KEYPAIR * kPair,
                                   const PKI_X509_REQ     * req,
                                   const char             * subj_s, 
                                   const char             * serial_s,
                                   uint64_t                 validity,
                                   const PKI_X509_PROFILE * conf,
                                   const PKI_ALGOR        * algor,
                                   const PKI_CONFIG       * oids,
                                   HSM *hsm ) {
  PKI_X509_CERT *ret = NULL;
  PKI_X509_CERT_VALUE *val = NULL;
  PKI_X509_NAME *subj = NULL;
  PKI_X509_NAME *issuer = NULL;
  PKI_DIGEST_ALG *digest = NULL;
  PKI_X509_KEYPAIR_VALUE *signingKey = NULL;
  PKI_TOKEN *tk = NULL;

  PKI_X509_KEYPAIR_VALUE  *certPubKeyVal = NULL;

  int rv = 0;
  int ver = 2;

  int64_t notBeforeVal = 0;

  ASN1_INTEGER *serial = NULL;

  char *ver_s = NULL;

  /* Check if the REQUIRED PKEY has been passed */
  if (!kPair || !kPair->value) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return (NULL);
  };

  signingKey = kPair->value;

  /* TODO: This has to be fixed, to work on every option */
  if ( subj_s )
  {
    subj = PKI_X509_NAME_new ( subj_s );
  }
  else if (conf || req)
  {
    char *tmp_s = NULL;

    // Let's use the configuration option first
    if (conf) {

      // Get the value of the DN, if present
      if ((tmp_s = PKI_CONFIG_get_value( conf, 
                                 "/profile/subject/dn")) != NULL ) {
        // Builds from the DN in the config  
        subj = PKI_X509_NAME_new(tmp_s);
        PKI_Free ( tmp_s );
      }
    }

    // If we still do not have a name, let's check
    // the request for one
    if (req && !subj) {

      const PKI_X509_NAME * req_subj = NULL;

      // Copy the name from the request
      if ((req_subj = PKI_X509_REQ_get_data(req, 
				    PKI_X509_DATA_SUBJECT)) != NULL) {
        subj = PKI_X509_NAME_dup(req_subj);
      }
    }

    // If no name is provided, let's use an empty one
    // TODO: Shall we remove this and fail instead ?
    if (!subj) subj = PKI_X509_NAME_new( "" );
  }
  else
  {
    struct utsname myself;
    char tmp_name[1024];

    if (uname(&myself) < 0) {
      subj = PKI_X509_NAME_new( "" );
    } else {
      sprintf( tmp_name, "CN=%s", myself.nodename );
      subj = PKI_X509_NAME_new( tmp_name );
    }
  }

  if (!subj) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s );
    goto err;
  }

  if( ca_cert ) {
    const PKI_X509_NAME *ca_subject = NULL;

    /* Let's get the ca_cert subject and dup that data */
    // ca_subject = (PKI_X509_NAME *) 
    //     X509_get_subject_name( (X509 *) ca_cert );
    ca_subject = PKI_X509_CERT_get_data( ca_cert, 
        PKI_X509_DATA_SUBJECT );

    if( ca_subject ) {
      issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *)ca_subject);
    } else {
      PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
      goto err;
    }

  } else {
    issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *) subj);
  }

  if( !issuer ) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
    goto err;
  }

  if(( ret = PKI_X509_CERT_new_null()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    goto err;
  }

  /* Alloc memory structure for the Certificate */
  if((ret->value = ret->cb->create()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    return (NULL);
  }

  val = ret->value;

  if(( ver_s = PKI_CONFIG_get_value( conf, "/profile/version")) != NULL ) {
    ver = atoi( ver_s ) - 1;
    if ( ver < 0 ) 
      ver = 0;
    PKI_Free ( ver_s );
  } else {
    ver = 2;
  };

  if (!X509_set_version(val,ver)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_VERSION, NULL);
    goto err;
  }

  if (serial_s) {
    char * tmp_s = (char *) serial_s;
    serial = s2i_ASN1_INTEGER(NULL, tmp_s);
  } else {
    // If cacert we assume it is a normal cert - let's create a
    // random serial number, otherwise - it's a self-signed, use
    // the usual 'fake' 0
    if ( ca_cert ) {
      unsigned char bytes[11];
      RAND_bytes(bytes, sizeof(bytes));
      bytes[0] = 0;

      serial = PKI_INTEGER_new_bin(bytes, sizeof(bytes));
    } else {
      serial = s2i_ASN1_INTEGER( NULL, "0");
    };
  };

  if(!X509_set_serialNumber( val, serial )) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SERIAL, serial_s);
    goto err;
  }

  /* Set the issuer Name */
  // rv = X509_set_issuer_name((X509 *) ret, (X509_NAME *) issuer);
  if(!X509_set_issuer_name( val, (X509_NAME *) issuer)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
    goto err;
  }

  /* Set the subject Name */
  if(!X509_set_subject_name(val, (X509_NAME *) subj)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, NULL);
    goto err;
  }

  /* Set the start date (notBefore) */
  if (conf)
  {
    int years = 0;
    int days  = 0;
    int hours = 0;
    int mins  = 0;
    int secs  = 0;

    char *tmp_s = NULL;

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/years")) != NULL ) {
      years = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/days")) != NULL ) {
      days = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/hours")) != NULL ) {
      hours = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/minutes")) != NULL ) {
      mins = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/seconds")) != NULL ) {
      secs = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    notBeforeVal =   secs +
            ( mins * 60 ) + 
            ( hours * 3600 ) + 
            ( days   * 3600 * 24 ) + 
            ( years * 3600 * 24 * 365 );
  };

  /* Set the validity (notAfter) */
  if( conf && validity == 0 )
  {
    long long years = 0;
    long long days  = 0;
    long long hours = 0;
    long long mins  = 0;
    long long secs  = 0;

    char *tmp_s = NULL;

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/years")) != NULL ) {
      years = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/days")) != NULL ) {
      days = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/hours")) != NULL ) {
      hours = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/minutes")) != NULL ) {
      mins = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/minutes")) != NULL ) {
      secs = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    validity =   (unsigned long long) secs +
          (unsigned long long) ( mins   * 60 ) + 
          (unsigned long long) ( hours * 3600 ) + 
          (unsigned long long) ( days   * 3600 * 24 ) + 
          (unsigned long long) ( years * 3600 * 24 * 365 );
  };

  if (validity <= 0) validity = 30 * 3600 * 24;

#if ( LIBPKI_OS_BITS == LIBPKI_OS32 )
  long notBeforeVal32 = (long) notBeforeVal;
  if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal32 ) == NULL)
  {
#else
  if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal ) == NULL)
  {
#endif
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_NOTBEFORE, NULL);
    goto err;
  }

  /* Set the end date in a year */
  if (X509_gmtime_adj(X509_get_notAfter(val),(long int) validity) == NULL)
  {
    PKI_DEBUG("ERROR: can not set notAfter field!");
    goto err;
  }

  /* Copy the PKEY if it is in the request, otherwise use the
     public part of the PKI_X509_CERT */
  if (req)
  {
    certPubKeyVal = (PKI_X509_KEYPAIR_VALUE *) 
       PKI_X509_REQ_get_data(req, PKI_X509_DATA_KEYPAIR_VALUE);

    if( !certPubKeyVal ) {
      PKI_DEBUG("ERROR, can not get pubkey from req!");
      goto err;
    }
  }
  else
  {
    /* Self Signed -- Same Public Key! */
    certPubKeyVal = signingKey;
  }

  if (!ca_cert && conf)
  {
    char *tmp_s = NULL;

    if(( tmp_s = PKI_X509_PROFILE_get_value( conf, 
        "/profile/keyParams/algorithm")) != NULL )
    {
      PKI_ALGOR *myAlg = NULL;
      PKI_DIGEST_ALG *dgst = NULL;

      if((myAlg = PKI_ALGOR_get_by_name( tmp_s )) != NULL )
      {
        if(!algor) algor = myAlg;

        if((dgst = PKI_ALGOR_get_digest( myAlg )) != NULL )
        {
          PKI_DEBUG("Got Signing Algorithm: %s, %s",
            PKI_DIGEST_ALG_get_parsed(dgst), PKI_ALGOR_get_parsed(myAlg));
          digest = dgst;
        }
        else
        {
          PKI_DEBUG("Can not parse digest algorithm from %s", tmp_s);
        }
      }
      else
      {
        PKI_DEBUG("Can not parse key algorithm from %s", tmp_s);
      }
      PKI_Free ( tmp_s );
    }
  }

  if (conf)
  {
    PKI_KEYPARAMS *kParams = NULL;
    PKI_SCHEME_ID scheme;

    scheme = PKI_ALGOR_get_scheme( algor );

    kParams = PKI_KEYPARAMS_new(scheme, conf);
    if (kParams)
    {
      /* Sets the point compression */
      switch ( kParams->scheme )
      {
#ifdef ENABLE_ECDSA
        case PKI_SCHEME_ECDSA:
            if ( (int) kParams->ec.form > 0 )
            {
# if OPENSSL_VERSION_NUMBER < 0x1010000fL
              EC_KEY_set_conv_form(certPubKeyVal->pkey.ec, 
              			   (point_conversion_form_t) kParams->ec.form);
# else
              EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(certPubKeyVal), 
              (point_conversion_form_t) kParams->ec.form);
# endif
            }
          if ( kParams->ec.asn1flags > -1 )
          {
# if OPENSSL_VERSION_NUMBER < 0x1010000fL
            EC_KEY_set_asn1_flag(certPubKeyVal->pkey.ec,
              kParams->ec.asn1flags );
# else
            EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(certPubKeyVal),
              kParams->ec.asn1flags );
# endif
          }
          break;
#endif
        case PKI_SCHEME_RSA:
        case PKI_SCHEME_DSA:
          break;

        default:
          // Nothing to do
          PKI_ERROR(PKI_ERR_GENERAL, "Signing Scheme Uknown %d!", kParams->scheme);
          break;
      }
    }
  }

  if (!X509_set_pubkey(val, certPubKeyVal))
  {
    PKI_DEBUG("ERROR, can not set pubkey in cert!");
    goto err;
  }

  if (conf)
  {
    if((tk = PKI_TOKEN_new_null()) == NULL )
    {
      PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
      goto err;
    }

    PKI_TOKEN_set_cert(tk, ret);

    if (ca_cert) {
      PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ca_cert);
    } else {
      PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ret);
    }

    if (req) PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req );
    if (kPair) PKI_TOKEN_set_keypair ( tk, (PKI_X509_KEYPAIR *)kPair );

    rv = PKI_X509_EXTENSIONS_cert_add_profile(conf, oids, ret, tk);
    if (rv != PKI_OK)
    {
      PKI_DEBUG( "ERROR, can not set extensions!");

      tk->cert = NULL;
      tk->cacert = NULL;
      tk->req = NULL;
      tk->keypair = NULL;

      PKI_TOKEN_free ( tk );

      goto err;
    }

    // Cleanup for the token (used only to add extensions)
    tk->cert = NULL;
    tk->cacert = NULL;
    tk->req = NULL;
    tk->keypair = NULL;
    PKI_TOKEN_free ( tk );
  }

  if (!digest)
  {
    if (!algor)
    {
      PKI_log_debug("Getting the Digest Algorithm from the CA cert");

      // Let's get the Digest Algorithm from the CA Cert
      if (ca_cert)
      {
        if((algor = PKI_X509_CERT_get_data(ca_cert,
              PKI_X509_DATA_ALGORITHM )) == NULL)
        {
          PKI_log_err("Can not retrieve DATA algorithm from CA cert");
        }
      }
    }

    // If we have an Algor from either the passed argument or
    // the CA Certificate, extract the digest from it. Otherwise
    // get the digest from the signing key
    if (algor)
    {
      if((digest = PKI_ALGOR_get_digest(algor)) == NULL )
      {
        PKI_log_err("Can not get digest from algor");
      }
    }

    // Check, if still no digest, let's try from the signing Key
    if (digest == NULL)
    {
      if ((digest = PKI_DIGEST_ALG_get_by_key( kPair )) == NULL)
      {
        PKI_log_err("Can not infer digest algor from the key pair");
      }
    }
  }

  // No Digest Here ? We failed...
  if (digest == NULL)
  {
    PKI_log_err("PKI_X509_CERT_new()::Can not get the digest!");
    return( NULL );
  }

  // Sign the data
  if (PKI_X509_sign(ret, digest, kPair) == PKI_ERR)
  {
    PKI_log_err ("Can not sign certificate [%s]",
      ERR_error_string(ERR_get_error(), NULL ));
    PKI_X509_CERT_free ( ret );
    return NULL;
  }

#if ( OPENSSL_VERSION_NUMBER >= 0x0090900f )

# if OPENSSL_VERSION_NUMBER < 0x1010000fL
  PKI_X509_CERT_VALUE *cVal = (PKI_X509_CERT_VALUE *) ret->value;

  if (cVal && cVal->cert_info)
  {
    PKI_log_debug("Signature = %s", 
      PKI_ALGOR_get_parsed(cVal->cert_info->signature));
  }
# endif

  //  PKI_X509_CINF_FULL *cFull = NULL;
  //  cFull = (PKI_X509_CINF_FULL *) cVal->cert_info;
  //  cFull->enc.modified = 1;
#endif

  return ret;

err:

  if (ret) PKI_X509_CERT_free(ret);
  if (subj) PKI_X509_NAME_free(subj);
  if (issuer) PKI_X509_NAME_free(issuer);

  return NULL;
}

/*!
 * \brief Signs a PKI_X509_CERT
 */

int PKI_X509_CERT_sign(PKI_X509_CERT *cert, PKI_X509_KEYPAIR *kp,
    PKI_DIGEST_ALG *digest) {

  const PKI_ALGOR *alg = NULL;

  if( !cert || !cert->value || !kp || !kp->value ) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return PKI_ERR;
  }

  if(!digest) {
    if((alg = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_ALGORITHM))!=NULL) {
      digest = PKI_ALGOR_get_digest ( alg );
    }
  }

  if(!digest) {
    if((digest = PKI_DIGEST_ALG_get_by_key(kp)) == NULL) {
      PKI_log_err("PKI_X509_CERT_new()::Can not get digest algor "
          "from key");
      return PKI_ERR;
    }
  }

  if( PKI_X509_sign(cert, digest, kp) == PKI_ERR) {
    PKI_log_err ("PKI_X509_CERT_new()::Can not sign certificate [%s]",
      ERR_error_string(ERR_get_error(), NULL ));
    return PKI_ERR;
  }

  return PKI_OK;
};

/*!
 * \brief Signs a PKI_X509_CERT by using a configured PKI_TOKEN
 */

int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk,
    PKI_DIGEST_ALG *digest) {

  PKI_X509_KEYPAIR *kp = NULL;

  if( !cert || !cert->value || !tk ) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return PKI_ERR;
  };

  if( PKI_TOKEN_login( tk ) == PKI_ERR ) {
    PKI_ERROR(PKI_ERR_HSM_LOGIN, NULL);
    return PKI_ERR;
  };

  if((kp = PKI_TOKEN_get_keypair( tk )) == NULL ) {
    return PKI_ERR;
  };

  return PKI_X509_CERT_sign ( cert, kp, digest );
};
Exemple #10
0
static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
	     int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
	{
	int ret=0;
	ASN1_INTEGER *bs=NULL;
	X509_STORE_CTX xsc;
	EVP_PKEY *upkey;

	upkey = X509_get_pubkey(xca);
	EVP_PKEY_copy_parameters(upkey,pkey);
	EVP_PKEY_free(upkey);

	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
		{
		BIO_printf(bio_err,"Error initialising X509 store\n");
		goto end;
		}
	if (sno) bs = sno;
	else if (!(bs = load_serial(CAfile, serialfile, create)))
		goto end;

	if (!X509_STORE_add_cert(ctx,x)) goto end;

	/* NOTE: this certificate can/should be self signed, unless it was
	 * a certificate request in which case it is not. */
	X509_STORE_CTX_set_cert(&xsc,x);
	if (!reqfile && !X509_verify_cert(&xsc))
		goto end;

	if (!X509_check_private_key(xca,pkey))
		{
		BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
		goto end;
		}

	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
	if (!X509_set_serialNumber(x,bs)) goto end;

	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
		goto end;

	/* hardwired expired */
	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
		goto end;

	if (clrext)
		{
		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
		}

	if (conf)
		{
		X509V3_CTX ctx2;
		X509_set_version(x,2); /* version 3 certificate */
                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
                X509V3_set_nconf(&ctx2, conf);
                if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
		}

	if (!X509_sign(x,pkey,digest)) goto end;
	ret=1;
end:
	X509_STORE_CTX_cleanup(&xsc);
	if (!ret)
		ERR_print_errors(bio_err);
	if (!sno) ASN1_INTEGER_free(bs);
	return ret;
	}
Exemple #11
0
int PKI_X509_CERT_set_data(PKI_X509_CERT *x, int type, void *data) {

	long *aLong = NULL;
	PKI_TIME *aTime = NULL;
	PKI_INTEGER *aInt = NULL;
	PKI_X509_NAME *aName = NULL;
	PKI_X509_KEYPAIR_VALUE *aKey = NULL;

	int ret = 0;

	PKI_X509_CERT_VALUE *xVal = NULL;

	if( !x || !x->value || !data) {
		PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
		return (PKI_ERR);
	}

	xVal = PKI_X509_get_value( x );

	switch( type ) {
		case PKI_X509_DATA_VERSION:
			aLong = (long *) data;
			ret = X509_set_version( xVal, *aLong );
			break;

		case PKI_X509_DATA_SERIAL:
			aInt = (PKI_INTEGER *) data;
			ret = X509_set_serialNumber( xVal, aInt);
			break;

		case PKI_X509_DATA_SUBJECT:
			aName = (PKI_X509_NAME *) data;
			ret = X509_set_subject_name( xVal, aName );
			break;

		case PKI_X509_DATA_ISSUER:
			aName = (PKI_X509_NAME *) data;
			ret = X509_set_issuer_name( xVal, aName );
			break;

		case PKI_X509_DATA_NOTBEFORE:
			aTime = (PKI_TIME *) data;
			ret = X509_set_notBefore( xVal, aTime );
			break;

		case PKI_X509_DATA_NOTAFTER:
			aTime = (PKI_TIME *) data;
			ret = X509_set_notAfter( xVal, aTime );
			break;

		case PKI_X509_DATA_KEYPAIR_VALUE:
			aKey = data;
			ret = X509_set_pubkey( xVal, aKey);
			break;

		case PKI_X509_DATA_ALGORITHM:
		case PKI_X509_DATA_SIGNATURE_ALG1:
			if (xVal->cert_info != NULL)
			{
				// if (xVal->cert_info->signature != NULL) X509_ALGOR_free(xVal->cert_info->signature);
				xVal->cert_info->signature = (X509_ALGOR *) data;
			}
			break;

		case PKI_X509_DATA_SIGNATURE_ALG2:
			// if (xVal->sig_alg != NULL ) X509_ALGOR_free(xVal->sig_alg);
			xVal->sig_alg = (X509_ALGOR *) data;
			break;

		default:
			/* Not Recognized/Supported DATATYPE */
			ret = 0;
			break;
	}

	if (!ret) return PKI_ERR;

	return PKI_OK;

}
Exemple #12
0
unsigned char *SCEP_MSG_decrypt( SCEP_MSG *msg, EVP_PKEY *ppkey, 
		X509 *cert, long *len ) {

	char *ret = NULL;
	char *data = NULL;

	BIO *bio = NULL;
	BIO *bio_err = NULL;
	BIO *bio_dup = NULL;

	X509 *foo_cert = NULL;
	EVP_PKEY *pkey = NULL;

	SCEP_RECIP_INFO *rinfo;

        if ((bio_err=BIO_new(BIO_s_file())) != NULL)
		BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	/* Get the recipient information to build the fake
	 * certificate needed into the PKCS7_decrypt function */
	rinfo = &(msg->env_data.recip_info);

	/* We need a private key */
	if( ppkey )
		pkey = ppkey;
	else
		pkey = msg->signer_pkey;

	if( !pkey ) return (NULL);

	if( cert ) {
		foo_cert = cert;
	} else {
		if( (foo_cert = X509_new()) == NULL ) {
			BIO_printf(bio_err, "%s:%d: foo_cert not alloc\n", __FILE__,
				__LINE__);

			goto err;
		};

		X509_set_issuer_name(foo_cert,rinfo->ias->issuer);
		X509_set_subject_name(foo_cert,rinfo->ias->issuer);
		X509_set_serialNumber(foo_cert,rinfo->ias->serial);
		X509_set_pubkey(foo_cert, pkey);
	}

	bio = BIO_new(BIO_s_mem());
	if (PKCS7_decrypt( msg->env_data.p7env, pkey, foo_cert, bio, 0) == 0) {
		// printf("%s:%d: decryption failed\n", __FILE__,
		// 	__LINE__);
		goto err;
	}
	BIO_flush(bio);
	if( len ) *len = BIO_get_mem_data(bio, &data);

	switch ( msg->messageType ) {
	   case MSG_CERTREP:
		if( msg->env_data.crl = d2i_X509_CRL_bio(bio,NULL) ) {
			/* There is a CRL */
			ret = (char *) msg->env_data.crl;
		}
		// p7 = d2i_PKCS7_bio(bio, NULL);
		break;
	   case MSG_PKCSREQ:
		msg->env_data.content.req = d2i_X509_REQ_bio(bio, NULL);
		ret = (char *) msg->env_data.content.req;
		break;
	   case MSG_GETCERTINITIAL:
		// req->rd.is = d2i_issuer_and_subject_bio(bio, NULL);
		break;
	   case MSG_GETCERT:
	   case MSG_GETCRL:
		msg->env_data.content.ias = d2i_PKCS7_ias_bio(NULL, bio);
		ret = (char *) msg->env_data.content.ias;
		break;
	case MSG_V2PROXY: // unsupported
	case MSG_V2REQUEST: // unsupported
	default:
		// BIO_printf(bio_err, "%s:%d: unknown message type: %s\n",
		// 	__FILE__, __LINE__, msg->messageType);
		break;
	}

err:
	if( foo_cert && !cert ) X509_free( foo_cert );
	if( bio ) BIO_free(bio);

	ERR_clear_error();

	return ret;
}