A pure rotation always rotates around the origin. Meaning, that the center of rotation is always (0, 0, 0) of whatever local coordinate system the things you are rotating are defined in. Just like when you scale an object, the center of that scaling is also always (0, 0, 0).
In order to rotate an object around another center of rotation other than the origin (0, 0, 0), you gonna have to transform (i.e. translate) your desired center of rotation to that origin first, do the rotation, and then translate back.
So, no matter how you do it exactly, (e.g. a sequence of glRotatef() calls, encoding those rotations in a matrix or in a quaternion or in an axis-angle, or hell, even if you use 2D and Java 2D’s AffineTransform, it is exactly the same:
T^-1 x R x T
where R is your rotation and T is the translation to bring your desired center of rotation to the origin. Likewise, T^-1 denotes the “inverse” translation of T.