Question:
Do they have a yahoo Answers where you live?
2006-09-14 15:54:56 UTC
Do they have a yahoo Answers where you live?
43 answers:
badgurl
2006-09-14 16:43:14 UTC
nope, I usually go over to my neighbor's house to participate.
Ginger/Virginia
2006-09-14 15:57:43 UTC
Yahoo Answers is everywhere that the internet can reach. If you want an alternative to Yahoo Answers, call or go to your public library. They answer questions too (for free).
angela
2006-09-14 15:56:46 UTC
Yes, because Yahoo! Answers is on the WWW.

the

WORLD

Wide

Web.
Lara^mt
2006-09-14 16:04:38 UTC
no not me!! i have to climb up a mountain and meditate untill finally i get invisioned by the spirits of mount Imcachua which provide me with Yahoo Answers. i've been told to keep this a secret to my people of my villiage for yahoo answers holds a power - an evil power which my people may not be able to handle at least for now
reaching ♥ you
2006-09-14 15:55:57 UTC
Yes
Ms. Pelled Babby Schmidt
2006-09-14 15:57:54 UTC
Yeah, it's called Yahoo! Respuestas.
Pepper's Mommy
2006-09-14 15:57:25 UTC
Duhhhhhhhhhhhhh
blueyes2001
2006-09-14 15:57:28 UTC
Yes, I am on the east coast of the good ole USA
p.g
2006-09-14 18:12:43 UTC
Yup
onlyafewwillknow
2006-09-14 16:00:11 UTC
NO they don't.

Every time I answer a question I have to go across the border.
▒Яenée▒
2006-09-14 16:19:13 UTC
Yes I do think I do......I have seen it around. Even went there a few times.
nadaclue
2006-09-14 16:08:03 UTC
yes
nina buena
2006-09-14 15:56:58 UTC
yes
TheOnlyOne_05
2006-09-14 16:01:13 UTC
Yeah its called the internet



people that are tring to be silly are not half silly
uofsmike
2006-09-14 15:56:33 UTC
yes
babydqueenb43
2006-09-14 15:55:52 UTC
yes
marcus j
2006-09-14 15:55:33 UTC
yes
CrazySexyCool
2006-09-14 15:57:31 UTC
U again???? God!! When r u going to stop asking dumb questions!!! Yahoo Asnwers in on the INTERNET!!!! IT IS EVERYWHERE!!!!!!!!!
2006-09-14 16:05:34 UTC
why, no, they don't--and it is quite aggravating to have to jet-set all over the world just to use computers in a locale that does. off to singapore now...tah-tah!
Armerys
2006-09-14 15:57:41 UTC
Of course!
2006-09-14 15:57:36 UTC
Yes. How about you?
Dee I
2006-09-14 16:04:36 UTC
WORLD WIDE WEB mean anything to you!!! It's everywhere dude.
RASCUACHE
2006-09-14 15:58:08 UTC
yes in NM
mojojo66
2006-09-14 15:57:25 UTC
Hey everyone, this is the mentality that you'll be voting for if you vote for Liberals!
Jubei
2006-09-14 15:58:39 UTC
yes i have
preciousmoments1962
2006-09-14 15:55:38 UTC
I think it's everywhere my dear
2006-09-14 15:56:08 UTC
yeah
Kev32189
2006-09-14 15:57:01 UTC
no i never heard of it before.
jopuppy
2006-09-14 15:56:44 UTC
well i guess so because im on it right now.
notyours
2006-09-14 15:56:33 UTC
not on every corner
2006-09-14 15:56:36 UTC
yes, smartypants. They do.
2006-09-14 15:56:35 UTC
i think everybody as one it is on the internet...LOL
Comfortably Numb™
2006-09-14 15:56:34 UTC
nothing like that here
2006-09-14 15:56:22 UTC
yes you stupid head
blak2thgrin
2006-09-14 15:57:29 UTC
nope, bout you?
2006-09-14 15:55:51 UTC
DURR I'M HERE AREN'T I?
joalteeth
2006-09-14 15:55:39 UTC
not over here.
2006-09-14 15:55:46 UTC
No, and I'm glad they don't.
John J
2006-09-14 15:57:30 UTC
no
ND36
2006-09-14 15:57:53 UTC
ok wtf. you just wasted your points and gave everyone else 2. loserr
2006-09-14 16:01:27 UTC
23 October 2001

Source: Google archive of sci.crypt.



These are the messages Beale Screamer posted anonymously to newsgroup sci.crypt. Arranged chronologically here, but dates and times were probably assigned by the anonymous remailers.



Any messages missed, please tell: jya@pipeline.com







--------------------------------------------------------------------------------



Microsoft DRM - Technical description, 2001-10-18 09:10:41 PST



FreeMe source - Multiswap.c,h, 2001-10-18 15:34:26 PST



FreeMe source - ecc.c,h, 2001-10-18 15:40:26 PST



FreeMe source - msdrm.c,h, 2001-10-18 16:20:33 PST



FreeMe README file, 2001-10-18 16:26:19 PST



FreeMe source - main.c, 2001-10-18 16:31:25 PST





--------------------------------------------------------------------------------



Viewing message <17620O8I37182.4630787037@anonymous.poster>





From: Anonymous (anonymous@anonymous.poster.com)

Subject: Microsoft DRM - Technical description

Newsgroups: sci.crypt

Date: 2001-10-18 09:10:41 PST





-----BEGIN PGP SIGNED MESSAGE-----











Microsoft's Digital Rights Management Scheme - Technical Details



By "Beale Screamer"











This document describes version 2 of the Microsoft Digital Rights



Management (MS-DRM), as applied to audio (.wma files). The sources



for this material are varied, and some of the information might be



slightly incomplete; however, the fundamental ideas are solid and



easily verified. There is no attempt at describing the older version



1 of DRM. While version 1 is widely used (probably more widely than



version 2!), and the scheme is somewhat simpler, the purpose of this



is to describe the latest technology and not necessarily allow all



existing systems to be broken. The ideas described here are also



implemented in the software originally distributed with this document



(but as an independent piece, so the software may or may not be



available from where you have obtained this document), so a real



implementation can be examined. Not all of the information here is



needed in order to write the software that removes the encryption, but



some of the more interesting points surrounding the MS-DRM scheme and



software are given even if not necessary. Also note that no code is



included in this document, either real code or pseudo-code. All



that's in this document is a straight mathematical discussion, which



should be fully protected under the 1st Amendment to the



U.S. Constitution. I have no doubt that the corporate entities that



this document offends will attempt to suppress it, but I don't think



any argument they make could hold up to Constitutional scrutiny.







The basic components of MS-DRM involve use of elliptic curve



cryptography (ECC) for public key cryptography, DES for a block



cipher, RC4 for a stream cipher, and SHA-1 for a hash function. There



is also a block cipher which I haven't seen before, used in the MS-DRM



system to build a MAC, or keyed hash function. This cipher will be



explained completely below, and while the remaining algorithms are



well-known, more will be said about Microsoft's use of ECC below.







In the discussion and examples below, all numbers are expressed in



hexadecimal in the standard ordering (most-to-least significant)



unless otherwise stated. The actual bytes comprising large numbers in



any code are stored little endian, so at times it is convenient to



look at data in that ordering, and this will be clearly marked when it



is done.







One confusing item is that binary data sent back and forth is encoded



using Base64, but not using the standard algorithm! For some reason,



Microsoft has decided to use the non-alphanumeric character '*'



instead of '/', and '!' instead of '+' in some places, and in other



places they replace '/' with '@' and '!' with '%'. This means that



any software dealing with these strings cannot use a standard Base64



decoder, but must use a custom-build decoder.











FILES INVOLVED







Several key DLLs are kept in \windows\system that relate to the MS-DRM



scheme.







drmv2clt.dll: Provides basic DRM version 2 functionality







blackbox.dll: Provides basic, machine-specific crypto for MS-DRM.



Functionality replaced by IndivBox.key when the local



system has been "individualized."







The other interesting place for files is in \windows\All Users\DRM



(this location is not necessarily fixed but comes from the registry



entry HKEY_LOCAL_MACHINE\Software\Microsoft\DRM\DataPath). Here's a



sampling of some of the files in this directory (these are hidden



system files, so be sure to turn on "view all files" in order to see



them!):







IndivBox.key: Despite the extension, this is really a DLL



that is an "individualized" version of blackbox.dll







drmv2.lic: The file of licenses (a structured IStorage file)







drmv2.sst: "Secure state" for each of the licenses. Also an IStorage



file, but each stream is RC4 encrypted.







v2ks.bla: The version 2 "key store" - this is where all the public/private



keys are kept (encrypted, of course!).







v2ksndv.bla: The individualized version 2 "key store."











A SIMPLE BLOCK CIPHER (MULTISWAP)







Microsoft is using a very simple block cipher to create a message



authentication code (MAC). As this is not a standard algorithm, I



will describe it fully. The main operations in this cipher are



32-bit multiplications and swaps of the two halves of 32-bit words, so



I have called this cipher the "MultiSwap" cipher.







The MultiSwap cipher works on 64-bit blocks, using a key that consists



of 12 32-bit words, and a current state (or initialization vector)



that is 64-bits long. In the Microsoft implementation, the least



significant bits of all 12 words are set to 1, although once the



cipher is understood it is clear that really only 10 of the words



require this bit to be set. The basic operation of the cipher is a



transformation that is done on the first 32-bit word of the plaintext



block using the first 6 key words, and then repeated for the other



plaintext word and remaining key words.







Let k[0], k[1], k[2], k[3], k[4], and k[5] denote the first 6 key



words, and let s[0] and s[1] denote the two words of the state. To



transform a 32-bit input word x, first define the following function







f(a)=swap(swap(swap(swap(swap(a*k[0])*k[1])*k[2])*k[3])*k[4]) + k[5]







where * is multiplication modulo 2^(32), and "swap" is an operation



which exchanges the two 16-bit halves of a 32-bit word. The complete



transformation of a 32-bit word x then consists of s[1]=s[1]+f(x+s[0])



and s[0]=f(x+s[0]). This is first done with the value x set to the



first 32 bits of the input, and then repeated with x set to the second



32 bits and the using keys k[6] through k[11]. The output of the



block cipher is the new state s[0] and s[1].







The reason this block cipher can be inverted is because all the key



words are odd, which means they have multiplicative inverses modulo



2^(32). To invert f(), just do the operations in the reverse order:



first subtract off k[5], then do the multiply/swap operations with the



inverses of k[4] through k[0]. Notice that only the multiplicative



key words really need to be odd, so there is no reason for the least



significant bit of k[5] or k[11] to be set; however, Microsoft sets



these bits anyway.







This block cipher is never used for encryption, but is used to create



a message authentication code (MAC) in the standard way. Assuming the



length of the message to be hashed is a multiple of 8 bytes (64 bits),



the cipher is initialized with a state of all zeros, and then used to



encrypt the entire data. The output of the last block (the final



state) is the MAC for that message. This is used in computing packet



keys to encrypt protected content by MS-DRM, as will be explained



later.











ELLIPTIC CURVE CRYPTOGRAPHY







For ECC, Microsoft is using an elliptic curve over Zp, where p is a



160 bit prime number (given below). The curve consists of the points



that lie on the curve y^2=x^3+ax+b, where the operations are done over



the field Zp and a and b are coefficients that are given below.







All values are represented as packed binary values: in other words, a



single value over Zp is encoded simply as 20 bytes, stored in little



endian order. A point on the elliptic curve is therefore a 40 byte



block, which consists of two 20 byte little endian values (the x



coordinate followed by the y coordinate). Here are the parameters for



the elliptic curve used in MS-DRM:







p (modulus): 89abcdef012345672718281831415926141424f7



coefficient a: 37a5abccd277bce87632ff3d4780c009ebe41497



coefficient b: 0dd8dabf725e2f3228e85f1ad78fdedf9328239e



generator x: 8723947fd6a3a1e53510c07dba38daf0109fa120



generator y: 445744911075522d8c3c5856d4ed7acda379936f



Order of curve: 89abcdef012345672716b26eec14904428c2a675







These constants are fixed, and used by all parties in the MS-DRM



system. The "nerd appeal" of the modulus is high when you see this



number in hexadecimal: it includes counting in the hexadecimal, as



well as the digits of fundamental constants e, pi, and sqrt(2).







In order to use this public key system, any user must have a



private/public key pair. Since the security of the system relies



pretty heavily on the private keys remaining secret (even from the



user of the system on which they reside), they are carefully hidden.



In fact, there are keys hidden in various files that are used,



including blackbox.dll, v2ks.bla, and IndivBox.key. For example, once



the player has been individualized, IndivBox.key is created, and there



are at least two keys embedded into this file: a 64-bit key used for



RC4, and a 160-bit private key for use in ECC. The ECC private key is



used as the basic client key (the corresponding public key is stored



unencrypted in the key store file, and used as the initial part of the



"client id" sent when requesting a license), and additional key pairs



are stored in part of the keystore file (v2ks.bla or v2ksndv.bla),



encrypted with the RC4 key.







These secret keys are stored in linked lists that contain 32 bits per



node (so the key as a whole is not in contiguous memory), interspersed



with the code in the library (IndivBox.key for example). The idea is



that they can be read by that library, used internally by that



library, and never communicated outside the library. Since the



IndivBox.key file is shuffled in a random way for each client, these



keys would be extremely difficult to extract from the file itself.



Fortunately, we don't have to: these keys are part of the object state



that is maintained by this library, and since the offset within this



object of these secret keys is known, we can let the library itself



extract the secret keys! The code for this simply loads up the "black



box" library, has it initialize an instance of the object, and then



reads the keys right out of that object. This is clearly a weakness



in the code which can be corrected by the DRM software fairly easily,



but for now it is the basis of our exploit.











GETTING A LICENSE







Each protected media file is encrypted with a "content key" that will



unlock the packets of the media stream. We describe briefly how a



license (containing a content key) is obtained for information



purposes, but the license acquisition protocol is not really important



for unlocking that content. Simply use the MS Media player, have it



request and decrypt the licenses, store them in drmv2.lic, and then we



can extract them directly from that file.







A protected media file is apparently recognized by the presence of a



DRMV2 object in the .wma file header. This object has GUID



298ae614-2622-4c17-b935-dae07ee9289c, and contains an XML object 6



bytes into the data part of the object. Among other things, this



header contains a "KID" element identifying the key used to unlock the



content. The drmv2.lic file is then checked to see if a license with



this KID exists locally. If the license doesn't exist, a license



request is formed, which sends an encrypted "client id" to the license



server. This is sent as a "challenge," which consists of 168 bytes in



the MS-Base64 encoding. The first 80 bytes are two ECC points, which



make up an ECC encrypted random session key, and the remaining 88



bytes are the "client id" encrypted using RC4 and the session key.



The ECC encryption is done using a public key that seems to be fixed



for all clients, so it is safe to assume that this corresponds to a



private key that is common to all license servers and built in to that



side of the system (without access to the server side code, it was



impossible to find the corresponding private key).







After some interaction, the license comes back as mime type



application/x-drm-v2, as an escaped XML-encoded license in the



following format











...base64 encoded license...








where x.x.x.x is most likely "2.0.0.0". To make things tricky for a



sniffer, the license is actually RC4 encrypted using the same session



key that was established by the client when sending the challenge.



The client then decrypts the license and stores it in the drmv2.lic



file.











GETTING THE CONTENT KEY







Getting the content key from a license is pretty easy once the client



knows what its public/private key pairs are, and has a copy of the



license obtained from drmv2.lic. The license entry is an XML object



with an element for "ENABLINGBITS", which has sub-elements ALGORITHM



(which should have type "MSDRM"), PUBKEY, VALUE, and SIGNATURE. The



PUBKEY element should match one of the client's public keys, or else



there a problem! The VALUE element is the ECC-encrypted content key,



which can be decrypted by the private key that corresponds to the



given PUBKEY.







The content key has a specific format: the y coordinate is ignored,



and when the x coordinate is written in storage order (little endian),



the first byte is the length of the content key (which may always be



7), which is followed by that many bytes of the content key. While



the content key is tied to the encoded media file (which may be common



to many users), the enabling bits value will be different for each



user, and tied to that user's public/private keys. Because of this,



licenses are not transferable from one user to another, even though



the media files themselves are (the new user must obtain his own



license from the license server).







We go through an example now of finding a content key. In this



example, we have identified our public and private keys as the



following values:







Public key x: 1957f96f3327a25bba52166ad7fcc74087b9734b



Public key y: 8939e1b1ed988182d34d17ebbcb0e03a82d062e7







Private key: 757ff01b853496452eea0b0646c3a357a6f33509







We're looking at a file RIAALuvsMe.wma, and find in the header the



following bit of XML:







nA67jM7dNGIUQIkP5v7hSQ==







The actual KID seems to be a Base64 encoding of a GUID, but it is



treated as a string (uninterpreted) by the software, so the origin



doesn't seem to make much difference.







The license is inside the drmv2.lic file, which is a structured "DOC



file", meaning it can be accessed through the IStorage and IStream



