Esempio n. 1
0
void userInput(int grid[9][9])
{
    int x,
        y,
        data;

    for(y = 0; y < 9; ++y)
        for(x = 0; x < 9; ++x)
        {
            grid[x][y] = data = 10;//10 is used to tell the print function to print an X, it also ensures that the following loop will also always be entered
            printGrid(grid);//Print the grid, including the current location marker

            while(!((data >= 0) && (data <= 9)))
            {
                //get and clean the user input, note it does not require the enter key to be hit (++Bonus)
                data = digitConverter(getch());
            }

            grid[x][y] = data;//Assign the coveted user input into its most holy of resting places
        }

        if(validity(grid) == 0)
        {
            printf("Try again!%c\n", 0x7);
            initialize(grid);
            userInput(grid);
        }

    return;
}
int
main ()
{
    different (5);
    validity (5, data ());
    invalid (data2 ());
    return 0;
}
void angry_prof(int tick) {
    int n,k;
    int i;
    
    for (i =0; i < tick; i++){
        scanf("%d %d",&n,&k);
        validity(n,k);   
    }
}
TEST(ValidMoveRightTest, SomethingInWayPreventsGreatJump){
	std::list<Position> allPosns;
	allPosns.push_back(Position(Vector2(0, 0), 50, 50));
	allPosns.push_back(Position(Vector2(75, 0), 50, 50));
	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);
	Position expectedNextMove(Vector2(24, 0), 50, 50);
	Vector2 speed(126, 0);
	Position validMove = validity.getValidMove(Position(Vector2(0, 0), 50, 50), speed);
	EXPECT_EQ(validMove, expectedNextMove) << "Got: " << validMove.getX() << " " << validMove.getY();
}
TEST(MoveTest, CannotMoveOutOfNorthOrWestBoundaries){
	std::list<Position> allPosns;
	Position myPosn = Position(Vector2(0, 0), 10, 10);
	allPosns.push_back(myPosn);
	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);

	Vector2 speed(-10, 0);
	Position validMove = validity.getValidMove(myPosn, speed);
	EXPECT_EQ(validMove, myPosn)<< "Got: " << validMove.getX() << " " << validMove.getY();
}
TEST(ValidMoveRightTest, ValidMoveReturnsClosestPositionToEdgeIfMoveNotValid){
	std::list<Position> allPosns;
	allPosns.push_back(Position(Vector2(0, 0), 50, 50));
	allPosns.push_back(Position(Vector2(75, 0), 50, 50));
	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);
	Position expectedNextMove(Vector2(24, 0), 50, 50);
	Vector2 speed(40, 0);
	Position validMove = validity.getValidMove(Position(Vector2(0, 0), 50, 50), speed);
	EXPECT_EQ(validMove, expectedNextMove)<< "Got: " << validMove.getX() << " " << validMove.getY();
}
TEST(ValidMoveRightTest, ValidMoveReturnsSameMoveIfItIsValid){
	std::list<Position> allPosns;
	allPosns.push_back(Position(Vector2(0, 0), 50, 50));

	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);
	Vector2 speed(25, 0);
	Position nextMove(Vector2(25, 0), 50, 50);
	Position validMove = validity.getValidMove(Position(Vector2(0, 0), 50, 50), speed);
	
	EXPECT_EQ(validMove, nextMove); 
}
TEST(ValidMoveDownTest, StandardMoveDownWorks){
	std::list<Position> allPosns;
	Position myPosn = Position(Vector2(20, 10), 20, 10);
	allPosns.push_back(Position(Vector2(30, 30), 10, 10));
	allPosns.push_back(myPosn);
	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);

	Position expectedNextMove(Vector2(20, 19), 20, 10);
	Vector2 speed(0, 50);
	Position validMove = validity.getValidMove(myPosn, speed);
	EXPECT_EQ(validMove, expectedNextMove)<< "Got: " << validMove.getX() << " " << validMove.getY();
}
Esempio n. 9
0
int SudokuTime(int grid[9][9])
{
    int x,
        y,
        testNumber;

    ++count; //How many steps it took to solve. I guess this could be a rough measure of how complicated the puzzle was?

	//Find the cell that this function will work on
    for(y = 0; y < 9; ++y)
    {
        for(x = 0; x < 9; ++x)
        {
            if(grid[x][y] == 0)
                break;
        }

        if(grid[x][y] == 0)
            break;
    }

//Find a number that fits and move on to the next cell
    for(testNumber = 1; testNumber <= 9; ++testNumber)
    {
        grid[x][y] = testNumber;
        if(validity(grid))//If it is valid, prepare to move onto the next tile
        {
            if((count % 10000) == 0)
            {
                printGrid(grid);
                printf("\nCurrent iteration = %ld", count);
            }

            if((x == 8) && (y == 8))//If its the last available cell then collapse the recursion chain
                return 1;
            else if(SudokuTime(grid))//If the next tile is valid, break out of the function
                return 1;
            else
                continue;//Really just a statement to fluff out the code
        }
        else if((x == 8) && (y == 8) && (testNumber == 9))//Unable to solve the puzzle
        {
            grid[x][y] = 0;
            printf("\nSorry the puzzle as you entered it was not solvable.\n\n\nBetter luck next time!\n");
            return 1;
        }
    }

    grid[x][y] = 0;//Process failed, reset to 0 and prepare to backtrack

    return 0;//Safety net, if unsure, always default to back up and try again!
    //Also, without this return statement, the compiler throws a warning my way :(
}
Esempio n. 10
0
TEST(ValidMoveLeftTest, IfThinPieceCenterCloserThanThickPieceCenterThickPieceStillConsideredClosest){
	std::list<Position> allPosns;
	allPosns.push_back(Position(Vector2(150, 20), 50, 50));
	allPosns.push_back(Position(Vector2(75, 0), 10, 50));
	allPosns.push_back(Position(Vector2(75, 50), 50, 50));
	ValidMove validity(Position(Vector2(0, 0), 500, 500), allPosns);

	Position expectedNextMove(Vector2(126, 20), 50, 50);
	Vector2 speed(-150, 0);
	Position validMove = validity.getValidMove(Position(Vector2(150, 20), 50, 50), speed);
	EXPECT_EQ(validMove, expectedNextMove)<< "Got: " << validMove.getX() << " " << validMove.getY();
}
Esempio n. 11
0
int main()
{
	char exp[100];

	printf ("Enter an expression \n");
	gets(exp);

	printf ("%s \n", exp);

	validity(exp);

	getch();

}
Esempio n. 12
0
main()
{
    stack s;
    char str[30],*p=NULL;
    int i;
    while(1)
    {
        printf("\nenter your expression : ");
        gets(str);
        init(&s,strlen(str));
        if(validity(&s,str))
        {
            printf("\nexpression is valid..so,");
            convert(&s,str);
        }
        else
            printf("\nexpression is invalid");
    }
    return 0;
}
// -----------------------------------------------------------------------------
// CSatNotifyCallControlRequest::CompleteAlphaId
// This method completes an outstanding asynchronous 
// NotifyCallControlRequest request. 
// -----------------------------------------------------------------------------
//
void CSatNotifyCallControlRequest::CompleteAlphaId
        (
        RSat::TAlphaIdBuf& aAlphaId, 
        RSat::TControlResult aResult,
        TInt aErrorCode                
        )
    {
    OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CSATNOTIFYCALLCONTROLREQUEST_COMPLETEALPHAID_1, "CSAT: CSatNotifyCallControlRequest::CompleteAlphaId");

	// Reset req handle. Returns the deleted req handle
    TTsyReqHandle reqHandle = iNotificationsTsy->iSatReqHandleStore->
		ResetTsyReqHandle( CSatTsy::ESatNotifyCallControlRequestPCmdReqType );
		
    // Check that someone has requested this notification
    if ( CSatTsy::ESatReqHandleUnknown != reqHandle )
        {
        if ( KErrNone == aErrorCode )
            {
            // Temporary storage for Alpha Id 
            RSat::TAlphaId alphaIdTemp;
            // Alpha ID validity
            RSat::TAlphaIdValidity validity( RSat::EValidAlpaId );
            alphaIdTemp.iStatus = RSat::EAlphaIdProvided;
            alphaIdTemp.iAlphaId.Copy( aAlphaId );
            // Fill the call control structure
            RSat::TCallControlV2& callControlV2 = ( *iCallControlV2Pckg )();
            // Set default control result
            callControlV2.SetCcGeneralResult( aResult );          
            callControlV2.SetAlphaId( validity, alphaIdTemp );  
            }
        OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CSATNOTIFYCALLCONTROLREQUEST_COMPLETEALPHAID_2,  "CSAT: CSatNotifyCallControlRequest::CompleteAlphaId completing" );
        // Complete notification
        iNotificationsTsy->iSatTsy->ReqCompleted( reqHandle, aErrorCode );
        }
    else
        {
        OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CSATNOTIFYCALLCONTROLREQUEST_COMPLETEALPHAID_3,  "CSAT: CSatNotifyCallControlRequest::CompleteAlphaId Request not ongoing" );
        }
    }
