Exemple #1
0
char * PKI_X509_CERT_get_parsed(const PKI_X509_CERT *x,
				PKI_X509_DATA type ) {

  char *ret = NULL;

  PKI_X509_KEYPAIR *k = NULL;
  const PKI_X509_KEYPAIR_VALUE *pkey = NULL;


  if( !x ) return (NULL);

  switch( type ) {
    case PKI_X509_DATA_SERIAL:
      ret = PKI_INTEGER_get_parsed((PKI_INTEGER *) 
		      		   PKI_X509_CERT_get_data(x, type));
      break;

    case PKI_X509_DATA_SUBJECT:
    case PKI_X509_DATA_ISSUER:
      ret = PKI_X509_NAME_get_parsed((PKI_X509_NAME *) 
		      		     PKI_X509_CERT_get_data(x, type));
      break;

    case PKI_X509_DATA_NOTBEFORE:
    case PKI_X509_DATA_NOTAFTER:
      ret = PKI_TIME_get_parsed((PKI_TIME *)PKI_X509_CERT_get_data(x, type));
      break;

    case PKI_X509_DATA_ALGORITHM:
      ret = (char *) PKI_ALGOR_get_parsed((PKI_ALGOR *) 
		      			  PKI_X509_CERT_get_data(x,type));
      break;

    case PKI_X509_DATA_PUBKEY:
    case PKI_X509_DATA_KEYPAIR_VALUE:
      if ((pkey = PKI_X509_CERT_get_data(x, type)) != NULL) {
        k = PKI_X509_new_dup_value(PKI_DATATYPE_X509_KEYPAIR, pkey, NULL);
        ret = PKI_X509_KEYPAIR_get_parsed( k );
        PKI_X509_KEYPAIR_free(k);
      }
      break;

    case PKI_X509_DATA_KEYSIZE:
      PKI_ERROR(PKI_ERR_PARAM_TYPE, "Deprecated Cert Datatype");
      break;

    case PKI_X509_DATA_CERT_TYPE:
    case PKI_X509_DATA_SIGNATURE:
    case PKI_X509_DATA_EXTENSIONS:
    default:
      /* Not Recognized/Supported DATATYPE */
      return (NULL);
  }

  return (ret);
}
Exemple #2
0
PKI_X509_CERT_TYPE PKI_X509_CERT_get_type(const PKI_X509_CERT *x) {

  PKI_X509_CERT_TYPE ret = PKI_X509_CERT_TYPE_USER;
  const PKI_X509_NAME *subj = NULL;
  const PKI_X509_NAME *issuer = NULL;
  BASIC_CONSTRAINTS *bs = NULL;
  PKI_X509_EXTENSION *ext = NULL;

  if (!x || !x->value || (x->type != PKI_DATATYPE_X509_CERT) ) 
          return PKI_X509_CERT_TYPE_UNKNOWN;

  subj = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_SUBJECT );
  issuer = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_ISSUER );

  if ( subj && issuer ) {
    if ( PKI_X509_NAME_cmp( subj, issuer ) == 0) {
      ret |= PKI_X509_CERT_TYPE_ROOT;
    }
  }

  if((ext = PKI_X509_CERT_get_extension_by_id ( x, 
          NID_basic_constraints)) != NULL ) {
    if(( bs = ext->value )) {
      if ( bs->ca ) ret |= PKI_X509_CERT_TYPE_CA;
      BASIC_CONSTRAINTS_free ( bs );
    }
    PKI_X509_EXTENSION_free ( ext );
  }

  if((ext = PKI_X509_CERT_get_extension_by_id ( x, 
          NID_proxyCertInfo )) != NULL ) {
    if ( ret & PKI_X509_CERT_TYPE_CA ) {
      PKI_log_err ( "Certificate Error, Proxy Cert info set",
              "in a CA certificate!");
    } else {
      ret |= PKI_X509_CERT_TYPE_PROXY;
    }

    PKI_X509_EXTENSION_free ( ext );
  }

  return ret;
  
}
Exemple #3
0
int check_crl ( PKI_X509_CRL *x_crl, PKI_X509_CERT *x_cacert,
		OCSPD_CONFIG *conf ) {

	PKI_X509_KEYPAIR_VALUE *pkey = NULL;
	PKI_X509_KEYPAIR *k = NULL;

	int ret = -1;

	if (!conf) return (-1);

	PKI_RWLOCK_read_lock ( &conf->crl_lock );
	if( !x_crl || !x_crl->value || !x_cacert || !x_cacert->value ) {
		if( conf->verbose ) {
			if(!x_crl || !x_crl->value) 
					PKI_log_err ("CRL missing");
			if(!x_cacert || !x_cacert->value) 
					PKI_log_err("CA cert missing");
		}
		PKI_RWLOCK_release_read ( &conf->crl_lock );
		return(-1);
	}

	/* Gets the Public Key of the CA Certificate */
	if((pkey = PKI_X509_CERT_get_data( x_cacert, 
				PKI_X509_DATA_PUBKEY )) == NULL ) { 
		PKI_log_err( "Can not parse PubKey from CA Cert");
		PKI_RWLOCK_release_read ( &conf->crl_lock );
		return(-3);
	}

	if ((k = PKI_X509_new_value(PKI_DATATYPE_X509_KEYPAIR, pkey, NULL))
							== NULL ) {
		PKI_log_err ("Memory Error!");
		PKI_RWLOCK_release_read ( &conf->crl_lock );
		return(-3);
	}
	
	if ( PKI_X509_verify ( x_crl, k ) == PKI_OK ) {
		PKI_log_debug("CRL signature is verified!");
		ret = PKI_OK;
	} else {
		ret = PKI_ERR;
	}

	k->value = NULL;
	PKI_X509_KEYPAIR_free ( k );

	PKI_RWLOCK_release_read ( &conf->crl_lock );

	if ( ret > 0 ) {
		PKI_log(PKI_LOG_INFO, "CRL matching CA cert ok [ %d ]",
				ret);
	}

	return ret;
}
Exemple #4
0
int PKI_X509_CERT_get_keysize(const PKI_X509_CERT *x ) {

  const PKI_X509_KEYPAIR_VALUE *pkey = NULL;

  if (!x || !x->value) return (0);

  if ((pkey = PKI_X509_CERT_get_data(x, 
				     PKI_X509_DATA_KEYPAIR_VALUE)) == NULL) {
    return (0);
  }

  return PKI_X509_KEYPAIR_VALUE_get_size(pkey);
}
Exemple #5
0
const PKI_X509_CRL_ENTRY * PKI_X509_CRL_lookup_cert(const PKI_X509_CRL *x, 
                const PKI_X509_CERT *cert) {

  const PKI_INTEGER *serial = NULL;

  if (!x || !cert) return NULL;

  if ((serial = PKI_X509_CERT_get_data(cert, 
               PKI_X509_DATA_SERIAL )) == NULL ) {
    return ( NULL );
  }

  return PKI_X509_CRL_lookup ( x, serial );
}
Exemple #6
0
int PKI_X509_CERT_get_keysize ( PKI_X509_CERT *x ) {

	int keysize = 0;
	PKI_X509_KEYPAIR_VALUE *pkey = NULL;

	if( !x || !x->value ) return (0);

	if((pkey = PKI_X509_CERT_get_data(x, 
				PKI_X509_DATA_KEYPAIR_VALUE))==NULL){
		return (0);
	}

	keysize = PKI_X509_KEYPAIR_VALUE_get_size( pkey );
 
	return keysize;
}
Exemple #7
0
PKI_DIGEST *PKI_X509_CERT_key_hash(const PKI_X509_CERT *x,
				   const PKI_DIGEST_ALG *alg ) {

  const PKI_X509_KEYPAIR_VALUE *key = NULL;
  PKI_DIGEST *keyHash = NULL;

  if ( !x || !x->value ) return NULL;

  if ( !alg ) alg = PKI_DIGEST_ALG_DEFAULT;

  if ((key = PKI_X509_CERT_get_data(x, PKI_X509_DATA_KEYPAIR_VALUE)) == NULL)
    return NULL;

  if ((keyHash = PKI_X509_KEYPAIR_VALUE_pub_digest(key, alg)) == NULL)
    return NULL;

  return keyHash;
}
Exemple #8
0
int PKI_X509_CERT_is_selfsigned(const PKI_X509_CERT *x ) {

  PKI_X509_KEYPAIR *kp = NULL;
  const PKI_X509_KEYPAIR *kval = NULL;
  int ret = -1;

  if (!x) return PKI_ERR;

  kval = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_PUBKEY );
  if ( !kval ) return PKI_ERR;

  kp = PKI_X509_new_dup_value(PKI_DATATYPE_X509_KEYPAIR, kval, NULL);
  if ( !kp ) return PKI_ERR;

  ret = PKI_X509_verify ( x, kp );
  PKI_X509_KEYPAIR_free ( kp );

  return ret;
}
Exemple #9
0
int PKI_X509_CERT_check_pubkey(PKI_X509_CERT *x, PKI_X509_KEYPAIR *k)
{
	int ret = 0;

	X509_PUBKEY *pub_key = NULL;
	PKI_X509_KEYPAIR_VALUE *k_val = NULL;

	PKI_STRING *c_pubkey = NULL;
	PKI_STRING *k_pubkey = NULL;

	// Input checks
	if (!x || !x->value || !k || !k->value) return -1;

	// Gets the certificate's public key bits
	c_pubkey = PKI_X509_CERT_get_data(x, PKI_X509_DATA_PUBKEY_BITSTRING);
	if (!c_pubkey) return -99;

	// Gets the Key Value from the KeyPair
	k_val = PKI_X509_get_value(k);
	if (!k_val) 
	{
		// Let's return ok, because in HSMs we might not have
		// access to the pubkey data
		return 0;
	}

	// Gets the KeyPair public key bits
	if (!X509_PUBKEY_set(&pub_key, k_val)) return -99;

	// Now let's point to tke KeyPair's public key
	k_pubkey = pub_key->public_key;

	// Compares the two bit strings
	ret = PKI_STRING_cmp(c_pubkey, k_pubkey);
	
	// Frees the memory
	X509_PUBKEY_free(pub_key);

	// Let's return the result of the operation
	return ret;
}
Exemple #10
0
PKI_STACK * PKI_X509_CERT_get_email (const PKI_X509_CERT *x ) {

  PKI_STACK *sk = NULL;
  PKI_X509_NAME_RDN **list = NULL;
  const PKI_X509_NAME *name = NULL;

  // PKI_X509_EXTENSION_STACK * ext_list = NULL;

  PKI_X509_EXTENSION * ext = NULL;

  if(!x || !x->value) return NULL;

  if((sk = PKI_STACK_new_null()) == NULL)
    return NULL;

  name = PKI_X509_CERT_get_data(x, PKI_X509_DATA_SUBJECT);

  // Maybe we find something in the DN...
  if(name) {

    int curr = 0;

    PKI_X509_NAME_RDN *el = NULL;
    list = PKI_X509_NAME_get_list(name, PKI_X509_NAME_TYPE_EMAIL);
    
    for(curr = 0; el != NULL; curr++ ) {
      el = list[curr];
      PKI_STACK_push( sk, PKI_X509_NAME_RDN_value(el));
    }
  }
  
  if((ext = PKI_X509_CERT_get_extension_by_name(x, 
                                         "subjectAltName")) != NULL) {
      PKI_log_debug("Got subjectAltName: Code Still Missing!");
  }

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

  PKI_X509_KEYPAIR_VALUE  *certPubKeyVal = NULL;

  int rv = 0;
  int ver = 2;

  int64_t notBeforeVal = 0;

  ASN1_INTEGER *serial = NULL;

  char *ver_s = NULL;

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

  signingKey = kPair->value;

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

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

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

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

      const PKI_X509_NAME * req_subj = NULL;

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

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

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

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

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

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

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

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

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

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

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

  val = ret->value;

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

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

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

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

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

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

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

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

    char *tmp_s = NULL;

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

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

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

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

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

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

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

    char *tmp_s = NULL;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    scheme = PKI_ALGOR_get_scheme( algor );

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

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

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

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

    PKI_TOKEN_set_cert(tk, ret);

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

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

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

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

      PKI_TOKEN_free ( tk );

      goto err;
    }

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

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

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

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

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

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

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