interfaces (and it can be browsed by the Microsoft Visual Studio "DOC



File Viewer" tool if you're curious). The top level drmv2.lic file



has a lower-level IStorage object for each KID, which can contain a



set of licenses for each KID. In order to guarantee valid IStorage



names, the KID is first processed to change all '/' characters to '@',



and all '!' to '%'. The names of the IStream objects containing the



licenses again look like Base64 encoded GUIDs, which turn out to be



the LID (license ID?) element stored in the license. This can be



verified once the license is obtained, but we're not sure how to



generate LID's from the content header information, and so can't



directly open the appropriate LID stream. Instead, we simply



enumerate through all available streams for this KID, testing each one



for a PUBKEY element (see below) that we know. This is taken to be



the license for this content. While this is really just a guess as to



the proper workings, it seems to work fine in all our tests.







Inside the license we find the following XML (this has been formatted



so that it's easier to look at - in the actual file this would all be



on one line).



















S3O5h0DH*NdqFlK6W6InM2*5VxnnYtCCOuCwvOsXTdOCgZjtseE5iQ==











VEsbPedfwrybrpkg0fhoOfe5eB9ef0R7QTxgX7NbtMIFK!h*4Pk7ek



PUqlDIRqYwQkgCGE0r0qtQdCUYszT!b7XedCIpsApQjstaFmafahM=











KpxCm6lSXH8dTPI359jToftSEuLiP9v*zpHAy!kDEhlYkw6mkfQzlg==















The SIGNATURE element above is just random garbage. We didn't make a



real signature for this example (among other things, we don't have a



certified public key, which would have to follow this in a real



license. Requiring such a signature keeps people from creating their



own licenses, since only those that have been issued valid



certificates can do so).







First look at the PUBKEY part. If this is run through a Base64



decoder (modified for the MS character set as described earlier) you



get the following binary values, shown below as a memory dump:







0000: 4B 73 B9 87 40 C7 FC D7 6A 16 52 BA 5B A2 27 33



0010: 6F F9 57 19 E7 62 D0 82 3A E0 B0 BC EB 17 4D D3



0020: 82 81 98 ED B1 E1 39 89







Notice how this is exactly our public key from above, stored in little



endian order! So this license is for our machine.







Next, take the VALUE element above, run it through a Base64 decoder,



and interpret the 80 byte result as 4 20-byte values stored in little



endian order. These four numbers are as follows:







Encrypted u.x: & 1f78b9f73968f8d12099ae9bbcc25fe73d1b4b54



u.y: & 7a3bf9e07fe82b05c2b45bb35f603c417b447f5e



v.x: & 18257450abd22b4d1802484230a646c850aad443



v.y: & 136a9f66165acb8e500ab0292274deb56ffe34b3







To decrypt this value, first we multiply the point u by our private



key, resulting in the point







x: 399c72d525a9b65b7543a3e3adc88ce0f6a38db5



y: 66cfa6bdbfbb93b906b22deb36792363d8e8adc2







and then subtract this point from v to get







x: c91590616b4b3707



y: 753e24e50d437e147b4998376f163dc27b639a7a







Since x is so short, we have almost certainly gotten our content key.



Writing in storage order (little endian), x is







0000: 07 37 4B 6B 61 90 15 C9







which means that the content key has length 7 (from the first byte),



and the actual key is the string of bytes 374B6B619015C9.











DECRYPTING THE CONTENT







The content encryption process is simpler to explain than decryption,



so we start with that. The content key is not used directly, but is



processed for several different uses. First, the content key is



hashed using the SHA-1 hashing algorithm, producing a 20-bit output.



The first 12 bytes of this output are used as an RC4 key, and a block



of 16 words (or 64 bytes) of zeros is encrypted. The least



significant bits of the first 12 words of this output are all set, and



are used as the MultiSwap key. The next 2 words are the encryption



in-whitening mask and the next 2 words are the encryption



out-whitening mask (this will be explained later). The last 8 bytes



of the original SHA-1 hash output are used as a DES key.







To encrypt the content so that packets can be accessed randomly (for



seeks), the content cannot be encrypted as one single stream.



However, to strengthen the cipher we also don't want to re-use the



same key for every packet. To satisfy both of these goals, MS-DRM



uses the following scheme to encrypt a packet: First, the packet (with



size rounded down to a multiple of 8 bytes) is run through



MultiSwapMAC to produce a 64-bit MAC. For some reason, the 32-bit



halves of this MAC are swapped before further processing. Next, the



entire packet is RC4 encrypted using the swapped MAC as an 8-byte RC4



key. The 8-byte MAC (with swapped halves) is then run through a



"whitened DES" by first XORing with the in-whitening mask, then



running through DES (using the DES key from the last paragraph), and



then XORing the result with the out-whitening mask. The resulting 8



bytes are then placed in the final encrypted packet, overwriting the



last full 8-byte block (not the last 8 bytes of the packet, but



blocking the packet from the beginning into 8 byte pieces, and



overwriting the last full piece).







To decrypt such a packet, first locate the last full 8-byte block, run



it through the whitened DES decryption, and the result is used as an



RC4 key to decrypt the packet. This will produce the correct packet



except for 8 bytes: those in the position of the last full 8-byte



block are wrong, since they were overwritten in the last phase of the



encryption. However, by swapping the halves of the RC4 key, we have



the MAC for the original packet up to and including the original bytes



in this position. Since the MAC is actually created out of a block



cipher, we can recover the original 8 bytes as follows: run the entire



packet through MultiSwapMAC up to the block in question, but not



including it. This output is the next-to-last state seen by



MultiSwapMAC in the encryption MAC computation, and we just recovered



the final output of the MAC, so we can put these two values into the



block cipher decryption to obtain the original data of this 8-byte



block. The original 8-bytes are placed back into the packet, and now



the entire original contents are restored!







This is a pretty clever scheme: by using a MAC constructed from a



block cipher, individual packet keys can be computed and encoded into



the encrypted packet with absolutely no increase in space, and since



the size is maintained nothing in the structure of the content file



(describing packet sizes or other parameters) needs to be changed at



all. The encrypted content can be completely transparent to



applications that deal with .wma files in a non-content-sensitive



manner.







We finish this section showing an example of content decryption, using



the content key from the previous paragraph. We first process the



content key by running it through SHA-1 to obtain







15 CB 92 F9 97 2E C8 75 29 4F 12 65 36 B6 C6 DB AC A2 40 35







The first 12 bytes are used as an RC4 key to encrypt a block of all



zeros, giving







0000: 80 0A 2D 48 D1 FD 7E ED 83 69 4A 7D A5 D5 EE C4



0010: 4E E1 64 52 D1 71 98 26 9A F3 14 E3 51 C8 B6 92



0020: D4 93 E4 57 97 6D 63 EF 0E 06 07 54 F7 DD ED 38



0030: E8 CA A0 D0 83 13 F1 DB C1 70 AE 56 61 7D FB 94







The first 48 bytes are interpreted as 12 32-bit words, stored little



endian, and are saved as the MultiSwap key after setting all least



significant bits. So the key values are k[0]=0x482D0A81,



k[1]=0xED7EFDD1, etc. The last 16 bytes of the RC4-encrypted block



are the whitening masks for DES, and the key for DES is given as the



last 8 bytes of the SHA-1 hash value.







Assume we get a packet with size 1450 bytes, which is 181 8-byte



blocks followed by 2 additional bytes. Numbering the byte positions



as 0 through 1449, we look at the bytes in positions 1440 through 1447



(the last full 8-byte block), and find that they are







A8 49 65 36 A2 33 18 09







XORing with the encryption out-whitening mask (the last 8 bytes from



the RC4-encrypted block above) we get







69 39 CB 60 C3 4E E3 9D







and decrypting with DES using key 36 B6 C6 DB AC A2 40 35 gives







FD EF 98 7D 8B 77 72 FD







and finally XORing with the encryption in-whitening mask (the



next-to-last 8-byte piece in the RC4-encrypted block above) gives







15 25 38 AD 08 64 83 26







This is then used as an RC4 key to decrypt the packet. To replace



bytes at positions 1440 through 1447 with the correct values, take



the RC4 value and swap the words around to get







08 64 83 26 15 25 38 AD







This is the MultiSwapMAC of the input packet using bytes 0 through



1447. We run bytes 0 through 1439 through MultiSwapMAC to get







D9 F7 D9 53 A9 6E 14 D9







and then use this as the state input, along with the original MAC



output as the data input to the MultiSwapDecode function to obtain







DA 05 D8 EB 97 FE 1E 7B







These 8 bytes are placed in positions 1440 through 1447, and then the



entire original packet is restored.











OTHER ISSUES







Communication between different DLL modules is encrypted and checked



at multiple points. This works roughly as follows: Objects are



initialized with communication parameters by sending certified public



keys to the object you want to communicate with. The second object



verifies these certificates, generates a random session key (which it



uses to generate a MultiSwap key in addition to the use as a session



key), and sends the encrypted session key back to the calling object.



Future "sensitive communication" is RC4 encrypted with the session key,



and run through MultiSwapMAC to verify integrity (after padding with



zeros to make the data a multiple of 64 bits). This is done for data



sent both to and from the object.







Presumably, this is done so that anyone monitoring parameters passed



between DLL modules wouldn't see any "sensitive data," although its



use for this purpose is pretty limited. However, it does lead to some



interesting and strange situations: when blackbox is sent a packet to



decrypt, it decrypts it, and then immediately *re-encrypts* it using



the session key to send it back to the media player! So in decrypting



a packet, the computer actually goes through a decrypt/encrypt/decrypt



sequence of operations!







One very important effect of this scheme is that Microsoft fully



controls who gets to write modules that interact with the basic



Microsoft media modules. Without a certified public key (and the



corresponding private key) it is impossible to write a compatible DLL



that interfaces with their code. Since Microsoft controls the issuing



of certified public keys, they also have complete control over who is



allowed to make compatible and competing products. Microsoft's



reputation for being generous to competitors is well-known, so this



effectively gives Microsoft a technically guaranteed monopoly power.







Of course, these certificates and private keys must be distributed



with any "Microsoft blessed" software as well, and in fact exist in



the media player and blackbox DLLs. They're not hard to extract, if



you know where to look, but I won't give them here. They would be of



limited use anyway, since Microsoft also has a "revocation list"



mechanism built in to the Media player software, meaning that they can



revoke any of these certificates at their whim, remotely disabling any



software that depends on that certificate for communication.























-----BEGIN PGP SIGNATURE-----



Version: 2.6.2







iQCVAwUBO5qt3JCr1f2GXCalAQE8ygP9Gb4Dm0ZQ5GePjAIfMFyqYVtUNSUUfj7A



3ZLwbMwUtnRHeYDGWRJEqvJMPf4SujKHcwQL3LtefrhH7dOn6r4AyUQV6ymezpd/



AMY53ONufawU+T8YgilEe2WCDRc4Y/uDbQFZIhcPQ+H78nzFSvdj+FzQ7pKrxsIr



QWe1ZNP4xfY=



=WL0q



-----END PGP SIGNATURE-----





______________________________________________________________________________

Posted Via Binaries.net = SPEED+RETENTION+COMPLETION = http://www.binaries.net



--------------------------------------------------------------------------------



From: Frog2 (FrogRemailer@NoReply.Invalid.com)

Subject: FreeMe source - Multiswap.c,h

Newsgroups: sci.crypt

Date: 2001-10-18 15:34:26 PST





Split into .c and .h files



--------------------- Start of MultiSwap.h ----------------------



#if !defined( _MULTISWAP_H_ )

#define _MULTISWAP_H_



typedef struct multiswapkey_st {

struct {

int multikey[5];

int multiinv[5];

int additive;

} round[2];

} MULTISWAPKEY;



void MultiSwapSetKey(MULTISWAPKEY * out, unsigned int *datain);

void MultiSwapEncode(MULTISWAPKEY * key, unsigned int *state,

unsigned int *datain, unsigned int *dataout);

void MultiSwapMAC(MULTISWAPKEY * key, unsigned int *data, int num64bits,

unsigned int *out);

void MultiSwapDecode(MULTISWAPKEY * key, unsigned int *state,

unsigned int *datain, unsigned int *dataout);



#endif



--------------------- Start of MultiSwap.c ----------------------



#include "MultiSwap.h"





static int mod232inv(int x)

{

int rval = x;

int i;



for (i = 0; i < 30; i++)

rval *= rval * x;



return rval;

}





void MultiSwapSetKey(MULTISWAPKEY * out, unsigned int *datain)

{

int i;



for (i = 0; i < 5; i++) {

out->round[0].multikey[i] = datain[i] | 1;

out->round[0].multiinv[i] = mod232inv(datain[i] | 1);

out->round[1].multikey[i] = datain[6 + i] | 1;

out->round[1].multiinv[i] = mod232inv(datain[6 + i] | 1);

}



/* Note that the "| 1" part isn't necessary here, since we don't

* need multiplicative inverses. But they do it anyway!

*/



out->round[0].additive = datain[5] | 1;

out->round[1].additive = datain[11] | 1;

}





void MultiSwapEncode(MULTISWAPKEY * key, unsigned int *state,

unsigned int *datain, unsigned int *dataout)

{

unsigned int cst = state[0];



cst += datain[0];

cst *= key->round[0].multikey[0];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multikey[1];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multikey[2];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multikey[3];

cst = (cst >> 16) | (cst << 16);

cst = cst * key->round[0].multikey[4] + key->round[0].additive;

dataout[1] = cst + state[1];



cst += datain[1];

cst *= key->round[1].multikey[0];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multikey[1];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multikey[2];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multikey[3];

cst = (cst >> 16) | (cst << 16);

cst = cst * key->round[1].multikey[4] + key->round[1].additive;

dataout[1] += cst;



dataout[0] = cst;

}





void MultiSwapMAC(MULTISWAPKEY * key, unsigned int *data, int num64bits,

unsigned int *out)

{

unsigned int state[2];

unsigned int newstate[2] = { 0, 0 };

int i;



for (i = 0; i < num64bits; i++) {

state[0] = newstate[0];

state[1] = newstate[1];

MultiSwapEncode(key, state, data + 2 * i, newstate);

}



out[0] = newstate[0];

out[1] = newstate[1];

}





void MultiSwapDecode(MULTISWAPKEY * key, unsigned int *state,

unsigned int *datain, unsigned int *dataout)

{

unsigned int cst = datain[0];

unsigned int tmp;



dataout[1] = datain[1] - cst;

cst = (cst - key->round[1].additive) * key->round[1].multiinv[4];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multiinv[3];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multiinv[2];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multiinv[1];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[1].multiinv[0];

tmp = dataout[1] - state[1];

dataout[1] = cst - tmp;

cst = tmp;



cst = (cst - key->round[0].additive) * key->round[0].multiinv[4];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multiinv[3];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multiinv[2];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multiinv[1];

cst = (cst >> 16) | (cst << 16);

cst *= key->round[0].multiinv[0];



dataout[0] = cst - state[0];

}



--------------------------------------------------------------------------------



From: Nomen Nescio (nobody@dizum.com)

Subject: FreeMe source - ecc.c,h

Newsgroups: sci.crypt

Date: 2001-10-18 15:40:26 PST





Split into .c and .h files



--------------------- Start of ecc.h ----------------------



#if !defined( _ECC_H )

#define _ECC_H



#include



/*

* If the "neg" field of the BIGNUM struct is set, then this point is

* the identity. This is a terrible way to do this, since it's not

* clear what the future of this flag is -- however, for now it works,

* and it's fast...

*/



typedef struct eccpt_st {

BIGNUM *x, *y;

} ECCpt;



typedef struct eccparam_st {

BIGNUM *modulus; /* Curve is over Z_modulus */

BIGNUM *a, *b; /* Curve coefficients */

ECCpt generator; /* Generator for our operations */

ECCpt pubkey; /* Public key */

BIGNUM *privkey; /* Corresponding private key */

} ECC;





ECC *ECC_new_set(BIGNUM * p, BIGNUM * a, BIGNUM * b, ECCpt g);

void ECC_free(ECC * ecc);

void ECCpt_init(ECCpt * pt);

void ECCpt_free(ECCpt * pt);

int ECCpt_is_valid_pt(ECCpt * a, ECC * ecc);

int ECCpt_is_equal(ECCpt * a, ECCpt * b);

void ECCpt_add(ECCpt * r, ECCpt * a, ECCpt * b, ECC * ecc);

void ECCpt_mul(ECCpt * r, ECCpt * a, BIGNUM * n, ECC * ecc);



#endif



--------------------- Start of ecc.c ----------------------



/* General purpose elliptic curve routines. */



#include

#include

#include "ecc.h"





static int ECC_param_ok(BIGNUM * p, BIGNUM * a, BIGNUM * b)

{

BIGNUM *tmp1, *tmp2;

BN_CTX *ctx;

int retval;



if ((p == NULL) || (a == NULL) || (b == NULL))

return 0;



tmp1 = BN_new();

tmp2 = BN_new();

ctx = BN_CTX_new();



BN_mod_mul(tmp1, a, a, p, ctx);

BN_mod_mul(tmp1, tmp1, a, p, ctx);

BN_lshift(tmp1, tmp1, 2);

BN_mod(tmp1, tmp1, p, ctx);



tmp2 = BN_new();

BN_set_word(tmp2, 27);

BN_mod_mul(tmp2, tmp2, b, p, ctx);

BN_mod_mul(tmp2, tmp2, b, p, ctx);



BN_add(tmp2, tmp1, tmp2);

BN_mod(tmp2, tmp2, p, ctx);



retval = !BN_is_zero(tmp2);



BN_CTX_free(ctx);

BN_free(tmp1);

BN_free(tmp2);



return retval;

}





ECC *ECC_new_set(BIGNUM * p, BIGNUM * a, BIGNUM * b, ECCpt g)

{

ECC *ecc;



if (!ECC_param_ok(p, a, b))

return NULL;



ecc = malloc(sizeof(ECC));

if (ecc != NULL) {

ecc->modulus = BN_dup(p);

ecc->a = BN_dup(a);

ecc->b = BN_dup(b);

ecc->generator.x = BN_dup(g.x);

ecc->generator.y = BN_dup(g.y);

ecc->pubkey.x = ecc->pubkey.y = NULL;

ecc->privkey = NULL;

}



return ecc;

}





void ECC_free(ECC * ecc)

{

if (ecc != NULL) {

BN_free(ecc->modulus);

ecc->modulus = NULL;

BN_free(ecc->a);

ecc->a = NULL;

BN_free(ecc->b);

ecc->b = NULL;

BN_free(ecc->generator.x);

ecc->generator.x = NULL;

BN_free(ecc->generator.y);

ecc->generator.y = NULL;

if (ecc->pubkey.x != NULL) {

BN_free(ecc->pubkey.x);

ecc->pubkey.x = NULL;

BN_free(ecc->pubkey.y);

ecc->pubkey.y = NULL;

}

if (ecc->privkey != NULL) {

BN_free(ecc->privkey);

ecc->privkey = NULL;

} free(ecc);

}

}





void ECCpt_init(ECCpt * pt)

{

pt->x = BN_new();

pt->y = BN_new();

}





void ECCpt_free(ECCpt * pt)

{

BN_free(pt->x);

pt->x = NULL;

BN_free(pt->y);

pt->y = NULL;

}





int ECCpt_is_valid_pt(ECCpt * a, ECC * ecc)

{

/* check that y^2 = x^3 + a x + b */

BIGNUM *tmp1, *tmp2;

BN_CTX *ctx;

int retval;



ctx = BN_CTX_new();

tmp1 = BN_dup(a->x);

BN_mod_mul(tmp1, tmp1, tmp1, ecc->modulus, ctx);

BN_add(tmp1, tmp1, ecc->a);

BN_mod_mul(tmp1, tmp1, a->x, ecc->modulus, ctx);

BN_add(tmp1, tmp1, ecc->b);

if (BN_cmp(tmp1, ecc->modulus) >= 0)

BN_sub(tmp1, tmp1, ecc->modulus);



tmp2 = BN_dup(a->y);

BN_mod_mul(tmp2, tmp2, tmp2, ecc->modulus, ctx);



retval = (BN_cmp(tmp1, tmp2) == 0);

BN_free(tmp1);

BN_free(tmp2);

BN_CTX_free(ctx);

return retval;

}





int ECCpt_is_equal(ECCpt * a, ECCpt * b)

{

if (a->x->neg && b->x->neg)

return 1;

return ((BN_cmp(a->x, b->x) == 0) && (BN_cmp(a->y, b->y) == 0));

}





void ECCpt_add(ECCpt * r, ECCpt * a, ECCpt * b, ECC * ecc)

{

BN_CTX *ctx;

BIGNUM *tmp1, *tmp2;

BIGNUM *lambda;



if (a->x->neg) {

BN_copy(r->x, b->x);

BN_copy(r->y, b->y);

return;

}



if (b->x->neg) {

BN_copy(r->x, a->x);

BN_copy(r->y, a->y);

return;

}



tmp1 = BN_new();

if (BN_cmp(a->x, b->x) == 0) {

BN_add(tmp1, a->y, b->y);

if (BN_cmp(tmp1, ecc->modulus) == 0) {

BN_free(tmp1);

r->x->neg = 1; /* Set to identity */

return;

}

}



ctx = BN_CTX_new();

tmp2 = BN_new();

lambda = BN_new();

if (ECCpt_is_equal(a, b)) {

BN_set_word(tmp1, 3);

BN_mod_mul(tmp1, tmp1, a->x, ecc->modulus, ctx);

BN_mod_mul(tmp1, tmp1, a->x, ecc->modulus, ctx);

BN_add(tmp1, tmp1, ecc->a);

BN_mod(tmp1, tmp1, ecc->modulus, ctx);

BN_lshift1(tmp2, a->y);

BN_mod_inverse(tmp2, tmp2, ecc->modulus, ctx);

BN_mod_mul(lambda, tmp1, tmp2, ecc->modulus, ctx);

} else {

BN_sub(tmp1, b->x, a->x);

if (tmp1->neg)

BN_add(tmp1, ecc->modulus, tmp1);

tmp2 = BN_mod_inverse(NULL, tmp1, ecc->modulus, ctx);

BN_sub(tmp1, b->y, a->y);

if (tmp1->neg)

BN_add(tmp1, ecc->modulus, tmp1);

BN_mod_mul(lambda, tmp1, tmp2, ecc->modulus, ctx);

}



BN_mod_mul(tmp1, lambda, lambda, ecc->modulus, ctx);

BN_sub(tmp1, tmp1, a->x);

if (tmp1->neg)

BN_add(tmp1, ecc->modulus, tmp1);

BN_sub(tmp2, tmp1, b->x);

if (tmp2->neg)

BN_add(tmp2, ecc->modulus, tmp2);



BN_sub(tmp1, a->x, tmp2);

if (tmp1->neg)

BN_add(tmp1, ecc->modulus, tmp1);

BN_mod_mul(tmp1, lambda, tmp1, ecc->modulus, ctx);

BN_sub(r->y, tmp1, a->y);

if (r->y->neg)

BN_add(r->y, ecc->modulus, r->y);



BN_free(r->x);

r->x = tmp2;

tmp2 = NULL;



BN_free(lambda);

BN_free(tmp1);

BN_CTX_free(ctx);

}





void ECCpt_mul(ECCpt * r, ECCpt * a, BIGNUM * n, ECC * ecc)

{

ECCpt tmp;

int numbits, i;



tmp.x = BN_dup(a->x);

tmp.y = BN_dup(a->y);

r->x->neg = 1;

numbits = BN_num_bits(n);

for (i = numbits - 1; i >= 0; i--) {

if (BN_is_bit_set(n, i))

ECCpt_add(r, r, &tmp, ecc);

if (i > 0)

ECCpt_add(r, r, r, ecc);

}

}



--------------------------------------------------------------------------------



Viewing message





From: Anonymous Coredump (mixmaster@remailer.segfault.net)

Subject: FreeMe source - msdrm.c,h

Newsgroups: sci.crypt

Date: 2001-10-18 16:20:33 PST





Split into .c and .h files



--------------------- Start of msdrm.h ----------------------



#if !defined( _MSDRM_H_ )

#define _MSDRM_H_



#include

#include "ecc.h"

#include "MultiSwap.h"



typedef unsigned char uchar;



#define MS_BN_LEN 20



typedef struct ms_bn_st {

uchar d[MS_BN_LEN];

} MS_BN;



typedef struct ms_eccpt_st {

MS_BN x, y;

} MS_ECCpt;



typedef struct contkey_st {

uchar ckey[MS_BN_LEN];

int ckeylen;

uchar keyhash[20];

des_key_schedule keysched;

uchar outmask[8];

uchar inmask[8];

MULTISWAPKEY hashkey;

} CONTKEY;



wchar_t *get_element(wchar_t * tag, wchar_t * str);

void MSDRM_decr_packet(uchar * data, int len, CONTKEY * ckey);

CONTKEY *MSDRM_init(wchar_t * license);



extern struct globalinfo_st {

int verbose;

void *fileheader;

char *ofname;

int packetlen;

int numpackets;

CONTKEY *content_key;

wchar_t *kid;

int hasV1header;

int hasV2header;

} globalinfo;



#endif



--------------------- Start of msdrm.c ----------------------



#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "ecc.h"

#include "msdrm.h"



extern void error_exit(char *msg);

extern void printwcs(wchar_t * msg);



typedef struct bboxobj_st {

void *jtable;

void *jtbl2;

void *jtbl3;

MS_BN ecprivkey;

MS_ECCpt ecpt1;

uchar clientid[84]; /* First part is public key */

uchar hwid[20];

uchar rc4key[6];

uchar pad1[2];

int numkeypairs;

uchar *keypairs;

} BBOXOBJ;



#define MAXKEYPAIRS 50



struct keypair_st {

MS_ECCpt public;

MS_BN private;

} keypair[MAXKEYPAIRS];

int numkeypairs = 0;





static MS_BN msec_mod = {

{0xf7, 0x24, 0x14, 0x14, 0x26, 0x59, 0x41, 0x31, 0x18, 0x28,

0x18, 0x27, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89}

};



static MS_BN msec_a = {

{0x97, 0x14, 0xe4, 0xeb, 0x09, 0xc0, 0x80, 0x47, 0x3d, 0xff,

0x32, 0x76, 0xe8, 0xbc, 0x77, 0xd2, 0xcc, 0xab, 0xa5, 0x37}

};



static MS_BN msec_b = {

{0x9e, 0x23, 0x28, 0x93, 0xdf, 0xde, 0x8f, 0xd7, 0x1a, 0x5f,

0xe8, 0x28, 0x32, 0x2f, 0x5e, 0x72, 0xbf, 0xda, 0xd8, 0x0d}

};



static MS_BN msec_gx = {

{0x20, 0xa1, 0x9f, 0x10, 0xf0, 0xda, 0x38, 0xba, 0x7d, 0xc0,

0x10, 0x35, 0xe5, 0xa1, 0xa3, 0xd6, 0x7f, 0x94, 0x23, 0x87}

};



static MS_BN msec_gy = {

{0x6f, 0x93, 0x79, 0xa3, 0xcd, 0x7a, 0xed, 0xd4, 0x56, 0x58,

0x3c, 0x8c, 0x2d, 0x52, 0x75, 0x10, 0x91, 0x44, 0x57, 0x44}

};





static void printMSBN(MS_BN * num)

{

int i;

for (i = MS_BN_LEN - 1; i >= 0; i--)

fprintf(stderr, "%02x", num->d[i]);

}





static BIGNUM *MS_BN_to_BN(MS_BN * msnum, BIGNUM * r)

{

uchar bigendian[MS_BN_LEN];

int i;



for (i = 0; i < MS_BN_LEN; i++)

bigendian[i] = msnum->d[MS_BN_LEN - 1 - i];



return BN_bin2bn(bigendian, MS_BN_LEN, r);

}





static void MS_ECCpt_to_ECCpt(MS_ECCpt * mspt, ECCpt * r)

{

MS_BN_to_BN(&mspt->x, r->x);

MS_BN_to_BN(&mspt->y, r->y);

}





static ECC *MSECC_new_set()

{

BIGNUM *tmod, *ta, *tb;

ECC *ecc;

ECCpt tg;



tmod = BN_new();

ta = BN_new();

tb = BN_new();

ECCpt_init(&tg);



MS_BN_to_BN(&msec_mod, tmod);

MS_BN_to_BN(&msec_a, ta);

MS_BN_to_BN(&msec_b, tb);

MS_BN_to_BN(&msec_gx, tg.x);

MS_BN_to_BN(&msec_gy, tg.y);



ecc = ECC_new_set(tmod, ta, tb, tg);



BN_free(tmod);

BN_free(ta);

BN_free(tb);

ECCpt_free(&tg);



return ecc;

}





static void MSECC_set_privkey(MS_BN * pk, ECC * ecc)

{

if (ecc->privkey == NULL)

ecc->privkey = BN_new();

MS_BN_to_BN(pk, ecc->privkey);

}





static void BN_to_MS_BN(BIGNUM * in, MS_BN * out)

{

MS_BN tmp;

int bytelen, i;



bytelen = BN_num_bytes(in);

if (bytelen > MS_BN_LEN)

error_exit

("Bug in code: Result is too big in BN_to_MS_BN");



for (i = 0; i < MS_BN_LEN; i++)

tmp.d[i] = 0;



BN_bn2bin(in, (uchar *) & tmp.d[MS_BN_LEN - bytelen]);



for (i = 0; i < MS_BN_LEN; i++)

out->d[i] = tmp.d[MS_BN_LEN - 1 - i];

}





static void MSECC_decrypt(MS_ECCpt * r, MS_ECCpt * ctext, ECC * ecc)

{

ECCpt u, v;



if (ecc->privkey == NULL)

error_exit

("Bug in code: MSECC_decrypt called with no private key!");



ECCpt_init(&u);

ECCpt_init(&v);

MS_ECCpt_to_ECCpt(&ctext[0], &u);

MS_ECCpt_to_ECCpt(&ctext[1], &v);



ECCpt_mul(&u, &u, ecc->privkey, ecc);

BN_sub(u.y, ecc->modulus, u.y);

ECCpt_add(&v, &v, &u, ecc);



BN_to_MS_BN(v.x, &r->x);

BN_to_MS_BN(v.y, &r->y);



ECCpt_free(&u);

ECCpt_free(&v);

}





static int MS_Base64Decode(wchar_t * str, char **buff)

{

wchar_t *cp;

char *ocp;

int len, val, count, block, ocount;



len = wcslen(str);

if ((*buff = malloc((len * 3) / 4)) == NULL)

error_exit("Memory allocation failed in MS_Base64Decode.");



ocp = *buff;

count = 0;

block = 0;

ocount = 0;

for (cp = str; *cp != L'\0'; cp++) {

if ((*cp >= L'A') && (*cp <= L'Z'))

val = *cp - L'A';

else if ((*cp >= L'a') && (*cp <= L'z'))

val = *cp - L'a' + 26;

else if ((*cp >= L'0') && (*cp <= L'9'))

val = *cp - L'0' + 52;

else if ((*cp == L'+') || (*cp == L'!'))

val = 62;

else if ((*cp == L'/') || (*cp == L'*'))

val = 63;

else if (*cp == L'=') {

if (count == 2) {

*ocp++ = block >> 4;

ocount++;

} else {

*ocp++ = (block >> 10);

*ocp++ = (block >> 2) & 0xff;

ocount += 2;

} break;

} else

val = -1;



if (val >= 0) {

block = (block << 6) | val;

if (++count == 4) {

*ocp++ = block >> 16;

*ocp++ = (block >> 8) & 0xff;

*ocp++ = block & 0xff;

ocount += 3;

count = 0;

}

}

}



return ocount;

}





void MSDRM_decr_packet(uchar * data, int len, CONTKEY * ckey)

{

RC4_KEY rc4state;

int num64bits = len / 8;

uchar work2[8];

int i;

unsigned int pustate[2];

unsigned int tmpd[2];

uchar *keystart = data + (num64bits - 1) * 8;



if (len < 16) {

for (i = 0; i < len; i++)

data[i] ^= ckey->keyhash[i];

return;

}



for (i = 0; i < 8; i++)

keystart[i] ^= ckey->inmask[i];



des_ecb_encrypt((const_des_cblock *) keystart,

(des_cblock *) work2, ckey->keysched, 0);



for (i = 0; i < 8; i++)

work2[i] ^= ckey->outmask[i];



RC4_set_key(&rc4state, 8, work2);

RC4(&rc4state, len, data, data);



MultiSwapMAC(&ckey->hashkey, (unsigned int *) data, num64bits - 1,

pustate);

tmpd[0] = ((int *) work2)[1];

tmpd[1] = ((int *) work2)[0];

MultiSwapDecode(&ckey->hashkey, pustate, tmpd,

(unsigned int *) keystart);

}





static void MSDRM_setup(MS_BN * privkey, wchar_t * value, CONTKEY * out)

{

ECC *msecc;

MS_ECCpt dec;

RC4_KEY rc4state;

uchar rc4buff[64];

int len;

char *dynbuff;



msecc = MSECC_new_set();

MSECC_set_privkey(privkey, msecc);



len = MS_Base64Decode(value, &dynbuff);

MSECC_decrypt(&dec, (MS_ECCpt *) dynbuff, msecc);

free(dynbuff);



ECC_free(msecc);

msecc = NULL;



if ((uchar) dec.x.d[0] > MS_BN_LEN - 1)

error_exit("Decrypted content key is too big!");



out->ckeylen = (uchar) dec.x.d[0];

memcpy(out->ckey, &dec.x.d[1], out->ckeylen);



if (globalinfo.verbose) {

int i;

fprintf(stderr, "Content key:");

for (i = 0; i < out->ckeylen; i++)

fprintf(stderr, " %02x", out->ckey[i]);

fprintf(stderr, "\n");

}



SHA1(out->ckey, out->ckeylen, out->keyhash);



des_set_key_unchecked((des_cblock *) (&out->keyhash[12]),

out->keysched);



RC4_set_key(&rc4state, 12, out->keyhash);

memset(rc4buff, 0, sizeof(rc4buff));

RC4(&rc4state, sizeof(rc4buff), rc4buff, rc4buff);



memcpy(out->outmask, &rc4buff[48], 8);

memcpy(out->inmask, &rc4buff[56], 8);



MultiSwapSetKey(&out->hashkey, (unsigned int *) rc4buff);

}





/* Stupid little fake XML parser. */



static wchar_t *find_close(wchar_t * str)

{

while ((*str != L'\0') && (*str != L'>')) {

if (*str == L'"') {

if ((str = wcschr(str + 1, L'"')) == NULL)

return NULL;

} str++;

}



if (*str == L'\0')

return NULL;

else

return str + 1;

}





wchar_t *get_element(wchar_t * tag, wchar_t * str)

{

int len = wcslen(tag);

wchar_t *tmptag;

wchar_t *start, *end;

wchar_t *rval = NULL;



if ((tmptag = malloc((len + 4) * sizeof(wchar_t))) == NULL)

error_exit("Memory allocation failed in get_element (1)");



swprintf(tmptag, L"<%s", tag);



while (1) {

if ((start = wcsstr(str, tmptag)) == NULL)

goto exit;

if (!iswalnum(start[len + 1]))

break;

str = start + len + 1;

}



swprintf(tmptag, L"", tag);

end = wcsstr(str, tmptag);



if (end == NULL) {

goto exit;

} else {

wchar_t *realstart = find_close(start);

if ((realstart == NULL) || (realstart > end)) {

goto exit;

} else {

wchar_t *tmp =

malloc((end - realstart +

1) * sizeof(wchar_t));

if (tmp == NULL)

error_exit

("Memory allocation failed in get_element (2)");

memcpy(tmp, realstart,

(end - realstart) * sizeof(wchar_t));

tmp[end - realstart] = L'\0';

rval = tmp;

}

}



exit:

free(tmptag);

return rval;

}







/*

* getDRMDataPath allocates extra room on the end (20 wchars) for

* appending a filename

*/

static wchar_t *getDRMDataPath()

{

HKEY key_drm;

long stat;

DWORD dtype, dlen;

wchar_t *buff;



stat =

RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DRM", 0,

KEY_READ, &key_drm);

if (FAILED(stat))

return NULL;



stat =

RegQueryValueEx(key_drm, "DataPath", NULL, NULL, NULL, &dlen);

if (FAILED(stat))

return NULL;



if ((buff =

(wchar_t *) malloc(dlen + 20 * sizeof(wchar_t))) == NULL)

error_exit("Memory allocation failed in getDRMDataPath");



stat =

RegQueryValueEx(key_drm, "DataPath", NULL, &dtype,

(uchar *) buff, &dlen);

if (FAILED(stat)) {

free(buff);

return NULL;

}



RegCloseKey(key_drm);



return buff;

}