Esempio n. 14
0
RefPtr<DtlsIdentity> DtlsIdentity::Generate() {
    UniquePK11SlotInfo slot(PK11_GetInternalSlot());
    if (!slot) {
        return nullptr;
    }

    uint8_t random_name[16];

    SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), random_name,
                   sizeof(random_name));
    if (rv != SECSuccess)
        return nullptr;

    std::string name;
    char chunk[3];
    for (size_t i = 0; i < sizeof(random_name); ++i) {
        SprintfLiteral(chunk, "%.2x", random_name[i]);
        name += chunk;
    }

    std::string subject_name_string = "CN=" + name;
    UniqueCERTName subject_name(CERT_AsciiToName(subject_name_string.c_str()));
    if (!subject_name) {
        return nullptr;
    }

    unsigned char paramBuf[12]; // OIDs are small
    SECItem ecdsaParams = { siBuffer, paramBuf, sizeof(paramBuf) };
    SECOidData* oidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
    if (!oidData || (oidData->oid.len > (sizeof(paramBuf) - 2))) {
        return nullptr;
    }
    ecdsaParams.data[0] = SEC_ASN1_OBJECT_ID;
    ecdsaParams.data[1] = oidData->oid.len;
    memcpy(ecdsaParams.data + 2, oidData->oid.data, oidData->oid.len);
    ecdsaParams.len = oidData->oid.len + 2;

    SECKEYPublicKey *pubkey;
    UniqueSECKEYPrivateKey private_key(
        PK11_GenerateKeyPair(slot.get(),
                             CKM_EC_KEY_PAIR_GEN, &ecdsaParams, &pubkey,
                             PR_FALSE, PR_TRUE, nullptr));
    if (private_key == nullptr)
        return nullptr;
    UniqueSECKEYPublicKey public_key(pubkey);
    pubkey = nullptr;

    UniqueCERTSubjectPublicKeyInfo spki(
        SECKEY_CreateSubjectPublicKeyInfo(public_key.get()));
    if (!spki) {
        return nullptr;
    }

    UniqueCERTCertificateRequest certreq(
        CERT_CreateCertificateRequest(subject_name.get(), spki.get(), nullptr));
    if (!certreq) {
        return nullptr;
    }

    // From 1 day before todayto 30 days after.
    // This is a sort of arbitrary range designed to be valid
    // now with some slack in case the other side expects
    // some before expiry.
    //
    // Note: explicit casts necessary to avoid
    //       warning C4307: '*' : integral constant overflow
    static const PRTime oneDay = PRTime(PR_USEC_PER_SEC)
                                 * PRTime(60)  // sec
                                 * PRTime(60)  // min
                                 * PRTime(24); // hours
    PRTime now = PR_Now();
    PRTime notBefore = now - oneDay;
    PRTime notAfter = now + (PRTime(30) * oneDay);

    UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
    if (!validity) {
        return nullptr;
    }

    unsigned long serial;
    // Note: This serial in principle could collide, but it's unlikely
    rv = PK11_GenerateRandomOnSlot(slot.get(),
                                   reinterpret_cast<unsigned char *>(&serial),
                                   sizeof(serial));
    if (rv != SECSuccess) {
        return nullptr;
    }

    UniqueCERTCertificate certificate(
        CERT_CreateCertificate(serial, subject_name.get(), validity.get(),
                               certreq.get()));
    if (!certificate) {
        return nullptr;
    }

    PLArenaPool *arena = certificate->arena;

    rv = SECOID_SetAlgorithmID(arena, &certificate->signature,
                               SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0);
    if (rv != SECSuccess)
        return nullptr;

    // Set version to X509v3.
    *(certificate->version.data) = SEC_CERTIFICATE_VERSION_3;
    certificate->version.len = 1;

    SECItem innerDER;
    innerDER.len = 0;
    innerDER.data = nullptr;

    if (!SEC_ASN1EncodeItem(arena, &innerDER, certificate.get(),
                            SEC_ASN1_GET(CERT_CertificateTemplate))) {
        return nullptr;
    }

    SECItem *signedCert = PORT_ArenaZNew(arena, SECItem);
    if (!signedCert) {
        return nullptr;
    }

    rv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len,
                         private_key.get(),
                         SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
    if (rv != SECSuccess) {
        return nullptr;
    }
    certificate->derCert = *signedCert;

    RefPtr<DtlsIdentity> identity = new DtlsIdentity(Move(private_key),
            Move(certificate),
            ssl_kea_ecdh);
    return identity.forget();
}
      int
      process(const tendrils& i, const tendrils& o)
      {
        cv::Mat mask_resized = *mask;
        cv::Mat rvec, tvec, K;
        this->K->convertTo(K, CV_32F);
        R->convertTo(rvec, CV_32F);
        cv::Rodrigues(rvec.clone(), rvec);
        T->convertTo(tvec, CV_32F);
        cam_params->centerX = K.at<float>(0, 2);
        cam_params->centerY = K.at<float>(1, 2);
        cam_params->xRes = mask_resized.size().width;
        cam_params->yRes = mask_resized.size().height;
        cam_params->focalLength = K.at<float>(0, 0);

        //get the camera pose
        Eigen::Vector3f axis(rvec.at<float>(0), rvec.at<float>(1), rvec.at<float>(2));
        surfels::Transform3f objPose(Eigen::AngleAxisf(axis.norm(), axis.normalized()));
        objPose.pretranslate(Eigen::Vector3f(tvec.at<float>(0), tvec.at<float>(1), tvec.at<float>(2)));
        surfels::Transform3f camPose = objPose.inverse(Eigen::Isometry);
        //extract the cloud
        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
        cloud->resize(mask_resized.size().width * mask_resized.size().height);
        cloud->width = mask_resized.size().width;
        cloud->height = mask_resized.size().height;
        cvToCloudXYZ(*points3d, *cloud);
        //compute normals

        // Estimate normals
        pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
        pcl::PointCloud<pcl::Normal> result;
        ne.setNormalEstimationMethod(ne.AVERAGE_DEPTH_CHANGE);
        ne.setMaxDepthChangeFactor(0.02f);
        ne.setNormalSmoothingSize(10.0f);
        ne.setInputCloud(cloud);
        ne.compute(result);
        //copy into required structures
        boost::shared_ptr<boost::multi_array<Eigen::Vector3f, 2> > points(new boost::multi_array<Eigen::Vector3f, 2>());
        boost::shared_ptr<boost::multi_array<Eigen::Vector3f, 2> > normals(
            new boost::multi_array<Eigen::Vector3f, 2>());
        boost::shared_ptr<boost::multi_array<bool, 2> > canAdd(new boost::multi_array<bool, 2>());
        boost::shared_ptr<boost::multi_array<bool, 2> > validity(new boost::multi_array<bool, 2>());

        points->resize(boost::extents[cloud->width][cloud->height]);
        normals->resize(boost::extents[cloud->width][cloud->height]);
        canAdd->resize(boost::extents[cloud->width][cloud->height]);
        validity->resize(boost::extents[cloud->width][cloud->height]);

        for (unsigned int x = 0; x < cloud->width; x++)
        {
          for (unsigned int y = 0; y < cloud->height; y++)
          {
            bool mask_value = mask_resized.at<unsigned char>(y, x) > 0;
            pcl::Normal n = result(x, y);
            pcl::PointXYZ p = (*cloud)(x, y);
            (*points)[x][y] = Eigen::Vector3f(p.x, p.y, p.z);
            (*normals)[x][y] = Eigen::Vector3f(n.normal_x, n.normal_y, n.normal_z).normalized();
            (*validity)[x][y] = (*canAdd)[x][y] = mask_value;
          }
        }

        //fill in updatedata
        surfels::SurfelUpdateData update_data;
        update_data.currentTime = time++;
        update_data.camParams = *cam_params;
        update_data.camTransform = camPose;
        update_data.image = *image;
        update_data.pointGrid = points;
        update_data.normalGrid = normals;
        update_data.validityGrid = validity;
        update_data.willingToAdd = canAdd;

        //perform the update
        std::vector<bool> can_update(model->surfels.size(), true);
        std::vector<unsigned int> removed;
        surfels::updateSurfelModel(*model, update_data, *params, can_update, removed);
        return ecto::OK;
      }