#if ( OPENSSL_VERSION_NUMBER >= 0x0090900f )

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

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

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

  return ret;

err:

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

  return NULL;
}

/*!
 * \brief Signs a PKI_X509_CERT
 */

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

  const PKI_ALGOR *alg = NULL;

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

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

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

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

  return PKI_OK;
};

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

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

  PKI_X509_KEYPAIR *kp = NULL;

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

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

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

  return PKI_X509_CERT_sign ( cert, kp, digest );
};
Exemple #12
0
CA_ENTRY_CERTID * CA_ENTRY_CERTID_new ( PKI_X509_CERT *cert, 
					PKI_DIGEST_ALG * digestAlg ) {

	CA_ENTRY_CERTID *ret = NULL;

	PKI_STRING *keyString = NULL;
	PKI_DIGEST *keyDigest = NULL;

	PKI_X509_NAME *iName = NULL;
	PKI_DIGEST *nameDigest = NULL;

	/* Check for needed info */
	if ( !cert || !cert->value ) return NULL;

	/* Use SHA1 as default digest algorithm */
	if ( !digestAlg ) digestAlg = PKI_DIGEST_ALG_SHA1;

	// Allocate Memory for the CA_ENTRY_CERTID
	if((ret = PKI_Malloc(sizeof(CA_ENTRY_CERTID))) == NULL) {
		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
		goto err;
	}

	/* Retrieves the subject name from the certificate */
	if ((iName = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_SUBJECT)) == NULL)
	{
		PKI_log_err("Can not get certificate's subject");
		goto err;
	};

	// Let's build the HASH of the Name
	if((nameDigest = PKI_X509_NAME_get_digest(iName, digestAlg)) == NULL) {
		PKI_log_err("Can not get digest string from certificate's subject");
		goto err;
	};

	// Assign the new OCTET string tothe nameHash field
	if (( ret->nameHash = PKI_STRING_new ( PKI_STRING_OCTET,
			(char *) nameDigest->digest, (ssize_t) nameDigest->size )) == NULL ) {
		PKI_log_err("Can not assign nameHash to CERTID");
		goto err;
	};
	
	// Let's get the key bitstring from the certificate
	if (( keyString = PKI_X509_CERT_get_data( cert, 
				PKI_X509_DATA_PUBKEY_BITSTRING)) == NULL ) {
		PKI_log_err("Can not get certificate's pubkey bitstring");
		goto err;

	} else {
		// We build the keyDigest from the keyString
		if((keyDigest = PKI_STRING_get_digest (keyString, 
				digestAlg)) == NULL ) {
			PKI_log_err("Can not create new keyDigest from keyString");
			goto err;
		};
	};

	if((ret->keyHash = PKI_STRING_new ( PKI_STRING_OCTET,
				(char *) keyDigest->digest, (ssize_t) keyDigest->size )) == NULL ) {
		PKI_log_err("Can not assign keyHash to CERTID");
		goto err;
	};

	/* Set the Digest Algorithm used */
	if((ret->hashAlgorithm = PKI_ALGORITHM_new_digest( digestAlg )) == NULL ) {
		if( ret ) CA_ENTRY_CERTID_free ( ret );
		PKI_log_err("ERROR, can not create a new hashAlgorithm!");
		return NULL;
	};

	if ( nameDigest ) PKI_DIGEST_free ( nameDigest );
	if ( keyDigest  ) PKI_DIGEST_free ( keyDigest );

	return ret;

err:
	if ( nameDigest ) PKI_DIGEST_free ( nameDigest );
	if ( keyDigest  ) PKI_DIGEST_free ( keyDigest );

	if ( ret ) CA_ENTRY_CERTID_free ( ret );

	return ( NULL );
}