Esempio n. 1
0
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
    X509 *x;
    EVP_PKEY *pk;
    RSA *rsa;
    X509_NAME *name = NULL;
    
    if (*pkeyp == NULL) {
        if ((pk=EVP_PKEY_new()) == NULL) {
            return(0);
        }
    } else {
        pk = *pkeyp;
    }
    
    if (*x509p == NULL) {
        if ((x = X509_new()) == NULL) {
            goto err;
        }
    } else {
        x = *x509p;
    }
    
    rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);
    if (!EVP_PKEY_assign_RSA(pk, rsa)) {
        goto err;
    }
    
    X509_set_version(x, 2);
    ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
    X509_gmtime_adj(X509_get_notBefore(x), 0);
    X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*365*years);
    X509_set_pubkey(x, pk);
    
    name = X509_get_subject_name(x);
    
    /* This function creates and adds the entry, working out the
     * correct string type and performing checks on its length.
     */
    X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (unsigned char*)"NVIDIA GameStream Client", -1, -1, 0);
    
    /* Its self signed so set the issuer name to be the same as the
     * subject.
     */
    X509_set_issuer_name(x, name);
    
    /* Add various extensions: standard extensions */
    add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
    add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");
    
    add_ext(x, NID_subject_key_identifier, "hash");
    
    if (!X509_sign(x, pk, EVP_sha1())) {
        goto err;
    }
    
    *x509p = x;
    *pkeyp = pk;
    
    return(1);
err:
    return(0);
}
Esempio n. 2
0
int
x509_main(int argc, char **argv)
{
	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 checkend = 0, checkoffset = 0;
	unsigned long nmflag = 0, certflag = 0;
	const char *errstr = NULL;

	if (single_execution) {
		if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	reqfile = 0;

	STDout = BIO_new_fp(stdout, BIO_NOCLOSE);

	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;
		} 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 = strtonum(*(++argv), 1, INT_MAX, &errstr);
			if (errstr) {
				BIO_printf(bio_err, "bad number of days: %s\n", errstr);
				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;
		} else if (strcmp(*argv, "-CA") == 0) {
			if (--argc < 1)
				goto bad;
			CAfile = *(++argv);
			CA_flag = ++num;
		} 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;
			ASN1_INTEGER_free(sno);
			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;
		}
		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 = strtonum(*(++argv), 0, INT_MAX, &errstr);
			if (errstr) {
				BIO_printf(bio_err, "checkend unusable: %s\n", errstr);
				goto bad;
			}
			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;
		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;
	}

	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, "Certificate");

	if (x == NULL)
		goto end;
	if (CA_flag) {
		xca = load_cert(bio_err, CAfile, CAformat, NULL, "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);
		} 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=");
				if (pkey->type == EVP_PKEY_RSA)
					BN_print(STDout, pkey->pkey.rsa->n);
				else
						if (pkey->type == EVP_PKEY_DSA)
							BN_print(STDout, pkey->pkey.dsa->pub_key);
				else
						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 = malloc(z);
				if (m == NULL) {
					BIO_printf(bio_err, "out of mem\n");
					goto end;
				}

				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");

				free(m);
			} else if (text == i) {
				X509_print_ex(STDout, 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, "Private key");
					if (Upkey == NULL)
						goto end;
				}
				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, "CA Private Key");
					if (CApkey == NULL)
						goto end;
				}
				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, "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(&NETSCAPE_X509_it, 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:
	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);
	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);
	free(passin);

	return (ret);
}
Esempio n. 3
0
File: sscep.c Progetto: flomar/sscep
int
main(int argc, char **argv) {
	//ENGINE *e = NULL;
	int			c, host_port = 80, count = 1;
	char			*host_name, *p, *dir_name = NULL;
	char			http_string[16384];
	struct http_reply	reply;
	unsigned int		n;
	unsigned char		md[EVP_MAX_MD_SIZE];
	struct scep		scep_t;
	FILE			*fp = NULL;
	BIO			*bp;
	STACK_OF(X509)		*nextcara = NULL;
	X509 				*cert=NULL;
	PKCS7 p7;
	int i;
	int required_option_space;
	


#ifdef WIN32
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	//printf("Starting sscep\n");
	//fprintf(stdout, "%s: starting sscep on WIN32, sscep version %s\n",	pname, VERSION);
       
	wVersionRequested = MAKEWORD( 2, 2 );
 
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 )
	{
	  /* Tell the user that we could not find a usable */
	  /* WinSock DLL.                                  */
	  return;
	}
 
	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */
 
	if ( LOBYTE( wsaData.wVersion ) != 2 ||
	        HIBYTE( wsaData.wVersion ) != 2 )
	{
	    /* Tell the user that we could not find a usable */
	    /* WinSock DLL.                                  */
	    WSACleanup( );
	    return; 
	}

