Your constraints can be satisfied with 5 control points, probably with 4. If more control points are needed for subsequent modifications use InsertKnot to add knots and control points. InsertKnot does not change the shape of the curve.
Use two curves rather than one. Create horizontal helper lines on either side of the middle point, and have next to end control point for each curve on the helper lines. That insures middle point will be locally the highest point, and the curves will have tangency continuity. If you need curvature continuity use Match after confirming the control points are on the helper lines.
Your sketch should work just fine if you follow David Cockey’s advice and move your P2 and P3 to a horizontal line that passes through your point P. If the general shape of the curve you want to end up with is like you show then you should be able to get exactly what you want by moving P2 and P3 only along the horizontal line and P1 and P4 anywhere you like. It will take some iterative playing with the points. David’s suggestion of treating the two sides as separate curves with one end of each at point P will ensure that the finished curve will go through P and will make it easier to adjust each side independently. Keeping P2 and P3 locked to the horizontal line is extremely key to having the two sides tangent at point P. Once you get each side adjusted to your liking you can join the curves into one if you wish.
sorry for the late reply, Here is a cleaner and faster version:
private void RunScript(List<Point3d> pts, Point3d p, ref object A)
{
Plane perpFrame;
Plane horiFrame;
double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
var baseLine = new Line(pts[0], pts[5]).ToNurbsCurve();
baseLine.PerpendicularFrameAt(0.5, out perpFrame);
var perpLine = new Line(perpFrame.Origin, p);
baseLine.FrameAt(0.5, out horiFrame);
var tempPt = pts[2];
tempPt.Transform(Transform.Mirror(perpFrame));
pts[3] = tempPt;
var c = NurbsCurve.Create(false, 5, pts);
for (var i = 0; i < 300; i++)
{
Box bb;
c.GetBoundingBox(horiFrame, out bb);
var edge = new Rectangle3d(bb.Plane, bb.X, bb.Y).ToPolyline().SegmentAt(0);
var tp = edge.ClosestPoint(p, true);
var v = new Vector3d(p - tp);
pts[2] += v;
pts[3] += v;
tp = Intersection.CurveLine(c, edge, tol, tol)[0].PointA;
var tpPerpToPerpLine = perpLine.ClosestPoint(tp, true);
pts[3] += new Vector3d(tpPerpToPerpLine - tp);
c = NurbsCurve.Create(false, 5, pts);
if (p.DistanceTo(tp) < tol) break;
}
A = c;
}