This had me scratching my head for awhile.
At first I thought that glGetRenderbufferParameterivOES would properly detect Retina screen at 960×640 but it keeps returning 480×320.

A little explanation on Retina screen first. Older devices have 320×480 screen resolution. With new iPhone 4 and iPod Touch 4G the screen has 640×960 but on the same physical area. This means that each pixel is 4 times as small.
To properly simulate older games resolutions iOS will replace each of your 320×480 game pixel by 4, this way your game will look identical.

So the API handles this differently. If you developed for iPad you notice that glGetRenderbufferParameterivOES return 1024×768 but not retina displays. Instead you have to check it yourself:

int w = 320;
int h = 480;
float ver = [[[UIDevice currentDevice] systemVersion] floatValue];
// You can't detect screen resolutions in pre 3.2 devices, but they are all 320x480
if (ver >= 3.2f)
	UIScreen* mainscr = [UIScreen mainScreen];
	w = mainscr.currentMode.size.width;
	h = mainscr.currentMode.size.height;
if (w == 640 && h == 960) // Retina display detected
        // Set contentScale Factor to 2
	self.contentScaleFactor = 2.0;
        // Also set our glLayer contentScale Factor to 2
	CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
	eaglLayer.contentsScale=2; //new line

Easy right? Remember, you must do this before calling glGetRenderbufferParameterivOES.
For touch positions just multiply each position by the scale factor.

I’ve only tested this on the simulator since I don’t own an iPhone 4 but it should work and detect either you are on a regular or retina screen.