#endif
	/* Initialize scep layer */
	init_scep();

	/* Set program name */
	pname = argv[0];

	/* Set timeout */
	timeout = TIMEOUT;


	/* Check operation parameter */
	if (!argv[1]) {
		usage();
	} else if (!strncmp(argv[1], "getca", 5)) {
		operation_flag = SCEP_OPERATION_GETCA;
	} else if (!strncmp(argv[1], "enroll", 6)) {
		operation_flag = SCEP_OPERATION_ENROLL;
	} else if (!strncmp(argv[1], "getcert", 7)) {
		operation_flag = SCEP_OPERATION_GETCERT;
	} else if (!strncmp(argv[1], "getcrl", 6)) {
		operation_flag = SCEP_OPERATION_GETCRL;
	} else if (!strncmp(argv[1], "getnextca", 9)) {
		operation_flag = SCEP_OPERATION_GETNEXTCA;
	} else {
		fprintf(stderr, "%s: missing or illegal operation parameter\n",
				argv[0]);
		usage();
	}
	/* Skip first parameter and parse the rest of the command */
	optind++;
	while ((c = getopt(argc, argv, "c:C:de:E:f:g:hF:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:m:HM:")) != -1)
                switch(c) {
			case 'c':
				c_flag = 1;
				c_char = optarg;
				break;
			case 'C':
				C_flag = 1;
				C_char = optarg;
				break;
			case 'd':
				d_flag = 1;
				break;
			case 'e':
				e_flag = 1;
				e_char = optarg;
				break;
			case 'E':
				E_flag = 1;
				E_char = optarg;
				break;
			case 'F':
				F_flag = 1;
				F_char = optarg;
				break;
			case 'f':
				f_flag = 1;
				f_char = optarg;
				break;
			case 'g':
				g_flag = 1;
				g_char = optarg;
				break;
			case 'h'://TODO change to eg. ID --inform=ID
				h_flag = 1;
				break;
			case 'H':
				H_flag = 1;
				break;
			case 'i':
				i_flag = 1;
				i_char = optarg;
				break;
			case 'k':
				k_flag = 1;
				k_char = optarg;
				break;
			case 'K':
				K_flag = 1;
				K_char = optarg;
				break;
			case 'l':
				l_flag = 1;
				l_char = optarg;
				break;
			case 'L':
				L_flag = 1;
				L_char = optarg;
				break;
			case 'm':
				m_flag = 1;
				m_char = optarg;
				break;
			case 'M':
				if(!M_flag) {
					/* if this is the first time the option appears, create a
					 * new string.
					 */
					required_option_space = strlen(optarg) + 1;
					M_char = malloc(required_option_space);
					if(!M_char)
						error_memory();
					strncpy(M_char, optarg, required_option_space);
					// set the flag, so we already have a string
					M_flag = 1;
				} else {
					/* we already have a string, just extend it. */
					// old part + new part + &-sign + null byte
					required_option_space = strlen(M_char) + strlen(optarg) + 2;
					M_char = realloc(M_char, required_option_space);
					if(!M_char)
						error_memory();
					strncat(M_char, "&", 1);
					strncat(M_char, optarg, strlen(optarg));
				}
				break;
			case 'n':
				n_flag = 1;
				n_num = atoi(optarg);
				break;
			case 'O':
				O_flag = 1;
				O_char = optarg;
				break;
			case 'p':
				p_flag = 1;
				p_char = optarg;
				break;
			case 'r':
				r_flag = 1;
				r_char = optarg;
				break;
			case 'R':
				R_flag = 1;
				break;
			case 's':
				s_flag = 1;
				/*s_char = optarg;*/
				s_char = handle_serial(optarg);
				break;
			case 'S':
				S_flag = 1;
				S_char = optarg;
				break;
			case 't':
				t_flag = 1;
				t_num = atoi(optarg);
				break;
			case 'T':
				T_flag = 1;
				T_num = atoi(optarg);
				break;
			case 'u':
				u_flag = 1;
				url_char = optarg;
				break;
			case 'v':
				v_flag = 1;
				break;
			case 'w':
				w_flag = 1;
				w_char = optarg;
				break;
			default:
			  printf("argv: %s\n", argv[optind]);
				usage();
                }
	argc -= optind;
	argv += optind;

	/* If we debug, include verbose messages also */
	if (d_flag)
		v_flag = 1;
	
	if(f_char){
		scep_conf_init(f_char);
	}else{
		scep_conf = NULL;    //moved init to here otherwise compile error on windows
	}
	/* Read in the configuration file: */
	/*if (f_char) {
	#ifdef WIN32
		if ((fopen_s(&fp, f_char, "r")))
	#else
		if (!(fp = fopen(f_char, "r")))
	#endif
			fprintf(stderr, "%s: cannot open %s\n", pname, f_char);
		else {
			init_config(fp);
			(void)fclose(fp);
		}
	}*/
	if (v_flag)
		fprintf(stdout, "%s: starting sscep, version %s\n",
			pname, VERSION);

	/*
	* Create a new SCEP transaction and self-signed
	* certificate based on cert request
	*/
	if (v_flag)
		fprintf(stdout, "%s: new transaction\n", pname);
	new_transaction(&scep_t);

	/*enable Engine Support */
	if (g_flag) {
		scep_t.e = scep_engine_init(scep_t.e);
	}
	
	/*
	 * Check argument logic.
	 */
	if (!c_flag) {
		if (operation_flag == SCEP_OPERATION_GETCA) {
			fprintf(stderr,
			  "%s: missing CA certificate filename (-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		} else {
			fprintf(stderr,
				"%s: missing CA certificate (-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (operation_flag == SCEP_OPERATION_GETNEXTCA) {
			fprintf(stderr,
			  "%s: missing nextCA certificate target filename (-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		} else {
			fprintf(stderr,
				"%s: missing nextCA certificate target filename(-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}
	if (!C_flag) {
		if (operation_flag == SCEP_OPERATION_GETNEXTCA) {
			fprintf(stderr,
			  "%s: missing nextCA certificate chain filename (-C)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}
	if (operation_flag == SCEP_OPERATION_ENROLL) {
		if (!k_flag) {
			fprintf(stderr, "%s: missing private key (-k)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!r_flag) {
			fprintf(stderr, "%s: missing request (-r)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);

		}
		if (!l_flag) {
			fprintf(stderr, "%s: missing local cert (-l)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		/* Set polling limits */
		if (!n_flag)
			n_num = MAX_POLL_COUNT;
		if (!t_flag)
			t_num = POLL_TIME;
		if (!T_flag)
			T_num = MAX_POLL_TIME;
	}
	if (operation_flag == SCEP_OPERATION_GETCERT) {
		if (!l_flag) {
			fprintf(stderr, "%s: missing local cert (-l)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!s_flag) {
			fprintf(stderr, "%s: missing serial no (-s)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!w_flag) {
			fprintf(stderr, "%s: missing cert file (-w)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!k_flag) {
			fprintf(stderr, "%s: missing private key (-k)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}
	if (operation_flag == SCEP_OPERATION_GETCRL) {
		if (!l_flag) {
			fprintf(stderr, "%s: missing local cert (-l)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!w_flag) {
			fprintf(stderr, "%s: missing crl file (-w)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!k_flag) {
			fprintf(stderr, "%s: missing private key (-k)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}

	/* Break down the URL */
	if (!u_flag) {
		fprintf(stderr, "%s: missing URL (-u)\n", pname);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (strncmp(url_char, "http://", 7) && !p_flag) {
		fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (p_flag) {
		#ifdef WIN32
		host_name = _strdup(p_char);
		#else
		host_name = strdup(p_char);
		#endif
		dir_name = url_char;
	}

	/* Break down the URL */
	if (!u_flag) {
		fprintf(stderr, "%s: missing URL (-u)\n", pname);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (strncmp(url_char, "http://", 7) && !p_flag) {
		fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (p_flag) {
		#ifdef WIN32
		host_name = _strdup(p_char);
		#else
		host_name = strdup(p_char);
		#endif
		dir_name = url_char;
	}
	#ifdef WIN32
	else if (!(host_name = _strdup(url_char + 7)))
	#else
	else if (!(host_name = strdup(url_char + 7)))
	#endif
		error_memory();
	p = host_name;
	c = 0;
	while (*p != '\0') {
		if (*p == '/' && !p_flag && !c) {
			*p = '\0';
			if (*(p+1)) dir_name = p + 1;
			c = 1;
		}
		if (*p == ':') {
			*p = '\0';
			if (*(p+1)) host_port = atoi(p+1);
		}
		p++;
	}
	if (!dir_name) {
		fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (host_port < 1 || host_port > 65550) {
		fprintf(stderr, "%s: illegal port number %d\n", pname,
				host_port);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (v_flag) {
		fprintf(stdout, "%s: hostname: %s\n", pname, host_name);
		fprintf(stdout, "%s: directory: %s\n", pname, dir_name);
		fprintf(stdout, "%s: port: %d\n", pname, host_port);
	}

	/* Check algorithms */
	if (!E_flag) {
		enc_alg = (EVP_CIPHER *)EVP_des_cbc();
	} else if (!strncmp(E_char, "blowfish", 8)) {
		enc_alg = (EVP_CIPHER *)EVP_bf_cbc();
	} else if (!strncmp(E_char, "des", 3)) {
		enc_alg = (EVP_CIPHER *)EVP_des_cbc();
	} else if (!strncmp(E_char, "3des", 4)) {
		enc_alg = (EVP_CIPHER *)EVP_des_ede3_cbc();
	} else if (!strncmp(E_char, "aes", 3)) {
		enc_alg = (EVP_CIPHER *)EVP_aes_256_cbc();
	} else {
		fprintf(stderr, "%s: unsupported algorithm: %s\n",
			pname, E_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (!S_flag) {
		sig_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(S_char, "md5", 3)) {
		sig_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(S_char, "sha1", 4)) {
		sig_alg = (EVP_MD *)EVP_sha1();
	} else {
		fprintf(stderr, "%s: unsupported algorithm: %s\n",
			pname, S_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	/* Fingerprint algorithm */
	if (!F_flag) {
		fp_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(F_char, "md5", 3)) {
		fp_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(F_char, "sha1", 4)) {
		fp_alg = (EVP_MD *)EVP_sha1();
	} else {
		fprintf(stderr, "%s: unsupported algorithm: %s\n",
			pname, F_char);
		exit (SCEP_PKISTATUS_ERROR);
	}

	/*
	 * Switch to operation specific code
	 */
	switch(operation_flag) {
		case SCEP_OPERATION_GETCA:
			if (v_flag)
				fprintf(stdout, "%s: SCEP_OPERATION_GETCA\n",
					pname);

			/* Set CA identifier */
			if (!i_flag)
				i_char = CA_IDENTIFIER;

			/* Forge the HTTP message */

			if(!M_flag){
				snprintf(http_string, sizeof(http_string),
				 "GET %s%s?operation=GetCACert&message=%s "
				 "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
						i_char);

			}else{
				snprintf(http_string, sizeof(http_string),
					"GET %s%s?operation=GetCACert&message=%s&%s "
					"HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
						i_char, M_char);

			}



			if (d_flag){
				printf("%s: requesting CA certificate\n", pname);
				fprintf(stdout, "%s: scep msg: %s", pname,
									http_string);
			}

			/*
			 * Send http message.
			 * Response is written to http_response struct "reply".
			 */
			reply.payload = NULL;
			if ((c = send_msg (&reply, http_string, host_name,
					host_port, operation_flag)) == 1) {
				fprintf(stderr, "%s: error while sending "
					"message\n", pname);
				exit (SCEP_PKISTATUS_NET);
			}
			if (reply.payload == NULL) {
				fprintf(stderr, "%s: no data, perhaps you "
				   "should define CA identifier (-i)\n", pname);
				exit (SCEP_PKISTATUS_SUCCESS);
			}
			if (v_flag){
				printf("%s: valid response from server\n", pname);
			}
			if (reply.type == SCEP_MIME_GETCA_RA) {
				/* XXXXXXXXXXXXXXXXXXXXX chain not verified */
				write_ca_ra(&reply);
			}
			/* Read payload as DER X.509 object: */
			bp = BIO_new_mem_buf(reply.payload, reply.bytes);
			cacert = d2i_X509_bio(bp, NULL);

			/* Read and print certificate information */
			if (!X509_digest(cacert, fp_alg, md, &n)) {
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			if (v_flag){
				printf("%s: %s fingerprint: ", pname,
					OBJ_nid2sn(EVP_MD_type(fp_alg)));
				for (c = 0; c < (int)n; c++) {
					printf("%02X%c",md[c],
						(c + 1 == (int)n) ?'\n':':');
				}

			}

			/* Write PEM-formatted file: */
			#ifdef WIN32
			if ((fopen_s(&fp,c_char , "w")))
			#else
			if (!(fp = fopen(c_char, "w")))
			#endif
			{
				fprintf(stderr, "%s: cannot open CA file for "
					"writing\n", pname);
				exit (SCEP_PKISTATUS_ERROR);
			}
			if (PEM_write_X509(fp, c_char) != 1) {
				fprintf(stderr, "%s: error while writing CA "
					"file\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			if (v_flag)
			printf("%s: CA certificate written as %s\n",
				pname, c_char);
			(void)fclose(fp);
			pkistatus = SCEP_PKISTATUS_SUCCESS;
			break;

		case SCEP_OPERATION_GETNEXTCA:
				if (v_flag)
					fprintf(stdout, "%s: SCEP_OPERATION_GETNEXTCA\n",
						pname);

				/* Set CA identifier */
				if (!i_flag)
					i_char = CA_IDENTIFIER;

				/* Forge the HTTP message */
				if(!M_flag){
					snprintf(http_string, sizeof(http_string),
					 "GET %s%s?operation=GetNextCACert&message=%s "
					 "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
							i_char);

				}else{
					snprintf(http_string, sizeof(http_string),
						"GET %s%s?operation=GetNextCACert&message=%s&%s "
						"HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
							i_char, M_char);

				}


				if (d_flag){
					printf("%s: requesting nextCA certificate\n", pname);
					fprintf(stdout, "%s: scep msg: %s", pname,
						http_string);
				}

				/*
				 * Send http message.
				 * Response is written to http_response struct "reply".
				 */
				reply.payload = NULL;
				if ((c = send_msg (&reply, http_string, host_name,
						host_port, operation_flag)) == 1) {
					if(v_flag){
					fprintf(stderr, "%s: error while sending "
						"message\n", pname);
					fprintf(stderr, "%s: getnextCA might be not available"
											"\n", pname);
					}
					exit (SCEP_PKISTATUS_NET);
				}
				if (reply.payload == NULL) {
					fprintf(stderr, "%s: no data, perhaps you "
					   "there is no nextCA available\n", pname);
					exit (SCEP_PKISTATUS_SUCCESS);
				}

				if(d_flag)
				printf("%s: valid response from server\n", pname);

				if (reply.type == SCEP_MIME_GETNEXTCA) {
					/* XXXXXXXXXXXXXXXXXXXXX chain not verified */

					//write_ca_ra(&reply);

					/* Set the whole struct as 0 */
					memset(&scep_t, 0, sizeof(scep_t));

					scep_t.reply_payload = reply.payload;
					scep_t.reply_len = reply.bytes;
					scep_t.request_type = SCEP_MIME_GETNEXTCA;

					pkcs7_verify_unwrap(&scep_t , C_char);

					//pkcs7_unwrap(&scep_t);
				}


				/* Get certs */
				p7 = *(scep_t.reply_p7);
				nextcara = scep_t.reply_p7->d.sign->cert;

			    if (v_flag) {
					printf ("verify and unwrap: found %d cert(s)\n", sk_X509_num(nextcara));
			        }

			    for (i = 0; i < sk_X509_num(nextcara); i++) {
			    		char buffer[1024];
			    		char name[1024];
			    		memset(buffer, 0, 1024);
			    		memset(name, 0, 1024);

			    		cert = sk_X509_value(nextcara, i);
			    		if (v_flag) {
			    			printf("%s: found certificate with\n"
			    				"  subject: '%s'\n", pname,
			    				X509_NAME_oneline(X509_get_subject_name(cert),
			    					buffer, sizeof(buffer)));
			    			printf("  issuer: %s\n",
			    				X509_NAME_oneline(X509_get_issuer_name(cert),
			    					buffer, sizeof(buffer)));
			    		}

			    		/* Create name */
			    		snprintf(name, 1024, "%s-%d", c_char, i);


			    		/* Write PEM-formatted file: */
			    		if (!(fp = fopen(name, "w"))) {
			    			fprintf(stderr, "%s: cannot open cert file for writing\n",
			    					pname);
			    			exit (SCEP_PKISTATUS_FILE);
			    		}
			    		if (v_flag)
			    			printf("%s: writing cert\n", pname);
			    		if (d_flag)
			    			PEM_write_X509(stdout, cert);
			    		if (PEM_write_X509(fp, cert) != 1) {
			    			fprintf(stderr, "%s: error while writing certificate "
			    				"file\n", pname);
			    			ERR_print_errors_fp(stderr);
			    			exit (SCEP_PKISTATUS_FILE);
			    		}
			    		if(v_flag)
			    		printf("%s: certificate written as %s\n", pname, name);
			    		(void)fclose(fp);
			    }



				pkistatus = SCEP_PKISTATUS_SUCCESS;
				break;

		case SCEP_OPERATION_GETCERT:
		case SCEP_OPERATION_GETCRL:
			/* Read local certificate */
			if (!l_flag) {
			  fprintf(stderr, "%s: missing local cert (-l)\n", pname);
			  exit (SCEP_PKISTATUS_FILE);
			}
			read_cert(&localcert, l_char);

		case SCEP_OPERATION_ENROLL:
			/*
			 * Read in CA cert, private key and certificate
			 * request in global variables.
			 */

		        read_ca_cert();

			if (!k_flag) {
			  fprintf(stderr, "%s: missing private key (-k)\n", pname);
			  exit (SCEP_PKISTATUS_FILE);
			}
			
			if(scep_conf != NULL) {
				sscep_engine_read_key_new(&rsa, k_char, scep_t.e);
			} else {
				read_key(&rsa, k_char);
			}


			if ((K_flag && !O_flag) || (!K_flag && O_flag)) {
			  fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname);
			  exit (SCEP_PKISTATUS_FILE);
			}

			if (K_flag) {
				//TODO auf hwcrhk prfen?
				if(scep_conf != NULL) {
					sscep_engine_read_key_old(&renewal_key, K_char, scep_t.e);
				} else {
					read_key(&renewal_key, K_char);
				}
			}

			if (O_flag) {
				read_cert(&renewal_cert, O_char);
			}

			if (operation_flag == SCEP_OPERATION_ENROLL) {
				read_request();
				scep_t.transaction_id = key_fingerprint(request);			
				if (v_flag) {
					printf("%s:  Read request with transaction id: %s\n", pname, scep_t.transaction_id);
				}
			}

			
			if (operation_flag != SCEP_OPERATION_ENROLL)
				goto not_enroll;
			
			if (! O_flag) {
				if (v_flag)
					fprintf(stdout, "%s: generating selfsigned "
					"certificate\n", pname);
			  new_selfsigned(&scep_t);
			}
			else {
			  /* Use existing certificate */
			  scep_t.signercert = renewal_cert;
			  scep_t.signerkey = renewal_key;
			}

			/* Write the selfsigned certificate if requested */
			if (L_flag) {
				/* Write PEM-formatted file: */
				#ifdef WIN32
				if ((fopen_s(&fp, L_char, "w"))) {
				#else
				if (!(fp = fopen(L_char, "w"))) {
				#endif
					fprintf(stderr, "%s: cannot open "
					  "file for writing\n", pname);
					exit (SCEP_PKISTATUS_ERROR);
				}
				if (PEM_write_X509(fp,scep_t.signercert) != 1) {
					fprintf(stderr, "%s: error while "
					  "writing certificate file\n", pname);
					ERR_print_errors_fp(stderr);
					exit (SCEP_PKISTATUS_ERROR);
				}
				printf("%s: selfsigned certificate written "
					"as %s\n", pname, L_char);
				(void)fclose(fp);
			}
			/* Write issuer name and subject (GetCertInitial): */
			if (!(scep_t.ias_getcertinit->subject =
					X509_REQ_get_subject_name(request))) {
				fprintf(stderr, "%s: error getting subject "
					"for GetCertInitial\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
not_enroll:
			if (!(scep_t.ias_getcertinit->issuer =
					 X509_get_issuer_name(cacert))) {
				fprintf(stderr, "%s: error getting issuer "
					"for GetCertInitial\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			/* Write issuer name and serial (GETC{ert,rl}): */
			scep_t.ias_getcert->issuer =
				 scep_t.ias_getcertinit->issuer;
			scep_t.ias_getcrl->issuer =
				 scep_t.ias_getcertinit->issuer;
			if (!(scep_t.ias_getcrl->serial =
					X509_get_serialNumber(cacert))) {
				fprintf(stderr, "%s: error getting serial "
					"for GetCertInitial\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			/* User supplied serial number */
			if (s_flag) {
				BIGNUM *bn;
				ASN1_INTEGER *ai;
				int len = BN_dec2bn(&bn , s_char);
				if (!len || !(ai = BN_to_ASN1_INTEGER(bn, NULL))) {
					fprintf(stderr, "%s: error converting serial\n", pname);
					ERR_print_errors_fp(stderr);
					exit (SCEP_PKISTATUS_SS);
				 }
				 scep_t.ias_getcert->serial = ai;
			}
		break;
	}

	switch(operation_flag) {
		case SCEP_OPERATION_ENROLL:
			if (v_flag)
				fprintf(stdout,
					"%s: SCEP_OPERATION_ENROLL\n", pname);
			/* Resum mode: set GetCertInitial */
			if (R_flag) {
				if (n_num == 0)
					exit (SCEP_PKISTATUS_SUCCESS);
				printf("%s: requesting certificate (#1)\n",
					pname);
				scep_t.request_type = SCEP_REQUEST_GETCERTINIT;
				count++;
			} else {
				printf("%s: sending certificate request\n",
					pname);
				scep_t.request_type = SCEP_REQUEST_PKCSREQ;
			}
			break;

		case SCEP_OPERATION_GETCERT:
			if (v_flag)
				fprintf(stdout,
					"%s: SCEP_OPERATION_GETCERT\n", pname);

			scep_t.request_type = SCEP_REQUEST_GETCERT;
			printf("%s: requesting certificate\n",pname);
			break;

		case SCEP_OPERATION_GETCRL:
			if (v_flag)
				fprintf(stdout,
					"%s: SCEP_OPERATION_GETCRL\n", pname);

			scep_t.request_type = SCEP_REQUEST_GETCRL;
			printf("%s: requesting crl\n",pname);
			break;
		}

		/* Enter polling loop */
		while (scep_t.pki_status != SCEP_PKISTATUS_SUCCESS) {
			/* create payload */
			pkcs7_wrap(&scep_t);

			/* URL-encode */
			p = url_encode((char *)scep_t.request_payload,
				scep_t.request_len);

			/*Test mode print SCEP request and don't send it*/
			if(m_flag){

				/* Write output file : */
#ifdef WIN32
				if ((fopen_s(&fp, m_char, "w")))
#else
				if (!(fp = fopen(m_char, "w")))
#endif
				{
					fprintf(stderr, "%s: cannot open output file for "
						"writing\n", m_char);
				}else
				{
					printf("%s: writing PEM fomatted PKCS#7\n", pname);
							PEM_write_PKCS7(fp, scep_t.request_p7);
				}

				//printf("Print SCEP Request:\n %s\n",scep_t.request_payload);
				return 0;
			}

			/* Forge the HTTP message */
		/*	snprintf(http_string, sizeof(http_string),
				"GET %s%s?operation="
				"PKIOperation&message="
				"%s HTTP/1.0\r\n\r\n",
				p_flag ? "" : "/", dir_name, p);*/

			if(!M_flag){
				snprintf(http_string, sizeof(http_string),
				 "GET %s%s?operation=PKIOperation&message=%s "
				 "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p);

			}else{
				snprintf(http_string, sizeof(http_string),
					"GET %s%s?operation=PKIOperation&message=%s&%s "
					"HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,p, M_char);

			}

			if (d_flag)
				fprintf(stdout, "%s: scep msg: %s",
					pname, http_string);

			/* send http */
			reply.payload = NULL;
			if ((c = send_msg (&reply, http_string, host_name,
					host_port, operation_flag)) == 1) {
				fprintf(stderr, "%s: error while sending "
					"message\n", pname);
				exit (SCEP_PKISTATUS_NET);
			}
			/* Verisign Onsite returns strange reply...
			 * XXXXXXXXXXXXXXXXXXX */
			if ((reply.status == 200) && (reply.payload == NULL)) {
				/*
				scep_t.pki_status = SCEP_PKISTATUS_PENDING;
				break;
				*/
				exit (SCEP_PKISTATUS_ERROR);
			}
			printf("%s: valid response from server\n", pname);

			/* Check payload */
			scep_t.reply_len = reply.bytes;
			scep_t.reply_payload = (unsigned char *)reply.payload;
			pkcs7_unwrap(&scep_t);
			pkistatus = scep_t.pki_status;

			switch(scep_t.pki_status) {
				case SCEP_PKISTATUS_SUCCESS:
					break;
				case SCEP_PKISTATUS_PENDING:
					/* Check time limits */
					if (((t_num * count) >= T_num) ||
					    (count > n_num)) {
						exit (pkistatus);
					}
					scep_t.request_type =
						SCEP_REQUEST_GETCERTINIT;

					/* Wait for poll interval */
					if (v_flag)
					  printf("%s: waiting for %d secs\n",
						pname, t_num);
					sleep(t_num);
					printf("%s: requesting certificate "
						"(#%d)\n", pname, count);

					/* Add counter */
					count++;
					break;

				case SCEP_PKISTATUS_FAILURE:

					/* Handle failure */
					switch (scep_t.fail_info) {
						case SCEP_FAILINFO_BADALG:
						  exit (SCEP_PKISTATUS_BADALG);
						case SCEP_FAILINFO_BADMSGCHK:
						  exit (SCEP_PKISTATUS_BADMSGCHK);
						case SCEP_FAILINFO_BADREQ:
						  exit (SCEP_PKISTATUS_BADREQ);
						case SCEP_FAILINFO_BADTIME:
						  exit (SCEP_PKISTATUS_BADTIME);
						case SCEP_FAILINFO_BADCERTID:
						  exit (SCEP_PKISTATUS_BADCERTID);
						/* Shouldn't be there... */
						default:
						  exit (SCEP_PKISTATUS_ERROR);
					}
				default:
					fprintf(stderr, "%s: unknown "
						"pkiStatus\n", pname);
					exit (SCEP_PKISTATUS_ERROR);
			}
	}
	/* We got SUCCESS, analyze the reply */
	switch (scep_t.request_type) {

		/* Local certificate */
		case SCEP_REQUEST_PKCSREQ:
		case SCEP_REQUEST_GETCERTINIT:
			write_local_cert(&scep_t);
			break;

		/* Other end entity certificate */
		case SCEP_REQUEST_GETCERT:
			write_other_cert(&scep_t);
			break;

			break;
		/* CRL */
		case SCEP_REQUEST_GETCRL:
			write_crl(&scep_t);
			break;
	}
	//TODO
	//richtiger ort für disable??
//	if(e){
//		ENGINE_finish(*e);
//		ENGINE_free(*e);
//	    hwEngine = NULL;
//	    ENGINE_cleanup();
//	}
//




	return (pkistatus);
}

void
usage() {
	fprintf(stdout, "\nsscep version %s\n\n" , VERSION);
	fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n"
	"\nAvailable OPERATIONs are\n"
	"  getca             Get CA/RA certificate(s)\n"
	"  getnextca         Get next CA/RA certificate(s)\n"
	"  enroll            Enroll certificate\n"
	"  getcert           Query certificate\n"
	"  getcrl            Query CRL\n"
	"\nGeneral OPTIONS\n"
	"  -u <url>          SCEP server URL\n"
	"  -p <host:port>    Use proxy server at host:port\n"
	"  -M <string>		 Monitor Information String name=value&name=value ...\n"
	"  -g                Enable Engine support\n"
	"  -h				 Keyforme=ID. \n"//TODO
	"  -f <file>         Use configuration file\n"
	"  -c <file>         CA certificate file (write if OPERATION is getca or getnextca)\n"
	"  -E <name>         PKCS#7 encryption algorithm (des|3des|blowfish|aes)\n"
	"  -S <name>         PKCS#7 signature algorithm (md5|sha1)\n"
	"  -v                Verbose operation\n"
	"  -d                Debug (even more verbose operation)\n"
	"\nOPTIONS for OPERATION getca are\n"
	"  -i <string>       CA identifier string\n"
	"  -F <name>         Fingerprint algorithm\n"
	"\nOPTIONS for OPERATION getnextca are\n"
	"  -C <file>         Local certificate chain file for signature verification in PEM format \n"
	"  -F <name>         Fingerprint algorithm\n"
	"  -c <file>         CA certificate file (write if OPERATION is getca or getnextca)\n"
	"  -w <file>         Write signer certificate in file (optional) \n"
	"\nOPTIONS for OPERATION enroll are\n"
 	"  -k <file>         Private key file\n"
	"  -r <file>         Certificate request file\n"
 	"  -K <file>         Signature private key file, use with -O\n"
 	"  -O <file>         Signature certificate (used instead of self-signed)\n"
	"  -l <file>         Write enrolled certificate in file\n"
	"  -e <file>         Use different CA cert for encryption\n"
	"  -L <file>         Write selfsigned certificate in file\n"
	"  -t <secs>         Polling interval in seconds\n"
	"  -T <secs>         Max polling time in seconds\n"
	"  -n <count>        Max number of GetCertInitial requests\n"
 	"  -R                Resume interrupted enrollment\n"
	"\nOPTIONS for OPERATION getcert are\n"
 	"  -k <file>         Private key file\n"
	"  -l <file>         Local certificate file\n"
	"  -s <number>       Certificate serial number\n"
	"  -w <file>         Write certificate in file\n"
	"\nOPTIONS for OPERATION getcrl are\n"
 	"  -k <file>         Private key file\n"
	"  -l <file>         Local certificate file\n"
	"  -w <file>         Write CRL in file\n\n", pname);
	exit(0);
}
Esempio n. 4
0
IoObject *IoCertificate_serialNumber(IoCertificate *self, IoObject *locals, IoMessage *m)
{
	return IONUMBER(ASN1_INTEGER_get(X509_get_serialNumber(X509(self))));
}
Esempio n. 5
0
static PyObject *
_decode_certificate (X509 *certificate, int verbose) {

	PyObject *retval = NULL;
	BIO *biobuf = NULL;
	PyObject *peer;
	PyObject *peer_alt_names = NULL;
	PyObject *issuer;
	PyObject *version;
	PyObject *sn_obj;
	ASN1_INTEGER *serialNumber;
	char buf[2048];
	int len;
	ASN1_TIME *notBefore, *notAfter;
	PyObject *pnotBefore, *pnotAfter;

	retval = PyDict_New();
	if (retval == NULL)
		return NULL;

	peer = _create_tuple_for_X509_NAME(
		X509_get_subject_name(certificate));
	if (peer == NULL)
		goto fail0;
	if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) {
		Py_DECREF(peer);
		goto fail0;
	}
	Py_DECREF(peer);

	if (verbose) {
		issuer = _create_tuple_for_X509_NAME(
			X509_get_issuer_name(certificate));
		if (issuer == NULL)
			goto fail0;
		if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) {
			Py_DECREF(issuer);
			goto fail0;
		}
		Py_DECREF(issuer);

		version = PyLong_FromLong(X509_get_version(certificate) + 1);
		if (PyDict_SetItemString(retval, "version", version) < 0) {
			Py_DECREF(version);
			goto fail0;
		}
		Py_DECREF(version);
	}

	/* get a memory buffer */
	biobuf = BIO_new(BIO_s_mem());

	if (verbose) {

		(void) BIO_reset(biobuf);
		serialNumber = X509_get_serialNumber(certificate);
		/* should not exceed 20 octets, 160 bits, so buf is big enough */
		i2a_ASN1_INTEGER(biobuf, serialNumber);
		len = BIO_gets(biobuf, buf, sizeof(buf)-1);
		if (len < 0) {
			_setSSLError(NULL, 0, __FILE__, __LINE__);
			goto fail1;
		}
		sn_obj = PyUnicode_FromStringAndSize(buf, len);
		if (sn_obj == NULL)
			goto fail1;
		if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) {
			Py_DECREF(sn_obj);
			goto fail1;
		}
		Py_DECREF(sn_obj);

		(void) BIO_reset(biobuf);
		notBefore = X509_get_notBefore(certificate);
		ASN1_TIME_print(biobuf, notBefore);
		len = BIO_gets(biobuf, buf, sizeof(buf)-1);
		if (len < 0) {
			_setSSLError(NULL, 0, __FILE__, __LINE__);
			goto fail1;
		}
		pnotBefore = PyUnicode_FromStringAndSize(buf, len);
		if (pnotBefore == NULL)
			goto fail1;
		if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) {
			Py_DECREF(pnotBefore);
			goto fail1;
		}
		Py_DECREF(pnotBefore);
	}

	(void) BIO_reset(biobuf);
	notAfter = X509_get_notAfter(certificate);
	ASN1_TIME_print(biobuf, notAfter);
	len = BIO_gets(biobuf, buf, sizeof(buf)-1);
	if (len < 0) {
		_setSSLError(NULL, 0, __FILE__, __LINE__);
		goto fail1;
	}
	pnotAfter = PyUnicode_FromStringAndSize(buf, len);
	if (pnotAfter == NULL)
		goto fail1;
	if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) {
		Py_DECREF(pnotAfter);
		goto fail1;
	}
	Py_DECREF(pnotAfter);

	/* Now look for subjectAltName */

	peer_alt_names = _get_peer_alt_names(certificate);
	if (peer_alt_names == NULL)
		goto fail1;
	else if (peer_alt_names != Py_None) {
		if (PyDict_SetItemString(retval, "subjectAltName",
					 peer_alt_names) < 0) {
			Py_DECREF(peer_alt_names);
			goto fail1;
		}
		Py_DECREF(peer_alt_names);
	}

	BIO_free(biobuf);
	return retval;

  fail1:
	if (biobuf != NULL)
		BIO_free(biobuf);
  fail0:
	Py_XDECREF(retval);
	return NULL;
}
static void ssl_log_cert_error(const char *file, int line, int level,
                               apr_status_t rv, const server_rec *s,
                               const conn_rec *c, const request_rec *r,
                               apr_pool_t *p, X509 *cert, const char *format,
                               va_list ap)
{
    char buf[HUGE_STRING_LEN];
    int msglen, n;
    char *name;

    apr_vsnprintf(buf, sizeof buf, format, ap);

    msglen = strlen(buf);

    if (cert) {
        BIO *bio = BIO_new(BIO_s_mem());

        if (bio) {
            /*
             * Limit the maximum length of the subject and issuer DN strings
             * in the log message. 300 characters should always be sufficient
             * for holding both the timestamp, module name, pid etc. stuff
             * at the beginning of the line and the trailing information about
             * serial, notbefore and notafter.
             */
            int maxdnlen = (HUGE_STRING_LEN - msglen - 300) / 2;

            BIO_puts(bio, " [subject: ");
            name = SSL_X509_NAME_to_string(p, X509_get_subject_name(cert),
                                           maxdnlen);
            if (!strIsEmpty(name)) {
                BIO_puts(bio, name);
            } else {
                BIO_puts(bio, "-empty-");
            }

            BIO_puts(bio, " / issuer: ");
            name = SSL_X509_NAME_to_string(p, X509_get_issuer_name(cert),
                                           maxdnlen);
            if (!strIsEmpty(name)) {
                BIO_puts(bio, name);
            } else {
                BIO_puts(bio, "-empty-");
            }

            BIO_puts(bio, " / serial: ");
            if (i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)) == -1)
                BIO_puts(bio, "(ERROR)");

            BIO_puts(bio, " / notbefore: ");
            ASN1_TIME_print(bio, X509_get_notBefore(cert));

            BIO_puts(bio, " / notafter: ");
            ASN1_TIME_print(bio, X509_get_notAfter(cert));

            BIO_puts(bio, "]");

            n = BIO_read(bio, buf + msglen, sizeof buf - msglen - 1);
            if (n > 0)
               buf[msglen + n] = '\0';

            BIO_free(bio);
        }
    }
    else {
        apr_snprintf(buf + msglen, sizeof buf - msglen,
                     " [certificate: -not available-]");
    }

    if (r) {
        ap_log_rerror(file, line, APLOG_MODULE_INDEX, level, rv, r, "%s", buf);
    }
    else if (c) {
        ap_log_cerror(file, line, APLOG_MODULE_INDEX, level, rv, c, "%s", buf);
    }
    else if (s) {
        ap_log_error(file, line, APLOG_MODULE_INDEX, level, rv, s, "%s", buf);
    }

}
Esempio n. 7
0
/** Generate and sign an X509 certificate with the public key <b>rsa</b>,
 * signed by the private key <b>rsa_sign</b>.  The commonName of the
 * certificate will be <b>cname</b>; the commonName of the issuer will be
 * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
 * starting from now.  Return a certificate on success, NULL on
 * failure.
 */
static X509 *
tor_tls_create_certificate(crypto_pk_env_t *rsa,
                           crypto_pk_env_t *rsa_sign,
                           const char *cname,
                           const char *cname_sign,
                           unsigned int cert_lifetime)
{
  time_t start_time, end_time;
  EVP_PKEY *sign_pkey = NULL, *pkey=NULL;
  X509 *x509 = NULL;
  X509_NAME *name = NULL, *name_issuer=NULL;

  tor_tls_init();

  start_time = time(NULL);

  tor_assert(rsa);
  tor_assert(cname);
  tor_assert(rsa_sign);
  tor_assert(cname_sign);
  if (!(sign_pkey = _crypto_pk_env_get_evp_pkey(rsa_sign,1)))
    goto error;
  if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0)))
    goto error;
  if (!(x509 = X509_new()))
    goto error;
  if (!(X509_set_version(x509, 2)))
    goto error;
  if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)start_time)))
    goto error;

  if (!(name = tor_x509_name_new(cname)))
    goto error;
  if (!(X509_set_subject_name(x509, name)))
    goto error;
  if (!(name_issuer = tor_x509_name_new(cname_sign)))
    goto error;
  if (!(X509_set_issuer_name(x509, name_issuer)))
    goto error;

  if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time))
    goto error;
  end_time = start_time + cert_lifetime;
  if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time))
    goto error;
  if (!X509_set_pubkey(x509, pkey))
    goto error;
  if (!X509_sign(x509, sign_pkey, EVP_sha1()))
    goto error;

  goto done;
 error:
  if (x509) {
    X509_free(x509);
    x509 = NULL;
  }
 done:
  tls_log_errors(NULL, LOG_WARN, "generating certificate");
  if (sign_pkey)
    EVP_PKEY_free(sign_pkey);
  if (pkey)
    EVP_PKEY_free(pkey);
  if (name)
    X509_NAME_free(name);
  if (name_issuer)
    X509_NAME_free(name_issuer);
  return x509;
}
Esempio n. 8
0
/**
 * setup callback to allow the user to examine certificates which have
 * failed to validate during fetch.
 */
static void
curl_start_cert_validate(struct curl_fetch_info *f,
			 struct cert_info *certs)
{
	int depth;
	BIO *mem;
	BUF_MEM *buf;
	struct ssl_cert_info ssl_certs[MAX_CERTS];
	fetch_msg msg;

	for (depth = 0; depth <= f->cert_depth; depth++) {
		assert(certs[depth].cert != NULL);

		/* get certificate version */
		ssl_certs[depth].version = X509_get_version(certs[depth].cert);

		/* not before date */
		mem = BIO_new(BIO_s_mem());
		ASN1_TIME_print(mem, X509_get_notBefore(certs[depth].cert));
		BIO_get_mem_ptr(mem, &buf);
		(void) BIO_set_close(mem, BIO_NOCLOSE);
		BIO_free(mem);
		memcpy(ssl_certs[depth].not_before,
		       buf->data,
		       min(sizeof(ssl_certs[depth].not_before) - 1,
			   (unsigned)buf->length));
		ssl_certs[depth].not_before[min(sizeof(ssl_certs[depth].not_before) - 1,
					    (unsigned)buf->length)] = 0;
		BUF_MEM_free(buf);

		/* not after date */
		mem = BIO_new(BIO_s_mem());
		ASN1_TIME_print(mem,
				X509_get_notAfter(certs[depth].cert));
		BIO_get_mem_ptr(mem, &buf);
		(void) BIO_set_close(mem, BIO_NOCLOSE);
		BIO_free(mem);
		memcpy(ssl_certs[depth].not_after,
		       buf->data,
		       min(sizeof(ssl_certs[depth].not_after) - 1,
			   (unsigned)buf->length));
		ssl_certs[depth].not_after[min(sizeof(ssl_certs[depth].not_after) - 1,
					   (unsigned)buf->length)] = 0;
		BUF_MEM_free(buf);

		/* signature type */
		ssl_certs[depth].sig_type =
			X509_get_signature_type(certs[depth].cert);

		/* serial number */
		ssl_certs[depth].serial =
			ASN1_INTEGER_get(
				X509_get_serialNumber(certs[depth].cert));

		/* issuer name */
		mem = BIO_new(BIO_s_mem());
		X509_NAME_print_ex(mem,
				   X509_get_issuer_name(certs[depth].cert),
				   0, XN_FLAG_SEP_CPLUS_SPC |
				   XN_FLAG_DN_REV | XN_FLAG_FN_NONE);
		BIO_get_mem_ptr(mem, &buf);
		(void) BIO_set_close(mem, BIO_NOCLOSE);
		BIO_free(mem);
		memcpy(ssl_certs[depth].issuer,
		       buf->data,
		       min(sizeof(ssl_certs[depth].issuer) - 1,
			   (unsigned) buf->length));
		ssl_certs[depth].issuer[min(sizeof(ssl_certs[depth].issuer) - 1,
					(unsigned) buf->length)] = 0;
		BUF_MEM_free(buf);

		/* subject */
		mem = BIO_new(BIO_s_mem());
		X509_NAME_print_ex(mem,
				   X509_get_subject_name(certs[depth].cert),
				   0,
				   XN_FLAG_SEP_CPLUS_SPC |
				   XN_FLAG_DN_REV |
				   XN_FLAG_FN_NONE);
		BIO_get_mem_ptr(mem, &buf);
		(void) BIO_set_close(mem, BIO_NOCLOSE);
		BIO_free(mem);
		memcpy(ssl_certs[depth].subject,
		       buf->data,
		       min(sizeof(ssl_certs[depth].subject) - 1,
			   (unsigned)buf->length));
		ssl_certs[depth].subject[min(sizeof(ssl_certs[depth].subject) - 1,
					 (unsigned) buf->length)] = 0;
		BUF_MEM_free(buf);

		/* type of certificate */
		ssl_certs[depth].cert_type =
			X509_certificate_type(certs[depth].cert,
					      X509_get_pubkey(certs[depth].cert));

		/* and clean up */
		certs[depth].cert->references--;
		if (certs[depth].cert->references == 0) {
			X509_free(certs[depth].cert);
		}
	}

	msg.type = FETCH_CERT_ERR;
	msg.data.cert_err.certs = ssl_certs;
	msg.data.cert_err.num_certs = depth;
	fetch_send_callback(&msg, f->fetch_handle);
}
Esempio n. 9
0
/* Creates an X509 certificate from a certificate request. */
EXPORT int IssueUserCertificate(unsigned char *certbuf, int *certlen, unsigned char *reqbuf, int reqlen)
{
	X509_REQ *req = NULL;
	EVP_PKEY *cakey = NULL, *rakey = NULL, *usrkey = NULL;
	X509 *cacert = NULL, *racert = NULL, *usrcert = NULL;
	X509_NAME *subject = NULL, *issuer = NULL;
	unsigned char *p = NULL;
	int ret = OPENSSLCA_NO_ERR, len;

	if (certbuf == NULL || certlen == NULL || reqbuf == NULL || reqlen == 0)
		return OPENSSLCA_ERR_ARGS;

	/* Decode request */
	if ((req = X509_REQ_new()) == NULL) {
		ret = OPENSSLCA_ERR_REQ_NEW;
		goto err;
	}
	p = reqbuf;
	if (d2i_X509_REQ(&req, &p, reqlen) == NULL) {
		ret = OPENSSLCA_ERR_REQ_DECODE;
		goto err;
	}

	/* Get public key from request */
	if ((usrkey = X509_REQ_get_pubkey(req)) == NULL) {
		ret = OPENSSLCA_ERR_REQ_GET_PUBKEY;
		goto err;
	}

	if (caIni.verifyRequests) {
		/* Get RA's public key */
		/* TODO: Validate RA certificate */
		ret = read_cert(&racert, CA_PATH(caIni.raCertFile));
		if (ret != OPENSSLCA_NO_ERR)
			goto err;
		if ((rakey = X509_get_pubkey(racert)) == NULL) {
			ret = OPENSSLCA_ERR_CERT_GET_PUBKEY;
			goto err;
		}

		/* Verify signature on request */
		if (X509_REQ_verify(req, rakey) != 1) {
			ret = OPENSSLCA_ERR_REQ_VERIFY;
			goto err;
		}
	}

	/* Get CA certificate */
	/* TODO: Validate CA certificate */
	ret = read_cert(&cacert, CA_PATH(caIni.caCertFile));
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	/* Get CA private key */
	ret = read_key(&cakey, CA_PATH(caIni.caKeyFile), caIni.caKeyPasswd);
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	/* Create user certificate */
	if ((usrcert = X509_new()) == NULL)
		return OPENSSLCA_ERR_CERT_NEW;

	/* Set version and serial number for certificate */
	if (X509_set_version(usrcert, 2) != 1) { /* V3 */
		ret = OPENSSLCA_ERR_CERT_SET_VERSION;
		goto err;
	}
	if (ASN1_INTEGER_set(X509_get_serialNumber(usrcert), get_serial()) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_SERIAL;
		goto err;
	}

	/* Set duration for certificate */
	if (X509_gmtime_adj(X509_get_notBefore(usrcert), 0) == NULL) {
		ret = OPENSSLCA_ERR_CERT_SET_NOTBEFORE;
		goto err;
	}
	if (X509_gmtime_adj(X509_get_notAfter(usrcert), EXPIRE_SECS(caIni.daysTillExpire)) == NULL) {
		ret = OPENSSLCA_ERR_CERT_SET_NOTAFTER;
		goto err;
	}

	/* Set public key */
	if (X509_set_pubkey(usrcert, usrkey) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_PUBKEY;
		goto err;
	}

	/* Set subject name */
	subject = X509_REQ_get_subject_name(req);
	if (subject == NULL) {
		ret = OPENSSLCA_ERR_REQ_GET_SUBJECT;
		goto err;
	}
	if (X509_set_subject_name(usrcert, subject) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_SUBJECT;
		goto err;
	}

	/* Set issuer name */
	issuer = X509_get_issuer_name(cacert);
	if (issuer == NULL) {
		ret = OPENSSLCA_ERR_CERT_GET_ISSUER;
		goto err;
	}
	if (X509_set_issuer_name(usrcert, issuer) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_ISSUER;
		goto err;
	}

	/* Add extensions */
	ret = add_ext(cacert, usrcert);
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	/* Sign user certificate with CA's private key */
	if (!X509_sign(usrcert, cakey, EVP_sha1()))
		return OPENSSLCA_ERR_CERT_SIGN;

	if (caIni.verifyAfterSign) {
		if (X509_verify(usrcert, cakey) != 1) {
			ret = OPENSSLCA_ERR_CERT_VERIFY;
			goto err;
		}
	}

#ifdef _DEBUG /* Output certificate in DER and PEM format */
	{
		FILE *fp = fopen(DBG_PATH("usrcert.der"), "wb");
		if (fp != NULL) {
			i2d_X509_fp(fp, usrcert);
			fclose(fp);
		}
		fp = fopen(DBG_PATH("usrcert.pem"), "w");
		if (fp != NULL) {
			X509_print_fp(fp, usrcert);
			PEM_write_X509(fp, usrcert);
			fclose(fp);
		}
	}
#endif

	/* Encode user certificate into DER format */
	len = i2d_X509(usrcert, NULL);
	if (len < 0) {
		ret = OPENSSLCA_ERR_CERT_ENCODE;
		goto err;
	}
	if (len > *certlen) {
		ret = OPENSSLCA_ERR_BUF_TOO_SMALL;
		goto err;
	}
	*certlen = len;
	p = certbuf;
	i2d_X509(usrcert, &p);

	if (caIni.addToIndex)
		add_to_index(usrcert);

	if (caIni.addToNewCerts)
		write_cert(usrcert);

err:
	print_err("IssueUserCertificate()", ret);

	/* Clean up */
	if (cacert)
		X509_free(cacert);
	if (cakey)
		EVP_PKEY_free(cakey);
	if (racert)
		X509_free(racert);
	if (rakey)
		EVP_PKEY_free(rakey);
	if (req)
		X509_REQ_free(req);
	if (usrcert != NULL)
		X509_free(usrcert);
	if (usrkey)
		EVP_PKEY_free(usrkey);

	return ret;
}
Esempio n. 10
0
static int janus_dtls_generate_keys(X509** certificate, EVP_PKEY** private_key) {
	static const int num_bits = 2048;
	BIGNUM* bne = NULL;
	RSA* rsa_key = NULL;
	X509_NAME* cert_name = NULL;

	JANUS_LOG(LOG_VERB, "Generating DTLS key / cert\n");

	/* Create a big number object. */
	bne = BN_new();
	if (!bne) {
		JANUS_LOG(LOG_FATAL, "BN_new() failed\n");
		goto error;
	}

	if (!BN_set_word(bne, RSA_F4)) {  /* RSA_F4 == 65537 */
		JANUS_LOG(LOG_FATAL, "BN_set_word() failed\n");
		goto error;
	}

	/* Generate a RSA key. */
	rsa_key = RSA_new();
	if (!rsa_key) {
		JANUS_LOG(LOG_FATAL, "RSA_new() failed\n");
		goto error;
	}

	/* This takes some time. */
	if (!RSA_generate_key_ex(rsa_key, num_bits, bne, NULL)) {
		JANUS_LOG(LOG_FATAL, "RSA_generate_key_ex() failed\n");
		goto error;
	}

	/* Create a private key object (needed to hold the RSA key). */
	*private_key = EVP_PKEY_new();
	if (!*private_key) {
		JANUS_LOG(LOG_FATAL, "EVP_PKEY_new() failed\n");
		goto error;
	}

	if (!EVP_PKEY_assign_RSA(*private_key, rsa_key)) {
		JANUS_LOG(LOG_FATAL, "EVP_PKEY_assign_RSA() failed\n");
		goto error;
	}
	/* The RSA key now belongs to the private key, so don't clean it up separately. */
	rsa_key = NULL;

	/* Create the X509 certificate. */
	*certificate = X509_new();
	if (!*certificate) {
		JANUS_LOG(LOG_FATAL, "X509_new() failed\n");
		goto error;
	}

	/* Set version 3 (note that 0 means version 1). */
	X509_set_version(*certificate, 2);

	/* Set serial number. */
	ASN1_INTEGER_set(X509_get_serialNumber(*certificate), (long)g_random_int());

	/* Set valid period. */
	X509_gmtime_adj(X509_get_notBefore(*certificate), -1 * DTLS_AUTOCERT_DURATION);  /* -1 year */
	X509_gmtime_adj(X509_get_notAfter(*certificate), DTLS_AUTOCERT_DURATION);  /* 1 year */

	/* Set the public key for the certificate using the key. */
	if (!X509_set_pubkey(*certificate, *private_key)) {
		JANUS_LOG(LOG_FATAL, "X509_set_pubkey() failed\n");
		goto error;
	}

	/* Set certificate fields. */
	cert_name = X509_get_subject_name(*certificate);
	if (!cert_name) {
		JANUS_LOG(LOG_FATAL, "X509_get_subject_name() failed\n");
		goto error;
	}
	X509_NAME_add_entry_by_txt(cert_name, "O", MBSTRING_ASC, (const unsigned char*)"Janus", -1, -1, 0);
	X509_NAME_add_entry_by_txt(cert_name, "CN", MBSTRING_ASC, (const unsigned char*)"Janus", -1, -1, 0);

	/* It is self-signed so set the issuer name to be the same as the subject. */
	if (!X509_set_issuer_name(*certificate, cert_name)) {
		JANUS_LOG(LOG_FATAL, "X509_set_issuer_name() failed\n");
		goto error;
	}

	/* Sign the certificate with the private key. */
	if (!X509_sign(*certificate, *private_key, EVP_sha1())) {
		JANUS_LOG(LOG_FATAL, "X509_sign() failed\n");
		goto error;
	}

	/* Free stuff and resurn. */
	BN_free(bne);
	return 0;

error:
	if (bne)
		BN_free(bne);
	if (rsa_key && !*private_key)
		RSA_free(rsa_key);
	if (*private_key)
		EVP_PKEY_free(*private_key);  /* This also frees the RSA key. */
	if (*certificate)
		X509_free(*certificate);
	return -1;
}
Esempio n. 11
0
/**
*失効リストチェック関数
* @author University of Tsukuba
* @param *pInData 証明書データ 
* @param lInLen 証明書データ長
* @param *data CRLファイルデータ
* @param len CRLファイルデータレングス
* @return   long  0:未失効 1:失効中 -1:異常 
* @since 2008.02
* @version 1.0
*/
long IDMan_CmCheckCRL(void *pInData, long lInLen, void * data,unsigned long int len )
{
	long 			lRet=-1L;
	/*FILE 			*fp;*/
	X509 			*x509=0x00;
	X509_CRL 		*x509crl=0x00;
	X509_NAME 		*x509crlissuer = 0x00;
	int				iRet=0;
	int				idx;
	X509_REVOKED	rtmp;
	char			*p,*p2;
	char 			szErrBuff[1024];
	BIO 			* BIOptr;

	ERR_load_crypto_strings();

	IDMan_StMemset(szErrBuff, 0x00, sizeof(szErrBuff));

	/** 証明書データパラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if (pInData == 0x00) 
	{
		/** −処理を中断する。 */
		return lRet;
	}
	/** 証明書長データパラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if (lInLen == 0)
	{
		/** −処理を中断する。 */
		return lRet;
	}

	/** 失効データパラメータチェックを行う。 */
	/** 失効データが存在しない場合、 */
	if (data==0x00 || len == 0)
	{
		/** −正常終了する。 */
		lRet =0;
		return lRet;
	}

	
	/** X509構造体の初期化を行う。 */
	/** エラー発生した場合、 */
	if((x509 = X509_new())== 0x00) 
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		return lRet;
	}

	/** DERファイルから、X509構造体にデータを読み込む。 */
	/** BIO構造の作成を行う。 */
	BIOptr = BIO_new(BIO_s_mem());

	/** BIO構造のリセットを行う。 */
	iRet = BIO_reset(BIOptr);
	/** エラー発生した場合、 */
	if(iRet != 1)
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造へ公開鍵証明書データの設定を行う。 */
	iRet = BIO_write(BIOptr,pInData,lInLen);
	/** エラー発生した場合、 */
	if( iRet != lInLen )
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}

	/** X509構造体の作成を行う。 */
	x509 =(X509 *) d2i_X509_bio(BIOptr,0x00);
	/** エラー発生した場合、 */
	if((x509 == 0x00))
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造の解放を行う。 */
	BIO_free(BIOptr);

	/** issuerDNの取得を行う。 */
	X509_NAME *x509issuer = X509_get_issuer_name(x509);
	p = X509_NAME_oneline(x509issuer, 0, 0);	
	/** CRL情報の取得を行う。 */
	x509crl = X509_CRL_new();

	/** BIO構造の作成を行う。 */
	BIOptr = BIO_new(BIO_s_mem());

	/** BIO構造のリセットを行う。 */
	iRet = BIO_reset(BIOptr);
	/** エラー発生した場合、 */
	if(iRet != 1)
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造へ失効リストデータの設定を行う。 */
	iRet = BIO_write(BIOptr,data,len);
	/** エラー発生した場合、 */
	if( iRet != (int)len )
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		BIO_free(BIOptr);
		return lRet;
	}
	/** x509crl構造へ失効リストデータの設定を行う。 */
	x509crl = (X509_CRL *) d2i_X509_CRL_bio(BIOptr,0x00);
	/** エラー発生した場合、 */
	if(x509crl==0x00) 
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		if(x509crl !=0x00)	X509_CRL_free(x509crl);
		BIO_free(BIOptr);
		return lRet;
	}

	/** BIO構造の解放を行う。 */
	BIO_free(BIOptr);

	/** シリアル番号の取得を行う。 */
	rtmp.serialNumber = X509_get_serialNumber(x509);

	/** CRLのissuerDNの取得を行う。 */
	/** エラー発生した場合、 */
	x509crlissuer = X509_CRL_get_issuer(x509crl);
	if ( x509crlissuer == 0x00 )
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		if(x509crl !=0x00)	X509_CRL_free(x509crl);
		return lRet;
	}

	/** 証明書とCRLのissuerDNの比較を行う。 */
	p2 = X509_NAME_oneline(x509crlissuer, 0, 0);
	/** エラー発生した場合、 */
	if( strcmp(p, p2) != 0)
	{
		/** −処理を中断する。 */
		ERR_error_string(ERR_get_error(), szErrBuff);
		if(x509 !=0x00)	X509_free(x509);
		if(x509crl !=0x00)	X509_CRL_free(x509crl);
		return lRet;
	}

	/** CRLのシリアル番号をソートする。 */
	if (!sk_is_sorted(x509crl->crl->revoked)) 
	{
		sk_sort(x509crl->crl->revoked);
	}
	/** CRLのシリアル番号を検索する。 */
	idx = sk_X509_REVOKED_find(x509crl->crl->revoked, &rtmp);
	/** 該当シリアル番号が存在する場合、 */
	if (idx >= 0) 
	{
		/** −戻り値に1を設定する。 */
		lRet =1;
	}
	/** 該当シリアル番号が存在しない場合、 */
	else
	{
		/** −戻り値に0を設定する。 */
		lRet =0;
	}

	/** X509の開放を行う。 */
	if(x509 !=0x00)	X509_free(x509);

	/** X509CRLの開放を行う。 */
	if(x509crl !=0x00)	X509_CRL_free(x509crl);

	return lRet;
}
Esempio n. 12
0
extern "C" ASN1_INTEGER* X509GetSerialNumber(X509* x509)
{
    return X509_get_serialNumber(x509);
}
Esempio n. 13
0
CFMutableDictionaryRef SDMMD__CreatePairingMaterial(CFDataRef devicePubkey)
{
	CFMutableDictionaryRef record = NULL;
	RSA *rsaBIOData = NULL;
	BIO *deviceBIO = SDMMD__create_bio_from_data(devicePubkey);
	if (deviceBIO) {
		PEM_read_bio_RSAPublicKey(deviceBIO, &rsaBIOData, NULL, NULL);
		BIO_free(deviceBIO);
	}
	else {
		printf("Could not decode device public key\\n");
	}

	RSA *rootKeyPair = RSA_generate_key(2048, 65537, NULL, NULL);
	if (!rootKeyPair) {
		printf("Could not allocate root key pair\n");
	}

	RSA *hostKeyPair = RSA_generate_key(2048, 65537, NULL, NULL);
	if (!hostKeyPair) {
		printf("Could not allocate host key pair\n");
	}

	sdmmd_return_t result = kAMDSuccess;

	EVP_PKEY *rootEVP = EVP_PKEY_new();
	if (!rootEVP) {
		printf("Could not allocate root EVP key\\n");
	}
	else {
		result = EVP_PKEY_assign(rootEVP, EVP_CTRL_RAND_KEY, PtrCast(rootKeyPair, char *));
		if (!result) {
			printf("Could not assign root key pair\n");
		}
	}

	EVP_PKEY *hostEVP = EVP_PKEY_new();
	if (!hostEVP) {
		printf("Could not allocate host EVP key\\n");
	}
	else {
		result = EVP_PKEY_assign(hostEVP, EVP_CTRL_RAND_KEY, PtrCast(hostKeyPair, char *));
		if (!result) {
			printf("Could not assign host key pair\n");
		}
	}

	EVP_PKEY *deviceEVP = EVP_PKEY_new();
	if (!deviceEVP) {
		printf("Could not allocate device EVP key\\n");
	}
	else {
		result = EVP_PKEY_assign(deviceEVP, EVP_CTRL_RAND_KEY, PtrCast(rsaBIOData, char *));
		if (!result) {
			printf("Could not assign device key pair\n");
		}
	}

	X509 *rootX509 = X509_new();
	if (!rootX509) {
		printf("Could not create root X509\\n");
	}
	else {
		X509_set_pubkey(rootX509, rootEVP);
		X509_set_version(rootX509, 2);

		ASN1_INTEGER *rootSerial = X509_get_serialNumber(rootX509);
		ASN1_INTEGER_set(rootSerial, 0);

		ASN1_TIME *rootAsn1time = ASN1_TIME_new();
		ASN1_TIME_set(rootAsn1time, 0);
		X509_set_notBefore(rootX509, rootAsn1time);
		ASN1_TIME_set(rootAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years
		X509_set_notAfter(rootX509, rootAsn1time);
		ASN1_TIME_free(rootAsn1time);

		SDMMD__add_ext(rootX509, NID_basic_constraints, "critical,CA:TRUE");
		SDMMD__add_ext(rootX509, NID_subject_key_identifier, "hash");

		result = X509_sign(rootX509, rootEVP, EVP_sha1());
		if (!result) {
			printf("Could not sign root cert\\n");
		}
	}

	X509 *hostX509 = X509_new();
	if (!hostX509) {
		printf("Could not create host X509\\n");
	}
	else {
		X509_set_pubkey(hostX509, hostEVP);
		X509_set_version(hostX509, 2);

		ASN1_INTEGER *hostSerial = X509_get_serialNumber(hostX509);
		ASN1_INTEGER_set(hostSerial, 0);

		ASN1_TIME *hostAsn1time = ASN1_TIME_new();
		ASN1_TIME_set(hostAsn1time, 0);
		X509_set_notBefore(hostX509, hostAsn1time);
		ASN1_TIME_set(hostAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years
		X509_set_notAfter(hostX509, hostAsn1time);
		ASN1_TIME_free(hostAsn1time);

		SDMMD__add_ext(hostX509, NID_basic_constraints, "critical,CA:FALSE");
		SDMMD__add_ext(hostX509, NID_subject_key_identifier, "hash");
		SDMMD__add_ext(hostX509, NID_key_usage, "critical,digitalSignature,keyEncipherment");

		result = X509_sign(hostX509, rootEVP, EVP_sha1());
		if (!result) {
			printf("Could not sign host cert\\n");
		}
	}

	X509 *deviceX509 = X509_new();
	if (!deviceX509) {
		printf("Could not create device X509\\n");
	}
	else {
		X509_set_pubkey(deviceX509, deviceEVP);
		X509_set_version(deviceX509, 2);

		ASN1_INTEGER *deviceSerial = X509_get_serialNumber(deviceX509);
		ASN1_INTEGER_set(deviceSerial, 0);

		ASN1_TIME *deviceAsn1time = ASN1_TIME_new();
		ASN1_TIME_set(deviceAsn1time, 0);
		X509_set_notBefore(deviceX509, deviceAsn1time);
		ASN1_TIME_set(deviceAsn1time, 0x12cc0300); // 60 sec * 60 minutes * 24 hours * 365 days * 10 years
		X509_set_notAfter(deviceX509, deviceAsn1time);
		ASN1_TIME_free(deviceAsn1time);

		SDMMD__add_ext(deviceX509, NID_basic_constraints, "critical,CA:FALSE");
		SDMMD__add_ext(deviceX509, NID_subject_key_identifier, "hash");
		SDMMD__add_ext(deviceX509, NID_key_usage, "critical,digitalSignature,keyEncipherment");

		result = X509_sign(deviceX509, rootEVP, EVP_sha1());
		if (!result) {
			printf("Could not sign device cert\\n");
		}
	}

	CFDataRef rootCert = SDMMD_CreateDataFromX509Certificate(rootX509);
	CFDataRef hostCert = SDMMD_CreateDataFromX509Certificate(hostX509);
	CFDataRef deviceCert = SDMMD_CreateDataFromX509Certificate(deviceX509);
	CFDataRef rootPrivKey = SDMMD_CreateDataFromPrivateKey(rootEVP);
	CFDataRef hostPrivKey = SDMMD_CreateDataFromPrivateKey(hostEVP);
	CFStringRef hostId = SDMMD_CreateUUID();

	record = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	if (record) {
		CFDictionarySetValue(record, CFSTR("RootCertificate"), rootCert);

		CFDictionarySetValue(record, CFSTR("HostCertificate"), hostCert);

		CFDictionarySetValue(record, CFSTR("DeviceCertificate"), deviceCert);

		CFDictionarySetValue(record, CFSTR("RootPrivateKey"), rootPrivKey);

		CFDictionarySetValue(record, CFSTR("HostPrivateKey"), hostPrivKey);

		CFDictionarySetValue(record, CFSTR("HostID"), hostId);
	}
	CFSafeRelease(rootCert);
	CFSafeRelease(hostCert);
	CFSafeRelease(deviceCert);
	CFSafeRelease(rootPrivKey);
	CFSafeRelease(hostPrivKey);
	CFSafeRelease(hostId);

	Safe(EVP_PKEY_free, rootEVP);
	Safe(EVP_PKEY_free, hostEVP);
	Safe(EVP_PKEY_free, deviceEVP);
	Safe(X509_free, rootX509);
	Safe(X509_free, hostX509);
	Safe(X509_free, deviceX509);

	return record;
}
Esempio n. 14
0
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
                          const EVP_MD *dgst)
{
    int nid;
    char is_dsa;

    if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
        is_dsa = 1;
    else
        is_dsa = 0;
    /* We now need to add another PKCS7_SIGNER_INFO entry */
    if (!ASN1_INTEGER_set(p7i->version, 1))
        goto err;
    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
                       X509_get_issuer_name(x509)))
        goto err;

    /*
     * because ASN1_INTEGER_set is used to set a 'long' we will do things the
     * ugly way.
     */
    M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
    if (!(p7i->issuer_and_serial->serial =
          M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
        goto err;

    /* lets keep the pkey around for a while */
    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
    p7i->pkey = pkey;

    /* Set the algorithms */
    if (is_dsa)
        p7i->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
    else
        p7i->digest_alg->algorithm = OBJ_nid2obj(EVP_MD_type(dgst));

    if (p7i->digest_alg->parameter != NULL)
        ASN1_TYPE_free(p7i->digest_alg->parameter);
    if ((p7i->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    p7i->digest_alg->parameter->type = V_ASN1_NULL;

    if (p7i->digest_enc_alg->parameter != NULL)
        ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
    nid = EVP_PKEY_type(pkey->type);
    if (nid == EVP_PKEY_RSA) {
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
        if (!(p7i->digest_enc_alg->parameter = ASN1_TYPE_new()))
            goto err;
        p7i->digest_enc_alg->parameter->type = V_ASN1_NULL;
    } else if (nid == EVP_PKEY_DSA) {
#if 1
        /*
         * use 'dsaEncryption' OID for compatibility with other software
         * (PKCS #7 v1.5 does specify how to handle DSA) ...
         */
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_dsa);
#else
        /*
         * ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for
         * CMS) would make more sense.
         */
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_dsaWithSHA1);
#endif
        p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit
                                                * 'parameter'! */
    } else if (nid == EVP_PKEY_EC) {
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA1);
        if (!(p7i->digest_enc_alg->parameter = ASN1_TYPE_new()))
            goto err;
        p7i->digest_enc_alg->parameter->type = V_ASN1_NULL;
    } else
        return (0);

    return (1);
 err:
    return (0);
}
Esempio n. 15
0
int x509_main(int argc, char **argv)
{
    ASN1_INTEGER *sno = NULL;
    ASN1_OBJECT *objtmp = NULL;
    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 enddate = 0;
    time_t checkoffset = 0;
    unsigned long nmflag = 0, certflag = 0;
    char nmflag_set = 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_ANY, &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;
        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);
            objtmp = NULL;
            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);
            objtmp = NULL;
            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:
            nmflag_set = 1;
            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;
#else
        case OPT_SUBJECT_HASH_OLD:
        case OPT_ISSUER_HASH_OLD:
            break;
#endif
        case OPT_DATES:
            startdate = ++num;
            enddate = ++num;
            break;
        case OPT_CHECKEND:
            checkend = 1;
            {
                intmax_t temp = 0;
                if (!opt_imax(opt_arg(), &temp))
                    goto opthelp;
                checkoffset = (time_t)temp;
                if ((intmax_t)checkoffset != temp) {
                    BIO_printf(bio_err, "%s: checkend time out of range %s\n",
                               prog, opt_arg());
                    goto opthelp;
                }
            }
            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;
    }

    if (!nmflag_set)
        nmflag = XN_FLAG_ONELINE;

    out = bio_open_default(outfile, 'w', outformat);
    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) {
        X509V3_CTX ctx2;
        if ((extconf = app_load_config(extfile)) == NULL)
            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', informat);
        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 ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
            BIO_printf(bio_err, "error unpacking public key\n");
            goto end;
        }
        i = X509_REQ_verify(req, 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 == NULL || !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, X509_REQ_get_subject_name(req)))
            goto end;
        if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
            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_get0_pubkey(req);
            X509_set_pubkey(x, pkey);
        }
    } else
        x = load_cert(infile, informat, "Certificate");

    if (x == NULL)
        goto end;
    if (CA_flag) {
        xca = load_cert(CAfile, CAformat, "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);
        }
        objtmp = NULL;
    }

    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);
        }
        objtmp = NULL;
    }

    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_get0_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 (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
                    BIGNUM *n;
                    RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, NULL, NULL);
                    BN_print(out, n);
                } else
#endif
#ifndef OPENSSL_NO_DSA
                if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) {
                    BIGNUM *dsapub = NULL;
                    DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &dsapub, NULL);
                    BN_print(out, dsapub);
                } else
#endif
                {
                    BIO_printf(out, "Wrong Algorithm type");
                }
                BIO_printf(out, "\n");
            } else if (pubkey == i) {
                EVP_PKEY *pkey;

                pkey = X509_get0_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);
            } 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);

                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) {
        ASN1_BIT_STRING *signature;
        unsigned char *s;
        X509_get0_signature(&signature, NULL, x);
        s = ASN1_STRING_data(signature);
        s[ASN1_STRING_length(signature) - 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 {
        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);
    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);
    ASN1_OBJECT_free(objtmp);
    OPENSSL_free(passin);
    return (ret);
}
Esempio n. 16
0
void Server::initializeCert() {
	QByteArray crt, key, pass;

	crt = getConf("certificate", QString()).toByteArray();
	key = getConf("key", QString()).toByteArray();
	pass = getConf("passphrase", QByteArray()).toByteArray();

	QList<QSslCertificate> ql;

	if (! key.isEmpty()) {
		qskKey = QSslKey(key, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass);
		if (qskKey.isNull())
			qskKey = QSslKey(key, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass);
	}
	if (qskKey.isNull() && ! crt.isEmpty()) {
		qskKey = QSslKey(crt, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass);
		if (qskKey.isNull())
			qskKey = QSslKey(crt, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass);
	}
	if (! qskKey.isNull()) {
		ql << QSslCertificate::fromData(crt);
		ql << QSslCertificate::fromData(key);
		for (int i=0;i<ql.size();++i) {
			const QSslCertificate &c = ql.at(i);
			if (isKeyForCert(qskKey, c)) {
				qscCert = c;
				ql.removeAt(i);
			}
		}
		qlCA = ql;
	}

	QString issuer;
#if QT_VERSION >= 0x050000
	QStringList issuerNames = qscCert.issuerInfo(QSslCertificate::CommonName);
	if (! issuerNames.isEmpty()) {
		issuer = issuerNames.first();
	}
#else
	issuer = qscCert.issuerInfo(QSslCertificate::CommonName);
#endif

	if (issuer == QString::fromUtf8("Murmur Autogenerated Certificate")) {
		log("Old autogenerated certificate is unusable for registration, invalidating it");
		qscCert = QSslCertificate();
		qskKey = QSslKey();
	}

	if (!qscCert.isNull() && issuer == QString::fromUtf8("Murmur Autogenerated Certificate v2") && ! Meta::mp.qscCert.isNull() && ! Meta::mp.qskKey.isNull() && (Meta::mp.qlBind == qlBind)) {
		qscCert = Meta::mp.qscCert;
		qskKey = Meta::mp.qskKey;
	}

	if (qscCert.isNull() || qskKey.isNull()) {
		if (! key.isEmpty() || ! crt.isEmpty()) {
			log("Certificate specified, but failed to load.");
		}
		qskKey = Meta::mp.qskKey;
		qscCert = Meta::mp.qscCert;
		if (qscCert.isNull() || qskKey.isNull()) {
			log("Generating new server certificate.");

			CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

			X509 *x509 = X509_new();
			EVP_PKEY *pkey = EVP_PKEY_new();
			RSA *rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL);
			EVP_PKEY_assign_RSA(pkey, rsa);

			X509_set_version(x509, 2);
			ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
			X509_gmtime_adj(X509_get_notBefore(x509),0);
			X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365*20);
			X509_set_pubkey(x509, pkey);

			X509_NAME *name=X509_get_subject_name(x509);

			X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char *>(const_cast<char *>("Murmur Autogenerated Certificate v2")), -1, -1, 0);
			X509_set_issuer_name(x509, name);
			add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE"));
			add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth"));
			add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash"));
			add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur"));

			X509_sign(x509, pkey, EVP_sha1());

			crt.resize(i2d_X509(x509, NULL));
			unsigned char *dptr=reinterpret_cast<unsigned char *>(crt.data());
			i2d_X509(x509, &dptr);

			qscCert = QSslCertificate(crt, QSsl::Der);
			if (qscCert.isNull())
				log("Certificate generation failed");

			key.resize(i2d_PrivateKey(pkey, NULL));
			dptr=reinterpret_cast<unsigned char *>(key.data());
			i2d_PrivateKey(pkey, &dptr);

			qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);
			if (qskKey.isNull())
				log("Key generation failed");

			setConf("certificate", qscCert.toPem());
			setConf("key", qskKey.toPem());
		}
	}
}
Esempio n. 17
0
Try<X509*> generate_x509(
    EVP_PKEY* subject_key,
    EVP_PKEY* sign_key,
    const Option<X509*>& parent_certificate,
    int serial,
    int days,
    Option<std::string> hostname)
{
  Option<X509_NAME*> issuer_name = None();
  if (parent_certificate.isNone()) {
    // If there is no parent certificate, then the subject and
    // signing key must be the same.
    if (subject_key != sign_key) {
      return Error("Subject vs signing key mismatch");
    }
  } else {
    // If there is a parent certificate, then set the issuer name to
    // be that of the parent.
    issuer_name = X509_get_subject_name(parent_certificate.get());

    if (issuer_name.get() == NULL) {
      return Error("Failed to get subject name of parent certificate: "
        "X509_get_subject_name");
    }
  }

  // Allocate the in-memory structure for the certificate.
  X509* x509 = X509_new();
  if (x509 == NULL) {
    return Error("Failed to allocate certification: X509_new");
  }

  // Set the version to V3.
  if (X509_set_version(x509, 2) != 1) {
    X509_free(x509);
    return Error("Failed to set version: X509_set_version");
  }

  // Set the serial number.
  if (ASN1_INTEGER_set(X509_get_serialNumber(x509), serial) != 1) {
    X509_free(x509);
    return Error("Failed to set serial number: ASN1_INTEGER_set");
  }

  // Make this certificate valid for 'days' number of days from now.
  if (X509_gmtime_adj(X509_get_notBefore(x509), 0) == NULL ||
      X509_gmtime_adj(X509_get_notAfter(x509),
                      60L * 60L * 24L * days) == NULL) {
    X509_free(x509);
    return Error("Failed to set valid days of certificate: X509_gmtime_adj");
  }

  // Set the public key for our certificate based on the subject key.
  if (X509_set_pubkey(x509, subject_key) != 1) {
    X509_free(x509);
    return Error("Failed to set public key: X509_set_pubkey");
  }

  // Figure out our hostname if one was not provided.
  if (hostname.isNone()) {
    const Try<std::string> _hostname = net::hostname();
    if (_hostname.isError()) {
      X509_free(x509);
      return Error("Failed to determine hostname");
    }

    hostname = _hostname.get();
  }

  // Grab the subject name of the new certificate.
  X509_NAME* name = X509_get_subject_name(x509);
  if (name == NULL) {
    X509_free(x509);
    return Error("Failed to get subject name: X509_get_subject_name");
  }

  // Set the country code, organization, and common name.
  if (X509_NAME_add_entry_by_txt(
          name,
          "C",
          MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>("US"),
          -1,
          -1,
          0) != 1) {
    X509_free(x509);
    return Error("Failed to set country code: X509_NAME_add_entry_by_txt");
  }

  if (X509_NAME_add_entry_by_txt(
          name,
          "O",
          MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>("Test"),
          -1,
          -1,
          0) != 1) {
    X509_free(x509);
    return Error("Failed to set organization name: X509_NAME_add_entry_by_txt");
  }

  if (X509_NAME_add_entry_by_txt(
          name,
          "CN",
          MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>(hostname.get().c_str()),
          -1,
          -1,
          0) != 1) {
    X509_free(x509);
    return Error("Failed to set common name: X509_NAME_add_entry_by_txt");
  }

  // Set the issuer name to be the same as the subject if it is not
  // already set (this is a self-signed certificate).
  if (issuer_name.isNone()) {
    issuer_name = name;
  }

  CHECK_SOME(issuer_name);
  if (X509_set_issuer_name(x509, issuer_name.get()) != 1) {
    X509_free(x509);
    return Error("Failed to set issuer name: X509_set_issuer_name");
  }

  // Sign the certificate with the sign key.
  if (X509_sign(x509, sign_key, EVP_sha1()) == 0) {
    X509_free(x509);
    return Error("Failed to sign certificate: X509_sign");
  }

  return x509;
}
Esempio n. 18
0
/* based on BSD-style licensed code of mod_ssl */
static int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509_STORE_CTX store_ctx;
    X509_OBJECT obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;
    EVP_PKEY *pubkey;
    long serial;
    int i, n, rc;
    char *cp;
    ASN1_TIME *last_update=NULL, *next_update=NULL;

    /* determine certificate ingredients in advance */
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    subject=X509_get_subject_name(cert);
    issuer=X509_get_issuer_name(cert);

    /* try to retrieve a CRL corresponding to the _subject_ of
     * the current certificate in order to verify it's integrity */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        cp=X509_NAME_oneline(subject, NULL, 0);
        s_log(LOG_INFO, "CRL: issuer: %s", cp);
        OPENSSL_free(cp);
        last_update=X509_CRL_get_lastUpdate(crl);
        next_update=X509_CRL_get_nextUpdate(crl);
        log_time(LOG_INFO, "CRL: last update", last_update);
        log_time(LOG_INFO, "CRL: next update", next_update);

        /* verify the signature on this CRL */
        pubkey=X509_get_pubkey(cert);
        if(X509_CRL_verify(crl, pubkey)<=0) {
            s_log(LOG_WARNING, "CRL: Invalid signature");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_CRL_SIGNATURE_FAILURE);
            X509_OBJECT_free_contents(&obj);
            if(pubkey)
                EVP_PKEY_free(pubkey);
            return 0; /* reject connection */
        }
        if(pubkey)
            EVP_PKEY_free(pubkey);

        /* check date of CRL to make sure it's not expired */
        if(!next_update) {
            s_log(LOG_WARNING, "CRL: Invalid nextUpdate field");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        if(X509_cmp_current_time(next_update)<0) {
            s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates");
            X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject connection */
        }
        X509_OBJECT_free_contents(&obj);
    }

    /* try to retrieve a CRL corresponding to the _issuer_ of
     * the current certificate in order to check for revocation */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        /* check if the current certificate is revoked by this CRL */
        n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
        for(i=0; i<n; i++) {
            revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
            if(ASN1_INTEGER_cmp(revoked->serialNumber,
                    X509_get_serialNumber(cert)) == 0) {
                serial=ASN1_INTEGER_get(revoked->serialNumber);
                cp=X509_NAME_oneline(issuer, NULL, 0);
                s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) "
                    "revoked per CRL from issuer %s", serial, serial, cp);
                OPENSSL_free(cp);
                X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
                X509_OBJECT_free_contents(&obj);
                return 0; /* reject connection */
            }
        }
        X509_OBJECT_free_contents(&obj);
    }
    return 1; /* accept connection */
}
Esempio n. 19
0
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
        {
        X509 *x;
        EVP_PKEY *pk;
        RSA *rsa;
        X509_NAME *name=NULL;
        
        if ((pkeyp == NULL) || (*pkeyp == NULL))
                {
                if ((pk=EVP_PKEY_new()) == NULL)
                        {
                        abort(); 
                        return(0);
                        }
                }
        else
                pk= *pkeyp;

        if ((x509p == NULL) || (*x509p == NULL))
                {
                if ((x=X509_new()) == NULL)
                        goto err;
                }
        else
                x= *x509p;

			
//		pRsaKey = RSA_generate_key(1024, 0x010001, NULL, NULL);

        rsa=RSA_generate_key(bits, RSA_F4, callback, NULL);
        if (!EVP_PKEY_assign_RSA(pk, rsa))
                {
                abort();
                goto err;
                }
        rsa=NULL;

        X509_set_version(x,2);
        ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
        X509_gmtime_adj(X509_get_notBefore(x),0);
        X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
        X509_set_pubkey(x,pk);

        name=X509_get_subject_name(x);

        /* This function creates and adds the entry, working out the
         * correct string type and performing checks on its length.
         * Normally we'd check the return value for errors...
         */
        X509_NAME_add_entry_by_txt(name,"C",
                                MBSTRING_ASC, "UK", -1, -1, 0);
        X509_NAME_add_entry_by_txt(name,"CN",
                                MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);

        /* Its self signed so set the issuer name to be the same as the
         * subject.
         */
        X509_set_issuer_name(x,name);

        /* Add various extensions: standard extensions */
        add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
        add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

        add_ext(x, NID_subject_key_identifier, "hash");

        /* Some Netscape specific extensions */
        add_ext(x, NID_netscape_cert_type, "sslCA");

        add_ext(x, NID_netscape_comment, "example comment extension");


#ifdef CUSTOM_EXT
        /* Maybe even add our own extension based on existing */
        {
                int nid;
                nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
                X509V3_EXT_add_alias(nid, NID_netscape_comment);
                add_ext(x, nid, "example comment alias");
        }
#endif
        
        if (!X509_sign(x,pk,EVP_md5()))
                goto err;

        *x509p=x;
        *pkeyp=pk;
        return(1);
err:
        return(0);
        }