static nsresult
GetAttestationCertificate(const UniquePK11SlotInfo& aSlot,
                          /*out*/ UniqueSECKEYPrivateKey& aAttestPrivKey,
                          /*out*/ UniqueCERTCertificate& aAttestCert,
                          const nsNSSShutDownPreventionLock& locker)
{
  MOZ_ASSERT(aSlot);
  if (NS_WARN_IF(!aSlot)) {
    return NS_ERROR_INVALID_ARG;
  }

  UniqueSECKEYPublicKey pubKey;

  // Construct an ephemeral keypair for this Attestation Certificate
  nsresult rv = GenEcKeypair(aSlot, aAttestPrivKey, pubKey, locker);
  if (NS_WARN_IF(NS_FAILED(rv) || !aAttestPrivKey || !pubKey)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to gen keypair, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  // Construct the Attestation Certificate itself
  UniqueCERTName subjectName(CERT_AsciiToName(kAttestCertSubjectName.get()));
  if (NS_WARN_IF(!subjectName)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to set subject name, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  UniqueCERTSubjectPublicKeyInfo spki(
    SECKEY_CreateSubjectPublicKeyInfo(pubKey.get()));
  if (NS_WARN_IF(!spki)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to set SPKI, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  UniqueCERTCertificateRequest certreq(
    CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr));
  if (NS_WARN_IF(!certreq)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to gen CSR, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  PRTime now = PR_Now();
  PRTime notBefore = now - kExpirationSlack;
  PRTime notAfter = now + kExpirationLife;

  UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
  if (NS_WARN_IF(!validity)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to gen validity, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  unsigned long serial;
  unsigned char* serialBytes =
    mozilla::BitwiseCast<unsigned char*, unsigned long*>(&serial);
  SECStatus srv = PK11_GenerateRandomOnSlot(aSlot.get(), serialBytes,
                                            sizeof(serial));
  if (NS_WARN_IF(srv != SECSuccess)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to gen serial, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }
  // Ensure that the most significant bit isn't set (which would
  // indicate a negative number, which isn't valid for serial
  // numbers).
  serialBytes[0] &= 0x7f;
  // Also ensure that the least significant bit on the most
  // significant byte is set (to prevent a leading zero byte,
  // which also wouldn't be valid).
  serialBytes[0] |= 0x01;

  aAttestCert = UniqueCERTCertificate(
    CERT_CreateCertificate(serial, subjectName.get(), validity.get(),
                           certreq.get()));
  if (NS_WARN_IF(!aAttestCert)) {
    MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
            ("Failed to gen certificate, NSS error #%d", PORT_GetError()));
    return NS_ERROR_FAILURE;
  }

  PLArenaPool* arena = aAttestCert->arena;

  srv = SECOID_SetAlgorithmID(arena, &aAttestCert->signature,
                              SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
                              /* wincx */ nullptr);
  if (NS_WARN_IF(srv != SECSuccess)) {
    return NS_ERROR_FAILURE;
  }

  // Set version to X509v3.
  *(aAttestCert->version.data) = SEC_CERTIFICATE_VERSION_3;
  aAttestCert->version.len = 1;

  SECItem innerDER = { siBuffer, nullptr, 0 };
  if (NS_WARN_IF(!SEC_ASN1EncodeItem(arena, &innerDER, aAttestCert.get(),
                                     SEC_ASN1_GET(CERT_CertificateTemplate)))) {
    return NS_ERROR_FAILURE;
  }

  SECItem* signedCert = PORT_ArenaZNew(arena, SECItem);
  if (NS_WARN_IF(!signedCert)) {
    return NS_ERROR_FAILURE;
  }

  srv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len,
                        aAttestPrivKey.get(),
                        SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
  if (NS_WARN_IF(srv != SECSuccess)) {
    return NS_ERROR_FAILURE;
  }
  aAttestCert->derCert = *signedCert;

  MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
          ("U2F Soft Token attestation certificate generated."));
  return NS_OK;
}
Esempio n. 17
0
  nsresult Generate()
  {
    nsresult rv;

    // Get the key slot for generation later
    UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
    if (!slot) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Remove existing certs with this name (if any)
    rv = RemoveExisting();
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Generate a new cert
    NS_NAMED_LITERAL_CSTRING(commonNamePrefix, "CN=");
    nsAutoCString subjectNameStr(commonNamePrefix + mNickname);
    UniqueCERTName subjectName(CERT_AsciiToName(subjectNameStr.get()));
    if (!subjectName) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Use the well-known NIST P-256 curve
    SECOidData* curveOidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1);
    if (!curveOidData) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Get key params from the curve
    ScopedAutoSECItem keyParams(2 + curveOidData->oid.len);
    keyParams.data[0] = SEC_ASN1_OBJECT_ID;
    keyParams.data[1] = curveOidData->oid.len;
    memcpy(keyParams.data + 2, curveOidData->oid.data, curveOidData->oid.len);

    // Generate cert key pair
    SECKEYPublicKey* tempPublicKey;
    UniqueSECKEYPrivateKey privateKey(
      PK11_GenerateKeyPair(slot.get(), CKM_EC_KEY_PAIR_GEN, &keyParams,
                           &tempPublicKey, true /* token */,
                           true /* sensitive */, nullptr));
    UniqueSECKEYPublicKey publicKey(tempPublicKey);
    tempPublicKey = nullptr;
    if (!privateKey || !publicKey) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Create subject public key info and cert request
    UniqueCERTSubjectPublicKeyInfo spki(
      SECKEY_CreateSubjectPublicKeyInfo(publicKey.get()));
    if (!spki) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }
    UniqueCERTCertificateRequest certRequest(
      CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr));
    if (!certRequest) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Valid from one day before to 1 year after
    static const PRTime oneDay = PRTime(PR_USEC_PER_SEC)
                               * PRTime(60)  // sec
                               * PRTime(60)  // min
                               * PRTime(24); // hours

    PRTime now = PR_Now();
    PRTime notBefore = now - oneDay;
    PRTime notAfter = now + (PRTime(365) * oneDay);
    UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
    if (!validity) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Generate random serial
    unsigned long serial;
    // This serial in principle could collide, but it's unlikely
    rv = MapSECStatus(PK11_GenerateRandomOnSlot(
           slot.get(), BitwiseCast<unsigned char*, unsigned long*>(&serial),
           sizeof(serial)));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Create the cert from these pieces
    UniqueCERTCertificate cert(
      CERT_CreateCertificate(serial, subjectName.get(), validity.get(),
                             certRequest.get()));
    if (!cert) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Update the cert version to X509v3
    if (!cert->version.data) {
      return NS_ERROR_INVALID_POINTER;
    }
    *(cert->version.data) = SEC_CERTIFICATE_VERSION_3;
    cert->version.len = 1;

    // Set cert signature algorithm
    PLArenaPool* arena = cert->arena;
    if (!arena) {
      return NS_ERROR_INVALID_POINTER;
    }
    rv = MapSECStatus(
           SECOID_SetAlgorithmID(arena, &cert->signature,
                                 SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Encode and self-sign the cert
    UniqueSECItem certDER(
      SEC_ASN1EncodeItem(nullptr, nullptr, cert.get(),
                         SEC_ASN1_GET(CERT_CertificateTemplate)));
    if (!certDER) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }
    rv = MapSECStatus(
           SEC_DerSignData(arena, &cert->derCert, certDER->data, certDER->len,
                           privateKey.get(),
                           SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Create a CERTCertificate from the signed data
    UniqueCERTCertificate certFromDER(
      CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &cert->derCert, nullptr,
                              true /* perm */, true /* copyDER */));
    if (!certFromDER) {
      return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
    }

    // Save the cert in the DB
    rv = MapSECStatus(PK11_ImportCert(slot.get(), certFromDER.get(),
                                      CK_INVALID_HANDLE, mNickname.get(),
                                      false /* unused */));
    if (NS_FAILED(rv)) {
      return rv;
    }

    // We should now have cert in the DB, read it back in nsIX509Cert form
    return GetFromDB();
  }