int fileExistsA(char *fname)

{

return (GetFileAttributes(fname) != -1);

}



int fileExistsW(wchar_t * fname)

{

char buffer[MAX_PATH];

int len;



len = wcslen(fname);

if (WideCharToMultiByte

(CP_ACP, 0, fname, len + 1, buffer, MAX_PATH, NULL, NULL) == 0)

return 0;



return fileExistsA(buffer);

}



void getKSFilename(wchar_t * ksname, char *libname)

{

wchar_t *basepath = getDRMDataPath();

wchar_t currks[MAX_PATH], lastks[MAX_PATH];

char abasepath[MAX_PATH];

char currlib[MAX_PATH], lastlib[MAX_PATH];

int fnum;



if (basepath != NULL) {

WideCharToMultiByte(CP_ACP, 0, basepath,

wcslen(basepath) + 1, abasepath,

MAX_PATH, NULL, NULL);

swprintf(lastks, L"%s\\v2ks.bla", basepath);

swprintf(currks, L"%s\\v2ksndv.bla", basepath);

sprintf(lastlib, "BlackBox.dll");

sprintf(currlib, "%s\\IndivBox.key", abasepath);

fnum = 1;

while (fileExistsW(currks) && (fileExistsA(currlib))) {

fnum++;

wcscpy(lastks, currks);

swprintf(currks, L"%s\\v2ks%03x.bla", basepath,

fnum);

strcpy(lastlib, currlib);

sprintf(currlib, "%s\\Indiv%03x.key", basepath,

fnum);

}

wcscpy(ksname, lastks);

strcpy(libname, lastlib);

free(basepath);

}

}





static int getkeypairs()

{

HMODULE mylib;

int rval;

BBOXOBJ *bbobj;

char errmsg[100];

wchar_t KSFilename[MAX_PATH];

char BBoxLib[MAX_PATH];

int i;



getKSFilename(KSFilename, BBoxLib);

if (globalinfo.verbose) {

fprintf(stderr, "BlackBox library to use: %s\n", BBoxLib);

fprintf(stderr, "Keystore to use: ");

printwcs(KSFilename);

fprintf(stderr, "\n");

}

mylib = LoadLibraryA(BBoxLib);

if (mylib == NULL) {

DWORD err = GetLastError();

sprintf(errmsg, "Failed loading library. Err code %08x",

err);

error_exit(errmsg);

} else {

typedef int (WINAPI * createfn) (BBOXOBJ **,

unsigned short *);

createfn create =

(createfn) GetProcAddress(mylib,

"IBlackBox_CreateInstance2");

if (create == NULL)

error_exit("Failed finding proc address.");

else {

rval = (*create) (&bbobj, KSFilename);



if (bbobj == NULL) {

sprintf(errmsg,

"Failed to create a black box object (err code %08x)\n",

rval);

error_exit(errmsg);

}



if (globalinfo.verbose) {

fprintf(stderr,

"Created BlackBox instance - extracting key pairs\n");

}



memcpy(&keypair[0].private, &bbobj->ecprivkey, 20);

memcpy(&keypair[0].public, bbobj->clientid, 40);

numkeypairs = bbobj->numkeypairs + 1;

for (i = 0; i < bbobj->numkeypairs; i++) {

memcpy(&keypair[i + 1].public,

bbobj->keypairs + 60 * i, 40);

memcpy(&keypair[i + 1].private,

bbobj->keypairs + 60 * i + 40, 20);

}



if (globalinfo.verbose) {

fprintf(stderr, "\n");

for (i = 0; i < numkeypairs; i++) {

fprintf(stderr,

"Public key %d x: ",

i + 1);

printMSBN(&keypair[i].public.x);

fprintf(stderr,

"\nPublic key %d y: ",

i + 1);

printMSBN(&keypair[i].public.y);

fprintf(stderr,

"\nPrivate key %d: ",

i + 1);

printMSBN(&keypair[i].private);

fprintf(stderr, "\n\n");

}

}

} FreeLibrary(mylib);

} return 0;

}





static CONTKEY *checkLicense(wchar_t * license)

{

wchar_t *ebits = NULL;

wchar_t *pubkey = NULL;

wchar_t *value = NULL;

MS_BN *privkey = NULL;

CONTKEY *ckey = NULL;

MS_BN *thispubkey;

int i;



if ((ebits = get_element(L"ENABLINGBITS", license)) == NULL)

error_exit("No ENABLINGBITS element in license!");



if ((pubkey = get_element(L"PUBKEY", ebits)) == NULL)

error_exit("No PUBKEY element in license!");



if ((value = get_element(L"VALUE", ebits)) == NULL)

error_exit("No VALUE element in license!");



MS_Base64Decode(pubkey, (char **) &thispubkey);

if (globalinfo.verbose) {

fprintf(stderr, "Checking license with PUBKEY ");

printMSBN(thispubkey);

fprintf(stderr, "\n");

}

for (i = 0; i < numkeypairs; i++) {

if (memcmp(thispubkey, (char *) &keypair[i].public, 40) ==

0) {

privkey = &keypair[i].private;

break;

}

}



if (privkey != NULL) {

if ((ckey = malloc(sizeof(CONTKEY))) == NULL)

error_exit

("Memory allocation failed in checkLicense");

if (globalinfo.verbose) {

fprintf(stderr,

"Matched public key! Proceeding...\n");

} MSDRM_setup(privkey, value, ckey);

}



free(thispubkey);

free(value);

free(pubkey);

free(ebits);



return ckey;

}





static CONTKEY *getContKey(wchar_t * licFile, wchar_t * kid)

{

HRESULT hr;

IStorage *pStg = NULL, *pStgChild = NULL;

IStream *pStrmLicense;

IEnumSTATSTG *penum = NULL;

STATSTG statstg, statstrm;

wchar_t *license = NULL;

unsigned long statLen, reallyRead;

CONTKEY *ckey;



hr = StgOpenStorage(licFile, NULL,

STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0,

&pStg);



if (FAILED(hr))

error_exit("Couldn't open license file!");



hr = pStg->lpVtbl->OpenStorage(pStg, kid, NULL,

STGM_READ | STGM_SHARE_EXCLUSIVE,

NULL, 0, &pStgChild);



if (FAILED(hr))

return NULL;



hr = pStgChild->lpVtbl->EnumElements(pStgChild, 0, NULL, 0,

&penum);

if (FAILED(hr))

error_exit("Couldn't EnumElements in storage.");



memset(&statstg, 0, sizeof(statstg));

hr = penum->lpVtbl->Next(penum, 1, &statstg, 0);

while (S_OK == hr) {

hr = pStgChild->lpVtbl->OpenStream(pStgChild,

statstg.pwcsName, NULL,

STGM_READ |

STGM_SHARE_EXCLUSIVE, 0,

&pStrmLicense);



if (FAILED(hr))

error_exit("Couldn't open license!");



hr = pStrmLicense->lpVtbl->Stat(pStrmLicense, &statstrm,

0);



statLen = (unsigned long) statstrm.cbSize.QuadPart / 2;

if ((license =

(wchar_t *) malloc(2 * (statLen + 1))) == NULL)

error_exit

("Memory allocation failed in getContKey.");

hr = pStrmLicense->lpVtbl->Read(pStrmLicense, license,

2 * statLen, &reallyRead);



if ((FAILED(hr)) || (reallyRead != 2 * statLen))

error_exit("License read failed.");



license[statLen] = 0;



pStrmLicense->lpVtbl->Release(pStrmLicense);



if ((ckey = checkLicense(license + 1)) != NULL) {

free(license);

pStgChild->lpVtbl->Release(pStgChild);

pStg->lpVtbl->Release(pStg);

return ckey;

}



free(license);



hr = penum->lpVtbl->Next(penum, 1, &statstg, 0);

}



return NULL;

}