Esempio n. 20
0
static void https_add_ssl_entries(connection *con) {
	X509 *xs;
	X509_NAME *xn;
	X509_NAME_ENTRY *xe;
	ASN1_INTEGER *xsn;
	int i, nentries;

	if (
		SSL_get_verify_result(con->ssl) != X509_V_OK
		|| !(xs = SSL_get_peer_certificate(con->ssl))
	) {
		return;
	}

	xn = X509_get_subject_name(xs);
	for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
		int xobjnid;
		const char * xobjsn;
		data_string *envds;

		if (!(xe = X509_NAME_get_entry(xn, i))) {
			continue;
		}
		xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
		xobjsn = OBJ_nid2sn(xobjnid);
		if (!xobjsn) {
			continue;
		}

		if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
			envds = data_string_init();
		}
		buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
		buffer_append_string(envds->key, xobjsn);
		buffer_copy_string_len(
			envds->value,
			(const char *)xe->value->data, xe->value->length
		);
		/* pick one of the exported values as "REMOTE_USER", for example
		 * ssl.verifyclient.username   = "******" or "SSL_CLIENT_S_DN_emailAddress"
		 */
		if (buffer_is_equal(con->conf.ssl_verifyclient_username, envds->key)) {
			data_string *ds;
			if (NULL == (ds = (data_string *)array_get_element(con->environment, "REMOTE_USER"))) {
				if (NULL == (ds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
					ds = data_string_init();
				}
				buffer_copy_string(ds->key, "REMOTE_USER");
				array_insert_unique(con->environment, (data_unset *)ds);
			}
			buffer_copy_string_buffer(ds->value, envds->value);
		}
		array_insert_unique(con->environment, (data_unset *)envds);
	}
	if (con->conf.ssl_verifyclient_export_cert) {
		BIO *bio;
		if (NULL != (bio = BIO_new(BIO_s_mem()))) {
			data_string *envds;
			int n;

			PEM_write_bio_X509(bio, xs);
			n = BIO_pending(bio);

			if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
				envds = data_string_init();
			}

			buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
			buffer_prepare_copy(envds->value, n+1);
			BIO_read(bio, envds->value->ptr, n);
			BIO_free(bio);
			envds->value->ptr[n] = '\0';
			envds->value->used = n+1;
			array_insert_unique(con->environment, (data_unset *)envds);
		}
	}

	/* Also got serial of the certificate */
	xsn = X509_get_serialNumber(xs);
	if (xsn)
	{
		data_string *envds;

		char * serialHex;
		BIGNUM *serialBN = NULL;

		serialBN = ASN1_INTEGER_to_BN(xsn,NULL);
		serialHex = BN_bn2hex(serialBN);

		if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
			envds = data_string_init();
		}

		buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_M_SERIAL"));
		buffer_copy_string(
			envds->value,
			serialHex
		);
		array_insert_unique(con->environment, (data_unset *)envds);
	}

	X509_free(xs);
}
Esempio n. 21
0
void anubis_dump_server_certificate(SSL *ssl) {
    X509 *x509Cert = SSL_get_peer_certificate(ssl);
    char buffer[1024];
    BIO *bio = NULL;
    char *buf = NULL;
    
    if(!x509Cert) {
        anubis_ssl_perror("SSL_get_peer_certificate()");
        return;
    }
    
    bio = BIO_new(BIO_s_mem());
    if(!bio) {
        anubis_ssl_perror("BIO_new()");
        X509_free(x509Cert);
        return;
    }//end if
    
    BIO_reset(bio);
    if(!PEM_write_bio_X509(bio, x509Cert)) {
        anubis_ssl_perror("PEM_write_bio_X509()");
        BIO_free(bio);
        X509_free(x509Cert);
        return;
    }
    BIO_get_mem_data(bio, &buf);
    anubis_out("Server certificate:\n%s", buf);
    // Cert Version
    long version = 0;
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VERSION)) {
        version = X509_get_version(x509Cert);
        fprintf(out_stream, "Version: %ld\n", version);
    }//end if
    
    // Cert Serial No. - Code adapted from OpenSSL's crypto/asn1/t_x509.c
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SERIAL)) {
        ASN1_INTEGER *bs;
        long l;
        int i;
        const char *neg;
        bs = X509_get_serialNumber(x509Cert);
        
        if (bs->length <= 4) {
            l = ASN1_INTEGER_get(bs);
            if (l < 0) {
                l= -l;
                neg = "-";
            }
            else
                neg = "";
            
            fprintf(out_stream, "Serial Number: %lu (%#lx)\n", l, l);
        }
        else {
            neg = (bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
            fprintf(out_stream, "Serial Number: %s", neg);
            for (i = 0; i < bs->length; i++) {
                fprintf(out_stream, "%02x%c", bs->data[i], (i+1 == bs->length)?'\n':':');
            }
        }
    }
    
    // Signature Algo...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SIGNAME)) {
        i2a_ASN1_OBJECT(bio, x509Cert->cert_info->signature->algorithm);
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Signature Algorithm:\n%s\n", buf);
    }
    
    // SSL Certificate Issuer...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_ISSUER)) {
        X509_NAME_oneline(X509_get_issuer_name(x509Cert), buffer, sizeof(buffer) - 1);
        fprintf(out_stream, "Issuer: %s\n", buffer);
    }
    
    // Validity...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VALIDITY)) {
        BIO_reset(bio);
        ASN1_TIME_print(bio, X509_get_notBefore(x509Cert));
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Not Valid Before: %s\n", buf);
        
        BIO_reset(bio);
        ASN1_TIME_print(bio, X509_get_notAfter(x509Cert));
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Not Valid After: %s\n", buf);
    }
    
    // SSL Certificate Subject...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SUBJECT)) {
        X509_NAME_oneline(X509_get_subject_name(x509Cert), buffer, sizeof(buffer) - 1);
        fprintf(out_stream, "Subject: %s\n", buffer);
    }
    
    // Public Key Algo...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_PUBKEY)) {
        BIO_reset(bio);
        i2a_ASN1_OBJECT(bio, x509Cert->cert_info->key->algor->algorithm);
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "Public Key Algorithm: %s\n", buf);
        
        // Public Key...
        EVP_PKEY *publicKey = NULL;
        publicKey = X509_get_pubkey(x509Cert);
        if (publicKey == NULL) {
            anubis_err("Public Key Could not load\n");
        }
        else {
            BIO_reset(bio);
            char *publicKeyType = NULL;
            int publicKeyLength = -1;
            switch (publicKey->type) {
                case EVP_PKEY_RSA:
                    
                    publicKeyType = "RSA";
                    
                    if (publicKey->pkey.rsa) {
                        publicKeyLength = BN_num_bits(publicKey->pkey.rsa->n);
                        RSA_print(bio, publicKey->pkey.rsa, 0);
                        BIO_get_mem_data(bio, &buf);
                    }
                    break;
                case EVP_PKEY_DSA:
                    
                    publicKeyType = "DSA";
                    
                    if (publicKey->pkey.dsa) {
                        DSA_print(bio, publicKey->pkey.dsa, 0);
                        BIO_get_mem_data(bio, &buf);
                    }
                    break;
                case EVP_PKEY_EC:
                    publicKeyType = "EC";
                    
                    if (publicKey->pkey.ec)  {
                        EC_KEY_print(bio, publicKey->pkey.ec, 0);
                        BIO_get_mem_data(bio, &buf);
                    }
                    break;
                default:
                    publicKeyType = "Unknown";
                    break;
            }
            
            EVP_PKEY_free(publicKey);
            fprintf(out_stream, "%d Public Key: ", publicKeyLength);
            if(!strcasecmp(publicKeyType, "RSA")) {
                fprintf(out_stream, "(%d bits)", publicKeyLength);
            }
            fprintf(out_stream, "\n");
            fprintf(out_stream, "%s\n", buf);
        }
    }
    
    // X509 v3...
    if (!(X509_FLAG_COMPAT & X509_FLAG_NO_EXTENSIONS) && sk_X509_EXTENSION_num(x509Cert->cert_info->extensions) > 0) {
        X509_EXTENSION *extension = NULL;
        ASN1_OBJECT *asn1Object = NULL;
        int tempInt2 = 0;
        BIO_reset(bio);
        for (int tempInt = 0; tempInt < sk_X509_EXTENSION_num(x509Cert->cert_info->extensions); tempInt++) {
            // Get Extension...
            extension = sk_X509_EXTENSION_value(x509Cert->cert_info->extensions, tempInt);
            
            asn1Object = X509_EXTENSION_get_object(extension);
            i2a_ASN1_OBJECT(bio, asn1Object);
            tempInt2 = X509_EXTENSION_get_critical(extension);
            BIO_printf(bio, ": %s\n", tempInt2 ? "critical" : "");
            
            // Print Extension value...
            if (!X509V3_EXT_print(bio, extension, X509_FLAG_COMPAT, 8)) {
                M_ASN1_OCTET_STRING_print(bio, extension->value);
            }
            BIO_printf(bio, "\n");
        }//end for
        
        BIO_get_mem_data(bio, &buf);
        fprintf(out_stream, "x509v3 Extensions: %s\n", buf);
    }//end if x509v3
    
    /*
    long verifyError = 0;
    // Verify Certificate...
    verifyError = SSL_get_verify_result(ssl);
    const char *verifyCertificate = "";
    if (verifyError == X509_V_OK)
        verifyCertificate = "Certificate passed verification";
    else
        verifyCertificate = X509_verify_cert_error_string(verifyError);
    fprintf(out_stream, "Validation: %s\n", verifyCertificate);
    */
    
    BIO_free(bio);
    X509_free(x509Cert);
    fflush(out_stream);
}//end anubis_dump_server_certificate
Esempio n. 22
0
int32_t mkcert(X509 **x509p, EVP_PKEY **pkeyp, int32_t bits, int32_t serial, int32_t days)
{
    bool bCreatedKey  = false;
    bool bCreatedX509 = false;
        // -----------------
        X509      * x    = NULL;
        EVP_PKEY  * pk   = NULL;
        RSA       * rsa  = NULL;
        X509_NAME * name = NULL;

        if ((pkeyp == NULL) || (*pkeyp == NULL))
        {
            if ((pk = EVP_PKEY_new()) == NULL)
            {
                abort();  // todo
                //return(0); unneeded after abort.
            }
            bCreatedKey = true;
        }
        else
            pk = *pkeyp;
        // -----------------------------------------
        if ((x509p == NULL) || (*x509p == NULL))
        {
            if ((x = X509_new()) == NULL)
            {
                if (bCreatedKey)
                {
                    EVP_PKEY_free(pk);
                }
                return(0);
            }

            bCreatedX509 = true;
        }
        else
            x = *x509p;
        // -----------------------------------------
//		pRsaKey = RSA_generate_key(1024, 0x010001, NULL, NULL);

#ifdef ANDROID
        rsa         = RSA_new();
        BIGNUM * e1 = BN_new();

        if ((NULL == rsa) || (NULL == e1))
            abort(); // todo

//      BN_set_word(e1, 65537);
        BN_set_word(e1, RSA_F4);

        if (!RSA_generate_key_ex(rsa, bits, e1, NULL))
            abort(); // todo

        BN_free(e1);
#else
        rsa = RSA_generate_key(bits, RSA_F4, callback, NULL);
#endif
        // -----------------------------------------
        if (!EVP_PKEY_assign_RSA(pk, rsa))
        {
            abort();  // todo
            //return(0); undeeded after abort.
        }
        // ------------------------------
        rsa = NULL;

        X509_set_version(x, 2);
        ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
        X509_gmtime_adj (X509_get_notBefore(x), 0);
        X509_gmtime_adj (X509_get_notAfter (x), static_cast<int64_t>(60*60*24*days));
        X509_set_pubkey (x, pk);

        name = X509_get_subject_name(x);

        /* This function creates and adds the entry, working out the
         * correct string type and performing checks on its length.
         * Normally we'd check the return value for errors...
         */
        X509_NAME_add_entry_by_txt(name,"C",
                                MBSTRING_ASC,
                                   (const uint8_t *)"UK",
                                   -1, -1, 0);
        X509_NAME_add_entry_by_txt(name,"CN",
                                MBSTRING_ASC,
                                   (const uint8_t *)"OpenSSL Group",
                                   -1, -1, 0);

        /* Its self signed so set the issuer name to be the same as the
         * subject.
         */
        X509_set_issuer_name(x, name);
        // ----------------------------------------------------------------------------
        /* Add various extensions: standard extensions */

        char * szConstraints  = new char[100]();
        char * szKeyUsage     = new char[100]();
        char * szSubjectKeyID = new char[100]();
        char * szCertType     = new char[100]();
        char * szComment      = new char[100]();
        // ----------------------------------------------------------------------------
        opentxs::OTString::safe_strcpy(szConstraints,  "critical,CA:TRUE",             99);
        opentxs::OTString::safe_strcpy(szKeyUsage,     "critical,keyCertSign,cRLSign", 99);
        opentxs::OTString::safe_strcpy(szSubjectKeyID, "hash",                         99);
        opentxs::OTString::safe_strcpy(szCertType,     "sslCA",                        99);
        opentxs::OTString::safe_strcpy(szComment,      "example comment extension",    99);
        // ----------------------------------------------------------------------------
        add_ext(x, NID_basic_constraints,      szConstraints);
        add_ext(x, NID_key_usage,              szKeyUsage);
        add_ext(x, NID_subject_key_identifier, szSubjectKeyID);
        add_ext(x, NID_netscape_cert_type,     szCertType); // Some Netscape specific extensions
        add_ext(x, NID_netscape_comment,       szComment);  // Some Netscape specific extensions
        // ----------------------------------------------------------------------------
        delete [] szConstraints;   szConstraints  = NULL;
        delete [] szKeyUsage;      szKeyUsage     = NULL;
        delete [] szSubjectKeyID;  szSubjectKeyID = NULL;
        delete [] szCertType;      szCertType     = NULL;
        delete [] szComment;       szComment      = NULL;
        // ----------------------------------------------------------------------------

#ifdef CUSTOM_EXT
        // Maybe even add our own extension based on existing
        {
                int32_t nid;
                nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
                X509V3_EXT_add_alias(nid, NID_netscape_comment);
                add_ext(x, nid, "example comment alias");
        }
#endif
        // ------------------------------
        if (!X509_sign(x, pk, EVP_md5()) || // TODO security:  md5 ???
            (NULL == x509p)              ||
            (NULL == pkeyp))
        {
            // ERROR
            //
            if (bCreatedX509)
                X509_free(x);

            // NOTE: not sure if x owns pk, in which case pk is already freed above.
            // Todo: find out and then determine whether or not to uncomment this.
            // (Presumably this would be a rare occurrence anyway.)
            //
//            if (bCreatedKey)
//                EVP_PKEY_free(pk);

            x  = NULL;
            pk = NULL;

            return 0;
        }
        // ------------------------------
        *x509p = x;
        *pkeyp = pk;

        return(1);
}
Esempio n. 23
0
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
	{
	long l;
	int ret=0,i;
	char *m=NULL,mlch = ' ';
	int nmindent = 0;
	X509_CINF *ci;
	ASN1_INTEGER *bs;
	EVP_PKEY *pkey=NULL;
	const char *neg;

	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
			mlch = '\n';
			nmindent = 12;
	}

	if(nmflags == X509_FLAG_COMPAT)
		nmindent = 16;

	ci=x->cert_info;
	if(!(cflag & X509_FLAG_NO_HEADER))
		{
		if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
		if (BIO_write(bp,"    Data:\n",10) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_VERSION))
		{
		l=X509_get_version(x);
		if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_SERIAL))
		{

		if (BIO_write(bp,"        Serial Number:",22) <= 0) goto err;

		bs=X509_get_serialNumber(x);
		if (bs->length <= 4)
			{
			l=ASN1_INTEGER_get(bs);
			if (l < 0)
				{
				l= -l;
				neg="-";
				}
			else
				neg="";
			if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
				goto err;
			}
		else
			{
			neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
			if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;

			for (i=0; i<bs->length; i++)
				{
				if (BIO_printf(bp,"%02x%c",bs->data[i],
					((i+1 == bs->length)?'\n':':')) <= 0)
					goto err;
				}
			}

		}

	if(!(cflag & X509_FLAG_NO_SIGNAME))
		{
		if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0) 
			goto err;
		if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
			goto err;
		if (BIO_puts(bp, "\n") <= 0)
			goto err;
		}

	if(!(cflag & X509_FLAG_NO_ISSUER))
		{
		if (BIO_printf(bp,"        Issuer:%c",mlch) <= 0) goto err;
		if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
		if (BIO_write(bp,"\n",1) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_VALIDITY))
		{
		if (BIO_write(bp,"        Validity\n",17) <= 0) goto err;
		if (BIO_write(bp,"            Not Before: ",24) <= 0) goto err;
		if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
		if (BIO_write(bp,"\n            Not After : ",25) <= 0) goto err;
		if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
		if (BIO_write(bp,"\n",1) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_SUBJECT))
		{
		if (BIO_printf(bp,"        Subject:%c",mlch) <= 0) goto err;
		if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
		if (BIO_write(bp,"\n",1) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_PUBKEY))
		{
		if (BIO_write(bp,"        Subject Public Key Info:\n",33) <= 0)
			goto err;
		if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
			goto err;
		if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
			goto err;
		if (BIO_puts(bp, "\n") <= 0)
			goto err;

		pkey=X509_get_pubkey(x);
		if (pkey == NULL)
			{
			BIO_printf(bp,"%12sUnable to load Public Key\n","");
			ERR_print_errors(bp);
			}
		else
			{
			EVP_PKEY_print_public(bp, pkey, 16, NULL);
			EVP_PKEY_free(pkey);
			}
		}

	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
		X509V3_extensions_print(bp, "X509v3 extensions",
					ci->extensions, cflag, 8);

	if(!(cflag & X509_FLAG_NO_SIGDUMP))
		{
		if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
		}
	if(!(cflag & X509_FLAG_NO_AUX))
		{
		if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
		}
	ret=1;
err:
	if (m != NULL) OPENSSL_free(m);
	return(ret);
	}
Esempio n. 24
0
extern "C" ASN1_INTEGER* CryptoNative_X509GetSerialNumber(X509* x509)
{
    return X509_get_serialNumber(x509);
}
Esempio n. 25
0
// Creates a X509 certificate, if rootcert is NULL this creates a root (self-signed) certificate.
// Is the name parameter is NULL, the hex value of the hash of the public key will be the subject name.
int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, int bits, int days, char* name, enum CERTIFICATE_TYPES certtype, struct util_cert* initialcert)
{
	X509 *x = NULL;
	X509_EXTENSION *ex = NULL;
	EVP_PKEY *pk = NULL;
	RSA *rsa = NULL;
	X509_NAME *cname=NULL;
	X509 **x509p = NULL;
	EVP_PKEY **pkeyp = NULL;
	char hash[UTIL_HASHSIZE];
	char serial[8];
	char nameStr[(UTIL_HASHSIZE * 2) + 2];
	BIGNUM *oBigNbr;

	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

	if (initialcert != NULL)
	{
		pk = X509_get_pubkey(initialcert->x509);
		rsa = EVP_PKEY_get1_RSA(initialcert->pkey);
		if ((x=X509_new()) == NULL) goto err;
	}
	else
	{
		if ((pkeyp == NULL) || (*pkeyp == NULL)) { if ((pk = EVP_PKEY_new()) == NULL) return 0; } else pk = *pkeyp;
		if ((x509p == NULL) || (*x509p == NULL)) { if ((x=X509_new()) == NULL) goto err; } else x = *x509p;
		oBigNbr = BN_new();
		rsa = RSA_new();
		BN_set_word(oBigNbr, RSA_F4);
		if (RSA_generate_key_ex(rsa, bits, oBigNbr, NULL) == -1)
		{
			RSA_free(rsa);
			BN_free(oBigNbr);
			abort();
			goto err;
		}
		BN_free(oBigNbr);
	}

	if (!EVP_PKEY_assign_RSA(pk, rsa))
	{
		RSA_free(rsa);
		abort();
		goto err;
	}
	rsa = NULL;

	util_randomtext(8, serial);
	X509_set_version(x, 2);
	ASN1_STRING_set(X509_get_serialNumber(x), serial, 8);
	X509_gmtime_adj(X509_get_notBefore(x),(long)60*60*24*-2);
	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
	X509_set_pubkey(x, pk);

	// Set the subject name
	cname = X509_get_subject_name(x);

	if (name == NULL)
	{
		// Computer the hash of the public key
		util_sha256((char*)x->cert_info->key->public_key->data, x->cert_info->key->public_key->length, hash);
		util_tohex(hash, UTIL_HASHSIZE, nameStr);
		X509_NAME_add_entry_by_txt(cname,"CN", MBSTRING_ASC, (unsigned char*)nameStr, -1, -1, 0);
	}
	else
	{
		// This function creates and adds the entry, working out the correct string type and performing checks on its length. Normally we'd check the return value for errors...
		X509_NAME_add_entry_by_txt(cname,"CN", MBSTRING_ASC, (unsigned char*)name, -1, -1, 0);
	}

	if (rootcert == NULL)
	{
		// Its self signed so set the issuer name to be the same as the subject.
		X509_set_issuer_name(x,cname);

		// Add various extensions: standard extensions
		util_add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
		util_add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

		util_add_ext(x, NID_subject_key_identifier, "hash");
		//util_add_ext(x, NID_netscape_cert_type, "sslCA");
		//util_add_ext(x, NID_netscape_comment, "example comment extension");

		if (!X509_sign(x, pk, EVP_sha256())) goto err;
	}
	else
	{
		// This is a sub-certificate
		cname=X509_get_subject_name(rootcert->x509);
		X509_set_issuer_name(x, cname);

		// Add usual cert stuff
		ex = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, "digitalSignature, keyEncipherment, keyAgreement");
		X509_add_ext(x, ex, -1);
		X509_EXTENSION_free(ex);

		// Add usages: TLS server, TLS client, Intel(R) AMT Console
		//ex = X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, "TLS Web Server Authentication, TLS Web Client Authentication, 2.16.840.1.113741.1.2.1, 2.16.840.1.113741.1.2.2");
		if (certtype == CERTIFICATE_TLS_SERVER)
		{
			// TLS server
			ex = X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, "TLS Web Server Authentication");
			X509_add_ext(x, ex, -1);
			X509_EXTENSION_free(ex);
		}
		else if (certtype == CERTIFICATE_TLS_CLIENT)
		{
			// TLS client
			ex = X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, "TLS Web Client Authentication");
			X509_add_ext(x, ex, -1);
			X509_EXTENSION_free(ex);
		}

		if (!X509_sign(x, rootcert->pkey, EVP_sha256())) goto err;
	}

	cert->x509 = x;
	cert->pkey = pk;

	return(1);