static void convertKID(wchar_t * kid)

{

while (*kid != L'\0') {

if (*kid == L'/')

*kid = L'@';

else if (*kid == L'!')

*kid = L'%';

kid++;

}

}





CONTKEY *MSDRM_init(wchar_t * kid)

{

CONTKEY *ckey;

wchar_t *licfile;



licfile = getDRMDataPath();

if (licfile == NULL)

error_exit("Couldn't get DRM data path from registry.");



wcscat(licfile, L"\\drmv2.lic");



if (globalinfo.verbose) {

fprintf(stderr, "License file full path: ");

printwcs(licfile);

fprintf(stderr, "\n");

}



getkeypairs();



convertKID(kid);

ckey = getContKey(licfile, kid);

if (ckey == NULL)

error_exit

("Couldn't find a valid license for this content.");



free(licfile);



return ckey;

}





--------------------------------------------------------------------------------



Viewing message





From: Anonymous (nobody@noisebox.remailer.org)

Subject: FreeMe README file

Newsgroups: sci.crypt

Date: 2001-10-18 16:26:19 PST





-----BEGIN PGP SIGNED MESSAGE-----





The software distributed with this README file removes content

protection from any Windows Media Audio file (.wma file) that uses DRM

version 2 (as implemented in Windows Media Player version 7). It has

been tested under Windows 98, so may or may not work with other Media

Player/OS combinations. Also be aware that many "protected content"

files out there are actually DRM version 1, especially if they are

older files. This software will not do anything to unprotect version

1 files.



There is another piece of software, called "unfuck", which similarly

removes protections, but there is a fundamental difference in how

these two pieces of software work. Unfuck works by allowing the

player to unprotect and uncompress the audio, and then captures the

audio samples on the way to the sound card. This software attacks the

problem directly: it simply removes the encryption from the protected

file, leaving everything else exactly the same. Because of this,

there is no loss of quality due to uncompressing and re-compressing

the content -- what you're left with is exactly the original content,

just not protected. It's also much faster.



Please be aware that this software is "proof-of-concept" or

"demonstration" level, not production level. While every effort has

been made to make sure that it works properly, it may fail in

unforeseen situations -- it has NOT been thoroughly tested! There

isn't much chance that this program will screw up your system, but use

at your own risk!



WARNING!!!!! I have just learned that the new Microsoft Media

Player EULA includes a clause that says they can *automatically*

modify the software on your system, without any confirmation from

you required! In other words, they can disable your software, or

force an upgrade so that FreeMe won't work, just because they feel

like it. Be careful out there!





CONTENTS:

README - This file

LICENSE - Yes, a license! Read it!

Technical - Full technical description of how MS DRMv2 works

Philosophy - My philosophy on why I released this, and what's wrong

with the DMCA

FreeMe.exe - The actual program

src/ - The source code



The first 4 files can possibly be widely re-distributed and mirrored

without much fear of real legal worries -- however, you will almost

certainly be harassed by several big and powerful companies, so keep

that in mind. The last two files (the program) cause more problems:

distributing these in the U.S. is almost certainly a violation of

the DMCA. However, outside the U.S. should be mostly ok -- so

mirror these on as many foreign sites as possible! Again, you may

be harassed by big and powerful companies, and might get threatening

letters from lawyers, so be prepared for that.





INSTALLATION:

There's just a single executable file "FreeMe.exe" to install. You

can copy it so that it's in your executable PATH (for example, copy

to directory C:\WINDOWS\COMMAND), or you can put a shortcut to it on

your desktop -- see below.





USAGE:

This is a command-line program, and the best way to run it is from

the command line. If it is installed, and the executable is in your

PATH, all you have to do is type "freeme x.wma" at a DOS prompt in

order to unprotect the file "x.wma". There is a verbose flag that

you can invoke to have it print out all sorts of information as it

discovers it (your public/private key pairs, KID of the file you're

unprotecting, content key, etc.). For example, typing "freeme -v

x.wma" unprotects the file as above, but in verbose mode. The

output file will be called "Freed-x.wma", where "x.wma" is the

original filename.



One problem with this being a command line utility is that many

audio files have very long file names, so you'll have to put the

filename in quotes in order for this to work, like so:

Prompt> freeme "Billy and the Boingers - The RIAA Stole My Soul.wma"



As an alternative, you can put a shortcut to the FreeMe.exe

executable on your desktop, and then can simply drag files from the

file explorer to FreeMe. However, there is one big problem with

this: the filename given to FreeMe is actually the short filename,

so if you did this with the file above, you'd end up with an output

file named something like "Freed-BILLYA~1.WMA" Unfortunately, I

don't know how to fix this -- maybe someone else out there does.





SOURCE CODE:

The full source code is included in the src/ directory, but you will

need a Win32 version of the OpenSSL package (and crypto library) in

order to compile it.



There are some definite problems with this code, which I would

suggest to people interested in improving what I've distributed:

First off, a lot of things in Windows seem to be designed to be

easier in C++ than in C; unfortunately, I don't know a lot about

Windows programming, and never have learned or used C++ at all, so

some of my code may be a little strange in its approach. Secondly,

my .asf/.wma file format processing is hopelessly naive. Surely

there are better ways to do this, or existing libraries to do it.

Also, I don't really do XML parsing, but just a very simplistic

scanning. This seems to work for every license I've seen, but using

a real XML parser would make this much more robust. Finally, a nice

pretty GUI would be good, but wasn't necessary for my

"proof-of-concept" code, so I didn't include it.



Finally, you know that Microsoft is going to make some changes that

will render my software useless. You've got the source code, so use

that as a starting point to change with them.





HOW TO CONTACT ME:

Being anonymous, it's hard to give a way to contact me. However, if

you have something very important to tell me, post to the sci.crypt

Usenet newsgroup with a subject that includes the phrase "To Beale

Screamer". My PGP key is given in this distribution, in case you

need it (and I will always sign anything I distribute).



Please don't inundate the poor people in sci.crypt with a bunch of

pointless comments. But I did want to give people some avenue for

contacting me if absolutely necessary.





MESSAGES:

I have included messages below for specific groups of people.



Users: Please respect the uses I have intended this software for. I

want to make a point with this software, and if you use it for

purposes of violating copyrights, the message stands a very good

chance of getting lost. Also, Microsoft is obviously going to

release patches to their media player in order to get around the

exploit in my software -- I think you'll be safe it you refuse

to upgrade from your current version of the Windows Media Player

(but see the warning above about "forced upgrades"). Unless they

want to sacrifice backward compatibility, you will at least be

able to work with your current (legally obtained) media files

for the near future.



Microsoft: You guys have put together a pretty good piece of

software. Really. The only real technical flaw is that

licenses can't be examined for their restrictions once they are

obtained. My real beef is with the media publishers' use of this

software, not the technology itself. However, it's easy to see

where software bloat and inefficiency comes from when this code

is examined: every main DLL has a separate copy of the elliptic

curve and other basic crypto routines, and parameters passed

back and forth between modules are encrypted giving unnecessary

overhead, not to mention all the checks of the code integrity,

checks for a debugger running, code encryption and decryption.

Perhaps you felt this was necessary for the "security through

obscurity" aspect, but I've got to tell you that this really

doesn't make a bit of difference. Make lean and mean code,

because the obscurity doesn't work as well as you think it does.

Also read the message below to the Justice Department!



Justice Department: Maybe this should really be addressed to the

state officials, since it looks like the current U.S.

administration doesn't care too much about monopoly powers being

abused. But for whoever is interested, there is a very serious

anti-competitive measure in this software. In particular, for

various modules of the software to be used, you must supply a

certified public key for communication. Guess who controls the

certification of public keys? Microsoft. So if someone wants

to make a competing product, which integrates well with the

Windows OS, you will need to get Microsoft's permission and

obtain a certificate from them. I don't know what their policy

is on this, so don't know if this power will be abused or not.

However, it has the potential for being a weapon Microsoft can

use to knock out any competition to their products.



Artists: Don't fear new distribution methods -- embrace them.

Technology is providing you the means to get your art directly

to consumers, avoiding the big record companies. They want a

piece of the action for YOUR creativity, and you don't need to

let them in on it any more. Your fans will treat you nicely,

unless you treat your fans poorly (take note of that Lars). Bo

Diddley didn't have anything to fear from his fans, but a lot to

fear from Leonard Chess. Think about that.



Publishers: Give us more options, not fewer. If you try to take

away our current rights, and dictate to us what we may or may

not do, you're going to get a lot of resistance. You better

find a way to play nicely soon, because technology is making it

possible for artists to make do without you at all. Try getting

some progressive thinkers into management -- current people

don't seem to be able to cope with the new environment that is

emerging.



- - --



Original Distribution Date: October 18, 2001

by "Beale Screamer"





-----BEGIN PGP SIGNATURE-----

Version: 2.6.2



iQCVAwUBO84IDZCr1f2GXCalAQGRcAP8CHkU6B42NZNiuhS/roxKJTljm36Doq+R

zrqFeO2JY9xMCMhBlYP6RRkDATdlMWNj/U3DLXJ/lBJYUeSwMT3vsUTUHOA/lGMQ

9VqYHmAEwImnKWBNDG694abVeCFa9H/FziLLjeJQ73ADcfjr4rJ/FpHMxrtb2YfF

K5QaP3QRXl0=

=RK34

-----END PGP SIGNATURE-----



--------------------------------------------------------------------------------



Viewing message





From: Anonymous (anonymous@anonymous.poster.com)

Subject: FreeMe source - main.c

Newsgroups: sci.crypt

Date: 2001-10-18 16:31:25 PST





Split into .c and .h files



--------------------- Start of main.c ----------------------



/*

* FreeMe main.c -- mostly a wma/asf file processor, with DRM part

* put off into msdrm.c

*/



#include

#include

#include

#include

#include

#include

#include "msdrm.h"



typedef unsigned int uint32_t;

typedef unsigned __int64 uint64_t;



#pragma pack(1)





typedef struct chunk_save_st {

GUID guid;

uint64_t len;

void *data;

struct chunk_save_st *next;

} CHUNKSAVE;



typedef int (*GUIDHANDLER) (FILE * fp, CHUNKSAVE * savep);



typedef struct guidaction_st {

GUID *guid;

char *name;

GUIDHANDLER fn;

} GUIDACTION;



typedef struct fileheader_st {

GUID clientGUID;

uint64_t filesize;

uint64_t fileCreateTime;

uint64_t numPackets;

uint64_t timeAtEnd;

uint64_t playDuration;

uint32_t timeAtStart;

uint32_t unknown1;

uint32_t unknown2;

uint32_t packetSize;

uint32_t packetSize2;

uint32_t uncompressedSize;

} FILEHEADER;



int handle_chunk(FILE * fp, CHUNKSAVE * chunk);

int handle_header(FILE * fp, CHUNKSAVE * chunk);

int handle_file_header(FILE * fp, CHUNKSAVE * chunk);

int handle_data(FILE * fp, CHUNKSAVE * chunk);

int handle_stream_header(FILE * fp, CHUNKSAVE * chunk);

int handle_copy(FILE * fp, CHUNKSAVE * chunk);

int handle_drmv1(FILE * fp, CHUNKSAVE * chunk);

int handle_drmv2(FILE * fp, CHUNKSAVE * chunk);



struct globalinfo_st globalinfo;



GUID HeaderGUID = { 0x75b22630, 0x668e, 0x11cf, {0xa6, 0xd9,

0x00, 0xaa, 0x00, 0x62,

0xce, 0x6c}

};



GUID DataGUID = { 0x75b22636, 0x668e, 0x11cf, {0xa6, 0xd9,

0x00, 0xaa, 0x00, 0x62,

0xce, 0x6c}

};



GUID FileHeaderGUID = { 0x8cabdca1, 0xa947, 0x11cf, {0x8e, 0xe4,

0x00, 0xc0, 0x0c,

0x20, 0x53, 0x65}

};



GUID StreamHeaderGUID = { 0xb7dc0791, 0xa9b7, 0x11cf, {0x8e, 0xe6,

0x00, 0xc0, 0x0c,

0x20, 0x53, 0x65}

};



GUID AudioStreamGUID = { 0xf8699e40, 0x5b4d, 0x11cf, {0xa8, 0xfd,

0x00, 0x80, 0x5f,

0x5c, 0x44, 0x2b}

};



GUID Unknown1GUID = { 0x5fbf03b5, 0xa92e, 0x11cf, {0x8e, 0xe3,

0x00, 0xc0, 0x0c, 0x20,

0x53, 0x65}

};



GUID Unknown2GUID = { 0x86d15240, 0x311d, 0x11d0, {0xa3, 0xa4,

0x00, 0xa0, 0xc9, 0x03,

0x48, 0xf6}

};



GUID DRMv2HeaderGUID = { 0x298ae614, 0x2622, 0x4c17, {0xb9, 0x35,

0xda, 0xe0, 0x7e,

0xe9, 0x28, 0x9c}

};



GUID DRMv1HeaderGUID = { 0x2211b3fb, 0xbd23, 0x11d2, {0xb4, 0xb7,

0x00, 0xa0, 0xc9,

0x55, 0xfc, 0x6e}

};



GUID ContentDescrGUID = { 0x75b22633, 0x668e, 0x11cf, {0xa6, 0xd9,

0x00, 0xaa, 0x00,

0x62, 0xce, 0x6c}

};



GUID PropertyListGUID = { 0xd2d0a440, 0xe307, 0x11d2, {0x97, 0xf0,

0x00, 0xa0, 0xc9,

0x5e, 0xa8, 0x50}

};



GUIDACTION known_guids[] = {

{&HeaderGUID, "Header", handle_header},

{&DataGUID, "Data", handle_data},

{&FileHeaderGUID, "File Header", handle_file_header},

{&StreamHeaderGUID, "Stream Header", handle_copy},

{&Unknown1GUID, "Header subchunk - unknown 1", handle_copy},

{&Unknown2GUID, "Header subchunk - unknown 2", handle_copy},

{&DRMv2HeaderGUID, "DRMV2 ContentHeader", handle_drmv2},

{&DRMv1HeaderGUID, "DRMv1 header", handle_drmv1},

{&ContentDescrGUID, "Content Description", handle_copy},

{&PropertyListGUID, "Property List", handle_copy},

{NULL, NULL, NULL}

};





void error_exit(char *msg)

{

fprintf(stderr, "%s\n", msg);

fprintf(stderr, "\n Press to acknowledge error.\n");

getchar();

exit(1);

}



void printwcs(wchar_t * msg)

{

int len, rval;

char *buff;



len = wcslen(msg);

if ((buff = malloc(len + 1)) == NULL)

error_exit("Memory allocation failed in printwcs");



rval = WideCharToMultiByte(CP_ACP, 0, msg, len + 1, buff, len + 1,

NULL, NULL);

if (rval == 0)

error_exit("WideCharToMultiByte failed in printwcs");



fputs(buff, stderr);

free(buff);

}





GUIDHANDLER find_guid(GUID * guid)

{

GUIDHANDLER handler = NULL;

GUIDACTION *curr;



curr = known_guids;

while (curr->guid != NULL) {

if (memcmp(curr->guid, guid, sizeof(GUID)) == 0) {

handler = curr->fn;

break;

} curr++;

}



return handler;

}





int handle_copy(FILE * fp, CHUNKSAVE * chunk)

{

unsigned long datalen = (unsigned long) (chunk->len - 24);



chunk->data = malloc(datalen);



if (chunk->data == NULL)

error_exit("Memory allocation failed in handle_copy");



if (fread(chunk->data, datalen, 1, fp) != 1) {

free(chunk->data);

chunk->data = NULL;

return 0;

}



return 1;

}





int handle_drmv1(FILE * fp, CHUNKSAVE * chunk)

{

unsigned long toskip = (unsigned long) (chunk->len - 24);



fseek(fp, toskip, SEEK_CUR);

globalinfo.hasV1header = 1;

if (globalinfo.verbose)

fprintf(stderr, "Found DRMv1 header object.\n");

return 1;

}





int handle_drmv2(FILE * fp, CHUNKSAVE * chunk)

{

unsigned long datalen = (unsigned long) (chunk->len - 24);

unsigned short *data = malloc(datalen);



if (globalinfo.verbose)

fprintf(stderr, "Found DRMv2 header object.\n");



if (data == NULL)

error_exit("Memory allocation in handle_drmv2 failed.");



fseek(fp, 6, SEEK_CUR);

if (fread(data, datalen - 6, 1, fp) != 1)

error_exit("Data read in handle_drmv2 failed.");



data[(datalen - 6) / 2] = L'\0';



globalinfo.kid = get_element(L"KID", data);

globalinfo.hasV2header = 1;



if (globalinfo.verbose) {

if (globalinfo.kid == NULL) {

fprintf(stderr,

"KID not found in header object!\n");

} else {

fprintf(stderr, "Found KID (");

printwcs(globalinfo.kid);

fprintf(stderr, ")\n");

}

}



free(data);

return 1;

}





int handle_packet(FILE * fp, int packetlen)

{

struct packethead_st {

uchar id;

short unknown1;

uchar flags;

uchar segTypeID;

} *info;

uchar *data;

int flagoffset = 13;

int objlen;

int dataoffset;

int rval = 0;



if ((data = malloc(packetlen)) == NULL)

error_exit("Memory allocation failed in handle_packet.");



if (fread(data, packetlen, 1, fp) != 1)

goto exit;



info = (struct packethead_st *) data;

if (info->id != 0x82)

error_exit("Unknown packet id - don't know what to do!");



if (info->flags & 0x40)

flagoffset += 2;



if (info->flags & 0x10)

flagoffset += 2;

else if (info->flags & 0x08)

flagoffset += 1;



if (info->flags & 0x01)

flagoffset += 1;



if (info->segTypeID == 0x55)

flagoffset += 1;

else if (info->segTypeID == 0x59)

flagoffset += 2;

else if (info->segTypeID == 0x5d)

flagoffset += 4;



if (data[flagoffset] != 8)

error_exit

("Flag says grouping - don't know how to do this!");



dataoffset = flagoffset + 9;

if (info->flags & 0x01)

error_exit("Need the data_length field - don't know how!");



objlen = *((int *) &data[flagoffset + 1]);



MSDRM_decr_packet(data + dataoffset, objlen,

globalinfo.content_key);



fwrite(data, packetlen, 1, stdout);

rval = 1;



exit:

free(data);

return rval;

}





int handle_data(FILE * fp, CHUNKSAVE * chunk)

{

struct datahead_st {

GUID unknownGUID;

uint64_t numPackets;

uchar unknown[2];

} datahead;

int packetcount = 0;

int lastpercent = -1;



if (fread(&datahead, sizeof(datahead), 1, fp) != 1)

return 0;



fwrite(chunk, 24, 1, stdout);

fwrite(&datahead, sizeof(datahead), 1, stdout);



if (globalinfo.verbose) {

fprintf(stderr, "Starting to process data packets\n");

fprintf(stderr, "%d packets of length %d\n",

globalinfo.numpackets, globalinfo.packetlen);

}



while (handle_packet(fp, globalinfo.packetlen)) {

packetcount++;

if (globalinfo.numpackets != 0) {

int percent, i;

percent =

((packetcount * 200) / globalinfo.numpackets +

1) / 2;

if (percent != lastpercent) {

fprintf(stderr, "|");

for (i = 0; i < percent / 2; i++)

fprintf(stderr, "#");

for (; i < 50; i++)

fprintf(stderr, " ");

fprintf(stderr, "| ");

fprintf(stderr, "%3d%%\r", percent);

lastpercent = percent;

}

}

}

fprintf(stderr, "\n");



return 0;

}





int handle_header(FILE * fp, CHUNKSAVE * chunk)

{

struct header_st {

int numchunks;

short unknown;

} header;

int i;

CHUNKSAVE *subchunk = NULL;

int savecount = 0;

CHUNKSAVE *head = NULL, *tail = NULL;

FILEHEADER *fileheader;

uint64_t bytesremoved = 0;



if (fread(&header, sizeof(header), 1, fp) != 1)

return 0;



for (i = 0; i < header.numchunks; i++) {

if (subchunk == NULL) {

if ((subchunk = malloc(sizeof(CHUNKSAVE))) == NULL)

error_exit

("Memory allocation failed in handle_header");

}

if (!handle_chunk(fp, subchunk))

return 0;

if (subchunk->data != NULL) {

if (tail == NULL)

head = subchunk;

else

tail->next = subchunk;

subchunk->next = NULL;

tail = subchunk;



if ((subchunk = malloc(sizeof(CHUNKSAVE))) == NULL)

error_exit

("Memory allocation failed in handle_header");



savecount++;

} else { bytesremoved += subchunk->len;

}

}



if (globalinfo.fileheader == NULL) {

error_exit("Didn't see file header!");

} else {

CHUNKSAVE *currchunk, *nextchunk;



if (!globalinfo.hasV2header) {

if (globalinfo.hasV1header)

error_exit

("This file is version 1 protected, not version 2.");

else

error_exit

("This file doesn't seem to be protected!");

}



if (!globalinfo.kid)

error_exit

("Version 2 protected, but no KID found!");



if (globalinfo.verbose)

fprintf(stderr, "Starting to look for license.\n");



globalinfo.content_key = MSDRM_init(globalinfo.kid);

if (globalinfo.content_key == NULL)

error_exit("Couldn't find a valid license!");



if (freopen(globalinfo.ofname, "wb", stdout) == NULL)

error_exit("Couldn't open output file.");



if (globalinfo.verbose)

fprintf(stderr, "Opened output file <%s>\n",

globalinfo.ofname);



currchunk = head;

fileheader =

(FILEHEADER *) ((CHUNKSAVE *) globalinfo.fileheader)->

data;

fileheader->filesize -= bytesremoved;

globalinfo.packetlen = fileheader->packetSize;

globalinfo.numpackets = (int) fileheader->numPackets;

header.numchunks = savecount;

chunk->len -= bytesremoved;

fwrite(chunk, 24, 1, stdout);

fwrite(&header, sizeof(header), 1, stdout);

while (currchunk != NULL) {

fwrite(currchunk, 24, 1, stdout);

fwrite(currchunk->data,

(unsigned long) (currchunk->len - 24), 1,

stdout);

nextchunk = currchunk->next;

free(currchunk->data);

free(currchunk);

currchunk = nextchunk;

}

}



return 1;

}





int handle_file_header(FILE * fp, CHUNKSAVE * chunk)

{

unsigned long datalen = (unsigned long) (chunk->len - 24);



if ((chunk->data = malloc(datalen)) == NULL)

error_exit

("Data allocation failed in handle_file_header.");



if (fread(chunk->data, datalen, 1, fp) != 1) {

free(chunk->data);

chunk->data = NULL;

return 0;

}



globalinfo.fileheader = chunk;



return 1;

}





int handle_chunk(FILE * fp, CHUNKSAVE * chunk)

{

GUIDHANDLER handler = NULL;

int retval = 0;



chunk->data = NULL;



if (fread(&chunk->guid, sizeof(chunk->guid), 1, fp) != 1)

return 0;



if (fread(&chunk->len, sizeof(chunk->len), 1, fp) != 1)

return 0;



handler = find_guid(&chunk->guid);



if (handler != NULL) {

retval = (handler) (fp, chunk);

} else {

long toskip = (long) (chunk->len - 24);

retval = (fseek(fp, toskip, SEEK_CUR) == 0);

retval = 1;

}



return retval;

}





int main(int argc, char *argv[])

{

CHUNKSAVE chunk;

int more = 1;

FILE *ifp;

char *fnamestart;

static char ofname[1000];



globalinfo.verbose = 0;

globalinfo.fileheader = NULL;

globalinfo.kid = NULL;

globalinfo.hasV1header = 0;

globalinfo.hasV2header = 0;

globalinfo.ofname = ofname;



if ((argc < 2) || (argc > 3))

error_exit("Usage: FreeMe [-v] protectedfile");



if ((strcmp(argv[1], "-v") != 0) && (argc == 3))

error_exit("Usage: FreeMe [-v] protectedfile");



if (argc == 3)

globalinfo.verbose = 1;



if ((ifp = fopen(argv[argc - 1], "rb")) == NULL) {

sprintf(ofname, "Couldn't open input file (%s)",

argv[argc - 1]);

error_exit(ofname);

}



ofname[0] = '\0';

if ((fnamestart = strrchr(argv[argc - 1], '\\')) != NULL) {

memcpy(ofname, argv[argc - 1],

fnamestart - argv[argc - 1] + 1);

ofname[fnamestart - argv[argc - 1] + 1] = '\0';

}

strcat(ofname, "Freed-");

strcat(ofname, (fnamestart ? fnamestart + 1 : argv[argc - 1]));



while (more)

more = handle_chunk(ifp, &chunk);



return 0;



I'll try to clear up some confusion on problems of character sets. This is

long, but hopefully not too torturous. I'll try to snare the better bits

from this and fit them in as examples in perlpodspec.





First off, my intent is to declare Unicode to be POD's "the reference

character set" (ugh, and I thought I could get out of this without using

SGML jargon), for purposes of resolving E sequences.



So, for example, if I say E<233>, that is to mean the e-acute character,

because in Unicode, code point 233 is e-acute.



Whether "print ord 233" on your terminal prints an e-acute, an ess-tsett, a

gimel, a "tsu" katakana, a double-dagger, or whether it lasers a hole thru

your monitor's glass, is a whole different problem.



E<233> does NOT mean "simply pass a literal 233 blindly thru to the

formatter".

E<233> and its exact synonym E both merely mean "make a reasonable

attempt to make an e-acute".



So,

If you're MacPerl's Shuck, that probably means knowing to remap

eacute/233 maps to 142, because 142 is the Mac ASCII code for e-acute.

If you're a pod2man, you emit a E\*' because that's how to make an

e-acute, last I heard.

If you're a pod2latex, you emit a \'{e}.

If you're a pod2html, you can emit an "é" or just as well emit a

"æ" or maybe even a literal character number 230 (presuming you aren't

doing anything perverse like declaring the HTML document's character set as

being KOI-8 or something -- in which case you'd better figure out how,

instead, to express an e-acute in KOI-8.)

If you're pod2text, and you suspect that mayhem might ensue if you emit

/any/ sort of eight bit value, then maybe you should just emit a plain "e".



This point is addressed in perlpodspec:

It is up to individual pod formatter to display good judgment when

confronted with an unrenderable character [...]

It is good practice to map Latin letters with

diacritics (like "EEeacute>"/"EE299>") to the corresponding

unaccented US-ASCII letter (like a simple character 101, "e"), but

clearly this is often not feasable, and an unrenderable character may

be represented as "?", or the like. A pod formatter may also note,

in a comment, a list of what unrenderable characters were

encountered.



Suppose you have an E<61>. That's a "=", and everything better be able to

display that. (Altho EBCDIC Perls may have to consult some sort of

ASCII-to-EBCDIC map to arrive at the fact that E<61> means an equals sign.)

(Why would you use an "E<61>" in the first place? Consider a paragraph

starting "E<61>for commands are useful". If you wrote "=for commands are

useful", it'd be interpreted as a real live =for command. Or you could

escape it with the delightfully enigmatic Z<> sequence: "Z<>=for commands

are useful", where the Z<> is the null [zero-width] sequence. It's handy

-- and mercifully not the only way to do it.)





Now suppose you have an E.

That's defined in xhtml-special.ent:



So it's synonymous with E<339> (or in hex E, or even in octal

E<0523>). For HTML, you can try œ or œ, for plaintext you

should probably stick with "oe" (altho some day it might be best to emit

the UTF-8 code for 339), and for nroff, I dunno, maybe there's an "\*(oe"

macro, otherwise "oe" seems best.





Now, a dagger! From xhtml-special.ent:



So E<8224> and E and E are synonymous. For HTML, emit

† or †, for US-ASCII plaintext, I don't know. Maybe a "+"?

Maybe "[dagger]"?

Shuck, on this point, should happily know that 8824 maps to Mac-ASCII code