err:
	return(0);
}
Esempio n. 26
0
static int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
{
	X509 *x;
	EVP_PKEY *pk;
	RSA *rsa;
	X509_NAME *name=NULL;
	
	switch_assert(pkeyp);
	switch_assert(x509p);

	if (*pkeyp == NULL) {
		if ((pk = EVP_PKEY_new()) == NULL) {
			abort(); 
		}
	} else {
		pk = *pkeyp;
	}

	if (*x509p == NULL) {
		if ((x = X509_new()) == NULL) {
			goto err;
		}
	} else {
		x = *x509p;
	}

	rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);

	if (!EVP_PKEY_assign_RSA(pk, rsa)) {
		abort();
		goto err;
	}

	rsa = NULL;

	X509_set_version(x, 0);
	ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
	X509_gmtime_adj(X509_get_notBefore(x), -(long)60*60*24*7);
	X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days);
	X509_set_pubkey(x, pk);

	name = X509_get_subject_name(x);

	/* This function creates and adds the entry, working out the
	 * correct string type and performing checks on its length.
	 * Normally we'd check the return value for errors...
	 */
	X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"US", -1, -1, 0);
	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"FreeSWITCH", -1, -1, 0);
							   

	/* Its self signed so set the issuer name to be the same as the
 	 * subject.
	 */
	X509_set_issuer_name(x, name);

	if (!X509_sign(x, pk, EVP_sha1()))
		goto err;

	*x509p = x;
	*pkeyp = pk;
	return(1);
 err:
	return(0);
}
Esempio n. 27
0
LWS_VISIBLE LWS_EXTERN int
lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a,
			     const char *san_b)
{
	GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
	GENERAL_NAME *gen = NULL;
	ASN1_IA5STRING *ia5 = NULL;
	X509_NAME *name;

	if (!gens)
		return 1;

	vhost->tls.ss = lws_zalloc(sizeof(*vhost->tls.ss), "sni cert");
	if (!vhost->tls.ss) {
		GENERAL_NAMES_free(gens);
		return 1;
	}

	vhost->tls.ss->x509 = X509_new();
	if (!vhost->tls.ss->x509)
		goto bail;

	ASN1_INTEGER_set(X509_get_serialNumber(vhost->tls.ss->x509), 1);
	X509_gmtime_adj(X509_get_notBefore(vhost->tls.ss->x509), 0);
	X509_gmtime_adj(X509_get_notAfter(vhost->tls.ss->x509), 3600);

	vhost->tls.ss->pkey = EVP_PKEY_new();
	if (!vhost->tls.ss->pkey)
		goto bail0;

	if (lws_tls_openssl_rsa_new_key(&vhost->tls.ss->rsa, 4096))
		goto bail1;

	if (!EVP_PKEY_assign_RSA(vhost->tls.ss->pkey, vhost->tls.ss->rsa))
		goto bail2;

	X509_set_pubkey(vhost->tls.ss->x509, vhost->tls.ss->pkey);

	name = X509_get_subject_name(vhost->tls.ss->x509);
	X509_NAME_add_entry_by_txt(name, "C",  MBSTRING_ASC,
				   (unsigned char *)"GB",          -1, -1, 0);
	X509_NAME_add_entry_by_txt(name, "O",  MBSTRING_ASC,
				   (unsigned char *)"somecompany", -1, -1, 0);
	if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8,
				   (unsigned char *)"temp.acme.invalid",
				   	   	   -1, -1, 0) != 1) {
		lwsl_notice("failed to add CN\n");
		goto bail2;
	}
	X509_set_issuer_name(vhost->tls.ss->x509, name);

	/* add the SAN payloads */

	gen = GENERAL_NAME_new();
	ia5 = ASN1_IA5STRING_new();
	if (!ASN1_STRING_set(ia5, san_a, -1)) {
		lwsl_notice("failed to set ia5\n");
		GENERAL_NAME_free(gen);
		goto bail2;
	}
	GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
	sk_GENERAL_NAME_push(gens, gen);

	if (X509_add1_ext_i2d(vhost->tls.ss->x509, NID_subject_alt_name,
			    gens, 0, X509V3_ADD_APPEND) != 1)
		goto bail2;

	GENERAL_NAMES_free(gens);

	if (san_b && san_b[0]) {
		gens = sk_GENERAL_NAME_new_null();
		gen = GENERAL_NAME_new();
		ia5 = ASN1_IA5STRING_new();
		if (!ASN1_STRING_set(ia5, san_a, -1)) {
			lwsl_notice("failed to set ia5\n");
			GENERAL_NAME_free(gen);
			goto bail2;
		}
		GENERAL_NAME_set0_value(gen, GEN_DNS, ia5);
		sk_GENERAL_NAME_push(gens, gen);

		if (X509_add1_ext_i2d(vhost->tls.ss->x509, NID_subject_alt_name,
				    gens, 0, X509V3_ADD_APPEND) != 1)
			goto bail2;

		GENERAL_NAMES_free(gens);
	}

	/* sign it with our private key */
	if (!X509_sign(vhost->tls.ss->x509, vhost->tls.ss->pkey, EVP_sha256()))
		goto bail2;

#if 0
	{/* useful to take a sample of a working cert for mbedtls to crib */
		FILE *fp = fopen("/tmp/acme-temp-cert", "w+");

		i2d_X509_fp(fp, vhost->tls.ss->x509);
		fclose(fp);
	}
#endif

	/* tell the vhost to use our crafted certificate */
	SSL_CTX_use_certificate(vhost->tls.ssl_ctx, vhost->tls.ss->x509);
	/* and to use our generated private key */
	SSL_CTX_use_PrivateKey(vhost->tls.ssl_ctx, vhost->tls.ss->pkey);

	return 0;

bail2:
	RSA_free(vhost->tls.ss->rsa);
bail1:
	EVP_PKEY_free(vhost->tls.ss->pkey);
bail0:
	X509_free(vhost->tls.ss->x509);
bail:
	lws_free(vhost->tls.ss);
	GENERAL_NAMES_free(gens);

	return 1;
}
Esempio n. 28
0
String SslCertificate::GetSerialNumber() const
{
	ASSERT(!IsEmpty());
	return Asn1ToString(X509_get_serialNumber(cert));
}
Esempio n. 29
0
DWORD
VMCACreateRevokedFromCert(
    X509 *pCert,
    X509_REVOKED **pRevoked)
{

    DWORD dwError = 0;
    X509_REVOKED *pTempRev = NULL;
    ASN1_TIME *pRevTime = NULL;
    ASN1_ENUMERATED *pCode = NULL;

    pCode = ASN1_ENUMERATED_new();
    if(pCode == NULL) {
        dwError = VMCA_OUT_MEMORY_ERR;
        BAIL_ON_ERROR(dwError);
    }

    pTempRev = X509_REVOKED_new();
    if (pTempRev == NULL) {
        dwError = VMCA_OUT_MEMORY_ERR;
        BAIL_ON_ERROR(dwError);
    }

    pRevTime = ASN1_TIME_new();
    if (pRevTime == NULL) {
        dwError = VMCA_OUT_MEMORY_ERR;
        BAIL_ON_ERROR(dwError);
    }

    ASN1_TIME_set(pRevTime, time(NULL));
    dwError = X509_REVOKED_set_serialNumber(pTempRev,
                    X509_get_serialNumber(pCert));
    BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_SET_SERIAL_FAIL);

    dwError = X509_REVOKED_set_revocationDate(pTempRev, pRevTime);
    BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_SET_TIME_FAIL);

    //TODO : Fix the UNSPECIFIED to real valid reason
    // which users can pass in.
    ASN1_ENUMERATED_set(pCode, CRL_REASON_UNSPECIFIED);
    dwError = X509_REVOKED_add1_ext_i2d(pTempRev,
                            NID_crl_reason, pCode, 0, 0);

    BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_REASON_FAIL);
    *pRevoked = pTempRev;