point 160, and so can display a dagger. (Assuming it's in the selected

display font. (BTW, someone has to fix Shuck -- it's in C++ (so don't ask

me!) and it doesn't understand modern syntaxes like C<< ... >>.)





Suppose you have a E (for which there is no (X)HTML mnemonic, by the

way). This is a Chinese character -- it happens to be the code point for

the traditional form of the glyph for "alligator". If you're pod2html, you

may blaze merrily forward and emit a 鰐 (or its exact equivalent in

decimal, 鰐) and if leave it up to the browser to do its best to

render that character. If you're a pod2text and know that you're talking

to a utf8 terminal, you can just emit the UTF-8 bytes for 0x9c10.

Otherwise, you should emit a "?" or a "[?]" or "[9c10]".

Or you might be devil-may-care and use my Text::Unidecode module, and

replace the E with unidecode("\x{9c10}"), which returns "E" (because

that's how you pronounce it in Mandarin! with tone 4, incidentally), and

emit that.





So what's needed is a data table that maps from all POD mnemonic names

(which is all XHTML entities, PLUS the few extra mnemonics that are

mentioned in perlpodspec).

This doesn't mean that HTML::Entities has to be core -- just something with

a big hash like what's in HTML::Entities, mapping from "eacute" to "\xE9",

and possibly one going the other way. The (X)HTML standard for entities

changes rather slowly, so I don't feel particularly upset at the idea of

duplicating the data. (Moreover, HTML::Entities currently seems to depend

on HTML::Parser, and I don't know whether HTML::Parser is ready to be made

core -- I've not been keeping up on its current state of development.)



I'd swear I'd seen an existing module just for this (i.e., like an

HTML::Entities, but for POD) but I can't now find it.

I'll produce such a thing ASAP if it doesn't already exist.







Also what many renderers will also need is something that maps from various

Unicode characters (like \xE9 or \x{2020}) to whatever it will use to

display those (like "\xE9" => "E\\*'" for *roff) for whatever characters

that it actually knows about. (For Shuck, this would consist of a

Unicode-to-MacASCII mapping.)

Such a Unicode-to-what-I-know mapping might include some best-I-can-do

forms, like mapping "\xE9" (eacute) to a mere "e".



Hopefully, except for the pod-mnemonics-to-Unicode table, all tables that

could be needed (e.g., a unicode-to-*roff-escapes table, a

unicode-to-macascii table, even the possibly necessary ascii-to-ebcdic

table) are all well known and widely available, if not necessarily as a

Perl module (yet!).







Now, there is another topic here, aside from what is the character set to

be used in resolving E sequences: what is the character encoding

of a given Perl/POD file. Currently the choices seem to be

some-8-bit-superset-of-USASCII (like Latin-1), utf8, and UTF16 (little- or

big-endian). If I understand these things right, a file that starts with a

BOM is UTF16, otherwise it's some-8-bit-superset-of-USASCII, unless/until

there's a "use utf8" pragma, which puts in it utf8 mode (until any "no

utf8" pragma).



I'm generally unhappy with the idea of literal byte values over 127 coming

up at all in POD files, but it's occasionally quite unavoidable, because

you can't use E<...>'s in verbatim paragraphs.

So if someone wants to discuss a "sub échanger { ..." in a verbatim

paragraph, there will /have/ to be 8th-bit bytes involved.

Since I think Perl allows subnames like "échanger" only in utf8 / utf16

files, it more or less follows that the default for POD should be utf8.

(Since if the default un-BOM'd encoding were something else, like Latin-1,

then a verbatim block with a utf8-encoded "sub échanger {" will come out

wrong, as "sub échanger {", to the confusion of all concerned.)



Now, it would be awful nice if there were a way to declare the

character-encoding of POD files, as something other than utf8/utf16 -- as

specifically Latin-1, MacASCII, whatever.

But there isn't currently, so it'll have to wait for a future perlpodspec.

(It'd presumably be a breeze to implement that ifwhen Perl supports

character set translation as a handle-discipline!)



PRINT EDITION | Subscribe to

SEARCH:NewsTop 20 E-mailed Articles





washingtonpost.com > Politics > 2004 Election > Presidential Debates

Subscribe to The Post

Email This Article

Transcript: Third Presidential Debate

Arizona State University, Tempe, Ariz.

October 13, 2004

Debate Transcript From FDCH E-Media, Inc.







Following is a transcript of the third and final presidential debate between between President Bush (R) and Sen. John F. Kerry (D). The moderator of the nationally televised debate is Bob Schieffer of CBS News.





Staff writers from The Washington Post and washingtonpost.com examine the candidates' claims and charges. The "referee" icon marks the spots of our calls and where you can make your call as well.



• Homeland Security

• Bush on Bin Laden

• Health Coverage

• Kerry's Health Care Costs

• Job Losses

• 'McCain-Kerry Commission'

• Kerry's Tax Votes

• Trade & Worker Training

• Quality of Jobs

• Middle Income Taxes

• Medical Malpractice Costs

• Drug Company 'Windfall'

• Kerry's Senate Record

• Social Security Costs

• Upper Income Taxes

• No Child Left Behind

• Congressional Black Caucus

• Pell Grants







____ Referee Contributors ____



Washington Post staff writers Glenn Kessler, Ceci Connolly, Thomas E. Ricks, Mike Allen, Jonathan Weisman and Mark Stencel and washingtonpost.com producers Mike Snyder, Kevin Hechtkopf, Chet Rhodes, Suzette McLoone, Ed O'Keefe, Kristen Fletcher, Mike Santa Rita, Kaukab Jhumra Smith and Ryan Thornburg.





___ Debate Coverage ___



Full Debate Video:

The final presidential debate, held at Arizona State University in Tempe, Ariz.





_____Thursday Discussions_____



• 10 a.m. ET: Post Associate Editor Robert G. Kaiser analyzes the third presidential debate.

• Noon ET: PBS "Washington Week" host and moderator of the vice presidential debate Gwen Ifill.

• 1 p.m. ET: washingtonpost.com's Chief Political Correspondent Terry M. Neal on the latest election news.





_____Latest News_____



• Full Coverage of Debates

• Latest Blogs on the Debate









SCHIEFFER: Good evening from Arizona State University in Tempe, Arizona. I'm Bob Schieffer of CBS News. I want to welcome you to the third and last of the 2004 debates between President George Bush and Senator John Kerry.



As Jim Lehrer told you before the first one, these debates are sponsored by the Commission on Presidential Debates.



Tonight the topic will be domestic affairs, but the format will be the same as that first debate. I'll moderate our discussion under detailed rules agreed to by the candidates, but the questions and the areas to be covered were chosen by me. I have not told the candidates or anyone else what they are.



To refresh your memory on the rules, I will ask a question. The candidate is allowed two minutes to answer. His opponent then has a minute and a half to offer a rebuttal.



At my discretion, I can extend the discussion by offering each candidate an additional 30 seconds.



A green light will come on to signal the candidate has 30 seconds left. A yellow light signals 15 seconds left. A red light means five seconds left.



There is also a buzzer, if it is needed.



The candidates may not question each other directly. There are no opening statements, but there will be two-minute closing statements.



There is an audience here tonight, but they have agreed to remain silent, except for right now, when they join me in welcoming President George Bush and Senator John Kerry.



(APPLAUSE)



SCHIEFFER: Gentleman, welcome to you both.



By coin toss, the first question goes to Senator Kerry.



Senator, I want to set the stage for this discussion by asking the question that I think hangs over all of our politics today and is probably on the minds of many people watching this debate tonight.



And that is, will our children and grandchildren ever live in a world as safe and secure as the world in which we grew up?



KERRY: Well, first of all, Bob, thank you for moderating tonight.



Thank you, Arizona State, for welcoming us.



And thank you to the Presidential Commission for undertaking this enormous task. We're proud to be here.



Mr. President, I'm glad to be here with you again to share similarities and differences with the American people.



Will we ever be safe and secure again? Yes. We absolutely must be. That's the goal.



Now, how do we achieve it is the most critical component of it.



I believe that this president, regrettably, rushed us into a war, made decisions about foreign policy, pushed alliances away. And, as a result, America is now bearing this extraordinary burden where we are not as safe as we ought to be.



The measurement is not: Are we safer? The measurement is: Are we as safe as we ought to be? And there are a host of options that this president had available to him, like making sure that at all our ports in America containers are inspected. Only 95 percent of them -- 95 percent come in today uninspected. That's not good enough.



People who fly on airplanes today, the cargo hold is not X-rayed, but the baggage is. That's not good enough. Firehouses don't have enough firefighters in them. Police officers are being cut from the streets of America because the president decided to cut the COPS program.



So we can do a better job of homeland security. I can do a better job of waging a smarter, more effective war on terror and guarantee that we will go after the terrorists.



I will hunt them down, and we'll kill them, we'll capture them. We'll do whatever is necessary to be safe.



But I pledge this to you, America: I will do it in the way that Franklin Roosevelt and Ronald Reagan and John Kennedy and others did, where we build the strongest alliances, where the world joins together, where we have the best intelligence and where we are able, ultimately, to be more safe and secure.



SCHIEFFER: Mr. President, you have 90 seconds.



BUSH: Thank you very much.



I want to thank Arizona State as well.



Yes, we can be safe and secure, if we stay on the offense against the terrorists and if we spread freedom and liberty around the world.



I have got a comprehensive strategy to not only chase down the Al Qaida, wherever it exists -- and we're making progress; three-quarters of Al Qaida leaders have been brought to justice -- but to make sure that countries that harbor terrorists are held to account.



As a result of securing ourselves and ridding the Taliban out of Afghanistan, the Afghan people had elections this weekend. And the first voter was a 19-year-old woman. Think about that. Freedom is on the march.



We held to account a terrorist regime in Saddam Hussein.



In other words, in order to make sure we're secure, there must be a comprehensive plan.



My opponent just this weekend talked about how terrorism could be reduced to a nuisance, comparing it to prostitution, illegal gambling. I think that attitude and that point of view is dangerous. I don't think you can secure America for the long run if you don't have a comprehensive view as to how to defeat these people.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

At home, we'll do everything we can to protect the homeland. I signed the homeland security bill to better align our assets and resources. My opponent voted against it.



We're doing everything we can to protect our borders and ports.



But absolutely we can be secure in the long run. It just takes good, strong leadership.



SCHIEFFER: Anything to add, Senator Kerry?



KERRY: Yes. When the president had an opportunity to capture or kill Osama bin Laden, he took his focus off of them, outsourced the job to Afghan warlords, and Osama bin Laden escaped.



Six months after he said Osama bin Laden must be caught dead or alive, this president was asked, "Where is Osama bin Laden?" He said, "I don't know. I don't really think about him very much. I'm not that concerned."



We need a president who stays deadly focused on the real war on terror.



SCHIEFFER: Mr. President?



Our Call

Analysis and video excerpt

Your Call

Reader's forum

BUSH: Gosh, I just don't think I ever said I'm not worried about Osama bin Laden. It's kind of one of those exaggerations.



Of course we're worried about Osama bin Laden. We're on the hunt after Osama bin Laden. We're using every asset at our disposal to get Osama bin Laden.



My opponent said this war is a matter of intelligence and law enforcement. No, this war is a matter of using every asset at our disposal to keep the American people protected.



SCHIEFFER: New question, Mr. President, to you.



We are talking about protecting ourselves from the unexpected, but the flu season is suddenly upon us. Flu kills thousands of people every year.



Suddenly we find ourselves with a severe shortage of flu vaccine. How did that happen?



BUSH: Bob, we relied upon a company out of England to provide about half of the flu vaccines for the United States citizen, and it turned out that the vaccine they were producing was contaminated. And so we took the right action and didn't allow contaminated medicine into our country.



We're working with Canada to hopefully -- that they'll produce a -- help us realize the vaccine necessary to make sure our citizens have got flu vaccinations during this upcoming season.



My call to our fellow Americans is if you're healthy, if you're younger, don't get a flu shot this year. Help us prioritize those who need to get the flu shot, the elderly and the young.



The CDC, responsible for health in the United States, is setting those priorities and is allocating the flu vaccine accordingly.



I haven't gotten a flu shot, and I don't intend to because I want to make sure those who are most vulnerable get treated.



We have a problem with litigation in the United States of America. Vaccine manufacturers are worried about getting sued, and therefore they have backed off from providing this kind of vaccine.



One of the reasons I'm such a strong believer in legal reform is so that people aren't afraid of producing a product that is necessary for the health of our citizens and then end up getting sued in a court of law.



But the best thing we can do now, Bob, given the circumstances with the company in England is for those of us who are younger and healthy, don't get a flu shot.



SCHIEFFER: Senator Kerry?



KERRY: This really underscores the problem with the American health-care system. It's not working for the American family. And it's gotten worse under President Bush over the course of the last years.



Five million Americans have lost their health insurance in this country. You've got about a million right here in Arizona, just shy, 950,000, who have no health insurance at all. 82,000 Arizonians lost their health insurance under President Bush's watch. 223,000 kids in Arizona have no health insurance at all.



All across our country -- go to Ohio, 1.4 million Ohioans have no health insurance, 114,000 of them lost it under President Bush; Wisconsin, 82,000, Wisconsites lost it under President Bush.



This president has turned his back on the wellness of America. And there is no system. In fact, it's starting to fall apart not because of lawsuits -- though they are a problem, and John Edwards and I are committed to fixing them -- but because of the larger issue that we don't cover Americans.



Children across our country don't have health care. We're the richest country on the face of the planet, the only industrialized nation in the world not to do it.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

I have a plan to cover all Americans. We're going to make it affordable and accessible. We're going to let everybody buy into the same health-care plan senators and congressmen give themselves.



SCHIEFFER: Mr. President, would you like to add something?



BUSH: I would. Thank you.



I want to remind people listening tonight that a plan is not a litany of complaints, and a plan is not to lay out programs that you can't pay for.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

He just said he wants everybody to be able to buy in to the same plan that senators and congressmen get. That costs the government $7,700 per family. If every family in America signed up, like the senator suggested, if would cost us $5 trillion over 10 years.



It's an empty promise. It's called bait and switch.



SCHIEFFER: Time's up.



BUSH: Thank you.



KERRY: Actually, it's not an empty promise.



It's really interesting, because the president used that very plan as a reason for seniors to accept his prescription drug plan. He said, if it's good enough for the congressmen and senators to have choice, seniors ought to have choice.



What we do is we have choice. I choose Blue Cross/Blue Shield. Other senators, other congressmen choose other programs.



But the fact is, we're going to help Americans be able to buy into it. Those that can afford it are going to buy in themselves. We're not giving this away for nothing.



SCHIEFFER: All right.



Senator Kerry, a new question. Let's talk about economic security. You pledged during the last debate that you would not raise taxes on those making less than $200,000 a year. But the price of everything is going up, and we all know it. Health care costs, as you all talking about, is skyrocketing, the cost of the war.



My question is, how can you or any president, whoever is elected next time, keep that pledge without running this country deeper into debt and passing on more of the bills that we're running up to our children?



KERRY: I'll tell you exactly how I can do it: by reinstating what President Bush took away, which is called pay as you go.



During the 1990s, we had pay-as-you-go rules. If you were going to pass something in the Congress, you had to show where you are going to pay for it and how.



President Bush has taken -- he's the only president in history to do this.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

He's also the only president in 72 years to lose jobs -- 1.6 million jobs lost. He's the only president to have incomes of families go down for the last three years; the only president to see exports go down; the only president to see the lowest level of business investment in our country as it is today.



Now, I'm going to reverse that. I'm going to change that. We're going to restore the fiscal discipline we had in the 1990s.



Every plan that I have laid out -- my health-care plan, my plan for education, my plan for kids to be able to get better college loans -- I've shown exactly how I'm going to pay for those.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

And we start -- we don't do it exclusively -- but we start by rolling back George Bush's unaffordable tax cut for the wealthiest people, people earning more than $200,000 a year, and we pass, hopefully, the McCain-Kerry Commission which identified some $60 billion that we can get.



We shut the loophole which has American workers actually subsidizing the loss of their own job. They just passed an expansion of that loophole in the last few days: $43 billion of giveaways, including favors to the oil and gas industry and the people importing ceiling fans from China.



I'm going to stand up and fight for the American worker. And I am going to do it in a way that's fiscally sound. I show how I pay for the health care, how we pay for the education.



I have a manufacturing jobs credit. We pay for it by shutting that loophole overseas. We raise the student loans. I pay for it by changing the relationship with the banks.



This president has never once vetoed one bill; the first president in a hundred years not to do that.



SCHIEFFER: Mr. President?



BUSH: Well, his rhetoric doesn't match his record.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

He been a senator for 20 years. He voted to increase taxes 98 times. When they tried to reduce taxes, he voted against that 127 times. He talks about being a fiscal conservative, or fiscally sound, but he voted over -- he voted 277 times to waive the budget caps, which would have cost the taxpayers $4.2 trillion.



He talks about PAYGO. I'll tell you what PAYGO means, when you're a senator from Massachusetts, when you're a colleague of Ted Kennedy, pay go means: You pay, and he goes ahead and spends.



He's proposed $2.2 trillion of new spending, and yet the so-called tax on the rich, which is also a tax on many small-business owners in America, raises $600 million by our account -- billion, $800 billion by his account.



There is a tax gap. And guess who usually ends up filling the tax gap? The middle class.



I propose a detailed budget, Bob. I sent up my budget man to the Congress, and he says, here's how we're going to reduce the deficit in half by five years. It requires pro-growth policies that grow our economy and fiscal sanity in the halls of Congress.



SCHIEFFER: Let's go to a new question, Mr. President. Two minutes. And let's continue on jobs.



You know, there are all kind of statistics out there, but I want to bring it down to an individual.



Mr. President, what do you say to someone in this country who has lost his job to someone overseas who's being paid a fraction of what that job paid here in the United States?



BUSH: I'd say, Bob, I've got policies to continue to grow our economy and create the jobs of the 21st century. And here's some help for you to go get an education. Here's some help for you to go to a community college.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

We've expanded trade adjustment assistance. We want to help pay for you to gain the skills necessary to fill the jobs of the 21st century.



You know, there's a lot of talk about how to keep the economy growing. We talk about fiscal matters. But perhaps the best way to keep jobs here in America and to keep this economy growing is to make sure our education system works.



I went to Washington to solve problems. And I saw a problem in the public education system in America. They were just shuffling too many kids through the system, year after year, grade after grade, without learning the basics.



And so we said: Let's raise the standards. We're spending more money, but let's raise the standards and measure early and solve problems now, before it's too late.



No, education is how to help the person who's lost a job. Education is how to make sure we've got a workforce that's productive and competitive.



Got four more years, I've got more to do to continue to raise standards, to continue to reward teachers and school districts that are working, to emphasize math and science in the classrooms, to continue to expand Pell Grants to make sure that people have an opportunity to start their career with a college diploma.



And so the person you talked to, I say, here's some help, here's some trade adjustment assistance money for you to go a community college in your neighborhood, a community college which is providing the skills necessary to fill the jobs of the 21st century. And that's what I would say to that person.



SCHIEFFER: Senator Kerry?



KERRY: I want you to notice how the president switched away from jobs and started talking about education principally.



Let me come back in one moment to that, but I want to speak for a second, if I can, to what the president said about fiscal responsibility.



Being lectured by the president on fiscal responsibility is a little bit like Tony Soprano talking to me about law and order in this country.



(LAUGHTER)



This president has taken a $5.6 trillion surplus and turned it into deficits as far as the eye can see. Health-care costs for the average American have gone up 64 percent; tuitions have gone up 35 percent; gasoline prices up 30 percent; Medicare premiums went up 17 percent a few days ago; prescription drugs are up 12 percent a year.



But guess what, America? The wages of Americans have gone down. The jobs that are being created in Arizona right now are paying about $13,700 less than the jobs that we're losing.



And the president just walks on by this problem. The fact is that he's cut job-training money. $1 billion was cut. They only added a little bit back this year because it's an election year.



They've cut the Pell Grants and the Perkins loans to help kids be able to go to college.



They've cut the training money. They've wound up not even extending unemployment benefits and not even extending health care to those people who are unemployed.



I'm going to do those things, because that's what's right in America: Help workers to transition in every respect.



SCHIEFFER: New question to you, Senator Kerry, two minutes. And it's still on jobs. You know, many experts say that a president really doesn't have much control over jobs. For example, if someone invents a machine that does the work of five people, that's progress. That's not the president's fault.



So I ask you, is it fair to blame the administration entirely for this loss of jobs?



KERRY: I don't blame them entirely for it. I blame the president for the things the president could do that has an impact on it.



Outsourcing is going to happen. I've acknowledged that in union halls across the country. I've had shop stewards stand up and say, "Will you promise me you're going to stop all this outsourcing?" And I've looked them in the eye and I've said, "No, I can't do that."



What I can promise you is that I will make the playing field as fair as possible, that I will, for instance, make certain that with respect to the tax system that you as a worker in America are not subsidizing the loss of your job.



Today, if you're an American business, you actually get a benefit for going overseas. You get to defer your taxes.



So if you're looking at a competitive world, you say to yourself, "Hey, I do better overseas than I do here in America."



That's not smart. I don't want American workers subsidizing the loss of their own job. And when I'm president, we're going to shut that loophole in a nanosecond and we're going to use that money to lower corporate tax rates in America for all corporations, 5 percent. And we're going to have a manufacturing jobs credit and a job hiring credit so we actually help people be able to hire here.



The second thing that we can do is provide a fair trade playing field. This president didn't stand up for Boeing when Airbus was violating international rules and subsidies. He discovered Boeing during the course of this campaign after I'd been talking about it for months.



The fact is that the president had an opportunity to stand up and take on China for currency manipulation. There are companies that wanted to petition the administration. They were told: Don't even bother; we're not going to listen to it.



The fact is that there have been markets shut to us that we haven't stood up and fought for. I'm going to fight for a fair trade playing field for the American worker. And I will fight for the American worker just as hard as I fight for my own job. That's what the American worker wants. And if we do that, we can have an impact.



Plus, we need fiscal discipline. Restore fiscal discipline, we'll do a lot better.



SCHIEFFER: Mr. President?



BUSH: Whew!



Let me start with the Pell Grants. In his last litany of misstatements. He said we cut Pell Grants. We've increased Pell Grants by a million students. That's a fact.



You know, he talks to the workers. Let me talk to the workers.



You've got more money in your pocket as a result of the tax relief we passed and he opposed.



If you have a child, you got a $1,000 child credit. That's money in your pocket.



If you're married, we reduced the marriage penalty. The code ought to encourage marriage, not discourage marriage.



We created a 10 percent bracket to help lower-income Americans. A family of four making $40,000 received about $1,700 in tax relief.



It's your money. The way my opponent talks, he said, "We're going to spend the government's money." No, we're spending your money. And when you have more money in your pocket, you're able to better afford things you want.



I believe the role of government is to stand side by side with our citizens to help them realize their dreams, not tell citizens how to live their lives.



My opponent talks about fiscal sanity. His record in the United States Senate does not match his rhetoric.



He voted to increase taxes 98 times and to bust the budget 277 times.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

SCHIEFFER: Senator Kerry?



KERRY: Bob, anybody can play with these votes. Everybody knows that.



I have supported or voted for tax cuts over 600 times. I broke with my party in order to balance the budget, and Ronald Reagan signed into law the tax cut that we voted for. I voted for IRA tax cuts. I voted for small-business tax cuts.



But you know why the Pell Grants have gone up in their numbers? Because more people qualify for them because they don't have money.



But they're not getting the $5,100 the president promised them. They're getting less money.



We have more people who qualify. That's not what we want.



BUSH: Senator, no one's playing with your votes. You voted to increase taxes 98 times. When they voted -- when they proposed reducing taxes, you voted against it 126 times.



He voted to violate the budget cap 277 times. You know, there's a main stream in American politics and you sit right on the far left bank. As a matter of fact, your record is such that Ted Kennedy, your colleague, is the conservative senator from Massachusetts.



SCHIEFFER: Mr. President, let's get back to economic issues. But let's shift to some other questions here.



Both of you are opposed to gay marriage. But to understand how you have come to that conclusion, I want to ask you a more basic question. Do you believe homosexuality is a choice?



BUSH: You know, Bob, I don't know. I just don't know. I do know that we have a choice to make in America and that is to treat people with tolerance and respect and dignity. It's important that we do that.



And I also know in a free society people, consenting adults can live the way they want to live.



And that's to be honored.



But as we respect someone's rights, and as we profess tolerance, we shouldn't change -- or have to change -- our basic views on the sanctity of marriage. I believe in the sanctity of marriage. I think it's very important that we protect marriage as an institution, between a man and a woman.



I proposed a constitutional amendment. The reason I did so was because I was worried that activist judges are actually defining the definition of marriage, and the surest way to protect marriage between a man and woman is to amend the Constitution.



It has also the benefit of allowing citizens to participate in the process. After all, when you amend the Constitution, state legislatures must participate in the ratification of the Constitution.



I'm deeply concerned that judges are making those decisions and not the citizenry of the United States. You know, Congress passed a law called DOMA, the Defense of Marriage Act.



My opponent was against it. It basically protected states from the action of one state to another. It also defined marriage as between a man and woman.



But I'm concerned that that will get overturned. And if it gets overturned, then we'll end up with marriage being defined by courts, and I don't think that's in our nation's interests.



SCHIEFFER: Senator Kerry?



KERRY: We're all God's children, Bob. And I think if you were to talk to Dick Cheney's daughter, who is a lesbian, she would tell you that she's being who she was, she's being who she was born as.



I think if you talk to anybody, it's not choice. I've met people who struggled with this for years, people who were in a marriage because they were living a sort of convention, and they struggled with it.



And I've met wives who are supportive of their husbands or vice versa when they finally sort of broke out and allowed themselves to live who they were, who they felt God had made them.



I think we have to respect that.



The president and I share the belief that marriage is between a man and a woman. I believe that. I believe marriage is between a man and a woman.



But I also believe that because we are the United States of America, we're a country with a great, unbelievable Constitution, with rights that we afford people, that you can't discriminate in the workplace. You can't discriminate in the rights that you afford people.



You can't disallow someone the right to visit their partner in a hospital. You have to allow people to transfer property, which is why I'm for partnership rights and so forth.



Now, with respect to DOMA and the marriage laws, the states have always been able to manage those laws. And they're proving today, every state, that they can manage them adequately.



SCHIEFFER: Senator Kerry, a new question for you.



The New York Times reports that some Catholic archbishops are telling their church members that it would be a sin to vote for a candidate like you because you support a woman's right to choose an abortion and unlimited stem-cell research.



What is your reaction to that?



KERRY: I respect their views. I completely respect their views. I am a Catholic. And I grew up learning how to respect those views. But I disagree with them, as do many.



I believe that I can't legislate or transfer to another American citizen my article of faith. What is an article of faith for me is not something that I can legislate on somebody who doesn't share that article of faith.



I believe that choice is a woman's choice. It's between a woman, God and her doctor. And that's why I support that.



Now, I will not allow somebody to come in and change Roe v. Wade.



The president has never said whether or not he would do that. But we know from the people he's tried to appoint to the court he wants to.



I will not. I will defend the right of Roe v. Wade.



Now, with respect to religion, you know, as I said, I grew up a Catholic. I was an altar boy. I know that throughout my life this has made a difference to me.



And as President Kennedy said when he ran for president, he said, "I'm not running to be a Catholic president. I'm running to be a president who happens to be Catholic."



My faith affects everything that I do, in truth. There's a great passage of the Bible that says, "What does it mean, my brother, to say you have faith if there are no deeds? Faith without works is dead."



And I think that everything you do in public life has to be guided by your faith, affected by your faith, but without transferring it in any official way to other people.



That's why I fight against poverty. That's why I fight to clean up the environment and protect this earth.



That's why I fight for equality and justice. All of those things come out of that fundamental teaching and belief of faith.



But I know this, that President Kennedy in his inaugural address told all of us that here on Earth, God's work must truly be our own. And that's what we have to -- I think that's the test of public service.



SCHIEFFER: Mr. President?



BUSH: I think it's important to promote a culture of life. I think a hospitable society is a society where every being counts and every person matters.



I believe the ideal world is one in which every child is protected in law and welcomed to life. I understand there's great differences on this issue of abortion, but I believe reasonable people can come together and put good law in place that will help reduce the number of abortions.



Take, for example, the ban on partial birth abortion. It's a brutal practice. People from both political parties came together in the halls of Congress and voted overwhelmingly to ban that practice. It made a lot of sense. My opponent, in that he's out of the mainstream, voted against that law.



What I'm saying is is that as we promote life and promote a culture of life, surely there are ways we can work together to reduce the number of abortions: continue to promote adoption laws -- it's a great alternative to abortion -- continue to fund and promote maternity group homes; I will continue to promote abstinence programs.



The last debate, my opponent said his wife was involved with those programs. That's great. I appreciate that very much. All of us ought to be involved with programs that provide a viable alternative to abortion.



SCHIEFFER: Mr. President, let's have a new question. It goes to you. And let's get back to economic issues.



Health insurance costs have risen over 36 percent over the last four years according to The Washington Post. We're paying more. We're getting less.



I would like to ask you: Who bears responsibility for this? Is it the government? Is it the insurance companies? Is it the lawyers? Is it the doctors? Is it the administration?



BUSH: Gosh, I sure hope it's not the administration.



There's a -- no, look, there's a systemic problem. Health care costs are on the rise because the consumers are not involved in the decision-making process. Most health care costs are covered by third parties. And therefore, the actual user of health care is not the purchaser of health care. And there's no market forces involved with health care.



It's one of the reasons I'm a strong believer in what they call health savings accounts. These are accounts that allow somebody to buy a low-premium, high-deductible catastrophic plan and couple it with tax-free savings. Businesses can contribute, employees can contribute on a contractual basis. But this is a way to make sure people are actually involved with the decision-making process on health care.



Secondly, I do believe the lawsuits -- I don't believe, I know -- that the lawsuits are causing health care costs to rise in America. That's why I'm such a strong believer in medical liability reform.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

In the last debate, my opponent said those lawsuits only caused the cost to go up by 1 percent. Well, he didn't include the defensive practice of medicine that costs the federal government some $28 billion a year and costs our society between $60 billion and $100 billion a year.



Thirdly, one of the reasons why there's still high cost in medicine is because this is -- they don't use any information technology. It's like if you looked at the -- it's the equivalent of the buggy and horse days, compared to other industries here in America.



And so, we've got to introduce high technology into health care. We're beginning to do it. We're changing the language. We want there to be electronic medical records to cut down on error, as well as reduce cost.



People tell me that when the health-care field is fully integrated with information technology, it'll wring some 20 percent of the cost out of the system.



And finally, moving generic drugs to the market quicker.



And so, those are four ways to help control the costs in health care.



SCHIEFFER: Senator Kerry?



KERRY: The reason health care costs are getting higher, one of the principal reasons is that this administration has stood in the way of common-sense efforts that would have reduced the costs. Let me give you a prime example.



In the Senate we passed the right of Americans to import drugs from Canada. But the president and his friends took it out in the House, and now you don't have that right. The president blocked you from the right to have less expensive drugs from Canada.



We also wanted Medicare to be able to negotiate bulk purchasing. The VA does that. The VA provides lower-cost drugs to our veterans. We could have done that in Medicare.



Medicare is paid for by the American taxpayer. Medicare belongs to you. Medicare is for seniors, who many of them are on fixed income, to lift them out of poverty.



KERRY: But rather than help you, the taxpayer, have lower cost, rather than help seniors have less expensive drugs, the president made it illegal -- illegal -- for Medicare to actually go out and bargain for lower prices.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

Result: $139 billion windfall profit to the drug companies coming out of your pockets. That's a large part of your 17 percent increase in Medicare premiums.



When I'm president, I'm sending that back to Congress and we're going to get a real prescription drug benefit.



Now, we also have people sicker because they don't have health insurance. So whether it's diabetes or cancer, they come to hospitals later and it costs America more.



We got to have health care for all Americans.



SCHIEFFER: Go ahead, Mr. President.



BUSH: I think it's important, since he talked about the Medicare plan, has he been in the United States Senate for 20 years? He has no record on reforming of health care. No record at all.



He introduced some 300 bills and he's passed five.



No record of leadership.



I came to Washington to solve problems. I was deeply concerned about seniors having to choose between prescription drugs and food. And so I led. And in 2006, our seniors will get a prescription drug coverage in Medicare.



SCHIEFFER: Senator Kerry? Thirty seconds.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

KERRY: Once again, the president is misleading America. I've actually passed 56 individual bills that I've personally written and, in addition to that, and not always under my name, there is amendments on certain bills.



But more importantly, with respect to the question of no record, I helped write -- I did write, I was one of the original authors of the early childhood health care and the expansion of health care that we did in the middle of the 1990s. And I'm very proud of that.



So the president's wrong.



SCHIEFFER: Let me direct the next question to you, Senator Kerry, and again, let's stay on health care.



You have, as you have proposed and as the president has commented on tonight, proposed a massive plan to extend health-care coverage to children. You're also talking about the government picking up a big part of the catastrophic bills that people get at the hospital.



And you have said that you can pay for this by rolling back the president's tax cut on the upper 2 percent.



You heard the president say earlier tonight that it's going to cost a whole lot more money than that.



I'd just ask you, where are you going to get the money?



KERRY: Well, two leading national news networks have both said the president's characterization of my health-care plan is incorrect. One called it fiction. The other called it untrue.



The fact is that my health-care plan, America, is very simple. It gives you the choice. I don't force you to do anything. It's not a government plan. The government doesn't require you to do anything. You choose your doctor. You choose your plan.



If you don't want to take the offer of the plan that I want to put forward, you don't have do. You can keep what you have today, keep a high deductible, keep high premiums, keep a high co-pay, keep low benefits.



But I got a better plan. And I don't think a lot of people are going to want to keep what they have today.



Here's what I do: We take over Medicaid children from the states so that every child in America is covered. And in exchange, if the states want to -- they're not forced to, they can choose to -- they cover individuals up to 300 percent of poverty. It's their choice.



I think they'll choose it, because it's a net plus of $5 billion to them.



We allow you -- if you choose to, you don't have to -- but we give you broader competition to allow you to buy into the same health care plan that senators and congressmen give themselves. If it's good enough for us, it's good enough for every American. I believe that your health care is just as important as any politician in Washington, D.C.



You want to buy into it, you can. We give you broader competition. That helps lower prices.



In addition to that, we're going to allow people 55 to 64 to buy into Medicare early. And most importantly, we give small business a 50 percent tax credit so that after we lower the costs of health care, they also get, whether they're self-employed or a small business, a lower cost to be able to cover their employees.



Now, what happens is when you begin to get people covered like that -- for instance in diabetes, if you diagnose diabetes early, you could save $50 billion in the health care system of America by avoiding surgery and dialysis. It works. And I'm going to offer it to America.



SCHIEFFER: Mr. President?



BUSH: In all due respect, I'm not so sure it's credible to quote leading news organizations about -- oh, nevermind. Anyway, let me quote the Lewin report. The Lewin report is a group of folks who are not politically affiliated. They analyzed the senator's plan. It cost $1.2 trillion.



The Lewin report accurately noted that there are going to be 20 million people, over 20 million people added to government-controlled health care. It would be the largest increase in government health care ever.



If you raise the Medicaid to 300 percent, it provides an incentive for small businesses not to provide private insurance to their employees. Why should they insure somebody when the government's going to insure it for them?



It's estimated that 8 million people will go from private insurance to government insurance.



We have a fundamental difference of opinion. I think government- run health will lead to poor-quality health, will lead to rationing, will lead to less choice.



Once a health-care program ends up in a line item in the federal government budget, it leads to more controls.



And just look at other countries that have tried to have federally controlled health care. They have poor-quality health care.



Our health-care system is the envy of the world because we believe in making sure that the decisions are made by doctors and patients, not by officials in the nation's capital.



SCHIEFFER: Senator?



KERRY: The president just said that government-run health care results in poor quality.



Now, maybe that explains why he hasn't fully funded the VA, and the VA hospital is having trouble, and veterans are complaining. Maybe that explains why Medicare patients are complaining about being pushed off of Medicare. He doesn't adequately fund it.



But let me just say to America: I am not proposing a government- run program. That's not what I have. I have Blue Cross/Blue Shield. Senators and congressmen have a wide choice. Americans ought to have it, too.



SCHIEFFER: Mr. President?



BUSH: Talk about the VA: We've increased VA funding by $22 billion in the four years since I've been president. That's twice the amount that my predecessor increased VA funding.



Of course we're meeting our obligation to our veterans, and the veterans know that.



We're expanding veterans' health care throughout the country. We're aligning facilities where the veterans live now. Veterans are getting very good health care under my administration, and they will continue to do so during the next four years.



SCHIEFFER: Mr. President, the next question is to you. We all know that Social Security is running out of money, and it has to be fixed. You have proposed to fix it by letting people put some of the money collected to pay benefits into private savings accounts. But the critics are saying that's going to mean finding $1 trillion over the next 10 years to continue paying benefits as those accounts are being set up.



So where do you get the money? Are you going to have to increase the deficit by that much over 10 years?



BUSH: First, let me make sure that every senior listening today understands that when we're talking about reforming Social Security, that they'll still get their checks.



I remember the 2000 campaign, people said: if George W. gets elected, your check will be taken away.



Well, people got their checks, and they'll continue to get their checks.



There is a problem for our youngsters, a real problem. And if we don't act today, the problem will be valued in the trillions.



And so I think we need to think differently.



We'll honor our commitment to our seniors. But for our children and our grandchildren, we need to have a different strategy.



And recognizing that, I called together a group of our fellow citizens to study the issue. It was a committee chaired by the late Senator Daniel Patrick Moynihan of New York, a Democrat. And they came up with a variety of ideas for people to look at.



I believe that younger workers ought to be allowed to take some of their own money and put it in a personal savings account, because I understand that they need to get better rates of return than the rates of return being given in the current Social Security trust.



And the compounding rate of interest effect will make it more likely that the Social Security system is solvent for our children and our grandchildren.



I will work with Republicans and Democrats. It'll be a vital issue in my second term. It is an issue that I am willing to take on, and so I'll bring Republicans and Democrats together.



And we're of course going to have to consider the costs. But I want to warn my fellow citizens: The cost of doing nothing, the cost of saying the current system is OK, far exceeds the costs of trying to make sure we save the system for our children.



SCHIEFFER: Senator Kerry?



KERRY: You just heard the president say that young people ought to be able to take money out of Social Security and put it in their own accounts.



Now, my fellow Americans, that's an invitation to disaster.



The CBO said very clearly that if you were to adopt the president's plan, there would be a $2 trillion hole in Social Security, because today's workers pay in to the system for today's retirees. And the CBO said -- that's the Congressional Budget Office; it's bipartisan -- they said that there would have to be a cut in benefits of 25 percent to 40 percent.



Now, the president has never explained to America, ever, hasn't done it tonight, where does the transitional money, that $2 trillion, come from?



Our Call

Analysis and video excerpt

Your Call

Reader's forum

He's already got $3 trillion, according to The Washington Post, of expenses that he's put on the line from his convention and the promises of this campaign, none of which are paid for. Not one of them are paid for.



The fact is that the president is driving the largest deficits in American history. He's broken the pay-as-you-go rules.



I have a record of fighting for fiscal responsibility. In 1985, I was one of the first Democrats -- broke with my party. We balanced the budget in the '90s. We paid down the debt for two years.



And that's what we're going to do. We're going to protect Social Security. I will not privatize it. I will not cut the benefits. And we're going to be fiscally responsible. And we will take care of Social Security.



SCHIEFFER: Let me just stay on Social Security with a new question for Senator Kerry, because, Senator Kerry, you have just said you will not cut benefits.



Alan Greenspan, the chairman of the Federal Reserve, says there's no way that Social Security can pay retirees what we have promised them unless we recalibrate.



What he's suggesting, we're going to cut benefits or we're going to have to raise the retirement age. We may have to take some other reform. But if you've just said, you've promised no changes, does that mean you're just going to leave this as a problem, another problem for our children to solve?



KERRY: Not at all. Absolutely not, Bob. This is the same thing we heard -- remember, I appeared on "Meet the Press" with Tim Russert in 1990-something. We heard the same thing. We fixed it.



In fact, we put together a $5.6 trillion surplus in the '90s that was for the purpose of saving Social Security. If you take the tax cut that the president of the United States has given -- President Bush gave to Americans in the top 1 percent of America -- just that tax cut that went to the top 1 percent of America would have saved Social Security until the year 2075.



The president decided to give it to the wealthiest Americans in a tax cut. Now, Alan Greenspan, who I think has done a terrific job in monetary policy, supports the president's tax cut. I don't. I support it for the middle class, not that part of it that goes to people earning more than $200,000 a year.



And when I roll it back and we invest in the things that I have talked about to move our economy, we're going to grow sufficiently, it would begin to cut the deficit in half, and we get back to where we were at the end of the 1990s when we balanced the budget and paid down the debt of this country.



Now, we can do that.



Now, if later on after a period of time we find that Social Security is in trouble, we'll pull together the top experts of the country. We'll do exactly what we did it he 1990s. And we'll make whatever adjustment is necessary.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

But the first and most important thing is to start creating jobs in America. The jobs the president is creating pay $9,000 less than the jobs that we're losing. And this is the first president in 72 years to preside over an economy in America that has lost jobs, 1.6 million jobs.



Eleven other presidents -- six Democrats and five Republicans -- had wars, had recessions, had great difficulties; none of them lost jobs the way this president has.



I have a plan to put America back to work. And if we're fiscally responsible and put America back to work, we're going to fix Social Security.



SCHIEFFER: Mr. President?



BUSH: He forgot to tell you he voted to tax Social Security benefits more than one time. I didn't hear any plan to fix Social Security. I heard more of the same.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

He talks about middle-class tax cuts. That's exactly where the tax cuts went. Most of the tax cuts went to low- and middle-income Americans. And now the tax code is more fair. Twenty percent of the upper-income people pay about 80 percent of the taxes in America today because of how we structured the tax cuts.



People listening out there know the benefits of the tax cuts we passed. If you have a child, you got tax relief. If you're married, you got tax relief. If you pay any tax at all, you got tax relief. All of which was opposed by my opponent.



And the tax relief was important to spur consumption and investment to get us out of this recession.



People need to remember: Six months prior to my arrival, the stock market started to go down. And it was one of the largest declines in our history. And then we had a recession and we got attacked, which cost us 1 million jobs.



But we acted. I led the Congress. We passed tax relief. And now this economy is growing. We added 1.9 million new jobs over the last 13 months.



Sure, there's more work to do. But the way to make sure our economy grows is not to raise taxes on small-business owners. It's not to increase the scope of the federal government. It's to make sure we have fiscal sanity and keep taxes low.



SCHIEFFER: Let's go to a new question, Mr. President.



I got more e-mail this week on this question than any other question. And it is about immigration.



I'm told that at least 8,000 people cross our borders illegally every day. Some people believe this is a security issue, as you know. Some believe it's an economic issue. Some see it as a human-rights issue.



How do you see it? And what we need to do about it?



BUSH: I see it as a serious problem. I see it as a security issue, I see it as an economic issue, and I see it as a human-rights issue.



We're increasing the border security of the United States. We've got 1,000 more Border Patrol agents on the southern border.



We're using new equipment. We're using unmanned vehicles to spot people coming across.



And we'll continue to do so over the next four years. It's a subject I'm very familiar with. After all, I was a border governor for a while.



Many people are coming to this country for economic reasons. They're coming here to work. If you can make 50 cents in the heart of Mexico, for example, or make $5 here in America, $5.15, you're going to come here if you're worth your salt, if you want to put food on the table for your families. And that's what's happening.



And so in order to take pressure off the borders, in order to make the borders more secure, I believe there ought to be a temporary worker card that allows a willing worker and a willing employer to mate up, so long as there's not an American willing to do that job, to join up in order to be able to fulfill the employers' needs.



That has the benefit of making sure our employers aren't breaking the law as they try to fill their workforce needs. It makes sure that the people coming across the border are humanely treated, that they're not kept in the shadows of our society, that they're able to go back and forth to see their families. See, the card, it'll have a period of time attached to it.



It also means it takes pressure off the border. If somebody is coming here to work with a card, it means they're not going to have to sneak across the border. It means our border patrol will be more likely to be able to focus on doing their job.



Now, it's very important for our citizens to also know that I don't believe we ought to have amnesty. I don't think we ought to reward illegal behavior. There are plenty of people standing in line to become a citizen. And we ought not to crowd these people ahead of them in line.



BUSH: If they want to become a citizen, they can stand in line, too.



And here is where my opponent and I differ. In September 2003, he supported amnesty for illegal aliens.



SCHIEFFER: Time's up.



Senator?



KERRY: Let me just answer one part of the last question quickly, and then I'll come to immigration.



The American middle class family isn't making it right now, Bob. And what the president said about the tax cuts has been wiped out by the increase in health care, the increase in gasoline, the increase in tuitions, the increase in prescription drugs.



The fact is, the take home pay of a typical American family as a share of national income is lower than it's been since 1929. And the take home pay of the richest .1 percent of Americans is the highest it's been since 1928.



Under President Bush, the middle class has seen their tax burden go up and the wealthiest's tax burden has gone down. Now that's wrong.



Now with respect to immigration reform, the president broke his promise on immigration reform. He said he would reform it. Four years later he is now promising another plan.



Here's what I'll do: Number one, the borders are more leaking today than they were before 9/11. The fact is, we haven't done what we need to do to toughen up our borders, and I will.



Secondly, we need a guest-worker program, but if it's all we have, it's not going to solve the problem.



The second thing we need is to crack down on illegal hiring. It's against the law in the United States to hire people illegally, and we ought to be enforcing that law properly.



And thirdly, we need an earned-legalization program for people who have been here for a long time, stayed out of trouble, got a job, paid their taxes, and their kids are American. We got to start moving them toward full citizenship, out of the shadows.



SCHIEFFER: Do you want to respond, Mr. President?



BUSH: Well, to say that the borders are not as protected as they were prior to September the 11th shows he doesn't know the borders. They're much better protected today than they were when I was the governor of Texas.



We have much more manpower and much more equipment there.



He just doesn't understand how the borders work, evidently, to say that. That is an outrageous claim.



And we'll continue to protect our borders. We're continuing to increase manpower and equipment.



SCHIEFFER: Senator?



KERRY: Four thousand people a day are coming across the border.



The fact is that we now have people from the Middle East, allegedly, coming across the border.



And we're not doing what we ought to do in terms of the technology. We have iris-identification technology. We have thumbprint, fingerprint technology today. We can know who the people are, that they're really the people they say they are when the cross the border.



We could speed it up. There are huge delays.



The fact is our borders are not as secure as they ought to be, and I'll make them secure.



SCHIEFFER: Next question to you, Senator Kerry.



The gap between rich and poor is growing wider. More people are dropping into poverty. Yet the minimum wage has been stuck at, what, $5.15 an hour now for about seven years. Is it time to raise it?



KERRY: Well, I'm glad you raised that question.



It's long overdue time to raise the minimum wage.



And, America, this is one of those issues that separates the president and myself.



We have fought to try to raise the minimum wage in the last years. But the Republican leadership of the House and Senate won't even let us have a vote on it. We're not allowed to vote on it. They don't want to raise the minimum wage. The minimum wage is the lowest minimum wage value it has been in our nation in 50 years.



If we raise the minimum wage, which I will do over several years to $7 an hour, 9.2 million women who are trying to raise their families would earn another $3,800 a year.



The president has denied 9.2 million women $3,800 a year, but he doesn't hesitate to fight for $136,000 to a millionaire.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

One percent of America got $89 billion last year in a tax cut, but people working hard, playing by the rules, trying to take care of their kids, family values, that we're supposed to value so much in America -- I'm tired of politicians who talk about family values and don't value families.



What we need to do is raise the minimum wage. We also need to hold onto equal pay. Women work for 76 cents on the dollar for the same work that men do. That's not right in America.



And we had an initiative that we were working on to raise women's pay. They've cut it off. They've stopped it. They don't enforce these kinds of things.



Now, I think that it a matter of fundamental right that if we raise the minimum wage, 15 million Americans would be positively affected. We'd put money into the hands of people who work hard, who obey the rules, who play for the American Dream.



And if we did that, we'd have more consumption ability in America, which is what we need right in order to kick our economy into gear. I will fight tooth and nail to pass the minimum wage.



BUSH: Actually, Mitch McConnell had a minimum-wage plan that I supported that would have increased the minimum wage.



But let me talk about what's really important for the worker you're referring to. And that's to make sure the education system works. It's to make sure we raise standards.



Listen, the No Child Left Behind Act is really a jobs act when you think about it. The No Child Left Behind Act says, "We'll raise standards. We'll increase federal spending. But in return for extra spending, we now want people to measure -- states and local jurisdictions to measure to show us whether or not a child can read or write or add and subtract."



You cannot solve a problem unless you diagnose the problem. And we weren't diagnosing problems. And therefore just kids were being shuffled through the school.



And guess who would get shuffled through? Children whose parents wouldn't speak English as a first language just move through.



Many inner-city kids just move through. We've stopped that practice now by measuring early. And when we find a problem, we spend extra money to correct it.



I remember a lady in Houston, Texas, told me, "Reading is the new civil right," and she's right. In order to make sure people have jobs for the 21st century, we've got to get it right in the education system, and we're beginning to close a minority achievement gap now.



You see, we'll never be able to compete in the 21st century unless we have an education system that doesn't quit on children, an education system that raises standards, an education that makes sure there's excellence in every classroom.



SCHIEFFER: Mr. President, I want to go back to something Senator Kerry said earlier tonight and ask a follow-up of my own. He said -- and this will be a new question to you -- he said that you had never said whether you would like to overturn Roe v. Wade. So I'd ask you directly, would you like to?



BUSH: What he's asking me is, will I have a litmus test for my judges? And the answer is, no, I will not have a litmus test. I will pick judges who will interpret the Constitution, but I'll have no litmus test.



SCHIEFFER: Senator Kerry, you'd like to respond?



KERRY: Is that a new question or a 30-second question?



SCHIEFFER: That's a new question for Senator -- for President Bush.



KERRY: Which time limit...



SCHIEFFER: You have 90 seconds.



KERRY: Thank you very much.



Well, again, the president didn't answer the question.



I'll answer it straight to America. I'm not going to appoint a judge to the Court who's going to undo a constitutional right, whether it's the First Amendment, or the Fifth Amendment, or some other right that's given under our courts today -- under the Constitution. And I believe that the right of choice is a constitutional right.



So I don't intend to see it undone.



Clearly, the president wants to leave in ambivalence or intends to undo it.



But let me go a step further. We have a long distance yet to travel in terms of fairness in America. I don't know how you can govern in this country when you look at New York City and you see that 50 percent of the black males there are unemployed, when you see 40 percent of Hispanic children -- of black children in some cities -- dropping out of high school.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

And yet the president who talks about No Child Left Behind refused to fully fund -- by $28 billion -- that particular program so you can make a difference in the lives of those young people.



Now right here in Arizona, that difference would have been $131 million to the state of Arizona to help its kids be able to have better education and to lift the property tax burden from its citizens. The president reneged on his promise to fund No Child Left Behind.



He'll tell you he's raised the money, and he has. But he didn't put in what he promised, and that makes a difference in the lives of our children.



SCHIEFFER: Yes, sir?



BUSH: Two things. One, he clearly has a litmus test for his judges, which I disagree with.



And secondly, only a liberal senator from Massachusetts would say that a 49 percent increase in funding for education was not enough.



We've increased funds. But more importantly, we've reformed the system to make sure that we solve problems early, before they're too late.



He talked about the unemployed. Absolutely we've got to make sure they get educated.



He talked about children whose parents don't speak English as a first language? Absolutely we've got to make sure they get educated.



And that's what the No Child Left Behind Act does.



SCHIEFFER: Senator?



KERRY: You don't measure it by a percentage increase. Mr. President, you measure it by whether you're getting the job done.



Five hundred thousand kids lost after-school programs because of your budget.



Now, that's not in my gut. That's not in my value system, and certainly not so that the wealthiest people in America can walk away with another tax cut.



$89 billion last year to the top 1 percent of Americans, but kids lost their after-school programs. You be the judge.



SCHIEFFER: All right, let's go to another question. And it is to Senator Kerry.



You have two minutes, sir.



Senator, the last debate, President Bush said he did not favor a draft. You agreed with him. But our National Guard and Reserve forces are being severely strained because many of them are being held beyond their enlistments. Some of them say that it's a back-door draft.



Is there any relief that could be offered to these brave Americans and their families?



If you became president, Senator Kerry, what would you do about this situation of holding National Guard and Reservists for these extended periods of time and these repeated call-ups that they're now facing?



KERRY: Well, I think the fact that they're facing these repeated call-ups, some of them two and three deployments, and there's a stop- loss policy that prevents people from being able to get out when their time was up, is a reflection of the bad judgment this president exercised in how he has engaged in the world and deployed our forces.



Our military is overextended. Nine out of 10 active-duty Army divisions are either in Iraq, going to Iraq or have come back from Iraq. One way or the other, they're wrapped up in it.



Now, I've proposed adding two active-duty divisions to the Armed Forces of the United States -- one combat, one support.



In addition, I'm going to double the number of Special Forces so that we can fight a more effective war on terror, with less pressure on the National Guard and Reserve. And what I would like to do is see the National Guard and Reserve be deployed differently here in our own country. There's much we can do with them with respect to homeland security. We ought to be doing that. And that would relieve an enormous amount of pressure.



But the most important thing to relieve the pressure on all of the armed forces is frankly to run a foreign policy that recognizes that America is strongest when we are working with real alliances, when we are sharing the burdens of the world by working through our statesmanship at the highest levels and our diplomacy to bring other nations to our side.



I've said it before, I say it again: I believe the president broke faith to the American people in the way that he took this nation to war. He said he would work through a real alliance. He said in Cincinnati we would plan carefully, we would take every precaution. Well, we didn't. And the result is our forces today are overextended.



The fact is that he did not choose to go to war as a last result. And America now is paying, already $120 billion, up to $200 billion before we're finished and much more probably. And that is the result of this president taking his eye off of Osama bin Laden.



SCHIEFFER: Mr. President?



BUSH: The best way to take the pressure off our troops is to succeed in Iraq, is to train Iraqis so they can do the hard work of democracy, is to give them a chance to defend their country, which is precisely what we're doing. We'll have 125,000 troops trained by the end of this year.



I remember going on an airplane in Bangor, Maine, to say thanks to the reservists and Guard that were headed overseas from Tennessee and North Carolina, Georgia. Some of them had been there before.



The people I talked to their spirits were high. They didn't view their service as a back-door draft. They viewed their service as an opportunity to serve their country.



My opponent, the senator, talks about foreign policy.



In our first debate he proposed America pass a global test. In order to defend ourselves, we'd have to get international approval. That's one of the major differences we have about defending our country.



I'll work with allies. I'll work with friends. We'll continue to build strong coalitions. But I will never turn over our national- security decisions to leaders of other countries.



We'll be resolute, we'll be strong, and we'll wage a comprehensive war against the terrorists.



SCHIEFFER: Senator?



KERRY: I have never suggested a test where we turn over our security to any nation. In fact, I've said the opposite: I will never turn the security of the United States over to any nation. No nation will ever have a veto over us.



But I think it makes sense, I think most Americans in their guts know, that we ought to pass a sort of truth standard. That's how you gain legitimacy with your own countrypeople, and that's how you gain legitimacy in the world.



But I'll never fail to protect the United States of America.



BUSH: In 1990, there was a vast coalition put together to run Saddam Hussein out of Kuwait. The international community, the international world said this is the right thing to do, but when it came time to authorize the use of force on the Senate floor, my opponent voted against the use of force.



Apparently you can't pass any test under his vision of the world.



SCHIEFFER: Mr. President, new question, two minutes.



You said that if Congress would vote to extend the ban on assault weapons, that you'd sign the legislation, but you did nothing to encourage the Congress to extend it. Why not?



BUSH: Actually, I made my intentions -- made my views clear. I did think we ought to extend the assault weapons ban, and was told the fact that the bill was never going to move, because Republicans and Democrats were against the assault weapon ban, people of both parties.



I believe law-abiding citizens ought to be able to own a gun. I believe in background checks at gun shows or anywhere to make sure that guns don't get in the hands of people that shouldn't have them.



But the best way to protect our citizens from guns is to prosecute those who commit crimes with guns. And that's why early in my administration I called the attorney general and the U.S. attorneys and said: Put together a task force all around the country to prosecute those who commit crimes with guns. And the prosecutions are up by about 68 percent -- I believe -- is the number.



Neighborhoods are safer when we crack down on people who commit crimes with guns.



To me, that's the best way to secure America.



SCHIEFFER: Senator?



KERRY: I believe it was a failure of presidential leadership not to reauthorize the assault weapons ban.



I am a hunter. I'm a gun owner. I've been a hunter since I was a kid, 12, 13 years old. And I respect the Second Amendment and I will not tamper with the Second Amendment.



But I'll tell you this. I'm also a former law enforcement officer. I ran one of the largest district attorney's offices in America, one of the ten largest. I put people behind bars for the rest of their life. I've broken up organized crime. I know something about prosecuting.



And most of the law enforcement agencies in America wanted that assault weapons ban. They don't want to go into a drug bust and be facing an AK-47.



I was hunting in Iowa last year with a sheriff from one of the counties there, and he pointed to a house in back of us, and said, "See the house over? We just did a drug bust a week earlier, and the guy we arrested had an AK-47 lying on the bed right beside him."



Because of the president's decision today, law enforcement officers will walk into a place that will be more dangerous. Terrorists can now come into America and go to a gun show and, without even a background check, buy an assault weapon today.



And that's what Osama bin Laden's handbook said, because we captured it in Afghanistan. It encouraged them to do it.



So I believe America's less safe.



If Tom DeLay or someone in the House said to me, "Sorry, we don't have the votes," I'd have said, "Then we're going to have a fight."



And I'd have taken it out to the country and I'd have had every law enforcement officer in the country visit those congressmen. We'd have won what Bill Clinton won.



SCHIEFFER: Let's go to a new question. For you, Senator Kerry, two minutes.



Affirmative action: Do you see a need for affirmative action programs, or have we moved far enough along that we no longer need to use race and gender as a factor in school admissions and federal and state contracts and so on?



KERRY: No, Bob, regrettably, we have not moved far enough along.



And I regret to say that this administration has even blocked steps that could help us move further along. I'll give you an example.



I served on the Small Business Committee for a long time. I was chairman of it once. Now I'm the senior Democrat on it. We used to -- you know, we have a goal there for minority set-aside programs, to try to encourage ownership in the country. They don't reach those goals. They don't even fight to reach those goals. They've tried to undo them.



The fact is that in too many parts of our country, we still have discrimination. And affirmative action is not just something that applies to people of color. Some people have a mistaken view of it in America. It also is with respect to women, it's with respect to other efforts to try to reach out and be inclusive in our country.



I think that we have a long way to go, regrettably. If you look at what's happened -- we've made progress, I want to say that at the same time.



During the Clinton years, as you may recall, there was a fight over affirmative action. And there were many people, like myself, who opposed quotas, who felt there were places where it was overreaching. So we had a policy called "Mend it, don't end it." We fixed it.



And we fixed it for a reason: because there are too many people still in this country who feel the stark resistance of racism, and so we have a distance to travel. As president, I will make certain we travel it.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

Now, let me just share something. This president is the first president ever, I think, not to meet with the NAACP. This is a president who hasn't met with the Black Congressional Caucus. This is a president who has not met with the civil rights leadership of our country.



If a president doesn't reach out and bring people in and be inclusive, then how are we going to get over those barriers? I see that as part of my job as president, and I'll make my best effort to do it.



SCHIEFFER: Mr. President?



BUSH: Well, first of all, it is just not true that I haven't met with the Black Congressional Caucus. I met with the Black Congressional Caucus at the White House.



And secondly, like my opponent, I don't agree we ought to have quotas. I agree, we shouldn't have quotas.



Our Call

Analysis and video excerpt

Your Call

Reader's forum

But we ought to have an aggressive effort to make sure people are educated, to make sure when they get out of high school there's Pell Grants available for them, which is what we've done. We've expanded Pell Grants by a million students.



Do you realize today in America, we spend $73 billion to help 10 million low- and middle-income families better afford college?



That's the access I believe is necessary, is to make sure every child learns to read, write, add and subtract early, to be able to build on that education by going to college so they can start their careers with a college diploma.



I believe the best way to help our small businesses is not only through small-business loans, which we have increased since I've been the president of the United States, but to unbundle government contracts so people have a chance to be able to bid and receive a contract to help get their business going.



Minority ownership of businesses are up, because we created an environment for the entrepreneurial spirit to be strong.



I believe part of a hopeful society is one in which somebody owns something. Today in America more minorities own a home than ever before. And that's hopeful, and that's positive.



SCHIEFFER: Mr. President, let's go to a new question.



You were asked before the invasion, or after the invasion, of Iraq if you'd checked with your dad. And I believe, I don't remember the quote exactly, but I believe you said you had checked with a higher authority.



I would like to ask you, what part does your faith play on your policy decisions?



BUSH: First, my faith plays a lot -- a big part in my life. And that's, when I answering that question, what I was really saying to the person was that I pray a lot. And I do.



And my faith is a very -- it's very personal. I pray for strength. I pray for wisdom. I pray for our troops in harm's way. I pray for my family. I pray for my little girls.



But I'm mindful in a free society that people can worship if they want to or not. You're equally an American if you choose to worship an almighty and if you choose not to.



If you're a Christian, Jew or Muslim, you're equally an American. That's the great thing about America, is the right to worship the way you see fit.



Prayer and religion sustain me. I receive calmness in the storms of the presidency.



I love the fact that people pray for me and my family all around the country. Somebody asked me one time, "Well, how do you know?" I said, "I just feel it."



Religion is an important part. I never want to impose my religion on anybody else.



But when I make decisions, I stand on principle, and the principles are derived from who I am.



I believe we ought to love our neighbor like we love ourself, as manifested in public policy through the faith-based initiative where we've unleashed the armies of compassion to help heal people who hurt.



I believe that God wants everybody to be free. That's what I believe.



And that's been part of my foreign policy. In Afghanistan, I believe that the freedom there is a gift from the Almighty. And I can't tell you how encouraged I am to see freedom on the march.



And so my principles that I make decisions on are a part of me, and religion is a part of me.



SCHIEFFER: Senator Kerry?



KERRY: Well, I respect everything that the president has said and certainly respect his faith. I think it's important and I share it. I think that he just said that freedom is a gift from the Almighty.



Everything is a gift from the Almighty. And as I measure the words of the Bible -- and we all do; different people measure different things -- the Koran, the Torah, or, you know, Native Americans who gave me a blessing the other day had their own special sense of connectedness to a higher being. And people all find their ways to express it.



I was taught -- I went to a church school and I was taught that the two greatest commandments are: Love the Lord, your God, with all your mind, your body and your soul, and love your neighbor as yourself. And frankly, I think we have a lot more loving of our neighbor to do in this country and on this planet.



We have a separate and unequal school system in the United States of America. There's one for the people who have, and there's one for the people who don't have. And we're struggling with that today.



And the president and I have a difference of opinion about how we live out our sense of our faith.



I talked about it earlier when I talked about the works and faith without works being dead.



I think we've got a lot more work to do. And as president, I will always respect everybody's right to practice religion as they choose -- or not to practice -- because that's part of America.



SCHIEFFER: Senator Kerry, after 9/11 -- and this is a new question for you -- it seemed to me that the country came together as I've never seen it come together since World War II. But some of that seems to have melted away. I think it's fair to say we've become pretty polarized, perhaps because of the political season.



But if you were elected president, or whoever is elected president, will you set a priority in trying to bring the nation back together? Or what would be your attitude on that?



KERRY: Very much so.



Let me pay a compliment to the president, if I may. I think in those days after 9/11, I thought the president did a terrific job. And I really was moved, as well as impressed, by the speech that he gave to the Congress.



And I think the hug Tom Daschle gave him at that moment was about as genuine a sense of there being no Democrats, no Republicans, we were all just Americans. That's where we were.



That's not where we are today. I regret to say that the president who called himself a uniter, not a divider, is now presiding over the most divided America in the recent memory of our country. I've never seen such ideological squabbles in the Congress of the United States. I've never seen members of a party locked out of meetings the way they're locked out today.



We have to change that. And as president, I am committed to changing that. I don't care if the idea comes from the other side or this side. I think we have to come together and work to change it.



And I've done that. Over 20 years in the United States Senate, I've worked with John McCain, who's sitting here, I've worked with other colleagues. I've reached across the aisle. I've tried to find the common ground, because that's what makes us strong as Americans.



And if Americans trust me with the presidency, I can pledge to you, we will have the most significant effort, openly -- not secret meetings in the White House with special interests, not ideologically driven efforts to push people aside -- but a genuine effort to try to restore America's hope and possibilities by bringing people together.



And one of the ways we're going to do it is, I'm going to work with my friend, John McCain, to further campaign finance reform so we get these incredible amounts of money out of the system and open it up to average people, so America is really represented by the people who make up America.



SCHIEFFER: Mr. President?



BUSH: My biggest disappointment in Washington is how partisan the town is. I had a record of working with Republicans and Democrats as the governor of Texas, and I was hopeful I'd be able to do the same thing.



And we made good progress early on. The No Child Left Behind Act, incredibly enough, was good work between me and my administration and people like Senator Ted Kennedy.



And we worked together with Democrats to relieve the tax burden on the middle class and all who pay taxes in order to make sure this economy continues to grow.



But Washington is a tough town. And the way I view it is there's a lot of entrenched special interests there, people who are, you know, on one side of the issue or another and they spend enormous sums of money and they convince different senators to taut their way or different congressmen to talk about their issue, and they dig in.



I'll continue, in the four years, to continue to try to work to do so.



My opponent said this is a bitterly divided time. Pretty divided in the 2000 election. So in other words, it's pretty divided during the 1990s as well.



We're just in a period -- we've got to work to bring it -- my opponent keeps mentioning John McCain, and I'm glad he did. John McCain is for me for president because he understands I have the right view in winning the war on terror and that my plan will succeed in Iraq. And my opponent has got a plan of retreat and defeat in Iraq.



SCHIEFFER: We've come, gentlemen, to our last question. And it occurred to me as I came to this debate tonight that the three of us share something. All three of us are surrounded by very strong women. We're all married to strong women. Each of us have two daughters that make us very proud.



I'd like to ask each of you, what is the most important thing you've learned from these strong women?



BUSH: To listen to them.



(LAUGHTER)



To stand up straight and not scowl.



(LAUGHTER)



I love the strong women around me. I can't tell you how much I love my wife and our daughters.



I am -- you know it's really interesting. I tell the people on the campaign trail, when I asked Laura to marry me, she said, "Fine, just so long as I never have to give a speech." I said, "OK, you've got a deal." Fortunately, she didn't hold me to that deal. And she's out campaigning along with our girls. And she speaks English a lot better than I do. I think people understand what she's saying.



But they see a compassionate, strong, great first lady in Laura Bush. I can't tell you how lucky I am. When I met her in the backyard at Joe and Jan O'Neill's in Midland, Texas, it was the classic backyard barbecue. O'Neill said, "Come on over. I think you'll find somebody who might interest you." So I said all right. I walked over there. There was only four of us there. And not only did she interest me, I guess you would say it was love at first sight.



SCHIEFFER: Senator Kerry?



KERRY: Well, I guess the president and you and I are three examples of lucky people who married up.



(LAUGHTER)



And some would say maybe me moreso than others.



(LAUGHTER)



But I can take it.



(LAUGHTER)



Can I say, if I could just say a word about a woman that you didn't ask about, but my mom passed away a couple years ago, just before I was deciding to run. And she was in the hospital, and I went in to talk to her and tell her what I was thinking of doing.



And she looked at me from her hospital bed and she just looked at me and she said, "Remember: integrity, integrity, integrity." Those are the three words that she left me with.



And my daughters and my wife are people who just are filled with that sense of what's right, what's wrong.



They also kick me around. They keep me honest. They don't let me get away with anything. I can sometimes take myself too seriously. They surely don't let me do that.



And I'm blessed, as I think the president is blessed, as I said last time. I've watched him with the first lady, who I admire a great deal, and his daughters. He's a great father. And I think we're both very lucky.



SCHIEFFER: Well, gentlemen, that brings us to the closing statements.



Senator Kerry, I believe you're first.



KERRY: My fellow Americans, as you heard from Bob Schieffer a moment ago, America is being tested by division. More than ever, we need to be united as a country.



And, like Franklin Roosevelt, I don't care whether an idea is a Republican idea or a Democrat idea. I just care whether it works for America and whether it's going to make us stronger.



These are dangerous times. I believe I offer tested, strong leadership that can calm the waters of the troubled world. And I believe that we can together do things that are within the grasp of Americans.



We can lift our schools up. We can create jobs that pay more than the jobs we're losing overseas. We can have health care for all Americans. We can further the cause of equality in our nation.



Let me just make it clear: I will never allow any country to have a veto over our security. Just as I fought for our country as a young man, with the same passion I will fight to defend this nation that I love.



And, with faith in God and with conviction in the mission of America, I believe that we can reach higher. I believe we can do better.



I think the greatest possibilities of our country, our dreams and our hopes, are out there just waiting for us to grab onto them. And I ask you to embark on that journey with me.



I ask you for your trust. I ask you for your help. I ask you to allow me the privilege of leading this great nation of ours, of helping us to be stronger here at home and to be respected again in the world and, most of all, to be safer forever.



Thank you. Goodnight. And God bless the United States of America.



SCHIEFFER: Mr. President?



BUSH: In the Oval Office, there's a painting by a friend of Laura and mine named -- by Tom Lee. And it's a West Texas painting, a painting of a mountain scene.



And he said this about it.



He said, "Sara and I live on the east side of the mountain. It's the sunrise side, not the sunset side. It's the side to see the day that is coming, not to see the day that is gone."



I love the optimism in that painting, because that's how I feel about America. And we've been through a lot together during the last 3 3/4 years. We've come through a recession, a stock market decline, an attack on our country.



And yet, because of the hard work of the American people and good policies, this economy is growing. Over the next four years, we'll make sure the economy continues to grow.



We reformed our school system, and now there's an achievement gap in America that's beginning to close. Over the next four years, we'll continue to insist on excellence in every classroom in America so that our children have a chance to realize the great promise of America.



Over the next four years, we'll continue to work to make sure health care is available and affordable.



Over the next four years, we'll continue to rally the armies of compassion, to help heal the hurt that exists in some of our country's neighborhoods.



I'm optimistic that we'll win the war on terror, but I understand it requires firm resolve and clear purpose. We must never waver in the face of this enemy that -- these ideologues of hate.



And as we pursue the enemy wherever it exists, we'll also spread freedom and liberty. We got great faith in the ability of liberty to transform societies, to convert a hostile world to a peaceful world.



My hope for America is a prosperous America, a hopeful America and a safer world.



I want to thank you for listening tonight.



I'm asking for your vote.



God bless you.



SCHIEFFER: Thank you, Mr. President.



Thank you, Senator Kerry.



Well, that brings these debates to a close, but the campaign goes on.



I want to wish both of you the very best of luck between now and Election Day.



That's it for us from Arizona State University in Tempe, Arizona. I'm Bob Schieffer at CBS News.



Goodnight, everyone
Jamie D
2006-09-14 15:55:52 UTC
yes they do thanks
Dragonfly :)
2006-09-14 15:55:39 UTC
duh yah...


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...