cleanup :
    if(pRevTime != NULL) {
        ASN1_TIME_free(pRevTime);
    }

    if(pCode !=NULL) {
        ASN1_ENUMERATED_free(pCode);
    }
    return dwError;

error:
    if(pTempRev != NULL)
    {
        X509_REVOKED_free(pTempRev);
    }
    goto cleanup;
}
Esempio n. 30
0
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
                  unsigned long cflag)
{
    long l;
    int ret = 0, i;
    char *m = NULL, mlch = ' ';
    int nmindent = 0;
    ASN1_INTEGER *bs;
    EVP_PKEY *pkey = NULL;
    const char *neg;

    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        mlch = '\n';
        nmindent = 12;
    }

    if (nmflags == X509_FLAG_COMPAT)
        nmindent = 16;

    if (!(cflag & X509_FLAG_NO_HEADER)) {
        if (BIO_write(bp, "Certificate:\n", 13) <= 0)
            goto err;
        if (BIO_write(bp, "    Data:\n", 10) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VERSION)) {
        l = X509_get_version(x);
        if (l >= 0 && l <= 2) {
            if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
                goto err;
        } else {
            if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
                goto err;
        }
    }
    if (!(cflag & X509_FLAG_NO_SERIAL)) {

        if (BIO_write(bp, "        Serial Number:", 22) <= 0)
            goto err;

        bs = X509_get_serialNumber(x);
        if (bs->length <= (int)sizeof(long)) {
                ERR_set_mark();
                l = ASN1_INTEGER_get(bs);
                ERR_pop_to_mark();
        } else {
            l = -1;
        }
        if (l != -1) {
            unsigned long ul;
            if (bs->type == V_ASN1_NEG_INTEGER) {
                ul = 0 - (unsigned long)l;
                neg = "-";
            } else {
                ul = l;
                neg = "";
            }
            if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, ul, neg, ul) <= 0)
                goto err;
        } else {
            neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
            if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
                goto err;

            for (i = 0; i < bs->length; i++) {
                if (BIO_printf(bp, "%02x%c", bs->data[i],
                               ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
                    goto err;
            }
        }

    }

    if (!(cflag & X509_FLAG_NO_SIGNAME)) {
        const X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x);
        if (X509_signature_print(bp, tsig_alg, NULL) <= 0)
            goto err;
    }

    if (!(cflag & X509_FLAG_NO_ISSUER)) {
        if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
            < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VALIDITY)) {
        if (BIO_write(bp, "        Validity\n", 17) <= 0)
            goto err;
        if (BIO_write(bp, "            Not Before: ", 24) <= 0)
            goto err;
        if (!ASN1_TIME_print(bp, X509_get0_notBefore(x)))
            goto err;
        if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
            goto err;
        if (!ASN1_TIME_print(bp, X509_get0_notAfter(x)))
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex
            (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
        X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x);
        ASN1_OBJECT *xpoid;
        X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey);
        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
            goto err;
        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
            goto err;
        if (i2a_ASN1_OBJECT(bp, xpoid) <= 0)
            goto err;
        if (BIO_puts(bp, "\n") <= 0)
            goto err;

        pkey = X509_get0_pubkey(x);
        if (pkey == NULL) {
            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
            ERR_print_errors(bp);
        } else {
            EVP_PKEY_print_public(bp, pkey, 16, NULL);
        }
    }

    if (!(cflag & X509_FLAG_NO_IDS)) {
        const ASN1_BIT_STRING *iuid, *suid;
        X509_get0_uids(x, &iuid, &suid);
        if (iuid != NULL) {
            if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
                goto err;
            if (!X509_signature_dump(bp, iuid, 12))
                goto err;
        }
        if (suid != NULL) {
            if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
                goto err;
            if (!X509_signature_dump(bp, suid, 12))
                goto err;
        }
    }

    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
        X509V3_extensions_print(bp, "X509v3 extensions",
                                X509_get0_extensions(x), cflag, 8);

    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
        const X509_ALGOR *sig_alg;
        const ASN1_BIT_STRING *sig;
        X509_get0_signature(&sig, &sig_alg, x);
        if (X509_signature_print(bp, sig_alg, sig) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_AUX)) {
        if (!X509_aux_print(bp, x, 0))
            goto err;
    }
    ret = 1;
 err:
    OPENSSL_free(m);
    return ret;
}